1/* 2 * sys-linux.c - System-dependent procedures for setting up 3 * PPP interfaces on Linux systems 4 * 5 * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. The name(s) of the authors of this software must not be used to 15 * endorse or promote products derived from this software without 16 * prior written permission. 17 * 18 * 3. Redistributions of any form whatsoever must retain the following 19 * acknowledgment: 20 * "This product includes software developed by Paul Mackerras 21 * <paulus@samba.org>". 22 * 23 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 24 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 25 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 26 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 28 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 29 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 30 * 31 * Derived from main.c and pppd.h, which are: 32 * 33 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in 44 * the documentation and/or other materials provided with the 45 * distribution. 46 * 47 * 3. The name "Carnegie Mellon University" must not be used to 48 * endorse or promote products derived from this software without 49 * prior written permission. For permission or any legal 50 * details, please contact 51 * Office of Technology Transfer 52 * Carnegie Mellon University 53 * 5000 Forbes Avenue 54 * Pittsburgh, PA 15213-3890 55 * (412) 268-4387, fax: (412) 268-7395 56 * tech-transfer@andrew.cmu.edu 57 * 58 * 4. Redistributions of any form whatsoever must retain the following 59 * acknowledgment: 60 * "This product includes software developed by Computing Services 61 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 62 * 63 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 64 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 65 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 66 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 67 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 68 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 69 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 70 */ 71 72#include <sys/ioctl.h> 73#include <sys/types.h> 74#include <sys/socket.h> 75#include <sys/time.h> 76#include <sys/errno.h> 77#include <sys/file.h> 78#include <sys/stat.h> 79#include <sys/utsname.h> 80#include <sys/sysmacros.h> 81 82#include <stdio.h> 83#include <stdlib.h> 84#include <syslog.h> 85#include <string.h> 86#include <time.h> 87#include <memory.h> 88#include <utmp.h> 89#include <mntent.h> 90#include <signal.h> 91#include <fcntl.h> 92#include <ctype.h> 93#include <termios.h> 94#include <unistd.h> 95 96/* This is in netdevice.h. However, this compile will fail miserably if 97 you attempt to include netdevice.h because it has so many references 98 to __memcpy functions which it should not attempt to do. So, since I 99 really don't use it, but it must be defined, define it now. */ 100 101#ifndef MAX_ADDR_LEN 102#define MAX_ADDR_LEN 7 103#endif 104 105#if __GLIBC__ >= 2 106#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */ 107#include <net/if.h> 108#include <net/if_arp.h> 109#include <net/route.h> 110#include <netinet/if_ether.h> 111#else 112#include <linux/types.h> 113#include <linux/if.h> 114#include <linux/if_arp.h> 115#include <linux/route.h> 116#include <linux/if_ether.h> 117#endif 118#include <netinet/in.h> 119#include <arpa/inet.h> 120 121#include <linux/ppp_defs.h> 122#include <linux/if_ppp.h> 123 124#include "pppd.h" 125#include "fsm.h" 126#include "ipcp.h" 127 128#ifdef IPX_CHANGE 129#include "ipxcp.h" 130#if __GLIBC__ >= 2 && \ 131 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0) 132#include <netipx/ipx.h> 133#else 134#include <linux/ipx.h> 135#endif 136#endif /* IPX_CHANGE */ 137 138#ifdef PPP_FILTER 139#include <pcap-bpf.h> 140#include <linux/filter.h> 141#endif /* PPP_FILTER */ 142 143#ifdef LOCKLIB 144#include <sys/locks.h> 145#endif 146 147#ifdef INET6 148#if !defined(_LINUX_IN6_H) && !defined(_UAPI_LINUX_IN6_H) 149/* 150 * This is in linux/include/net/ipv6.h. 151 */ 152 153struct in6_ifreq { 154 struct in6_addr ifr6_addr; 155 __u32 ifr6_prefixlen; 156 unsigned int ifr6_ifindex; 157}; 158#endif 159 160#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \ 161 memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \ 162 sin6.s6_addr16[0] = htons(0xfe80); \ 163 eui64_copy(eui64, sin6.s6_addr32[2]); \ 164 } while (0) 165 166#if defined(__ANDROID__) 167#include <net/route.h> 168#endif 169 170#endif /* INET6 */ 171 172/* We can get an EIO error on an ioctl if the modem has hung up */ 173#define ok_error(num) ((num)==EIO) 174 175static int tty_disc = N_TTY; /* The TTY discipline */ 176static int ppp_disc = N_PPP; /* The PPP discpline */ 177static int initfdflags = -1; /* Initial file descriptor flags for fd */ 178static int ppp_fd = -1; /* fd which is set to PPP discipline */ 179static int sock_fd = -1; /* socket for doing interface ioctls */ 180static int slave_fd = -1; /* pty for old-style demand mode, slave */ 181static int master_fd = -1; /* pty for old-style demand mode, master */ 182#ifdef INET6 183static int sock6_fd = -1; 184#endif /* INET6 */ 185 186/* 187 * For the old-style kernel driver, this is the same as ppp_fd. 188 * For the new-style driver, it is the fd of an instance of /dev/ppp 189 * which is attached to the ppp unit and is used for controlling it. 190 */ 191int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */ 192 193static int chindex; /* channel index (new style driver) */ 194 195static fd_set in_fds; /* set of fds that wait_input waits for */ 196static int max_in_fd; /* highest fd set in in_fds */ 197 198static int has_proxy_arp = 0; 199static int driver_version = 0; 200static int driver_modification = 0; 201static int driver_patch = 0; 202static int driver_is_old = 0; 203static int restore_term = 0; /* 1 => we've munged the terminal */ 204static struct termios inittermios; /* Initial TTY termios */ 205 206int new_style_driver = 0; 207 208static char loop_name[20]; 209static unsigned char inbuf[512]; /* buffer for chars read from loopback */ 210 211static int if_is_up; /* Interface has been marked up */ 212static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */ 213static int have_default_route; /* Gateway for default route added */ 214static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ 215static char proxy_arp_dev[16]; /* Device for proxy arp entry */ 216static u_int32_t our_old_addr; /* for detecting address changes */ 217static int dynaddr_set; /* 1 if ip_dynaddr set */ 218static int looped; /* 1 if using loop */ 219static int link_mtu; /* mtu for the link (not bundle) */ 220 221static struct utsname utsname; /* for the kernel version */ 222static int kernel_version; 223#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p)) 224 225#define MAX_IFS 100 226 227#define FLAGS_GOOD (IFF_UP | IFF_BROADCAST) 228#define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \ 229 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP) 230 231#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr) 232 233/* Prototypes for procedures local to this file. */ 234static int modify_flags(int fd, int clear_bits, int set_bits); 235static int translate_speed (int bps); 236static int baud_rate_of (int speed); 237static void close_route_table (void); 238static int open_route_table (void); 239static int read_route_table (struct rtentry *rt); 240static int defaultroute_exists (struct rtentry *rt); 241static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, 242 char *name, int namelen); 243static void decode_version (char *buf, int *version, int *mod, int *patch); 244static int set_kdebugflag(int level); 245static int ppp_registered(void); 246static int make_ppp_unit(void); 247static int setifstate (int u, int state); 248 249extern u_char inpacket_buf[]; /* borrowed from main.c */ 250 251/* 252 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, 253 * if it exists. 254 */ 255 256#define SET_SA_FAMILY(addr, family) \ 257 memset ((char *) &(addr), '\0', sizeof(addr)); \ 258 addr.sa_family = (family); 259 260/* 261 * Determine if the PPP connection should still be present. 262 */ 263 264extern int hungup; 265 266/* new_fd is the fd of a tty */ 267static void set_ppp_fd (int new_fd) 268{ 269 ppp_fd = new_fd; 270 if (!new_style_driver) 271 ppp_dev_fd = new_fd; 272} 273 274static int still_ppp(void) 275{ 276 if (new_style_driver) 277 return !hungup && ppp_fd >= 0; 278 if (!hungup || ppp_fd == slave_fd) 279 return 1; 280 if (slave_fd >= 0) { 281 set_ppp_fd(slave_fd); 282 return 1; 283 } 284 return 0; 285} 286 287/* 288 * modify_flags - set and clear flag bits controlling the kernel 289 * PPP driver. 290 */ 291static int modify_flags(int fd, int clear_bits, int set_bits) 292{ 293 int flags; 294 295 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1) 296 goto err; 297 flags = (flags & ~clear_bits) | set_bits; 298 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1) 299 goto err; 300 301 return 0; 302 303 err: 304 if (errno != EIO) 305 error("Failed to set PPP kernel option flags: %m"); 306 return -1; 307} 308 309/******************************************************************** 310 * 311 * sys_init - System-dependent initialization. 312 */ 313 314void sys_init(void) 315{ 316 /* Get an internet socket for doing socket ioctls. */ 317 sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 318 if (sock_fd < 0) 319 fatal("Couldn't create IP socket: %m(%d)", errno); 320 321#ifdef INET6 322 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0); 323 if (sock6_fd < 0) 324 sock6_fd = -errno; /* save errno for later */ 325#endif 326 327 FD_ZERO(&in_fds); 328 max_in_fd = 0; 329} 330 331/******************************************************************** 332 * 333 * sys_cleanup - restore any system state we modified before exiting: 334 * mark the interface down, delete default route and/or proxy arp entry. 335 * This shouldn't call die() because it's called from die(). 336 */ 337 338void sys_cleanup(void) 339{ 340/* 341 * Take down the device 342 */ 343 if (if_is_up) { 344 if_is_up = 0; 345 sifdown(0); 346 } 347 if (if6_is_up) 348 sif6down(0); 349 350/* 351 * Delete any routes through the device. 352 */ 353 if (have_default_route) 354 cifdefaultroute(0, 0, 0); 355 356 if (has_proxy_arp) 357 cifproxyarp(0, proxy_arp_addr); 358} 359 360/******************************************************************** 361 * 362 * sys_close - Clean up in a child process before execing. 363 */ 364void 365sys_close(void) 366{ 367 if (new_style_driver && ppp_dev_fd >= 0) 368 close(ppp_dev_fd); 369 if (sock_fd >= 0) 370 close(sock_fd); 371#ifdef INET6 372 if (sock6_fd >= 0) 373 close(sock6_fd); 374#endif 375 if (slave_fd >= 0) 376 close(slave_fd); 377 if (master_fd >= 0) 378 close(master_fd); 379} 380 381/******************************************************************** 382 * 383 * set_kdebugflag - Define the debugging level for the kernel 384 */ 385 386static int set_kdebugflag (int requested_level) 387{ 388 if (ppp_dev_fd < 0) 389 return 1; 390 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) { 391 if ( ! ok_error (errno) ) 392 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__); 393 return (0); 394 } 395 return (1); 396} 397 398/******************************************************************** 399 * 400 * tty_establish_ppp - Turn the serial port into a ppp interface. 401 */ 402 403int tty_establish_ppp (int tty_fd) 404{ 405 int ret_fd; 406 407/* 408 * Ensure that the tty device is in exclusive mode. 409 */ 410 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) { 411 if ( ! ok_error ( errno )) 412 warn("Couldn't make tty exclusive: %m"); 413 } 414/* 415 * Demand mode - prime the old ppp device to relinquish the unit. 416 */ 417 if (!new_style_driver && looped 418 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) { 419 error("ioctl(transfer ppp unit): %m, line %d", __LINE__); 420 return -1; 421 } 422/* 423 * Set the current tty to the PPP discpline 424 */ 425 426#ifndef N_SYNC_PPP 427#define N_SYNC_PPP 14 428#endif 429 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP; 430 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) { 431 if ( ! ok_error (errno) ) { 432 error("Couldn't set tty to PPP discipline: %m"); 433 return -1; 434 } 435 } 436 437 ret_fd = generic_establish_ppp(tty_fd); 438 439#define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP) 440#define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \ 441 | SC_LOG_FLUSH) 442 443 if (ret_fd >= 0) { 444 modify_flags(ppp_fd, SC_RCVB | SC_LOGB, 445 (kdebugflag * SC_DEBUG) & SC_LOGB); 446 } else { 447 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno)) 448 warn("Couldn't reset tty to normal line discipline: %m"); 449 } 450 451 return ret_fd; 452} 453 454/******************************************************************** 455 * 456 * generic_establish_ppp - Turn the fd into a ppp interface. 457 */ 458int generic_establish_ppp (int fd) 459{ 460 int x; 461 462 if (new_style_driver) { 463 int flags; 464 465 /* Open an instance of /dev/ppp and connect the channel to it */ 466 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) { 467 error("Couldn't get channel number: %m"); 468 goto err; 469 } 470 dbglog("using channel %d", chindex); 471 fd = open("/dev/ppp", O_RDWR); 472 if (fd < 0) { 473 error("Couldn't reopen /dev/ppp: %m"); 474 goto err; 475 } 476 (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 477 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) { 478 error("Couldn't attach to channel %d: %m", chindex); 479 goto err_close; 480 } 481 flags = fcntl(fd, F_GETFL); 482 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) 483 warn("Couldn't set /dev/ppp (channel) to nonblock: %m"); 484 set_ppp_fd(fd); 485 486 if (!looped) 487 ifunit = -1; 488 if (!looped && !multilink) { 489 /* 490 * Create a new PPP unit. 491 */ 492 if (make_ppp_unit() < 0) 493 goto err_close; 494 } 495 496 if (looped) 497 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0); 498 499 if (!multilink) { 500 add_fd(ppp_dev_fd); 501 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) { 502 error("Couldn't attach to PPP unit %d: %m", ifunit); 503 goto err_close; 504 } 505 } 506 507 } else { 508 /* 509 * Old-style driver: find out which interface we were given. 510 */ 511 set_ppp_fd (fd); 512 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) { 513 if (ok_error (errno)) 514 goto err; 515 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__); 516 } 517 /* Check that we got the same unit again. */ 518 if (looped && x != ifunit) 519 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x); 520 ifunit = x; 521 522 /* 523 * Fetch the initial file flags and reset blocking mode on the file. 524 */ 525 initfdflags = fcntl(fd, F_GETFL); 526 if (initfdflags == -1 || 527 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { 528 if ( ! ok_error (errno)) 529 warn("Couldn't set device to non-blocking mode: %m"); 530 } 531 } 532 533 /* 534 * Enable debug in the driver if requested. 535 */ 536 if (!looped) 537 set_kdebugflag (kdebugflag); 538 539 looped = 0; 540 541 return ppp_fd; 542 543 err_close: 544 close(fd); 545 err: 546 return -1; 547} 548 549/******************************************************************** 550 * 551 * tty_disestablish_ppp - Restore the serial port to normal operation. 552 * This shouldn't call die() because it's called from die(). 553 */ 554 555void tty_disestablish_ppp(int tty_fd) 556{ 557 if (!hungup) { 558/* 559 * Flush the tty output buffer so that the TIOCSETD doesn't hang. 560 */ 561 if (tcflush(tty_fd, TCIOFLUSH) < 0) 562 { 563 warn("tcflush failed: %m"); 564 goto flushfailed; 565 } 566/* 567 * Restore the previous line discipline 568 */ 569 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) { 570 if ( ! ok_error (errno)) 571 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__); 572 } 573 574 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) { 575 if ( ! ok_error (errno)) 576 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__); 577 } 578 579 /* Reset non-blocking mode on fd. */ 580 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) { 581 if ( ! ok_error (errno)) 582 warn("Couldn't restore device fd flags: %m"); 583 } 584 } 585flushfailed: 586 initfdflags = -1; 587 588 generic_disestablish_ppp(tty_fd); 589} 590 591/******************************************************************** 592 * 593 * generic_disestablish_ppp - Restore device components to normal 594 * operation, and reconnect the ppp unit to the loopback if in demand 595 * mode. This shouldn't call die() because it's called from die(). 596 */ 597void generic_disestablish_ppp(int dev_fd) 598{ 599 if (new_style_driver) { 600 close(ppp_fd); 601 ppp_fd = -1; 602 if (demand) { 603 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC); 604 looped = 1; 605 } else if (!doing_multilink && ppp_dev_fd >= 0) { 606 close(ppp_dev_fd); 607 remove_fd(ppp_dev_fd); 608 ppp_dev_fd = -1; 609 } 610 } else { 611 /* old-style driver */ 612 if (demand) 613 set_ppp_fd(slave_fd); 614 else 615 ppp_dev_fd = -1; 616 } 617} 618 619/* 620 * make_ppp_unit - make a new ppp unit for ppp_dev_fd. 621 * Assumes new_style_driver. 622 */ 623static int make_ppp_unit() 624{ 625 int x, flags; 626 627 if (ppp_dev_fd >= 0) { 628 dbglog("in make_ppp_unit, already had /dev/ppp open?"); 629 close(ppp_dev_fd); 630 } 631 ppp_dev_fd = open("/dev/ppp", O_RDWR); 632 if (ppp_dev_fd < 0) 633 fatal("Couldn't open /dev/ppp: %m"); 634 flags = fcntl(ppp_dev_fd, F_GETFL); 635 if (flags == -1 636 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) 637 warn("Couldn't set /dev/ppp to nonblock: %m"); 638 639 ifunit = req_unit; 640 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); 641 if (x < 0 && req_unit >= 0 && errno == EEXIST) { 642 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit); 643 ifunit = -1; 644 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); 645 } 646 if (x < 0) 647 error("Couldn't create new ppp unit: %m"); 648 return x; 649} 650 651/* 652 * cfg_bundle - configure the existing bundle. 653 * Used in demand mode. 654 */ 655void cfg_bundle(int mrru, int mtru, int rssn, int tssn) 656{ 657 if (!new_style_driver) 658 return; 659 660 /* set the mrru, mtu and flags */ 661 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0) 662 error("Couldn't set MRRU: %m"); 663 664 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK, 665 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0) 666 | (mrru? SC_MULTILINK: 0))); 667 668 /* connect up the channel */ 669 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0) 670 fatal("Couldn't attach to PPP unit %d: %m", ifunit); 671 add_fd(ppp_dev_fd); 672} 673 674/* 675 * make_new_bundle - create a new PPP unit (i.e. a bundle) 676 * and connect our channel to it. This should only get called 677 * if `multilink' was set at the time establish_ppp was called. 678 * In demand mode this uses our existing bundle instead of making 679 * a new one. 680 */ 681void make_new_bundle(int mrru, int mtru, int rssn, int tssn) 682{ 683 if (!new_style_driver) 684 return; 685 686 /* make us a ppp unit */ 687 if (make_ppp_unit() < 0) 688 die(1); 689 690 /* set the mrru and flags */ 691 cfg_bundle(mrru, mtru, rssn, tssn); 692} 693 694/* 695 * bundle_attach - attach our link to a given PPP unit. 696 * We assume the unit is controlled by another pppd. 697 */ 698int bundle_attach(int ifnum) 699{ 700 int master_fd; 701 702 if (!new_style_driver) 703 return -1; 704 705 master_fd = open("/dev/ppp", O_RDWR); 706 if (master_fd < 0) 707 fatal("Couldn't open /dev/ppp: %m"); 708 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) { 709 if (errno == ENXIO) { 710 close(master_fd); 711 return 0; /* doesn't still exist */ 712 } 713 fatal("Couldn't attach to interface unit %d: %m\n", ifnum); 714 } 715 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0) 716 fatal("Couldn't connect to interface unit %d: %m", ifnum); 717 modify_flags(master_fd, 0, SC_MULTILINK); 718 close(master_fd); 719 720 ifunit = ifnum; 721 return 1; 722} 723 724/* 725 * destroy_bundle - tell the driver to destroy our bundle. 726 */ 727void destroy_bundle(void) 728{ 729 if (ppp_dev_fd >= 0) { 730 close(ppp_dev_fd); 731 remove_fd(ppp_dev_fd); 732 ppp_dev_fd = -1; 733 } 734} 735 736/******************************************************************** 737 * 738 * clean_check - Fetch the flags for the device and generate 739 * appropriate error messages. 740 */ 741void clean_check(void) 742{ 743 int x; 744 char *s; 745 746 if (still_ppp()) { 747 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { 748 s = NULL; 749 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { 750 case SC_RCV_B7_0: 751 s = "all had bit 7 set to 1"; 752 break; 753 754 case SC_RCV_B7_1: 755 s = "all had bit 7 set to 0"; 756 break; 757 758 case SC_RCV_EVNP: 759 s = "all had odd parity"; 760 break; 761 762 case SC_RCV_ODDP: 763 s = "all had even parity"; 764 break; 765 } 766 767 if (s != NULL) { 768 warn("Receive serial link is not 8-bit clean:"); 769 warn("Problem: %s", s); 770 } 771 } 772 } 773} 774 775 776/* 777 * List of valid speeds. 778 */ 779 780struct speed { 781 int speed_int, speed_val; 782} speeds[] = { 783#ifdef B50 784 { 50, B50 }, 785#endif 786#ifdef B75 787 { 75, B75 }, 788#endif 789#ifdef B110 790 { 110, B110 }, 791#endif 792#ifdef B134 793 { 134, B134 }, 794#endif 795#ifdef B150 796 { 150, B150 }, 797#endif 798#ifdef B200 799 { 200, B200 }, 800#endif 801#ifdef B300 802 { 300, B300 }, 803#endif 804#ifdef B600 805 { 600, B600 }, 806#endif 807#ifdef B1200 808 { 1200, B1200 }, 809#endif 810#ifdef B1800 811 { 1800, B1800 }, 812#endif 813#ifdef B2000 814 { 2000, B2000 }, 815#endif 816#ifdef B2400 817 { 2400, B2400 }, 818#endif 819#ifdef B3600 820 { 3600, B3600 }, 821#endif 822#ifdef B4800 823 { 4800, B4800 }, 824#endif 825#ifdef B7200 826 { 7200, B7200 }, 827#endif 828#ifdef B9600 829 { 9600, B9600 }, 830#endif 831#ifdef B19200 832 { 19200, B19200 }, 833#endif 834#ifdef B38400 835 { 38400, B38400 }, 836#endif 837#ifdef B57600 838 { 57600, B57600 }, 839#endif 840#ifdef B76800 841 { 76800, B76800 }, 842#endif 843#ifdef B115200 844 { 115200, B115200 }, 845#endif 846#ifdef EXTA 847 { 19200, EXTA }, 848#endif 849#ifdef EXTB 850 { 38400, EXTB }, 851#endif 852#ifdef B230400 853 { 230400, B230400 }, 854#endif 855#ifdef B460800 856 { 460800, B460800 }, 857#endif 858#ifdef B921600 859 { 921600, B921600 }, 860#endif 861#ifdef B1000000 862 { 1000000, B1000000 }, 863#endif 864#ifdef B1152000 865 { 1152000, B1152000 }, 866#endif 867#ifdef B1500000 868 { 1500000, B1500000 }, 869#endif 870#ifdef B2000000 871 { 2000000, B2000000 }, 872#endif 873#ifdef B2500000 874 { 2500000, B2500000 }, 875#endif 876#ifdef B3000000 877 { 3000000, B3000000 }, 878#endif 879#ifdef B3500000 880 { 3500000, B3500000 }, 881#endif 882#ifdef B4000000 883 { 4000000, B4000000 }, 884#endif 885 { 0, 0 } 886}; 887 888/******************************************************************** 889 * 890 * Translate from bits/second to a speed_t. 891 */ 892 893static int translate_speed (int bps) 894{ 895 struct speed *speedp; 896 897 if (bps != 0) { 898 for (speedp = speeds; speedp->speed_int; speedp++) { 899 if (bps == speedp->speed_int) 900 return speedp->speed_val; 901 } 902 warn("speed %d not supported", bps); 903 } 904 return 0; 905} 906 907/******************************************************************** 908 * 909 * Translate from a speed_t to bits/second. 910 */ 911 912static int baud_rate_of (int speed) 913{ 914 struct speed *speedp; 915 916 if (speed != 0) { 917 for (speedp = speeds; speedp->speed_int; speedp++) { 918 if (speed == speedp->speed_val) 919 return speedp->speed_int; 920 } 921 } 922 return 0; 923} 924 925/******************************************************************** 926 * 927 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, 928 * at the requested speed, etc. If `local' is true, set CLOCAL 929 * regardless of whether the modem option was specified. 930 */ 931 932void set_up_tty(int tty_fd, int local) 933{ 934 int speed; 935 struct termios tios; 936 937 setdtr(tty_fd, 1); 938 if (tcgetattr(tty_fd, &tios) < 0) { 939 if (!ok_error(errno)) 940 fatal("tcgetattr: %m (line %d)", __LINE__); 941 return; 942 } 943 944 if (!restore_term) 945 inittermios = tios; 946 947 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); 948 tios.c_cflag |= CS8 | CREAD | HUPCL; 949 950 tios.c_iflag = IGNBRK | IGNPAR; 951 tios.c_oflag = 0; 952 tios.c_lflag = 0; 953 tios.c_cc[VMIN] = 1; 954 tios.c_cc[VTIME] = 0; 955 956 if (local || !modem) 957 tios.c_cflag ^= (CLOCAL | HUPCL); 958 959 switch (crtscts) { 960 case 1: 961 tios.c_cflag |= CRTSCTS; 962 break; 963 964 case -2: 965 tios.c_iflag |= IXON | IXOFF; 966 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ 967 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ 968 break; 969 970 case -1: 971 tios.c_cflag &= ~CRTSCTS; 972 break; 973 974 default: 975 break; 976 } 977 978 if (stop_bits >= 2) 979 tios.c_cflag |= CSTOPB; 980 981 speed = translate_speed(inspeed); 982 if (speed) { 983 cfsetospeed (&tios, speed); 984 cfsetispeed (&tios, speed); 985 } 986/* 987 * We can't proceed if the serial port speed is B0, 988 * since that implies that the serial port is disabled. 989 */ 990 else { 991 speed = cfgetospeed(&tios); 992 if (speed == B0) 993 fatal("Baud rate for %s is 0; need explicit baud rate", devnam); 994 } 995 996 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno)) 997 if (errno != EINTR) 998 fatal("tcsetattr: %m (line %d)", __LINE__); 999 1000 baud_rate = baud_rate_of(speed); 1001 restore_term = 1; 1002} 1003 1004/******************************************************************** 1005 * 1006 * setdtr - control the DTR line on the serial port. 1007 * This is called from die(), so it shouldn't call die(). 1008 */ 1009 1010void setdtr (int tty_fd, int on) 1011{ 1012 int modembits = TIOCM_DTR; 1013 1014 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits); 1015} 1016 1017/******************************************************************** 1018 * 1019 * restore_tty - restore the terminal to the saved settings. 1020 */ 1021 1022void restore_tty (int tty_fd) 1023{ 1024 if (restore_term) { 1025 restore_term = 0; 1026/* 1027 * Turn off echoing, because otherwise we can get into 1028 * a loop with the tty and the modem echoing to each other. 1029 * We presume we are the sole user of this tty device, so 1030 * when we close it, it will revert to its defaults anyway. 1031 */ 1032 if (!default_device) 1033 inittermios.c_lflag &= ~(ECHO | ECHONL); 1034 1035 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) { 1036 if (! ok_error (errno)) 1037 warn("tcsetattr: %m (line %d)", __LINE__); 1038 } 1039 } 1040} 1041 1042/******************************************************************** 1043 * 1044 * output - Output PPP packet. 1045 */ 1046 1047void output (int unit, unsigned char *p, int len) 1048{ 1049 int fd = ppp_fd; 1050 int proto; 1051 1052 dump_packet("sent", p, len); 1053 if (snoop_send_hook) snoop_send_hook(p, len); 1054 1055 if (len < PPP_HDRLEN) 1056 return; 1057 if (new_style_driver) { 1058 p += 2; 1059 len -= 2; 1060 proto = (p[0] << 8) + p[1]; 1061 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG)) 1062 fd = ppp_dev_fd; 1063 } 1064 if (write(fd, p, len) < 0) { 1065 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS 1066 || errno == ENXIO || errno == EIO || errno == EINTR) 1067 warn("write: warning: %m (%d)", errno); 1068 else 1069 error("write: %m (%d)", errno); 1070 } 1071} 1072 1073/******************************************************************** 1074 * 1075 * wait_input - wait until there is data available, 1076 * for the length of time specified by *timo (indefinite 1077 * if timo is NULL). 1078 */ 1079 1080void wait_input(struct timeval *timo) 1081{ 1082 fd_set ready, exc; 1083 int n; 1084 1085 ready = in_fds; 1086 exc = in_fds; 1087 n = select(max_in_fd + 1, &ready, NULL, &exc, timo); 1088 if (n < 0 && errno != EINTR) 1089 fatal("select: %m"); 1090} 1091 1092/* 1093 * add_fd - add an fd to the set that wait_input waits for. 1094 */ 1095void add_fd(int fd) 1096{ 1097 if (fd >= FD_SETSIZE) 1098 fatal("internal error: file descriptor too large (%d)", fd); 1099 FD_SET(fd, &in_fds); 1100 if (fd > max_in_fd) 1101 max_in_fd = fd; 1102} 1103 1104/* 1105 * remove_fd - remove an fd from the set that wait_input waits for. 1106 */ 1107void remove_fd(int fd) 1108{ 1109 FD_CLR(fd, &in_fds); 1110} 1111 1112 1113/******************************************************************** 1114 * 1115 * read_packet - get a PPP packet from the serial device. 1116 */ 1117 1118int read_packet (unsigned char *buf) 1119{ 1120 int len, nr; 1121 1122 len = PPP_MRU + PPP_HDRLEN; 1123 if (new_style_driver) { 1124 *buf++ = PPP_ALLSTATIONS; 1125 *buf++ = PPP_UI; 1126 len -= 2; 1127 } 1128 nr = -1; 1129 1130 if (ppp_fd >= 0) { 1131 nr = read(ppp_fd, buf, len); 1132 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN 1133 && errno != EIO && errno != EINTR) 1134 error("read: %m"); 1135 if (nr < 0 && errno == ENXIO) 1136 return 0; 1137 } 1138 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) { 1139 /* N.B. we read ppp_fd first since LCP packets come in there. */ 1140 nr = read(ppp_dev_fd, buf, len); 1141 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN 1142 && errno != EIO && errno != EINTR) 1143 error("read /dev/ppp: %m"); 1144 if (nr < 0 && errno == ENXIO) 1145 nr = 0; 1146 if (nr == 0 && doing_multilink) { 1147 remove_fd(ppp_dev_fd); 1148 bundle_eof = 1; 1149 } 1150 } 1151 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0) 1152 nr = 0; 1153 return (new_style_driver && nr > 0)? nr+2: nr; 1154} 1155 1156/******************************************************************** 1157 * 1158 * get_loop_output - get outgoing packets from the ppp device, 1159 * and detect when we want to bring the real link up. 1160 * Return value is 1 if we need to bring up the link, 0 otherwise. 1161 */ 1162int 1163get_loop_output(void) 1164{ 1165 int rv = 0; 1166 int n; 1167 1168 if (new_style_driver) { 1169 while ((n = read_packet(inpacket_buf)) > 0) 1170 if (loop_frame(inpacket_buf, n)) 1171 rv = 1; 1172 return rv; 1173 } 1174 1175 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0) 1176 if (loop_chars(inbuf, n)) 1177 rv = 1; 1178 1179 if (n == 0) 1180 fatal("eof on loopback"); 1181 1182 if (errno != EWOULDBLOCK && errno != EAGAIN) 1183 fatal("read from loopback: %m(%d)", errno); 1184 1185 return rv; 1186} 1187 1188/* 1189 * netif_set_mtu - set the MTU on the PPP network interface. 1190 */ 1191void 1192netif_set_mtu(int unit, int mtu) 1193{ 1194 struct ifreq ifr; 1195 1196 memset (&ifr, '\0', sizeof (ifr)); 1197 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); 1198 ifr.ifr_mtu = mtu; 1199 1200 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) 1201 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__); 1202} 1203 1204/* 1205 * netif_get_mtu - get the MTU on the PPP network interface. 1206 */ 1207int 1208netif_get_mtu(int unit) 1209{ 1210 struct ifreq ifr; 1211 1212 memset (&ifr, '\0', sizeof (ifr)); 1213 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); 1214 1215 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) { 1216 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__); 1217 return 0; 1218 } 1219 return ifr.ifr_mtu; 1220} 1221 1222/******************************************************************** 1223 * 1224 * tty_send_config - configure the transmit characteristics of 1225 * the ppp interface. 1226 */ 1227 1228void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp) 1229{ 1230 int x; 1231 1232 if (!still_ppp()) 1233 return; 1234 link_mtu = mtu; 1235 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { 1236 if (errno != EIO && errno != ENOTTY) 1237 error("Couldn't set transmit async character map: %m"); 1238 ++error_count; 1239 return; 1240 } 1241 1242 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0) 1243 | (sync_serial? SC_SYNC: 0); 1244 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x); 1245} 1246 1247/******************************************************************** 1248 * 1249 * tty_set_xaccm - set the extended transmit ACCM for the interface. 1250 */ 1251 1252void tty_set_xaccm (ext_accm accm) 1253{ 1254 if (!still_ppp()) 1255 return; 1256 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) { 1257 if ( ! ok_error (errno)) 1258 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__); 1259 } 1260} 1261 1262/******************************************************************** 1263 * 1264 * tty_recv_config - configure the receive-side characteristics of 1265 * the ppp interface. 1266 */ 1267 1268void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp) 1269{ 1270/* 1271 * If we were called because the link has gone down then there is nothing 1272 * which may be done. Just return without incident. 1273 */ 1274 if (!still_ppp()) 1275 return; 1276/* 1277 * Set the receiver parameters 1278 */ 1279 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { 1280 if (errno != EIO && errno != ENOTTY) 1281 error("Couldn't set channel receive MRU: %m"); 1282 } 1283 if (new_style_driver && ppp_dev_fd >= 0 1284 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) 1285 error("Couldn't set MRU in generic PPP layer: %m"); 1286 1287 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { 1288 if (errno != EIO && errno != ENOTTY) 1289 error("Couldn't set channel receive asyncmap: %m"); 1290 } 1291} 1292 1293/******************************************************************** 1294 * 1295 * ccp_test - ask kernel whether a given compression method 1296 * is acceptable for use. 1297 */ 1298 1299int 1300ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit) 1301{ 1302 struct ppp_option_data data; 1303 1304 memset (&data, '\0', sizeof (data)); 1305 data.ptr = opt_ptr; 1306 data.length = opt_len; 1307 data.transmit = for_transmit; 1308 1309 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0) 1310 return 1; 1311 1312 return (errno == ENOBUFS)? 0: -1; 1313} 1314 1315/******************************************************************** 1316 * 1317 * ccp_flags_set - inform kernel about the current state of CCP. 1318 */ 1319 1320void ccp_flags_set (int unit, int isopen, int isup) 1321{ 1322 int x; 1323 1324 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0); 1325 if (still_ppp() && ppp_dev_fd >= 0) 1326 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x); 1327} 1328 1329#ifdef PPP_FILTER 1330/* 1331 * set_filters - set the active and pass filters in the kernel driver. 1332 */ 1333int set_filters(struct bpf_program *pass, struct bpf_program *active) 1334{ 1335 struct sock_fprog fp; 1336 1337 fp.len = pass->bf_len; 1338 fp.filter = (struct sock_filter *) pass->bf_insns; 1339 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) { 1340 if (errno == ENOTTY) 1341 warn("kernel does not support PPP filtering"); 1342 else 1343 error("Couldn't set pass-filter in kernel: %m"); 1344 return 0; 1345 } 1346 fp.len = active->bf_len; 1347 fp.filter = (struct sock_filter *) active->bf_insns; 1348 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) { 1349 error("Couldn't set active-filter in kernel: %m"); 1350 return 0; 1351 } 1352 return 1; 1353} 1354#endif /* PPP_FILTER */ 1355 1356/******************************************************************** 1357 * 1358 * get_idle_time - return how long the link has been idle. 1359 */ 1360int 1361get_idle_time(u, ip) 1362 int u; 1363 struct ppp_idle *ip; 1364{ 1365 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0; 1366} 1367 1368/******************************************************************** 1369 * 1370 * get_ppp_stats - return statistics for the link. 1371 */ 1372int 1373get_ppp_stats(u, stats) 1374 int u; 1375 struct pppd_stats *stats; 1376{ 1377 struct ifpppstatsreq req; 1378 1379 memset (&req, 0, sizeof (req)); 1380 1381 req.stats_ptr = (caddr_t) &req.stats; 1382 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name)); 1383 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) { 1384 error("Couldn't get PPP statistics: %m"); 1385 return 0; 1386 } 1387 stats->bytes_in = req.stats.p.ppp_ibytes; 1388 stats->bytes_out = req.stats.p.ppp_obytes; 1389 stats->pkts_in = req.stats.p.ppp_ipackets; 1390 stats->pkts_out = req.stats.p.ppp_opackets; 1391 return 1; 1392} 1393 1394/******************************************************************** 1395 * 1396 * ccp_fatal_error - returns 1 if decompression was disabled as a 1397 * result of an error detected after decompression of a packet, 1398 * 0 otherwise. This is necessary because of patent nonsense. 1399 */ 1400 1401int ccp_fatal_error (int unit) 1402{ 1403 int flags; 1404 1405 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) { 1406 error("Couldn't read compression error flags: %m"); 1407 flags = 0; 1408 } 1409 return flags & SC_DC_FERROR; 1410} 1411 1412/******************************************************************** 1413 * 1414 * path_to_procfs - find the path to the proc file system mount point 1415 */ 1416static char proc_path[MAXPATHLEN]; 1417static int proc_path_len; 1418 1419static char *path_to_procfs(const char *tail) 1420{ 1421 struct mntent *mntent; 1422 FILE *fp; 1423 1424 if (proc_path_len == 0) { 1425 /* Default the mount location of /proc */ 1426 strlcpy (proc_path, "/proc", sizeof(proc_path)); 1427 proc_path_len = 5; 1428 fp = fopen(MOUNTED, "r"); 1429 if (fp != NULL) { 1430 while ((mntent = getmntent(fp)) != NULL) { 1431 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) 1432 continue; 1433 if (strcmp(mntent->mnt_type, "proc") == 0) { 1434 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path)); 1435 proc_path_len = strlen(proc_path); 1436 break; 1437 } 1438 } 1439 fclose (fp); 1440 } 1441 } 1442 1443 strlcpy(proc_path + proc_path_len, tail, 1444 sizeof(proc_path) - proc_path_len); 1445 return proc_path; 1446} 1447 1448/* 1449 * /proc/net/route parsing stuff. 1450 */ 1451#define ROUTE_MAX_COLS 12 1452FILE *route_fd = (FILE *) 0; 1453static char route_buffer[512]; 1454static int route_dev_col, route_dest_col, route_gw_col; 1455static int route_flags_col, route_mask_col; 1456static int route_num_cols; 1457 1458static int open_route_table (void); 1459static void close_route_table (void); 1460static int read_route_table (struct rtentry *rt); 1461 1462/******************************************************************** 1463 * 1464 * close_route_table - close the interface to the route table 1465 */ 1466 1467static void close_route_table (void) 1468{ 1469 if (route_fd != (FILE *) 0) { 1470 fclose (route_fd); 1471 route_fd = (FILE *) 0; 1472 } 1473} 1474 1475/******************************************************************** 1476 * 1477 * open_route_table - open the interface to the route table 1478 */ 1479static char route_delims[] = " \t\n"; 1480 1481static int open_route_table (void) 1482{ 1483 char *path; 1484 1485 close_route_table(); 1486 1487 path = path_to_procfs("/net/route"); 1488 route_fd = fopen (path, "r"); 1489 if (route_fd == NULL) { 1490 error("can't open routing table %s: %m", path); 1491 return 0; 1492 } 1493 1494 route_dev_col = 0; /* default to usual columns */ 1495 route_dest_col = 1; 1496 route_gw_col = 2; 1497 route_flags_col = 3; 1498 route_mask_col = 7; 1499 route_num_cols = 8; 1500 1501 /* parse header line */ 1502 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) { 1503 char *p = route_buffer, *q; 1504 int col; 1505 for (col = 0; col < ROUTE_MAX_COLS; ++col) { 1506 int used = 1; 1507 if ((q = strtok(p, route_delims)) == 0) 1508 break; 1509 if (strcasecmp(q, "iface") == 0) 1510 route_dev_col = col; 1511 else if (strcasecmp(q, "destination") == 0) 1512 route_dest_col = col; 1513 else if (strcasecmp(q, "gateway") == 0) 1514 route_gw_col = col; 1515 else if (strcasecmp(q, "flags") == 0) 1516 route_flags_col = col; 1517 else if (strcasecmp(q, "mask") == 0) 1518 route_mask_col = col; 1519 else 1520 used = 0; 1521 if (used && col >= route_num_cols) 1522 route_num_cols = col + 1; 1523 p = NULL; 1524 } 1525 } 1526 1527 return 1; 1528} 1529 1530/******************************************************************** 1531 * 1532 * read_route_table - read the next entry from the route table 1533 */ 1534 1535static int read_route_table(struct rtentry *rt) 1536{ 1537 char *cols[ROUTE_MAX_COLS], *p; 1538 int col; 1539 1540 memset (rt, '\0', sizeof (struct rtentry)); 1541 1542 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) 1543 return 0; 1544 1545 p = route_buffer; 1546 for (col = 0; col < route_num_cols; ++col) { 1547 cols[col] = strtok(p, route_delims); 1548 if (cols[col] == NULL) 1549 return 0; /* didn't get enough columns */ 1550 p = NULL; 1551 } 1552 1553 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); 1554 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); 1555 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); 1556 1557 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); 1558 rt->rt_dev = cols[route_dev_col]; 1559 1560 return 1; 1561} 1562 1563/******************************************************************** 1564 * 1565 * defaultroute_exists - determine if there is a default route 1566 */ 1567 1568static int defaultroute_exists (struct rtentry *rt) 1569{ 1570 int result = 0; 1571 1572 if (!open_route_table()) 1573 return 0; 1574 1575 while (read_route_table(rt) != 0) { 1576 if ((rt->rt_flags & RTF_UP) == 0) 1577 continue; 1578 1579 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) 1580 continue; 1581 if (SIN_ADDR(rt->rt_dst) == 0L) { 1582 result = 1; 1583 break; 1584 } 1585 } 1586 1587 close_route_table(); 1588 return result; 1589} 1590 1591/* 1592 * have_route_to - determine if the system has any route to 1593 * a given IP address. `addr' is in network byte order. 1594 * Return value is 1 if yes, 0 if no, -1 if don't know. 1595 * For demand mode to work properly, we have to ignore routes 1596 * through our own interface. 1597 */ 1598int have_route_to(u_int32_t addr) 1599{ 1600 struct rtentry rt; 1601 int result = 0; 1602 1603 if (!open_route_table()) 1604 return -1; /* don't know */ 1605 1606 while (read_route_table(&rt)) { 1607 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0) 1608 continue; 1609 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) { 1610 result = 1; 1611 break; 1612 } 1613 } 1614 1615 close_route_table(); 1616 return result; 1617} 1618 1619/******************************************************************** 1620 * 1621 * sifdefaultroute - assign a default route through the address given. 1622 */ 1623 1624int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) 1625{ 1626 struct rtentry rt; 1627 1628 if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { 1629 if (rt.rt_flags & RTF_GATEWAY) 1630 error("not replacing existing default route via %I", 1631 SIN_ADDR(rt.rt_gateway)); 1632 else 1633 error("not replacing existing default route through %s", 1634 rt.rt_dev); 1635 return 0; 1636 } 1637 1638 memset (&rt, 0, sizeof (rt)); 1639 SET_SA_FAMILY (rt.rt_dst, AF_INET); 1640 1641 rt.rt_dev = ifname; 1642 1643 if (kernel_version > KVERSION(2,1,0)) { 1644 SET_SA_FAMILY (rt.rt_genmask, AF_INET); 1645 SIN_ADDR(rt.rt_genmask) = 0L; 1646 } 1647 1648 rt.rt_flags = RTF_UP; 1649 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { 1650 if ( ! ok_error ( errno )) 1651 error("default route ioctl(SIOCADDRT): %m"); 1652 return 0; 1653 } 1654 1655 have_default_route = 1; 1656 return 1; 1657} 1658 1659/******************************************************************** 1660 * 1661 * cifdefaultroute - delete a default route through the address given. 1662 */ 1663 1664int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) 1665{ 1666 struct rtentry rt; 1667 1668 have_default_route = 0; 1669 1670 memset (&rt, '\0', sizeof (rt)); 1671 SET_SA_FAMILY (rt.rt_dst, AF_INET); 1672 SET_SA_FAMILY (rt.rt_gateway, AF_INET); 1673 1674 rt.rt_dev = ifname; 1675 1676 if (kernel_version > KVERSION(2,1,0)) { 1677 SET_SA_FAMILY (rt.rt_genmask, AF_INET); 1678 SIN_ADDR(rt.rt_genmask) = 0L; 1679 } 1680 1681 rt.rt_flags = RTF_UP; 1682 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { 1683 if (still_ppp()) { 1684 if ( ! ok_error ( errno )) 1685 error("default route ioctl(SIOCDELRT): %m"); 1686 return 0; 1687 } 1688 } 1689 1690 return 1; 1691} 1692 1693/******************************************************************** 1694 * 1695 * sifproxyarp - Make a proxy ARP entry for the peer. 1696 */ 1697 1698int sifproxyarp (int unit, u_int32_t his_adr) 1699{ 1700 struct arpreq arpreq; 1701 char *forw_path; 1702 1703 if (has_proxy_arp == 0) { 1704 memset (&arpreq, '\0', sizeof(arpreq)); 1705 1706 SET_SA_FAMILY(arpreq.arp_pa, AF_INET); 1707 SIN_ADDR(arpreq.arp_pa) = his_adr; 1708 arpreq.arp_flags = ATF_PERM | ATF_PUBL; 1709/* 1710 * Get the hardware address of an interface on the same subnet 1711 * as our local address. 1712 */ 1713 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev, 1714 sizeof(proxy_arp_dev))) { 1715 error("Cannot determine ethernet address for proxy ARP"); 1716 return 0; 1717 } 1718 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); 1719 1720 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) { 1721 if ( ! ok_error ( errno )) 1722 error("ioctl(SIOCSARP): %m"); 1723 return 0; 1724 } 1725 proxy_arp_addr = his_adr; 1726 has_proxy_arp = 1; 1727 1728 if (tune_kernel) { 1729 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward"); 1730 if (forw_path != 0) { 1731 int fd = open(forw_path, O_WRONLY); 1732 if (fd >= 0) { 1733 if (write(fd, "1", 1) != 1) 1734 error("Couldn't enable IP forwarding: %m"); 1735 close(fd); 1736 } 1737 } 1738 } 1739 } 1740 1741 return 1; 1742} 1743 1744/******************************************************************** 1745 * 1746 * cifproxyarp - Delete the proxy ARP entry for the peer. 1747 */ 1748 1749int cifproxyarp (int unit, u_int32_t his_adr) 1750{ 1751 struct arpreq arpreq; 1752 1753 if (has_proxy_arp) { 1754 has_proxy_arp = 0; 1755 memset (&arpreq, '\0', sizeof(arpreq)); 1756 SET_SA_FAMILY(arpreq.arp_pa, AF_INET); 1757 SIN_ADDR(arpreq.arp_pa) = his_adr; 1758 arpreq.arp_flags = ATF_PERM | ATF_PUBL; 1759 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); 1760 1761 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { 1762 if ( ! ok_error ( errno )) 1763 warn("ioctl(SIOCDARP): %m"); 1764 return 0; 1765 } 1766 } 1767 return 1; 1768} 1769 1770/******************************************************************** 1771 * 1772 * get_ether_addr - get the hardware address of an interface on the 1773 * the same subnet as ipaddr. 1774 */ 1775 1776static int get_ether_addr (u_int32_t ipaddr, 1777 struct sockaddr *hwaddr, 1778 char *name, int namelen) 1779{ 1780 struct ifreq *ifr, *ifend; 1781 u_int32_t ina, mask; 1782 char *aliasp; 1783 struct ifreq ifreq, bestifreq; 1784 struct ifconf ifc; 1785 struct ifreq ifs[MAX_IFS]; 1786 1787 u_int32_t bestmask=0; 1788 int found_interface = 0; 1789 1790 ifc.ifc_len = sizeof(ifs); 1791 ifc.ifc_req = ifs; 1792 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) { 1793 if ( ! ok_error ( errno )) 1794 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__); 1795 return 0; 1796 } 1797 1798/* 1799 * Scan through looking for an interface with an Internet 1800 * address on the same subnet as `ipaddr'. 1801 */ 1802 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); 1803 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { 1804 if (ifr->ifr_addr.sa_family == AF_INET) { 1805 ina = SIN_ADDR(ifr->ifr_addr); 1806 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); 1807/* 1808 * Check that the interface is up, and not point-to-point 1809 * nor loopback. 1810 */ 1811 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) 1812 continue; 1813 1814 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) 1815 continue; 1816/* 1817 * Get its netmask and check that it's on the right subnet. 1818 */ 1819 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) 1820 continue; 1821 1822 mask = SIN_ADDR(ifreq.ifr_addr); 1823 1824 if (((ipaddr ^ ina) & mask) != 0) 1825 continue; /* no match */ 1826 /* matched */ 1827 if (mask >= bestmask) { 1828 /* Compare using >= instead of > -- it is possible for 1829 an interface to have a netmask of 0.0.0.0 */ 1830 found_interface = 1; 1831 bestifreq = ifreq; 1832 bestmask = mask; 1833 } 1834 } 1835 } 1836 1837 if (!found_interface) return 0; 1838 1839 strlcpy(name, bestifreq.ifr_name, namelen); 1840 1841 /* trim off the :1 in eth0:1 */ 1842 aliasp = strchr(name, ':'); 1843 if (aliasp != 0) 1844 *aliasp = 0; 1845 1846 info("found interface %s for proxy arp", name); 1847/* 1848 * Now get the hardware address. 1849 */ 1850 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); 1851 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) { 1852 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name); 1853 return 0; 1854 } 1855 1856 memcpy (hwaddr, 1857 &bestifreq.ifr_hwaddr, 1858 sizeof (struct sockaddr)); 1859 1860 return 1; 1861} 1862 1863/* 1864 * get_if_hwaddr - get the hardware address for the specified 1865 * network interface device. 1866 */ 1867int 1868get_if_hwaddr(u_char *addr, char *name) 1869{ 1870 struct ifreq ifreq; 1871 int ret, sock_fd; 1872 1873 sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 1874 if (sock_fd < 0) 1875 return 0; 1876 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); 1877 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name)); 1878 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); 1879 close(sock_fd); 1880 if (ret >= 0) 1881 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6); 1882 return ret; 1883} 1884 1885/* 1886 * get_first_ethernet - return the name of the first ethernet-style 1887 * interface on this system. 1888 */ 1889char * 1890get_first_ethernet() 1891{ 1892 return "eth0"; 1893} 1894 1895/******************************************************************** 1896 * 1897 * Return user specified netmask, modified by any mask we might determine 1898 * for address `addr' (in network byte order). 1899 * Here we scan through the system's list of interfaces, looking for 1900 * any non-point-to-point interfaces which might appear to be on the same 1901 * network as `addr'. If we find any, we OR in their netmask to the 1902 * user-specified netmask. 1903 */ 1904 1905u_int32_t GetMask (u_int32_t addr) 1906{ 1907 u_int32_t mask, nmask, ina; 1908 struct ifreq *ifr, *ifend, ifreq; 1909 struct ifconf ifc; 1910 struct ifreq ifs[MAX_IFS]; 1911 1912 addr = ntohl(addr); 1913 1914 if (IN_CLASSA(addr)) /* determine network mask for address class */ 1915 nmask = IN_CLASSA_NET; 1916 else if (IN_CLASSB(addr)) 1917 nmask = IN_CLASSB_NET; 1918 else 1919 nmask = IN_CLASSC_NET; 1920 1921 /* class D nets are disallowed by bad_ip_adrs */ 1922 mask = netmask | htonl(nmask); 1923/* 1924 * Scan through the system's network interfaces. 1925 */ 1926 ifc.ifc_len = sizeof(ifs); 1927 ifc.ifc_req = ifs; 1928 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) { 1929 if ( ! ok_error ( errno )) 1930 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__); 1931 return mask; 1932 } 1933 1934 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); 1935 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { 1936/* 1937 * Check the interface's internet address. 1938 */ 1939 if (ifr->ifr_addr.sa_family != AF_INET) 1940 continue; 1941 ina = SIN_ADDR(ifr->ifr_addr); 1942 if (((ntohl(ina) ^ addr) & nmask) != 0) 1943 continue; 1944/* 1945 * Check that the interface is up, and not point-to-point nor loopback. 1946 */ 1947 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); 1948 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) 1949 continue; 1950 1951 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) 1952 continue; 1953/* 1954 * Get its netmask and OR it into our mask. 1955 */ 1956 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) 1957 continue; 1958 mask |= SIN_ADDR(ifreq.ifr_addr); 1959 break; 1960 } 1961 return mask; 1962} 1963 1964/******************************************************************** 1965 * 1966 * Internal routine to decode the version.modification.patch level 1967 */ 1968 1969static void decode_version (char *buf, int *version, 1970 int *modification, int *patch) 1971{ 1972 char *endp; 1973 1974 *version = (int) strtoul (buf, &endp, 10); 1975 *modification = 0; 1976 *patch = 0; 1977 1978 if (endp != buf && *endp == '.') { 1979 buf = endp + 1; 1980 *modification = (int) strtoul (buf, &endp, 10); 1981 if (endp != buf && *endp == '.') { 1982 buf = endp + 1; 1983 *patch = (int) strtoul (buf, &buf, 10); 1984 } 1985 } 1986} 1987 1988/******************************************************************** 1989 * 1990 * Procedure to determine if the PPP line discipline is registered. 1991 */ 1992 1993static int 1994ppp_registered(void) 1995{ 1996 int local_fd; 1997 int mfd = -1; 1998 int ret = 0; 1999 char slave[16]; 2000 2001 /* 2002 * We used to open the serial device and set it to the ppp line 2003 * discipline here, in order to create a ppp unit. But that is 2004 * not a good idea - the user might have specified a device that 2005 * they can't open (permission, or maybe it doesn't really exist). 2006 * So we grab a pty master/slave pair and use that. 2007 */ 2008 if (!get_pty(&mfd, &local_fd, slave, 0)) { 2009 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)"; 2010 return 0; 2011 } 2012 2013 /* 2014 * Try to put the device into the PPP discipline. 2015 */ 2016 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) { 2017 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__); 2018 } else 2019 ret = 1; 2020 2021 close(local_fd); 2022 close(mfd); 2023 return ret; 2024} 2025 2026/******************************************************************** 2027 * 2028 * ppp_available - check whether the system has any ppp interfaces 2029 * (in fact we check whether we can do an ioctl on ppp0). 2030 */ 2031 2032int ppp_available(void) 2033{ 2034 int s, ok, fd; 2035 struct ifreq ifr; 2036 int size; 2037 int my_version, my_modification, my_patch; 2038 int osmaj, osmin, ospatch; 2039 2040 /* get the kernel version now, since we are called before sys_init */ 2041 uname(&utsname); 2042 osmaj = osmin = ospatch = 0; 2043 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch); 2044 kernel_version = KVERSION(osmaj, osmin, ospatch); 2045 2046 fd = open("/dev/ppp", O_RDWR); 2047 if (fd >= 0) { 2048 new_style_driver = 1; 2049 2050 /* XXX should get from driver */ 2051 driver_version = 2; 2052 driver_modification = 4; 2053 driver_patch = 0; 2054 close(fd); 2055 return 1; 2056 } 2057 2058 if (kernel_version >= KVERSION(2,3,13)) { 2059 error("Couldn't open the /dev/ppp device: %m"); 2060 if (errno == ENOENT) 2061 no_ppp_msg = 2062 "You need to create the /dev/ppp device node by\n" 2063 "executing the following command as root:\n" 2064 " mknod /dev/ppp c 108 0\n"; 2065 else if (errno == ENODEV || errno == ENXIO) 2066 no_ppp_msg = 2067 "Please load the ppp_generic kernel module.\n"; 2068 return 0; 2069 } 2070 2071 /* we are running on a really really old kernel */ 2072 no_ppp_msg = 2073 "This system lacks kernel support for PPP. This could be because\n" 2074 "the PPP kernel module could not be loaded, or because PPP was not\n" 2075 "included in the kernel configuration. If PPP was included as a\n" 2076 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n" 2077 "ppp.o exists in /lib/modules/`uname -r`/net.\n" 2078 "See README.linux file in the ppp distribution for more details.\n"; 2079 2080/* 2081 * Open a socket for doing the ioctl operations. 2082 */ 2083 s = socket(AF_INET, SOCK_DGRAM, 0); 2084 if (s < 0) 2085 return 0; 2086 2087 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); 2088 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; 2089/* 2090 * If the device did not exist then attempt to create one by putting the 2091 * current tty into the PPP discipline. If this works then obtain the 2092 * flags for the device again. 2093 */ 2094 if (!ok) { 2095 if (ppp_registered()) { 2096 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); 2097 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; 2098 } 2099 } 2100/* 2101 * Ensure that the hardware address is for PPP and not something else 2102 */ 2103 if (ok) 2104 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0; 2105 2106 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP)) 2107 ok = 0; 2108 2109/* 2110 * This is the PPP device. Validate the version of the driver at this 2111 * point to ensure that this program will work with the driver. 2112 */ 2113 if (ok) { 2114 char abBuffer [1024]; 2115 2116 ifr.ifr_data = abBuffer; 2117 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr); 2118 if (size < 0) { 2119 error("Couldn't read driver version: %m"); 2120 ok = 0; 2121 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n"; 2122 2123 } else { 2124 decode_version(abBuffer, 2125 &driver_version, 2126 &driver_modification, 2127 &driver_patch); 2128/* 2129 * Validate the version of the driver against the version that we used. 2130 */ 2131 decode_version(VERSION, 2132 &my_version, 2133 &my_modification, 2134 &my_patch); 2135 2136 /* The version numbers must match */ 2137 if (driver_version != my_version) 2138 ok = 0; 2139 2140 /* The modification levels must be legal */ 2141 if (driver_modification < 3) { 2142 if (driver_modification >= 2) { 2143 /* we can cope with 2.2.0 and above */ 2144 driver_is_old = 1; 2145 } else { 2146 ok = 0; 2147 } 2148 } 2149 2150 close (s); 2151 if (!ok) { 2152 slprintf(route_buffer, sizeof(route_buffer), 2153 "Sorry - PPP driver version %d.%d.%d is out of date\n", 2154 driver_version, driver_modification, driver_patch); 2155 2156 no_ppp_msg = route_buffer; 2157 } 2158 } 2159 } 2160 return ok; 2161} 2162 2163#if defined(__ANDROID__) 2164void logwtmp (const char *line, const char *name, const char *host) {} 2165#elif !defined(HAVE_LOGWTMP) 2166/******************************************************************** 2167 * 2168 * Update the wtmp file with the appropriate user name and tty device. 2169 */ 2170 2171void logwtmp (const char *line, const char *name, const char *host) 2172{ 2173 struct utmp ut, *utp; 2174 pid_t mypid = getpid(); 2175#if __GLIBC__ < 2 2176 int wtmp; 2177#endif 2178 2179/* 2180 * Update the signon database for users. 2181 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996 2182 */ 2183 utmpname(_PATH_UTMP); 2184 setutent(); 2185 while ((utp = getutent()) && (utp->ut_pid != mypid)) 2186 /* nothing */; 2187 2188 if (utp) 2189 memcpy(&ut, utp, sizeof(ut)); 2190 else 2191 /* some gettys/telnetds don't initialize utmp... */ 2192 memset(&ut, 0, sizeof(ut)); 2193 2194 if (ut.ut_id[0] == 0) 2195 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); 2196 2197 strncpy(ut.ut_user, name, sizeof(ut.ut_user)); 2198 strncpy(ut.ut_line, line, sizeof(ut.ut_line)); 2199 2200 time(&ut.ut_time); 2201 2202 ut.ut_type = USER_PROCESS; 2203 ut.ut_pid = mypid; 2204 2205 /* Insert the host name if one is supplied */ 2206 if (*host) 2207 strncpy (ut.ut_host, host, sizeof(ut.ut_host)); 2208 2209 /* Insert the IP address of the remote system if IP is enabled */ 2210 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr) 2211 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr, 2212 sizeof(ut.ut_addr)); 2213 2214 /* CL: Makes sure that the logout works */ 2215 if (*host == 0 && *name==0) 2216 ut.ut_host[0]=0; 2217 2218 pututline(&ut); 2219 endutent(); 2220/* 2221 * Update the wtmp file. 2222 */ 2223#if __GLIBC__ >= 2 2224 updwtmp(_PATH_WTMP, &ut); 2225#else 2226 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY); 2227 if (wtmp >= 0) { 2228 flock(wtmp, LOCK_EX); 2229 2230 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut)) 2231 warn("error writing %s: %m", _PATH_WTMP); 2232 2233 flock(wtmp, LOCK_UN); 2234 2235 close (wtmp); 2236 } 2237#endif 2238} 2239#endif /* HAVE_LOGWTMP */ 2240 2241/******************************************************************** 2242 * 2243 * sifvjcomp - config tcp header compression 2244 */ 2245 2246int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) 2247{ 2248 u_int x; 2249 2250 if (vjcomp) { 2251 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { 2252 error("Couldn't set up TCP header compression: %m"); 2253 vjcomp = 0; 2254 } 2255 } 2256 2257 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID); 2258 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x); 2259 2260 return 1; 2261} 2262 2263/******************************************************************** 2264 * 2265 * sifup - Config the interface up and enable IP packets to pass. 2266 */ 2267 2268int sifup(int u) 2269{ 2270 int ret; 2271 2272 if ((ret = setifstate(u, 1))) 2273 if_is_up++; 2274 2275 return ret; 2276} 2277 2278/******************************************************************** 2279 * 2280 * sifdown - Disable the indicated protocol and config the interface 2281 * down if there are no remaining protocols. 2282 */ 2283 2284int sifdown (int u) 2285{ 2286 if (if_is_up && --if_is_up > 0) 2287 return 1; 2288 2289#ifdef INET6 2290 if (if6_is_up) 2291 return 1; 2292#endif /* INET6 */ 2293 2294 return setifstate(u, 0); 2295} 2296 2297#ifdef INET6 2298/******************************************************************** 2299 * 2300 * sif6up - Config the interface up for IPv6 2301 */ 2302 2303int sif6up(int u) 2304{ 2305 int ret; 2306 2307 if ((ret = setifstate(u, 1))) 2308 if6_is_up = 1; 2309 2310 return ret; 2311} 2312 2313/******************************************************************** 2314 * 2315 * sif6down - Disable the IPv6CP protocol and config the interface 2316 * down if there are no remaining protocols. 2317 */ 2318 2319int sif6down (int u) 2320{ 2321 if6_is_up = 0; 2322 2323 if (if_is_up) 2324 return 1; 2325 2326 return setifstate(u, 0); 2327} 2328#endif /* INET6 */ 2329 2330/******************************************************************** 2331 * 2332 * setifstate - Config the interface up or down 2333 */ 2334 2335static int setifstate (int u, int state) 2336{ 2337 struct ifreq ifr; 2338 2339 memset (&ifr, '\0', sizeof (ifr)); 2340 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); 2341 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { 2342 if (! ok_error (errno)) 2343 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__); 2344 return 0; 2345 } 2346 2347 if (state) 2348 ifr.ifr_flags |= IFF_UP; 2349 else 2350 ifr.ifr_flags &= ~IFF_UP; 2351 ifr.ifr_flags |= IFF_POINTOPOINT; 2352 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { 2353 if (! ok_error (errno)) 2354 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__); 2355 return 0; 2356 } 2357 return 1; 2358} 2359 2360/******************************************************************** 2361 * 2362 * sifaddr - Config the interface IP addresses and netmask. 2363 */ 2364 2365int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, 2366 u_int32_t net_mask) 2367{ 2368 struct ifreq ifr; 2369 struct rtentry rt; 2370 2371 memset (&ifr, '\0', sizeof (ifr)); 2372 memset (&rt, '\0', sizeof (rt)); 2373 2374 SET_SA_FAMILY (ifr.ifr_addr, AF_INET); 2375 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); 2376 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); 2377 2378 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); 2379/* 2380 * Set our IP address 2381 */ 2382 SIN_ADDR(ifr.ifr_addr) = our_adr; 2383 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { 2384 if (errno != EEXIST) { 2385 if (! ok_error (errno)) 2386 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); 2387 } 2388 else { 2389 warn("ioctl(SIOCSIFADDR): Address already exists"); 2390 } 2391 return (0); 2392 } 2393/* 2394 * Set the gateway address 2395 */ 2396 if (his_adr != 0) { 2397 SIN_ADDR(ifr.ifr_dstaddr) = his_adr; 2398 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { 2399 if (! ok_error (errno)) 2400 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__); 2401 return (0); 2402 } 2403 } 2404/* 2405 * Set the netmask. 2406 * For recent kernels, force the netmask to 255.255.255.255. 2407 */ 2408 if (kernel_version >= KVERSION(2,1,16)) 2409 net_mask = ~0L; 2410 if (net_mask != 0) { 2411 SIN_ADDR(ifr.ifr_netmask) = net_mask; 2412 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { 2413 if (! ok_error (errno)) 2414 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__); 2415 return (0); 2416 } 2417 } 2418/* 2419 * Add the device route 2420 */ 2421 if (kernel_version < KVERSION(2,1,16)) { 2422 SET_SA_FAMILY (rt.rt_dst, AF_INET); 2423 SET_SA_FAMILY (rt.rt_gateway, AF_INET); 2424 rt.rt_dev = ifname; 2425 2426 SIN_ADDR(rt.rt_gateway) = 0L; 2427 SIN_ADDR(rt.rt_dst) = his_adr; 2428 rt.rt_flags = RTF_UP | RTF_HOST; 2429 2430 if (kernel_version > KVERSION(2,1,0)) { 2431 SET_SA_FAMILY (rt.rt_genmask, AF_INET); 2432 SIN_ADDR(rt.rt_genmask) = -1L; 2433 } 2434 2435 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { 2436 if (! ok_error (errno)) 2437 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__); 2438 return (0); 2439 } 2440 } 2441 2442 /* set ip_dynaddr in demand mode if address changes */ 2443 if (demand && tune_kernel && !dynaddr_set 2444 && our_old_addr && our_old_addr != our_adr) { 2445 /* set ip_dynaddr if possible */ 2446 char *path; 2447 int fd; 2448 2449 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr"); 2450 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) { 2451 if (write(fd, "1", 1) != 1) 2452 error("Couldn't enable dynamic IP addressing: %m"); 2453 close(fd); 2454 } 2455 dynaddr_set = 1; /* only 1 attempt */ 2456 } 2457 our_old_addr = 0; 2458 2459 return 1; 2460} 2461 2462/******************************************************************** 2463 * 2464 * cifaddr - Clear the interface IP addresses, and delete routes 2465 * through the interface if possible. 2466 */ 2467 2468int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) 2469{ 2470 struct ifreq ifr; 2471 2472 if (kernel_version < KVERSION(2,1,16)) { 2473/* 2474 * Delete the route through the device 2475 */ 2476 struct rtentry rt; 2477 memset (&rt, '\0', sizeof (rt)); 2478 2479 SET_SA_FAMILY (rt.rt_dst, AF_INET); 2480 SET_SA_FAMILY (rt.rt_gateway, AF_INET); 2481 rt.rt_dev = ifname; 2482 2483 SIN_ADDR(rt.rt_gateway) = 0; 2484 SIN_ADDR(rt.rt_dst) = his_adr; 2485 rt.rt_flags = RTF_UP | RTF_HOST; 2486 2487 if (kernel_version > KVERSION(2,1,0)) { 2488 SET_SA_FAMILY (rt.rt_genmask, AF_INET); 2489 SIN_ADDR(rt.rt_genmask) = -1L; 2490 } 2491 2492 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { 2493 if (still_ppp() && ! ok_error (errno)) 2494 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__); 2495 return (0); 2496 } 2497 } 2498 2499 /* This way it is possible to have an IPX-only or IPv6-only interface */ 2500 memset(&ifr, 0, sizeof(ifr)); 2501 SET_SA_FAMILY(ifr.ifr_addr, AF_INET); 2502 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 2503 2504 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { 2505 if (! ok_error (errno)) { 2506 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); 2507 return 0; 2508 } 2509 } 2510 2511 our_old_addr = our_adr; 2512 2513 return 1; 2514} 2515 2516#ifdef INET6 2517/******************************************************************** 2518 * 2519 * sif6addr - Config the interface with an IPv6 link-local address 2520 */ 2521int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) 2522{ 2523 struct in6_ifreq ifr6; 2524 struct ifreq ifr; 2525 struct in6_rtmsg rt6; 2526 2527 if (sock6_fd < 0) { 2528 errno = -sock6_fd; 2529 error("IPv6 socket creation failed: %m"); 2530 return 0; 2531 } 2532 memset(&ifr, 0, sizeof (ifr)); 2533 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 2534 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { 2535 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__); 2536 return 0; 2537 } 2538 2539 /* Local interface */ 2540 memset(&ifr6, 0, sizeof(ifr6)); 2541 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); 2542 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 2543 ifr6.ifr6_prefixlen = 10; 2544 2545 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { 2546 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); 2547 return 0; 2548 } 2549 2550 /* Route to remote host */ 2551 memset(&rt6, 0, sizeof(rt6)); 2552 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); 2553 rt6.rtmsg_flags = RTF_UP; 2554 rt6.rtmsg_dst_len = 10; 2555 rt6.rtmsg_ifindex = ifr.ifr_ifindex; 2556 rt6.rtmsg_metric = 1; 2557 2558 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { 2559 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__); 2560 return 0; 2561 } 2562 2563 return 1; 2564} 2565 2566 2567/******************************************************************** 2568 * 2569 * cif6addr - Remove IPv6 address from interface 2570 */ 2571int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) 2572{ 2573 struct ifreq ifr; 2574 struct in6_ifreq ifr6; 2575 2576 if (sock6_fd < 0) { 2577 errno = -sock6_fd; 2578 error("IPv6 socket creation failed: %m"); 2579 return 0; 2580 } 2581 memset(&ifr, 0, sizeof(ifr)); 2582 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 2583 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { 2584 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__); 2585 return 0; 2586 } 2587 2588 memset(&ifr6, 0, sizeof(ifr6)); 2589 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); 2590 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 2591 ifr6.ifr6_prefixlen = 10; 2592 2593 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { 2594 if (errno != EADDRNOTAVAIL) { 2595 if (! ok_error (errno)) 2596 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__); 2597 } 2598 else { 2599 warn("cif6addr: ioctl(SIOCDIFADDR): No such address"); 2600 } 2601 return (0); 2602 } 2603 return 1; 2604} 2605#endif /* INET6 */ 2606 2607/* 2608 * get_pty - get a pty master/slave pair and chown the slave side 2609 * to the uid given. Assumes slave_name points to >= 16 bytes of space. 2610 */ 2611int 2612get_pty(master_fdp, slave_fdp, slave_name, uid) 2613 int *master_fdp; 2614 int *slave_fdp; 2615 char *slave_name; 2616 int uid; 2617{ 2618 int i, mfd, sfd = -1; 2619 char pty_name[16]; 2620 struct termios tios; 2621 2622#ifdef TIOCGPTN 2623 /* 2624 * Try the unix98 way first. 2625 */ 2626 mfd = open("/dev/ptmx", O_RDWR); 2627 if (mfd >= 0) { 2628 int ptn; 2629 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { 2630 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn); 2631 chmod(pty_name, S_IRUSR | S_IWUSR); 2632#ifdef TIOCSPTLCK 2633 ptn = 0; 2634 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) 2635 warn("Couldn't unlock pty slave %s: %m", pty_name); 2636#endif 2637 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) 2638 warn("Couldn't open pty slave %s: %m", pty_name); 2639 } 2640 } 2641#endif /* TIOCGPTN */ 2642 2643 if (sfd < 0) { 2644 /* the old way - scan through the pty name space */ 2645 for (i = 0; i < 64; ++i) { 2646 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", 2647 'p' + i / 16, i % 16); 2648 mfd = open(pty_name, O_RDWR, 0); 2649 if (mfd >= 0) { 2650 pty_name[5] = 't'; 2651 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); 2652 if (sfd >= 0) { 2653 fchown(sfd, uid, -1); 2654 fchmod(sfd, S_IRUSR | S_IWUSR); 2655 break; 2656 } 2657 close(mfd); 2658 } 2659 } 2660 } 2661 2662 if (sfd < 0) 2663 return 0; 2664 2665 strlcpy(slave_name, pty_name, 16); 2666 *master_fdp = mfd; 2667 *slave_fdp = sfd; 2668 if (tcgetattr(sfd, &tios) == 0) { 2669 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); 2670 tios.c_cflag |= CS8 | CREAD | CLOCAL; 2671 tios.c_iflag = IGNPAR; 2672 tios.c_oflag = 0; 2673 tios.c_lflag = 0; 2674 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) 2675 warn("couldn't set attributes on pty: %m"); 2676 } else 2677 warn("couldn't get attributes on pty: %m"); 2678 2679 return 1; 2680} 2681 2682/******************************************************************** 2683 * 2684 * open_loopback - open the device we use for getting packets 2685 * in demand mode. Under Linux, we use a pty master/slave pair. 2686 */ 2687int 2688open_ppp_loopback(void) 2689{ 2690 int flags; 2691 2692 looped = 1; 2693 if (new_style_driver) { 2694 /* allocate ourselves a ppp unit */ 2695 if (make_ppp_unit() < 0) 2696 die(1); 2697 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC); 2698 set_kdebugflag(kdebugflag); 2699 ppp_fd = -1; 2700 return ppp_dev_fd; 2701 } 2702 2703 if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) 2704 fatal("No free pty for loopback"); 2705 2706 set_ppp_fd(slave_fd); 2707 2708 flags = fcntl(master_fd, F_GETFL); 2709 if (flags == -1 || 2710 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1) 2711 warn("couldn't set master loopback to nonblock: %m"); 2712 2713 flags = fcntl(ppp_fd, F_GETFL); 2714 if (flags == -1 || 2715 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1) 2716 warn("couldn't set slave loopback to nonblock: %m"); 2717 2718 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) 2719 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__); 2720/* 2721 * Find out which interface we were given. 2722 */ 2723 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) 2724 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__); 2725/* 2726 * Enable debug in the driver if requested. 2727 */ 2728 set_kdebugflag (kdebugflag); 2729 2730 return master_fd; 2731} 2732 2733/******************************************************************** 2734 * 2735 * sifnpmode - Set the mode for handling packets for a given NP. 2736 */ 2737 2738int 2739sifnpmode(u, proto, mode) 2740 int u; 2741 int proto; 2742 enum NPmode mode; 2743{ 2744 struct npioctl npi; 2745 2746 npi.protocol = proto; 2747 npi.mode = mode; 2748 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { 2749 if (! ok_error (errno)) 2750 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode); 2751 return 0; 2752 } 2753 return 1; 2754} 2755 2756 2757/******************************************************************** 2758 * 2759 * sipxfaddr - Config the interface IPX networknumber 2760 */ 2761 2762int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) 2763{ 2764 int result = 1; 2765 2766#ifdef IPX_CHANGE 2767 int skfd; 2768 struct ifreq ifr; 2769 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; 2770 2771 skfd = socket (AF_IPX, SOCK_DGRAM, 0); 2772 if (skfd < 0) { 2773 if (! ok_error (errno)) 2774 dbglog("socket(AF_IPX): %m (line %d)", __LINE__); 2775 result = 0; 2776 } 2777 else { 2778 memset (&ifr, '\0', sizeof (ifr)); 2779 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 2780 2781 memcpy (sipx->sipx_node, node, IPX_NODE_LEN); 2782 sipx->sipx_family = AF_IPX; 2783 sipx->sipx_port = 0; 2784 sipx->sipx_network = htonl (network); 2785 sipx->sipx_type = IPX_FRAME_ETHERII; 2786 sipx->sipx_action = IPX_CRTITF; 2787/* 2788 * Set the IPX device 2789 */ 2790 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { 2791 result = 0; 2792 if (errno != EEXIST) { 2793 if (! ok_error (errno)) 2794 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__); 2795 } 2796 else { 2797 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists"); 2798 } 2799 } 2800 close (skfd); 2801 } 2802#endif 2803 return result; 2804} 2805 2806/******************************************************************** 2807 * 2808 * cipxfaddr - Clear the information for the IPX network. The IPX routes 2809 * are removed and the device is no longer able to pass IPX 2810 * frames. 2811 */ 2812 2813int cipxfaddr (int unit) 2814{ 2815 int result = 1; 2816 2817#ifdef IPX_CHANGE 2818 int skfd; 2819 struct ifreq ifr; 2820 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; 2821 2822 skfd = socket (AF_IPX, SOCK_DGRAM, 0); 2823 if (skfd < 0) { 2824 if (! ok_error (errno)) 2825 dbglog("socket(AF_IPX): %m (line %d)", __LINE__); 2826 result = 0; 2827 } 2828 else { 2829 memset (&ifr, '\0', sizeof (ifr)); 2830 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 2831 2832 sipx->sipx_type = IPX_FRAME_ETHERII; 2833 sipx->sipx_action = IPX_DLTITF; 2834 sipx->sipx_family = AF_IPX; 2835/* 2836 * Set the IPX device 2837 */ 2838 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { 2839 if (! ok_error (errno)) 2840 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__); 2841 result = 0; 2842 } 2843 close (skfd); 2844 } 2845#endif 2846 return result; 2847} 2848 2849/* 2850 * Use the hostname as part of the random number seed. 2851 */ 2852int 2853get_host_seed() 2854{ 2855 int h; 2856 char *p = hostname; 2857 2858 h = 407; 2859 for (p = hostname; *p != 0; ++p) 2860 h = h * 37 + *p; 2861 return h; 2862} 2863 2864/******************************************************************** 2865 * 2866 * sys_check_options - check the options that the user specified 2867 */ 2868 2869int 2870sys_check_options(void) 2871{ 2872#ifdef IPX_CHANGE 2873/* 2874 * Disable the IPX protocol if the support is not present in the kernel. 2875 */ 2876 char *path; 2877 2878 if (ipxcp_protent.enabled_flag) { 2879 struct stat stat_buf; 2880 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL 2881 && (path = path_to_procfs("/net/ipx_interface")) == NULL) 2882 || lstat(path, &stat_buf) < 0) { 2883 error("IPX support is not present in the kernel\n"); 2884 ipxcp_protent.enabled_flag = 0; 2885 } 2886 } 2887#endif 2888 if (demand && driver_is_old) { 2889 option_error("demand dialling is not supported by kernel driver " 2890 "version %d.%d.%d", driver_version, driver_modification, 2891 driver_patch); 2892 return 0; 2893 } 2894 if (multilink && !new_style_driver) { 2895 warn("Warning: multilink is not supported by the kernel driver"); 2896 multilink = 0; 2897 } 2898 return 1; 2899} 2900 2901#ifdef INET6 2902/* 2903 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI 2904 * 2905 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes 2906 * that the system has a properly configured Ethernet interface for this 2907 * function to return non-zero. 2908 */ 2909int 2910ether_to_eui64(eui64_t *p_eui64) 2911{ 2912 struct ifreq ifr; 2913 int skfd; 2914 const unsigned char *ptr; 2915 2916 skfd = socket(PF_INET6, SOCK_DGRAM, 0); 2917 if(skfd == -1) 2918 { 2919 warn("could not open IPv6 socket"); 2920 return 0; 2921 } 2922 2923 strcpy(ifr.ifr_name, "eth0"); 2924 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) 2925 { 2926 close(skfd); 2927 warn("could not obtain hardware address for eth0"); 2928 return 0; 2929 } 2930 close(skfd); 2931 2932 /* 2933 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] 2934 */ 2935 ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data; 2936 p_eui64->e8[0] = ptr[0] | 0x02; 2937 p_eui64->e8[1] = ptr[1]; 2938 p_eui64->e8[2] = ptr[2]; 2939 p_eui64->e8[3] = 0xFF; 2940 p_eui64->e8[4] = 0xFE; 2941 p_eui64->e8[5] = ptr[3]; 2942 p_eui64->e8[6] = ptr[4]; 2943 p_eui64->e8[7] = ptr[5]; 2944 2945 return 1; 2946} 2947#endif 2948