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