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