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