Home | History | Annotate | Line # | Download | only in pppd
      1 /*	NetBSD: sys-bsd.c,v 1.68 2013/06/24 20:43:48 christos Exp 	*/
      2 
      3 /*
      4  * sys-bsd.c - System-dependent procedures for setting up
      5  * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.)
      6  *
      7  * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  *
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  *
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in
     18  *    the documentation and/or other materials provided with the
     19  *    distribution.
     20  *
     21  * 3. The name "Carnegie Mellon University" must not be used to
     22  *    endorse or promote products derived from this software without
     23  *    prior written permission. For permission or any legal
     24  *    details, please contact
     25  *      Office of Technology Transfer
     26  *      Carnegie Mellon University
     27  *      5000 Forbes Avenue
     28  *      Pittsburgh, PA  15213-3890
     29  *      (412) 268-4387, fax: (412) 268-7395
     30  *      tech-transfer (at) andrew.cmu.edu
     31  *
     32  * 4. Redistributions of any form whatsoever must retain the following
     33  *    acknowledgment:
     34  *    "This product includes software developed by Computing Services
     35  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
     36  *
     37  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
     38  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     39  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
     40  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     41  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
     42  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     43  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     44  *
     45  * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved.
     46  *
     47  * Redistribution and use in source and binary forms, with or without
     48  * modification, are permitted provided that the following conditions
     49  * are met:
     50  *
     51  * 1. Redistributions of source code must retain the above copyright
     52  *    notice, this list of conditions and the following disclaimer.
     53  *
     54  * 2. Redistributions in binary form must reproduce the above copyright
     55  *    notice, this list of conditions and the following disclaimer in
     56  *    the documentation and/or other materials provided with the
     57  *    distribution.
     58  *
     59  * 3. The name(s) of the authors of this software must not be used to
     60  *    endorse or promote products derived from this software without
     61  *    prior written permission.
     62  *
     63  * 4. Redistributions of any form whatsoever must retain the following
     64  *    acknowledgment:
     65  *    "This product includes software developed by Paul Mackerras
     66  *     <paulus (at) samba.org>".
     67  *
     68  * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
     69  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     70  * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
     71  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     72  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
     73  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     74  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     75  */
     76 
     77 #include <sys/cdefs.h>
     78 #ifndef lint
     79 #if 0
     80 #define RCSID	"Id: sys-bsd.c,v 1.47 2000/04/13 12:04:23 paulus Exp "
     81 #else
     82 __RCSID("NetBSD: sys-bsd.c,v 1.68 2013/06/24 20:43:48 christos Exp ");
     83 #endif
     84 #endif
     85 
     86 /*
     87  * TODO:
     88  */
     89 
     90 #ifdef HAVE_CONFIG_H
     91 #include "config.h"
     92 #endif
     93 
     94 #include <stdio.h>
     95 #include <string.h>
     96 #include <stdlib.h>
     97 #include <unistd.h>
     98 #include <errno.h>
     99 #include <fcntl.h>
    100 #include <termios.h>
    101 #include <signal.h>
    102 #include <vis.h>
    103 #include <sys/ioctl.h>
    104 #include <sys/types.h>
    105 #include <sys/socket.h>
    106 #include <sys/time.h>
    107 #include <sys/stat.h>
    108 #include <sys/param.h>
    109 #if defined(NetBSD1_2) || defined(__NetBSD_Version__)
    110 #include <util.h>
    111 #endif
    112 #ifdef PPP_WITH_FILTER
    113 #include <net/bpf.h>
    114 #endif
    115 
    116 #include <net/if.h>
    117 #include <net/ppp_defs.h>
    118 #include <net/if_ppp.h>
    119 #include <net/route.h>
    120 #include <net/if_dl.h>
    121 #include <netinet/in.h>
    122 #ifdef __KAME__
    123 #include <netinet6/in6_var.h>
    124 #include <netinet6/nd6.h>
    125 #endif
    126 #include <ifaddrs.h>
    127 
    128 #ifdef INET6
    129 
    130 #define s6_addr32 __u6_addr.__u6_addr32	/* Non-standard */
    131 
    132 #define IN6_SOCKADDR_FROM_EUI64(s, eui64) do { \
    133 	(s)->sin6_family = AF_INET6; \
    134 	(s)->sin6_addr.s6_addr32[0] = htonl(0xfe800000); \
    135 	eui64_copy(eui64, (s)->sin6_addr.s6_addr32[2]); \
    136 	} while(0)
    137 #ifndef IN6_LLADDR_FROM_EUI64
    138 #ifdef __KAME__
    139 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do {			\
    140 	sin6.sin6_family = AF_INET6;				\
    141 	sin6.sin6_len = sizeof(struct sockaddr_in6);		\
    142 	sin6.sin6_addr.s6_addr[0] = 0xfe;			\
    143 	sin6.sin6_addr.s6_addr[1] = 0x80;			\
    144 	eui64_copy(eui64, sin6.sin6_addr.s6_addr[8]);		\
    145 } while (/*CONSTCOND*/0)
    146 #define IN6_IFINDEX(sin6, ifindex)	 			\
    147     /* KAME ifindex hack */					\
    148     *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] = htons(ifindex)
    149 #else
    150 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do {			\
    151 	memset(&sin6.s6_addr, 0, sizeof(struct in6_addr));	\
    152 	sin6.s6_addr16[0] = htons(0xfe80);			\
    153 	eui64_copy(eui64, sin6.s6_addr32[2]);			\
    154 } while (/*CONSTCOND*/0)
    155 #endif /* __KAME__ */
    156 #endif /* IN6_LLADDR_FROM_EUI64 */
    157 
    158 #endif /* INET6 */
    159 
    160 #if RTM_VERSION >= 3
    161 #include <sys/param.h>
    162 #if defined(NetBSD) && (NetBSD >= 199703)
    163 #include <netinet/if_inarp.h>
    164 #else	/* NetBSD 1.2D or later */
    165 #ifdef __FreeBSD__
    166 #include <netinet/if_ether.h>
    167 #else
    168 #include <net/if_ether.h>
    169 #endif
    170 #endif
    171 #endif
    172 
    173 #include "pppd.h"
    174 #include "pppd-private.h"
    175 #include "fsm.h"
    176 #include "ipcp.h"
    177 
    178 #ifdef RCSID
    179 static const char rcsid[] = RCSID;
    180 #endif
    181 
    182 static int initdisc = -1;	/* Initial TTY discipline for ppp_fd */
    183 static int initfdflags = -1;	/* Initial file descriptor flags for ppp_fd */
    184 static int ppp_fd = -1;		/* fd which is set to PPP discipline */
    185 static int rtm_seq;
    186 
    187 static int restore_term;	/* 1 => we've munged the terminal */
    188 static struct termios inittermios; /* Initial TTY termios */
    189 static struct winsize wsinfo;	/* Initial window size info */
    190 
    191 static int loop_slave = -1;
    192 static int loop_master = -1;
    193 static int doing_cleanup = 0;
    194 static char loop_name[20];
    195 
    196 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
    197 
    198 static int sock_fd;		/* socket for doing interface ioctls */
    199 #ifdef INET6
    200 static int sock6_fd = -1;	/* socket for doing ipv6 interface ioctls */
    201 #endif /* INET6 */
    202 static int ttyfd = -1;		/* the file descriptor of the tty */
    203 
    204 static fd_set in_fds;		/* set of fds that wait_input waits for */
    205 static int max_in_fd;		/* highest fd set in in_fds */
    206 
    207 static int if_is_up;		/* the interface is currently up */
    208 #ifdef INET6
    209 static int if6_is_up;		/* the interface is currently up */
    210 #endif /* INET6 */
    211 static u_int32_t ifaddrs[2];	/* local and remote addresses we set */
    212 static u_int32_t default_route_gateway;	/* gateway addr for default route */
    213 #ifdef INET6
    214 static eui64_t  default_route_gateway6; /* Gateway for default IPv6 route added */
    215 #endif /* INET6 */
    216 static u_int32_t proxy_arp_addr;	/* remote addr for proxy arp */
    217 
    218 /* Prototypes for procedures local to this file. */
    219 static int get_flags(int);
    220 static void set_flags(int, int);
    221 static int dodefaultroute(u_int32_t, int);
    222 static int get_ether_addr(u_int32_t, struct sockaddr_dl *);
    223 static void restore_loop(void);	/* Transfer ppp unit back to loopback */
    224 static int setifstate(int, int);
    225 
    226 
    227 static void
    228 set_queue_size(const char *fmt, int fd) {
    229 #ifdef TIOCSQSIZE
    230     int oqsize, qsize = 32768;
    231 
    232     /* Only for ptys */
    233     if (ioctl(fd, TIOCGQSIZE, &oqsize) == -1)
    234 	return;
    235 
    236     if (oqsize >= qsize)
    237 	return;
    238 
    239     if (ioctl(fd, TIOCSQSIZE, &qsize) == -1)
    240 	warn("%s: Cannot set tty queue size for %d from %d to %d", fmt, fd,
    241 	    oqsize, qsize);
    242     else
    243 	notice("%s: Changed queue size of %d from %d to %d", fmt, fd, oqsize,
    244 	    qsize);
    245 #endif
    246 }
    247 
    248 /********************************************************************
    249  *
    250  * Functions to read and set the flags value in the device driver
    251  */
    252 
    253 static int
    254 get_flags(int fd)
    255 {
    256     int flags;
    257 
    258     if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) == -1)
    259 	fatal("%s: ioctl(PPPIOCGFLAGS): %m", __func__);
    260 
    261     SYSDEBUG((LOG_DEBUG, "get flags = %x\n", flags));
    262     return flags;
    263 }
    264 
    265 /********************************************************************/
    266 
    267 static void
    268 set_flags(int fd, int flags)
    269 {
    270     SYSDEBUG((LOG_DEBUG, "set flags = %x\n", flags));
    271 
    272     if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) == -1)
    273 	fatal("%s: ioctl(PPPIOCSFLAGS, %x): %m", __func__, flags, errno);
    274 }
    275 
    276 /*
    277  * sys_init - System-dependent initialization.
    278  */
    279 void
    280 sys_init(void)
    281 {
    282     /* Get an internet socket for doing socket ioctl's on. */
    283     if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    284 	fatal("%s: Couldn't create IP socket: %m", __func__);
    285 
    286 #ifdef INET6
    287     if ((sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
    288 	/* check it at runtime */
    289 	sock6_fd = -1;
    290     }
    291 #endif
    292 
    293     FD_ZERO(&in_fds);
    294     max_in_fd = 0;
    295 }
    296 
    297 /*
    298  * sys_cleanup - restore any system state we modified before exiting:
    299  * mark the interface down, delete default route and/or proxy arp entry.
    300  * This should call die() because it's called from die().
    301  */
    302 void
    303 sys_cleanup(void)
    304 {
    305     struct ifreq ifr;
    306 
    307     doing_cleanup = 1;
    308     if (if_is_up) {
    309 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    310 	if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) >= 0
    311 	    && ((ifr.ifr_flags & IFF_UP) != 0)) {
    312 	    ifr.ifr_flags &= ~IFF_UP;
    313 	    ioctl(sock_fd, SIOCSIFFLAGS, &ifr);
    314 	}
    315     }
    316     if (ifaddrs[0] != 0)
    317 	cifaddr(0, ifaddrs[0], ifaddrs[1]);
    318     if (default_route_gateway)
    319 	cifdefaultroute(0, 0, default_route_gateway);
    320 #ifdef INET6
    321     if (default_route_gateway6.e32[0] != 0 || default_route_gateway6.e32[1] != 0)
    322 	cif6defaultroute(0, default_route_gateway6, default_route_gateway6);
    323 #endif
    324     if (proxy_arp_addr)
    325 	cifproxyarp(0, proxy_arp_addr);
    326     doing_cleanup = 0;
    327 }
    328 
    329 /*
    330  * sys_close - Clean up in a child process before execing.
    331  */
    332 void
    333 ppp_sys_close()
    334 {
    335     if (sock_fd >= 0)
    336 	close(sock_fd);
    337 #ifdef INET6
    338     if (sock6_fd >= 0)
    339 	close(sock6_fd);
    340 #endif
    341     if (loop_slave >= 0)
    342 	close(loop_slave);
    343     if (loop_master >= 0)
    344 	close(loop_master);
    345 }
    346 
    347 /*
    348  * sys_check_options - check the options that the user specified
    349  */
    350 int
    351 sys_check_options(void)
    352 {
    353 #ifndef CDTRCTS
    354     if (crtscts == 2) {
    355 	warn("%s: DTR/CTS flow control is not supported on this system",
    356 	    __func__);
    357 	return 0;
    358     }
    359 #endif
    360     return 1;
    361 }
    362 
    363 /*
    364  * ppp_check_kernel_support - check whether the system has any ppp interfaces
    365  * (in fact we check whether we can create one)
    366  */
    367 int
    368 ppp_check_kernel_support(void)
    369 {
    370     int s;
    371     extern char *no_ppp_msg;
    372     struct ifreq ifr;
    373 
    374 
    375     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    376 	fatal("%s: socket: %m", __func__);
    377 
    378     (void)memset(&ifr, 0, sizeof(ifr));
    379     strlcpy(ifr.ifr_name, "ppp0", sizeof(ifr.ifr_name));
    380     if (ioctl(s, SIOCIFCREATE, &ifr) == -1) {
    381 	int notmine = errno == EEXIST;
    382 	(void)close(s);
    383 	if (notmine)
    384 	    return 1;
    385 	goto out;
    386     }
    387     (void)ioctl(s, SIOCIFDESTROY, &ifr);
    388     (void)close(s);
    389     return 1;
    390 
    391 out:
    392     no_ppp_msg = "\
    393 This system lacks kernel support for PPP.  To include PPP support\n\
    394 in the kernel, please read the ppp(4) manual page.\n";
    395     return 0;
    396 }
    397 
    398 /*
    399  * tty_establish_ppp - Turn the serial port into a ppp interface.
    400  */
    401 int
    402 tty_establish_ppp(int fd)
    403 {
    404     int pppdisc = PPPDISC;
    405     int x;
    406     ttyfd = fd;
    407 
    408     if (demand) {
    409 	/*
    410 	 * Demand mode - prime the old ppp device to relinquish the unit.
    411 	 */
    412 	if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0)
    413 	    fatal("%s: ioctl(transfer ppp unit): %m", __func__);
    414     }
    415 
    416     set_queue_size(__func__, fd);
    417     /*
    418      * Save the old line discipline of fd, and set it to PPP.
    419      */
    420     if (ioctl(fd, TIOCGETD, &initdisc) < 0)
    421 	fatal("%s: ioctl(TIOCGETD): %m", __func__);
    422     if (ioctl(fd, TIOCSETD, &pppdisc) < 0)
    423 	fatal("%s: ioctl(TIOCSETD): %m", __func__);
    424 
    425     if (ioctl(fd, PPPIOCGUNIT, &x) < 0)
    426 	fatal("%s: ioctl(PPPIOCGUNIT): %m", __func__);
    427     if (!demand) {
    428 	/*
    429 	 * Find out which interface we were given.
    430 	 */
    431 	ifunit = x;
    432     } else {
    433 	/*
    434 	 * Check that we got the same unit again.
    435 	 */
    436 	if (x != ifunit)
    437 	    fatal("%s: transfer_ppp failed: wanted unit %d, got %d",
    438 		__func__, ifunit, x);
    439 	x = TTYDISC;
    440 	if (ioctl(loop_slave, TIOCSETD, &x) == -1)
    441 	    fatal("%s: ioctl(TIOCGETD): %m", __func__);
    442     }
    443 
    444     ppp_fd = fd;
    445 
    446     /*
    447      * Enable debug in the driver if requested.
    448      */
    449     if (kdebugflag) {
    450 	x = get_flags(fd);
    451 	x |= (kdebugflag & 0xFF) * SC_DEBUG;
    452 	set_flags(fd, x);
    453     }
    454 
    455     /*
    456      * Set device for non-blocking reads.
    457      */
    458     if ((initfdflags = fcntl(fd, F_GETFL)) == -1
    459 	|| fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
    460 	warn("%s: Couldn't set device to non-blocking mode: %m", __func__);
    461     }
    462 
    463     return fd;
    464 }
    465 
    466 /*
    467  * restore_loop - reattach the ppp unit to the loopback.
    468  */
    469 static void
    470 restore_loop(void)
    471 {
    472     int x;
    473 
    474     set_queue_size(__func__, loop_slave);
    475     /*
    476      * Transfer the ppp interface back to the loopback.
    477      */
    478     if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0)
    479 	fatal("%s: ioctl(transfer ppp unit): %m", __func__);
    480     x = PPPDISC;
    481     if (ioctl(loop_slave, TIOCSETD, &x) < 0)
    482 	fatal("%s: ioctl(TIOCSETD): %m", __func__);
    483 
    484     /*
    485      * Check that we got the same unit again.
    486      */
    487     if (ioctl(loop_slave, PPPIOCGUNIT, &x) < 0)
    488 	fatal("%s: ioctl(PPPIOCGUNIT): %m", __func__);
    489     if (x != ifunit)
    490 	fatal("%s: transfer_ppp failed: wanted unit %d, got %d", __func__,
    491 	    ifunit, x);
    492     ppp_fd = loop_slave;
    493 }
    494 
    495 
    496 /*
    497  * Determine if the PPP connection should still be present.
    498  */
    499 extern int hungup;
    500 
    501 /*
    502  * tty_disestablish_ppp - Restore the serial port to normal operation.
    503  * and reconnect the ppp unit to the loopback if in demand mode.
    504  * This shouldn't call die() because it's called from die().
    505  */
    506 void
    507 tty_disestablish_ppp(fd)
    508     int fd;
    509 {
    510     if (!doing_cleanup && demand)
    511 	restore_loop();
    512 
    513     if (!hungup || demand) {
    514 
    515 	/* Flush the tty output buffer so that the TIOCSETD doesn't hang.  */
    516 	if (tcflush(fd, TCIOFLUSH) < 0)
    517 	    if (!doing_cleanup)
    518 		warn("%s: tcflush failed: %m", __func__);
    519 
    520 	/* Restore old line discipline. */
    521 	if (initdisc >= 0 && ioctl(fd, TIOCSETD, &initdisc) < 0)
    522 	    if (!doing_cleanup)
    523 		error("%s: ioctl(TIOCSETD): %m", __func__);
    524 	initdisc = -1;
    525 
    526 	/* Reset non-blocking mode on fd. */
    527 	if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0)
    528 	    if (!doing_cleanup)
    529 		warn("%s: Couldn't restore device fd flags: %m", __func__);
    530     }
    531     initfdflags = -1;
    532 
    533     if (fd == ppp_fd)
    534 	ppp_fd = -1;
    535 }
    536 
    537 /*
    538  * cfg_bundle - configure the existing bundle.
    539  * Used in demand mode.
    540  */
    541 void
    542 cfg_bundle(int mrru, int mtru, int rssn, int tssn)
    543 {
    544     abort();
    545 #ifdef notyet
    546     int flags;
    547     struct ifreq ifr;
    548 
    549     if (!new_style_driver)
    550 	return;
    551 
    552     /* set the mrru, mtu and flags */
    553     if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
    554 	error("%s: Couldn't set MRRU: %m", __func__);
    555     flags = get_flags(ppp_dev_fd);
    556     flags &= ~(SC_MP_SHORTSEQ | SC_MP_XSHORTSEQ);
    557     flags |= (rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
    558 	    | (mrru? SC_MULTILINK: 0);
    559 
    560     set_flags(ppp_dev_fd, flags);
    561 
    562     /* connect up the channel */
    563     if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
    564 	fatal("%s: Couldn't attach to PPP unit %d: %m", __func__, ifunit);
    565     add_fd(ppp_dev_fd);
    566 #endif
    567 }
    568 
    569 /*
    570  * make_new_bundle - create a new PPP unit (i.e. a bundle)
    571  * and connect our channel to it.  This should only get called
    572  * if `multilink' was set at the time establish_ppp was called.
    573  * In demand mode this uses our existing bundle instead of making
    574  * a new one.
    575  */
    576 void
    577 make_new_bundle(int mrru, int mtru, int rssn, int tssn)
    578 {
    579     abort();
    580 #ifdef notyet
    581     if (!new_style_driver)
    582 	return;
    583 
    584     /* make us a ppp unit */
    585     if (make_ppp_unit() < 0)
    586 	die(1);
    587 
    588     /* set the mrru, mtu and flags */
    589     cfg_bundle(mrru, mtru, rssn, tssn);
    590 #endif
    591 }
    592 
    593 /*
    594  * bundle_attach - attach our link to a given PPP unit.
    595  * We assume the unit is controlled by another pppd.
    596  */
    597 int
    598 bundle_attach(int ifnum)
    599 {
    600     abort();
    601 #ifdef notyet
    602     if (!new_style_driver)
    603 	return -1;
    604 
    605     if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) {
    606 	if (errno == ENXIO)
    607 	    return 0;	/* doesn't still exist */
    608 	fatal("%s: Couldn't attach to interface unit %d: %m", __func__, ifnum);
    609     }
    610     if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
    611 	fatal("%s: Couldn't connect to interface unit %d: %m", __func__, ifnum);
    612     set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK);
    613 
    614     ifunit = ifnum;
    615 #endif
    616     return 1;
    617 }
    618 
    619 /*
    620  * destroy_bundle - tell the driver to destroy our bundle.
    621  */
    622 void destroy_bundle(void)
    623 {
    624 #if notyet
    625 	if (ppp_dev_fd >= 0) {
    626 		close(ppp_dev_fd);
    627 		remove_fd(ppp_dev_fd);
    628 		ppp_dev_fd = -1;
    629 	}
    630 #endif
    631 }
    632 
    633 /*
    634  * Check whether the link seems not to be 8-bit clean.
    635  */
    636 void
    637 clean_check(void)
    638 {
    639     int x;
    640     char *s;
    641 
    642     if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
    643 	s = NULL;
    644 	switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
    645 	case SC_RCV_B7_0:
    646 	    s = "bit 7 set to 1";
    647 	    break;
    648 	case SC_RCV_B7_1:
    649 	    s = "bit 7 set to 0";
    650 	    break;
    651 	case SC_RCV_EVNP:
    652 	    s = "odd parity";
    653 	    break;
    654 	case SC_RCV_ODDP:
    655 	    s = "even parity";
    656 	    break;
    657 	}
    658 	if (s != NULL) {
    659 	    struct ppp_rawin win;
    660 	    char buf[4 * sizeof(win.buf) + 1];
    661 	    int i;
    662 	    warn("%s: Serial link is not 8-bit clean:", __func__);
    663 	    warn("%s: All received characters had %s", __func__, s);
    664 	    if (ioctl(ppp_fd, PPPIOCGRAWIN, &win) == -1) {
    665 		warn("%s: ioctl(PPPIOCGRAWIN): %s", __func__, strerror(errno));
    666 		return;
    667 	    }
    668 	    for (i = 0; i < sizeof(win.buf); i++)
    669 		win.buf[i] = win.buf[i] & 0x7f;
    670 	    strvisx(buf, (char *)win.buf, win.count, VIS_CSTYLE);
    671 	    warn("%s: Last %d characters were: %s", __func__, (int)win.count,
    672 		buf);
    673 	}
    674     }
    675 }
    676 
    677 
    678 /*
    679  * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
    680  * at the requested speed, etc.  If `local' is true, set CLOCAL
    681  * regardless of whether the modem option was specified.
    682  *
    683  * For *BSD, we assume that speed_t values numerically equal bits/second.
    684  */
    685 void
    686 set_up_tty(int fd, int local)
    687 {
    688     struct termios tios;
    689 
    690     if (tcgetattr(fd, &tios) < 0)
    691 	fatal("%s: tcgetattr: %m", __func__);
    692 
    693     if (!restore_term) {
    694 	inittermios = tios;
    695 	ioctl(fd, TIOCGWINSZ, &wsinfo);
    696     }
    697 
    698     set_queue_size(__func__, fd);
    699 
    700     tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
    701     if (crtscts > 0 && !local) {
    702         if (crtscts == 2) {
    703 #ifdef CDTRCTS
    704             tios.c_cflag |= CDTRCTS;
    705 #endif
    706 	} else
    707 	    tios.c_cflag |= CRTSCTS;
    708     } else if (crtscts < 0) {
    709 	tios.c_cflag &= ~CRTSCTS;
    710 #ifdef CDTRCTS
    711 	tios.c_cflag &= ~CDTRCTS;
    712 #endif
    713     }
    714 
    715     tios.c_cflag |= CS8 | CREAD | HUPCL;
    716     if (local || !modem)
    717 	tios.c_cflag |= CLOCAL;
    718     tios.c_iflag = IGNBRK | IGNPAR;
    719     tios.c_oflag = 0;
    720     tios.c_lflag = 0;
    721     tios.c_cc[VMIN] = 1;
    722     tios.c_cc[VTIME] = 0;
    723 
    724     if (crtscts == -2) {
    725 	tios.c_iflag |= IXON | IXOFF;
    726 	tios.c_cc[VSTOP] = 0x13;	/* DC3 = XOFF = ^S */
    727 	tios.c_cc[VSTART] = 0x11;	/* DC1 = XON  = ^Q */
    728     }
    729 
    730     if (inspeed) {
    731 	cfsetospeed(&tios, inspeed);
    732 	cfsetispeed(&tios, inspeed);
    733     } else {
    734 	inspeed = cfgetospeed(&tios);
    735 	/*
    736 	 * We can't proceed if the serial port speed is 0,
    737 	 * since that implies that the serial port is disabled.
    738 	 */
    739 	if (inspeed == 0)
    740 	    fatal("%s: Baud rate for %s is 0; need explicit baud rate",
    741 		__func__, devnam);
    742     }
    743     baud_rate = inspeed;
    744 
    745     if (tcsetattr(fd, TCSAFLUSH, &tios) < 0)
    746 	fatal("%s: tcsetattr: %m", __func__);
    747 
    748     restore_term = 1;
    749 }
    750 
    751 /*
    752  * restore_tty - restore the terminal to the saved settings.
    753  */
    754 void
    755 restore_tty(int fd)
    756 {
    757     if (restore_term) {
    758 	if (!default_device) {
    759 	    /*
    760 	     * Turn off echoing, because otherwise we can get into
    761 	     * a loop with the tty and the modem echoing to each other.
    762 	     * We presume we are the sole user of this tty device, so
    763 	     * when we close it, it will revert to its defaults anyway.
    764 	     */
    765 	    inittermios.c_lflag &= ~(ECHO | ECHONL);
    766 	}
    767 	if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
    768 	    if (errno != ENXIO)
    769 		warn("%s: tcsetattr: %m", __func__);
    770 	ioctl(fd, TIOCSWINSZ, &wsinfo);
    771 	restore_term = 0;
    772     }
    773 }
    774 
    775 /*
    776  * setdtr - control the DTR line on the serial port.
    777  * This is called from die(), so it shouldn't call die().
    778  */
    779 void
    780 setdtr(int fd, int on)
    781 {
    782     int modembits = TIOCM_DTR;
    783 
    784     ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
    785 }
    786 
    787 #ifdef INET6
    788 /*
    789  * sif6addr - Config the interface with an IPv6 link-local address
    790  */
    791 int
    792 sif6addr(int unit, eui64_t our_eui64, eui64_t his_eui64)
    793 {
    794 #ifdef __KAME__
    795     int ifindex;
    796     struct in6_aliasreq addreq6;
    797 
    798     if (sock6_fd < 0) {
    799 	fatal("%s: No IPv6 socket available", __func__);
    800 	/*NOTREACHED*/
    801     }
    802 
    803     /* actually, this part is not kame local - RFC2553 conformant */
    804     ifindex = if_nametoindex(ifname);
    805     if (ifindex == 0) {
    806 	error("%s: sifaddr6: no interface %s", __func__, ifname);
    807 	return 0;
    808     }
    809 
    810     memset(&addreq6, 0, sizeof(addreq6));
    811     strlcpy(addreq6.ifra_name, ifname, sizeof(addreq6.ifra_name));
    812 
    813     /* my addr */
    814     IN6_LLADDR_FROM_EUI64(addreq6.ifra_addr, our_eui64);
    815     IN6_IFINDEX(addreq6.ifra_addr, ifindex);
    816 
    817 #ifdef notdef
    818     /* his addr */
    819     IN6_LLADDR_FROM_EUI64(addreq6.ifra_dstaddr, his_eui64);
    820     IN6_IFINDEX(addreq6.ifra_dstaddr, ifindex);
    821 #endif
    822 
    823     /* prefix mask: 72bit */
    824     addreq6.ifra_prefixmask.sin6_family = AF_INET6;
    825     addreq6.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
    826     memset(&addreq6.ifra_prefixmask.sin6_addr, 0xff,
    827 	sizeof(addreq6.ifra_prefixmask.sin6_addr) - sizeof(our_eui64));
    828     memset((char *)&addreq6.ifra_prefixmask.sin6_addr +
    829 	sizeof(addreq6.ifra_prefixmask.sin6_addr) - sizeof(our_eui64), 0x00,
    830 	sizeof(our_eui64));
    831 
    832     /* address lifetime (infty) */
    833     addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
    834     addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
    835 
    836     if (ioctl(sock6_fd, SIOCAIFADDR_IN6, &addreq6) < 0) {
    837 	error("%s: sif6addr: ioctl(SIOCAIFADDR_IN6): %m", __func__);
    838 	return 0;
    839     }
    840 
    841     return 1;
    842 #else
    843     struct in6_ifreq ifr6;
    844     struct ifreq ifr;
    845     struct in6_rtmsg rt6;
    846 
    847     if (sock6_fd < 0) {
    848 	fatal("%s: No IPv6 socket available", __func__);
    849 	/*NOTREACHED*/
    850     }
    851 
    852     memset(&ifr, 0, sizeof (ifr));
    853     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    854     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
    855 	error("%s: sif6addr: ioctl(SIOCGIFINDEX): %m", __func__);
    856 	return 0;
    857     }
    858 
    859     /* Local interface */
    860     memset(&ifr6, 0, sizeof(ifr6));
    861     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
    862     ifr6.ifr6_ifindex = ifindex;
    863     ifr6.ifr6_prefixlen = 10;
    864 
    865     if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
    866 	error("%s: sif6addr: ioctl(SIOCSIFADDR): %m", __func__);
    867 	return 0;
    868     }
    869 
    870     /* Route to remote host */
    871     memset(&rt6, 0, sizeof(rt6));
    872     IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
    873     rt6.rtmsg_flags = RTF_UP;
    874     rt6.rtmsg_dst_len = 10;
    875     rt6.rtmsg_ifindex = ifr.ifr_ifindex;
    876     rt6.rtmsg_metric = 1;
    877 
    878     if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
    879 	error("%s: sif6addr: ioctl(SIOCADDRT): %m", __func__);
    880 	return 0;
    881     }
    882 
    883     return 1;
    884 #endif
    885 }
    886 
    887 
    888 /*
    889  * cif6addr - Remove IPv6 address from interface
    890  */
    891 int
    892 cif6addr(int unit, eui64_t our_eui64, eui64_t his_eui64)
    893 {
    894 #ifdef __KAME__
    895     int ifindex;
    896     struct in6_ifreq delreq6;
    897 
    898     if (sock6_fd < 0) {
    899 	fatal("%s: No IPv6 socket available", __func__);
    900 	/*NOTREACHED*/
    901     }
    902 
    903     /* actually, this part is not kame local - RFC2553 conformant */
    904     ifindex = if_nametoindex(ifname);
    905     if (ifindex == 0) {
    906 	error("%s: cifaddr6: no interface %s", __func__, ifname);
    907 	return 0;
    908     }
    909 
    910     memset(&delreq6, 0, sizeof(delreq6));
    911     strlcpy(delreq6.ifr_name, ifname, sizeof(delreq6.ifr_name));
    912 
    913     /* my addr */
    914     IN6_LLADDR_FROM_EUI64(delreq6.ifr_ifru.ifru_addr, our_eui64);
    915     IN6_IFINDEX(delreq6.ifr_ifru.ifru_addr, ifindex);
    916 
    917     if (ioctl(sock6_fd, SIOCDIFADDR_IN6, &delreq6) < 0) {
    918 	error("%s: cif6addr: ioctl(SIOCDIFADDR_IN6): %m", __func__);
    919 	return 0;
    920     }
    921 
    922     return 1;
    923 #else
    924     struct ifreq ifr;
    925     struct in6_ifreq ifr6;
    926 
    927     if (sock6_fd < 0) {
    928 	fatal("%s: No IPv6 socket available", __func__);
    929 	/*NOTREACHED*/
    930     }
    931 
    932     memset(&ifr, 0, sizeof(ifr));
    933     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    934     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
    935 	error("%s: cif6addr: ioctl(SIOCGIFINDEX): %m", __func__);
    936 	return 0;
    937     }
    938 
    939     memset(&ifr6, 0, sizeof(ifr6));
    940     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
    941     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
    942     ifr6.ifr6_prefixlen = 10;
    943 
    944     if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
    945 	if (errno != EADDRNOTAVAIL) {
    946 	    if (! ok_error (errno))
    947 		error("%s: cif6addr: ioctl(SIOCDIFADDR): %m", __func__);
    948 	}
    949         else {
    950 	    warn("%s: cif6addr: ioctl(SIOCDIFADDR): No such address", __func__);
    951 	}
    952         return (0);
    953     }
    954     return 1;
    955 #endif
    956 }
    957 #endif /* INET6 */
    958 
    959 /*
    960  * get_pty - get a pty master/slave pair and chown the slave side
    961  * to the uid given.  Assumes slave_name points to >= 12 bytes of space.
    962  */
    963 int
    964 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
    965 {
    966     struct termios tios;
    967 
    968     if (openpty(master_fdp, slave_fdp, slave_name, NULL, NULL) < 0)
    969 	return 0;
    970 
    971     set_queue_size(__func__, *master_fdp);
    972     set_queue_size(__func__, *slave_fdp);
    973     fchown(*slave_fdp, uid, -1);
    974     fchmod(*slave_fdp, S_IRUSR | S_IWUSR);
    975     if (tcgetattr(*slave_fdp, &tios) == 0) {
    976 	tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
    977 	tios.c_cflag |= CS8 | CREAD | CLOCAL;
    978 	tios.c_iflag  = IGNPAR;
    979 	tios.c_oflag  = 0;
    980 	tios.c_lflag  = 0;
    981 	if (tcsetattr(*slave_fdp, TCSAFLUSH, &tios) < 0)
    982 	    warn("%s: couldn't set attributes on pty: %m", __func__);
    983     } else
    984 	warn("%s: couldn't get attributes on pty: %m", __func__);
    985 
    986     return 1;
    987 }
    988 
    989 
    990 /*
    991  * open_ppp_loopback - open the device we use for getting
    992  * packets in demand mode, and connect it to a ppp interface.
    993  * Here we use a pty.
    994  */
    995 int
    996 open_ppp_loopback(void)
    997 {
    998     int flags;
    999     struct termios tios;
   1000     int pppdisc = PPPDISC;
   1001 
   1002     if (openpty(&loop_master, &loop_slave, loop_name, NULL, NULL) < 0)
   1003 	fatal("%s: No free pty for loopback", __func__);
   1004     SYSDEBUG(("using %s for loopback", loop_name));
   1005 
   1006     if (tcgetattr(loop_slave, &tios) == 0) {
   1007 	tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
   1008 	tios.c_cflag |= CS8 | CREAD | CLOCAL;
   1009 	tios.c_iflag = IGNPAR;
   1010 	tios.c_oflag = 0;
   1011 	tios.c_lflag = 0;
   1012 	if (tcsetattr(loop_slave, TCSAFLUSH, &tios) < 0)
   1013 	    warn("%s: couldn't set attributes on loopback: %m", __func__);
   1014     }
   1015 
   1016     flags = fcntl(loop_master, F_GETFL);
   1017     if (flags == -1 || fcntl(loop_master, F_SETFL, flags | O_NONBLOCK) == -1)
   1018 	    warn("%s: couldn't set master loopback to nonblock: %m", __func__);
   1019 
   1020     flags = fcntl(loop_slave, F_GETFL);
   1021     if (flags == -1 || fcntl(loop_slave, F_SETFL, flags | O_NONBLOCK) == -1)
   1022 	    warn("%s: couldn't set slave loopback to nonblock: %m", __func__);
   1023 
   1024     ppp_fd = loop_slave;
   1025     if (ioctl(ppp_fd, TIOCSETD, &pppdisc) < 0)
   1026 	fatal("%s: ioctl(TIOCSETD): %m", __func__);
   1027 
   1028     /*
   1029      * Find out which interface we were given.
   1030      */
   1031     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
   1032 	fatal("%s: ioctl(PPPIOCGUNIT): %m", __func__);
   1033 
   1034     /*
   1035      * Enable debug in the driver if requested.
   1036      */
   1037     if (kdebugflag) {
   1038 	flags = get_flags(ppp_fd);
   1039 	flags |= (kdebugflag & 0xFF) * SC_DEBUG;
   1040 	set_flags(ppp_fd, flags);
   1041     }
   1042 
   1043     return loop_master;
   1044 }
   1045 
   1046 
   1047 /*
   1048  * output - Output PPP packet.
   1049  */
   1050 void
   1051 output(int unit, u_char *p, int len)
   1052 {
   1053     if (debug)
   1054 	dbglog("sent %P", p, len);
   1055 
   1056     if (write(ttyfd, p, len) < 0) {
   1057 	if (errno != EIO)
   1058 	    error("%s: write: %m", __func__);
   1059     }
   1060 }
   1061 
   1062 
   1063 /*
   1064  * wait_input - wait until there is data available,
   1065  * for the length of time specified by *timo (indefinite
   1066  * if timo is NULL).
   1067  */
   1068 void
   1069 wait_input(struct timeval *timo)
   1070 {
   1071     fd_set ready, eready;
   1072     int n;
   1073 
   1074     ready = in_fds;
   1075     eready = in_fds;
   1076     n = select(max_in_fd + 1, &ready, NULL, &eready, timo);
   1077     if (n < 0 && errno != EINTR)
   1078 	fatal("%s: select: %m", __func__);
   1079 }
   1080 
   1081 
   1082 /*
   1083  * add_fd - add an fd to the set that wait_input waits for.
   1084  */
   1085 void add_fd(int fd)
   1086 {
   1087     if (fd >= FD_SETSIZE)
   1088 	fatal("%s: descriptor too big", __func__);
   1089     FD_SET(fd, &in_fds);
   1090     if (fd > max_in_fd)
   1091 	max_in_fd = fd;
   1092 }
   1093 
   1094 /*
   1095  * remove_fd - remove an fd from the set that wait_input waits for.
   1096  */
   1097 void remove_fd(int fd)
   1098 {
   1099     FD_CLR(fd, &in_fds);
   1100 }
   1101 
   1102 #if 0
   1103 /*
   1104  * wait_loop_output - wait until there is data available on the
   1105  * loopback, for the length of time specified by *timo (indefinite
   1106  * if timo is NULL).
   1107  */
   1108 void
   1109 wait_loop_output(struct timeval *timo)
   1110 {
   1111     fd_set ready;
   1112     int n;
   1113 
   1114     FD_ZERO(&ready);
   1115     if (loop_master >= FD_SETSIZE)
   1116 	fatal("%s: descriptor too big", __func__);
   1117     FD_SET(loop_master, &ready);
   1118     n = select(loop_master + 1, &ready, NULL, &ready, timo);
   1119     if (n < 0 && errno != EINTR)
   1120 	fatal("%s: select: %m", __func__);
   1121 }
   1122 
   1123 
   1124 /*
   1125  * wait_time - wait for a given length of time or until a
   1126  * signal is received.
   1127  */
   1128 void
   1129 wait_time(struct timeval *timo)
   1130 {
   1131     int n;
   1132 
   1133     n = select(0, NULL, NULL, NULL, timo);
   1134     if (n < 0 && errno != EINTR)
   1135 	fatal("%s: select: %m", __func__);
   1136 }
   1137 #endif
   1138 
   1139 
   1140 /*
   1141  * read_packet - get a PPP packet from the serial device.
   1142  */
   1143 int
   1144 read_packet(u_char *buf)
   1145 {
   1146     int len;
   1147 
   1148     if ((len = read(ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) {
   1149 	if (errno == EWOULDBLOCK || errno == EINTR)
   1150 	    return -1;
   1151 	fatal("%s: read: %m", __func__);
   1152     }
   1153     return len;
   1154 }
   1155 
   1156 
   1157 /*
   1158  * get_loop_output - read characters from the loopback, form them
   1159  * into frames, and detect when we want to bring the real link up.
   1160  * Return value is 1 if we need to bring up the link, 0 otherwise.
   1161  */
   1162 int
   1163 get_loop_output(void)
   1164 {
   1165     int rv = 0;
   1166     int n;
   1167 
   1168     while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) {
   1169 	if (loop_chars(inbuf, n))
   1170 	    rv = 1;
   1171     }
   1172 
   1173     if (n == 0)
   1174 	fatal("%s: eof on loopback", __func__);
   1175     if (n == -1 && errno != EWOULDBLOCK)
   1176 	fatal("%s: read from loopback: %m", __func__);
   1177 
   1178     return rv;
   1179 }
   1180 
   1181 
   1182 /*
   1183  * ppp_set_mtu - set the MTU on the PPP network interface.
   1184  */
   1185 void
   1186 ppp_set_mtu(int unit, int mtu)
   1187 {
   1188     struct ifreq ifr;
   1189 
   1190     SYSDEBUG((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu));
   1191 
   1192     memset(&ifr, '\0', sizeof (ifr));
   1193     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
   1194     ifr.ifr_mtu = mtu;
   1195 
   1196     if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
   1197 	fatal("%s: ioctl(SIOCSIFMTU): %m", __func__);
   1198 }
   1199 
   1200 /*
   1201  * ppp_get_mtu - get the MTU on the PPP network interface.
   1202  */
   1203 int
   1204 ppp_get_mtu(int unit)
   1205 {
   1206     struct ifreq ifr;
   1207 
   1208     memset (&ifr, '\0', sizeof (ifr));
   1209     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
   1210 
   1211     if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
   1212 	error("%s: ioctl(SIOCGIFMTU): %m", __func__);
   1213 	return 0;
   1214     }
   1215     return ifr.ifr_mtu;
   1216 }
   1217 
   1218 /*
   1219  * tty_send_config - configure the transmit characteristics of
   1220  * the ppp interface.
   1221  */
   1222 void
   1223 tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
   1224 {
   1225     u_int x;
   1226 #if 0
   1227     /* Linux code does not do anything with the mtu here */
   1228     ifnet_set_mtu(-1, mtu);
   1229 #endif
   1230 
   1231     if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0)
   1232 	fatal("%s: ioctl(PPPIOCSASYNCMAP): %m", __func__);
   1233 
   1234     x = get_flags(ppp_fd);
   1235     x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT;
   1236     x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC;
   1237     x = ppp_sync_serial() ? x | SC_SYNC : x & ~SC_SYNC;
   1238     set_flags(ppp_fd, x);
   1239 }
   1240 
   1241 
   1242 /*
   1243  * ppp_set_xaccm - set the extended transmit ACCM for the interface.
   1244  */
   1245 void
   1246 tty_set_xaccm(ext_accm accm)
   1247 {
   1248     if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)
   1249 	warn("%s: ioctl(set extended ACCM): %m", __func__);
   1250 }
   1251 
   1252 
   1253 /*
   1254  * ppp_recv_config - configure the receive-side characteristics of
   1255  * the ppp interface.
   1256  */
   1257 void
   1258 tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
   1259 {
   1260     int x;
   1261 
   1262     if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
   1263 	fatal("%s: ioctl(PPPIOCSMRU): %m", __func__);
   1264     if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0)
   1265 	fatal("%s: ioctl(PPPIOCSRASYNCMAP): %m", __func__);
   1266     x = get_flags(ppp_fd);
   1267     x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;
   1268     set_flags(ppp_fd, x);
   1269 }
   1270 
   1271 /*
   1272  * ccp_test - ask kernel whether a given compression method
   1273  * is acceptable for use.  Returns 1 if the method and parameters
   1274  * are OK, 0 if the method is known but the parameters are not OK
   1275  * (e.g. code size should be reduced), or -1 if the method is unknown.
   1276  */
   1277 int
   1278 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
   1279 {
   1280     struct ppp_option_data data;
   1281 
   1282     data.ptr = opt_ptr;
   1283     data.length = opt_len;
   1284     data.transmit = for_transmit;
   1285     if (ioctl(ttyfd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
   1286 	return 1;
   1287     return (errno == ENOBUFS)? 0: -1;
   1288 }
   1289 
   1290 /*
   1291  * ccp_flags_set - inform kernel about the current state of CCP.
   1292  */
   1293 void
   1294 ccp_flags_set(int unit, int isopen, int isup)
   1295 {
   1296     int x;
   1297 
   1298     x = get_flags(ppp_fd);
   1299     x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN;
   1300     x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP;
   1301     set_flags(ppp_fd, x);
   1302 }
   1303 
   1304 /*
   1305  * ccp_fatal_error - returns 1 if decompression was disabled as a
   1306  * result of an error detected after decompression of a packet,
   1307  * 0 otherwise.  This is necessary because of patent nonsense.
   1308  */
   1309 int
   1310 ccp_fatal_error(int unit)
   1311 {
   1312     int x;
   1313 
   1314     x = get_flags(ppp_fd);
   1315     return x & SC_DC_FERROR;
   1316 }
   1317 
   1318 /*
   1319  * get_idle_time - return how long the link has been idle.
   1320  */
   1321 int
   1322 get_idle_time(int u, struct ppp_idle *ip)
   1323 {
   1324     return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0;
   1325 }
   1326 
   1327 /*
   1328  * get_ppp_stats - return statistics for the link.
   1329  */
   1330 int
   1331 get_ppp_stats(int u, struct pppd_stats *stats)
   1332 {
   1333     struct ifpppstatsreq req;
   1334 
   1335     memset (&req, 0, sizeof (req));
   1336     strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
   1337     if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
   1338 	error("%s: Couldn't get PPP statistics: %m", __func__);
   1339 	return 0;
   1340     }
   1341     stats->bytes_in = req.stats.p.ppp_ibytes;
   1342     stats->bytes_out = req.stats.p.ppp_obytes;
   1343     stats->pkts_in = req.stats.p.ppp_ipackets;
   1344     stats->pkts_out = req.stats.p.ppp_opackets;
   1345     return 1;
   1346 }
   1347 
   1348 
   1349 #ifdef PPP_WITH_FILTER
   1350 /*
   1351  * set_filters - transfer the pass and active filters to the kernel.
   1352  */
   1353 int
   1354 set_filters(struct bpf_program *pass_in, struct bpf_program *pass_out,
   1355     struct bpf_program *active_in, struct bpf_program *active_out)
   1356 {
   1357     int ret = 1;
   1358 
   1359     if (pass_in->bf_len > 0) {
   1360 	if (ioctl(ppp_fd, PPPIOCSIPASS, pass_in) < 0) {
   1361 	    error("%s: Couldn't set pass-filter-in in kernel: %m", __func__);
   1362 	    ret = 0;
   1363 	}
   1364     }
   1365 
   1366     if (pass_out->bf_len > 0) {
   1367 	if (ioctl(ppp_fd, PPPIOCSOPASS, pass_out) < 0) {
   1368 	    error("%s: Couldn't set pass-filter-out in kernel: %m", __func__);
   1369 	    ret = 0;
   1370 	}
   1371     }
   1372 
   1373     if (active_in->bf_len > 0) {
   1374 	if (ioctl(ppp_fd, PPPIOCSIACTIVE, active_in) < 0) {
   1375 	    error("%s: Couldn't set active-filter-in in kernel: %m", __func__);
   1376 	    ret = 0;
   1377 	}
   1378     }
   1379 
   1380     if (active_out->bf_len > 0) {
   1381 	if (ioctl(ppp_fd, PPPIOCSOACTIVE, active_out) < 0) {
   1382 	    error("%s: Couldn't set active-filter-out in kernel: %m", __func__);
   1383 	    ret = 0;
   1384 	}
   1385     }
   1386 
   1387     return ret;
   1388 }
   1389 #endif
   1390 
   1391 /*
   1392  * sifvjcomp - config tcp header compression
   1393  */
   1394 int
   1395 sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid)
   1396 {
   1397     u_int x;
   1398 
   1399     x = get_flags(ppp_fd);
   1400     x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP;
   1401     x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID;
   1402     set_flags(ppp_fd, x);
   1403     if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
   1404 	error("%s: ioctl(PPPIOCSMAXCID): %m", __func__);
   1405 	return 0;
   1406     }
   1407     return 1;
   1408 }
   1409 
   1410 /********************************************************************
   1411  *
   1412  * sifup - Config the interface up and enable IP packets to pass.
   1413  */
   1414 
   1415 int sifup(int u)
   1416 {
   1417     int ret;
   1418 
   1419     if ((ret = setifstate(u, 1)))
   1420 	if_is_up++;
   1421 
   1422     return ret;
   1423 }
   1424 
   1425 /********************************************************************
   1426  *
   1427  * sifdown - Disable the indicated protocol and config the interface
   1428  *	     down if there are no remaining protocols.
   1429  */
   1430 
   1431 int sifdown (int u)
   1432 {
   1433     if (if_is_up && --if_is_up > 0)
   1434 	return 1;
   1435 
   1436 #ifdef INET6
   1437     if (if6_is_up)
   1438 	return 1;
   1439 #endif /* INET6 */
   1440 
   1441     return setifstate(u, 0);
   1442 }
   1443 
   1444 #ifdef INET6
   1445 /********************************************************************
   1446  *
   1447  * sif6up - Config the interface up for IPv6
   1448  */
   1449 
   1450 int sif6up(int u)
   1451 {
   1452     int ret;
   1453 
   1454     if ((ret = setifstate(u, 1)))
   1455 	if6_is_up = 1;
   1456 
   1457     return ret;
   1458 }
   1459 
   1460 /********************************************************************
   1461  *
   1462  * sif6down - Disable the IPv6CP protocol and config the interface
   1463  *	      down if there are no remaining protocols.
   1464  */
   1465 
   1466 int sif6down (int u)
   1467 {
   1468     if6_is_up = 0;
   1469 
   1470     if (if_is_up)
   1471 	return 1;
   1472 
   1473     return setifstate(u, 0);
   1474 }
   1475 #endif /* INET6 */
   1476 
   1477 /********************************************************************
   1478  *
   1479  * setifstate - Config the interface up or down
   1480  */
   1481 
   1482 static int setifstate (int u, int state)
   1483 {
   1484     struct ifreq ifr;
   1485 
   1486     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
   1487     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
   1488 	error("%s: ioctl (SIOCGIFFLAGS): %m", __func__);
   1489 	return 0;
   1490     }
   1491     if (state)
   1492 	ifr.ifr_flags |= IFF_UP;
   1493     else
   1494 	ifr.ifr_flags &= ~IFF_UP;
   1495     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
   1496 	error("%s: ioctl(SIOCSIFFLAGS): %m", __func__);
   1497 	return 0;
   1498     }
   1499     if_is_up = 1;
   1500     return 1;
   1501 }
   1502 
   1503 /*
   1504  * sifnpmode - Set the mode for handling packets for a given NP.
   1505  */
   1506 int
   1507 sifnpmode(int u, int proto, enum NPmode mode)
   1508 {
   1509     struct npioctl npi;
   1510 
   1511     npi.protocol = proto;
   1512     npi.mode = mode;
   1513     if (ioctl(ppp_fd, PPPIOCSNPMODE, &npi) < 0) {
   1514 	error("%s: ioctl(set NP %d mode to %d): %m", __func__, proto, mode);
   1515 	return 0;
   1516     }
   1517     return 1;
   1518 }
   1519 
   1520 /*
   1521  * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
   1522  * if it exists.
   1523  */
   1524 #define SET_SA_FAMILY(addr, family)		\
   1525     BZERO((char *) &(addr), sizeof(addr));	\
   1526     addr.sa_family = (family); 			\
   1527     addr.sa_len = sizeof(addr);
   1528 
   1529 /*
   1530  * sifaddr - Config the interface IP addresses and netmask.
   1531  */
   1532 int
   1533 sifaddr(int u, u_int32_t o, u_int32_t h, u_int32_t m)
   1534 {
   1535     struct ifaliasreq ifra;
   1536     struct ifreq ifr;
   1537 
   1538     strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
   1539     SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
   1540     ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
   1541     SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
   1542     ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
   1543     if (m != 0) {
   1544 	SET_SA_FAMILY(ifra.ifra_mask, AF_INET);
   1545 	((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m;
   1546     } else
   1547 	BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
   1548     BZERO(&ifr, sizeof(ifr));
   1549     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
   1550     if (ioctl(sock_fd, SIOCDIFADDR, (caddr_t) &ifr) < 0) {
   1551 	if (errno != EADDRNOTAVAIL)
   1552 	    warn("%s: Couldn't remove interface address: %m", __func__);
   1553     }
   1554     if (ioctl(sock_fd, SIOCAIFADDR, (caddr_t) &ifra) < 0) {
   1555 	if (errno != EEXIST) {
   1556 	    error("%s: Couldn't set interface address: %m", __func__);
   1557 	    return 0;
   1558 	}
   1559 	warn("%s: Couldn't set interface address: Address %I already exists",
   1560 	    __func__, o);
   1561     }
   1562     ifaddrs[0] = o;
   1563     ifaddrs[1] = h;
   1564     return 1;
   1565 }
   1566 
   1567 /*
   1568  * cifaddr - Clear the interface IP addresses, and delete routes
   1569  * through the interface if possible.
   1570  */
   1571 int
   1572 cifaddr(int u, u_int32_t o, u_int32_t h)
   1573 {
   1574     struct ifaliasreq ifra;
   1575 
   1576     ifaddrs[0] = 0;
   1577     strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
   1578     SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
   1579     ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
   1580     SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
   1581     ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;
   1582     BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
   1583     if (ioctl(sock_fd, SIOCDIFADDR, (caddr_t) &ifra) < 0) {
   1584 	if (!doing_cleanup && errno != EADDRNOTAVAIL)
   1585 	    warn("%s: Couldn't delete interface address: %m", __func__);
   1586 	return 0;
   1587     }
   1588     return 1;
   1589 }
   1590 
   1591 /*
   1592  * sifdefaultroute - assign a default route through the address given.
   1593  */
   1594 int
   1595 sifdefaultroute(int u, u_int32_t l, u_int32_t g, bool replace)
   1596 {
   1597     if (replace)
   1598 	dodefaultroute(g, 'c');
   1599     return dodefaultroute(g, 's');
   1600 }
   1601 
   1602 /*
   1603  * cifdefaultroute - delete a default route through the address given.
   1604  */
   1605 int
   1606 cifdefaultroute(int u, u_int32_t l, u_int32_t g)
   1607 {
   1608     return dodefaultroute(g, 'c');
   1609 }
   1610 
   1611 /*
   1612  * dodefaultroute - talk to a routing socket to add/delete a default route.
   1613  */
   1614 static int
   1615 dodefaultroute(u_int32_t g, int cmd)
   1616 {
   1617     int routes;
   1618     struct {
   1619 	struct rt_msghdr	hdr;
   1620 	struct sockaddr_in	dst;
   1621 	struct sockaddr_in	gway;
   1622 	struct sockaddr_in	netmask;
   1623 	struct sockaddr_dl	ifp;
   1624     } rtmsg;
   1625 
   1626     if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
   1627 	if (!doing_cleanup)
   1628 	    error("%s: Couldn't %s default route: socket: %m", __func__,
   1629 		cmd == 's' ? "add" : "delete");
   1630 	return 0;
   1631     }
   1632 
   1633     memset(&rtmsg, 0, sizeof(rtmsg));
   1634 
   1635     rtmsg.hdr.rtm_type = cmd == 's' ? RTM_ADD : RTM_DELETE;
   1636     rtmsg.hdr.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
   1637     rtmsg.hdr.rtm_version = RTM_VERSION;
   1638     rtmsg.hdr.rtm_seq = ++rtm_seq;
   1639     rtmsg.hdr.rtm_addrs =
   1640 	RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_IFP;
   1641 
   1642     rtmsg.dst.sin_len = sizeof(rtmsg.dst);
   1643     rtmsg.dst.sin_family = AF_INET;
   1644     rtmsg.dst.sin_addr.s_addr = 0;
   1645 
   1646     rtmsg.gway.sin_len = sizeof(rtmsg.gway);
   1647     rtmsg.gway.sin_family = AF_INET;
   1648     rtmsg.gway.sin_addr.s_addr = g;
   1649 
   1650     rtmsg.netmask.sin_len = sizeof(rtmsg.netmask);
   1651     rtmsg.netmask.sin_family = AF_INET;
   1652     rtmsg.netmask.sin_addr.s_addr = 0;
   1653 
   1654     rtmsg.ifp.sdl_family = AF_LINK;
   1655     rtmsg.ifp.sdl_len = sizeof(rtmsg.ifp);
   1656     link_addr(ifname, &rtmsg.ifp);
   1657 
   1658     rtmsg.hdr.rtm_msglen = sizeof(rtmsg);
   1659 
   1660     if (write(routes, &rtmsg, sizeof(rtmsg)) < 0) {
   1661 	if (!doing_cleanup)
   1662 	    error("%s: Couldn't %s default route: %m", __func__,
   1663 		cmd == 's' ? "add" : "delete");
   1664 	close(routes);
   1665 	return 0;
   1666     }
   1667 
   1668     close(routes);
   1669     default_route_gateway = (cmd == 's') ? g : 0;
   1670     return 1;
   1671 }
   1672 
   1673 
   1674 #ifdef INET6
   1675 /*
   1676  * dodefaultroute - assign/clear a default route through the address given.
   1677  */
   1678 static int
   1679 dodefaultroute6(int u, eui64_t l, eui64_t g, char cmd)
   1680 {
   1681     struct {
   1682 	struct rt_msghdr rtm;
   1683 	struct sockaddr_in6 dst;
   1684 	struct sockaddr_in6 gw;
   1685     } rmsg;
   1686     static int seq;
   1687     int rtsock;
   1688 
   1689 #if defined(__USLC__)
   1690     g = l;			/* use the local address as gateway */
   1691 #endif
   1692     memset(&rmsg, 0, sizeof(rmsg));
   1693 
   1694     rmsg.rtm.rtm_msglen = sizeof (rmsg);
   1695     rmsg.rtm.rtm_version = RTM_VERSION;
   1696     rmsg.rtm.rtm_type = cmd == 's' ? RTM_ADD : RTM_DELETE;
   1697     rmsg.rtm.rtm_flags = RTF_GATEWAY;
   1698     rmsg.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
   1699     rmsg.rtm.rtm_pid = getpid();
   1700     rmsg.rtm.rtm_seq = seq++;
   1701 
   1702     rmsg.dst.sin6_family = AF_INET6;
   1703 
   1704     rmsg.gw.sin6_family = AF_INET6;
   1705     IN6_SOCKADDR_FROM_EUI64(&rmsg.gw, g);
   1706 
   1707     rtsock = socket(PF_ROUTE, SOCK_RAW, 0);
   1708 
   1709     if (rtsock < 0) {
   1710 	error("Can't %s default route: %m", cmd == 's' ? "add" : "remove");
   1711 	return 0;
   1712     }
   1713 
   1714     if (write(rtsock, &rmsg, sizeof(rmsg)) < 0)
   1715 	error("Can't %s default route: %m", cmd == 's' ? "add" : "remove");
   1716 
   1717     close(rtsock);
   1718 
   1719     default_route_gateway6 = g;
   1720     return 1;
   1721 }
   1722 
   1723 /*
   1724  * sif6defaultroute - assign a default route through the address given.
   1725  */
   1726 int
   1727 sif6defaultroute(int u, eui64_t l, eui64_t g)
   1728 {
   1729 	return dodefaultroute6(u, l, g, 's');
   1730 }
   1731 
   1732 /*
   1733  * cif6defaultroute - delete a default route through the address given.
   1734  */
   1735 int
   1736 cif6defaultroute(int u, eui64_t l, eui64_t g)
   1737 {
   1738 	return dodefaultroute6(u, l, g, 'c');
   1739 }
   1740 
   1741 #endif
   1742 
   1743 #if RTM_VERSION >= 3
   1744 
   1745 /*
   1746  * sifproxyarp - Make a proxy ARP entry for the peer.
   1747  */
   1748 static struct {
   1749     struct rt_msghdr		hdr;
   1750     struct sockaddr_inarp	dst;
   1751     struct sockaddr_dl		hwa;
   1752     char			extra[128];
   1753 } arpmsg;
   1754 
   1755 static int arpmsg_valid;
   1756 
   1757 int
   1758 sifproxyarp(int unit, u_int32_t hisaddr)
   1759 {
   1760     int routes;
   1761 
   1762     /*
   1763      * Get the hardware address of an interface on the same subnet
   1764      * as our local address.
   1765      */
   1766     memset(&arpmsg, 0, sizeof(arpmsg));
   1767     if (!get_ether_addr(hisaddr, &arpmsg.hwa)) {
   1768 	error("%s: Cannot determine ethernet address for proxy ARP", __func__);
   1769 	return 0;
   1770     }
   1771 
   1772     if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
   1773 	error("%s: Couldn't add proxy arp entry: socket: %m", __func__);
   1774 	return 0;
   1775     }
   1776 
   1777     arpmsg.hdr.rtm_type = RTM_ADD;
   1778     arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC | RTF_LLDATA;
   1779     arpmsg.hdr.rtm_version = RTM_VERSION;
   1780     arpmsg.hdr.rtm_seq = ++rtm_seq;
   1781     arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
   1782     arpmsg.hdr.rtm_inits = RTV_EXPIRE;
   1783     arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp);
   1784     arpmsg.dst.sin_family = AF_INET;
   1785     arpmsg.dst.sin_addr.s_addr = hisaddr;
   1786     arpmsg.dst.sin_other = SIN_PROXY;
   1787 
   1788     arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg
   1789 	+ RT_ROUNDUP(arpmsg.hwa.sdl_len);
   1790     if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
   1791 	error("%s: Couldn't add proxy arp entry: %m", __func__);
   1792 	close(routes);
   1793 	return 0;
   1794     }
   1795 
   1796     close(routes);
   1797     arpmsg_valid = 1;
   1798     proxy_arp_addr = hisaddr;
   1799     return 1;
   1800 }
   1801 
   1802 /*
   1803  * cifproxyarp - Delete the proxy ARP entry for the peer.
   1804  */
   1805 int
   1806 cifproxyarp(int unit, u_int32_t hisaddr)
   1807 {
   1808     int routes;
   1809 
   1810     if (!arpmsg_valid)
   1811 	return 0;
   1812     arpmsg_valid = 0;
   1813 
   1814     arpmsg.hdr.rtm_type = RTM_DELETE;
   1815     arpmsg.hdr.rtm_seq = ++rtm_seq;
   1816 
   1817     if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
   1818 	if (!doing_cleanup)
   1819 	    error("%s: Couldn't delete proxy arp entry: socket: %m", __func__);
   1820 	return 0;
   1821     }
   1822 
   1823     if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
   1824 	if (!doing_cleanup)
   1825 	    error("%s: Couldn't delete proxy arp entry: %m", __func__);
   1826 	close(routes);
   1827 	return 0;
   1828     }
   1829 
   1830     close(routes);
   1831     proxy_arp_addr = 0;
   1832     return 1;
   1833 }
   1834 
   1835 #else	/* RTM_VERSION */
   1836 
   1837 /*
   1838  * sifproxyarp - Make a proxy ARP entry for the peer.
   1839  */
   1840 int
   1841 sifproxyarp(int unit, u_int32_t hisaddr)
   1842 {
   1843     struct arpreq arpreq;
   1844     struct {
   1845 	struct sockaddr_dl	sdl;
   1846 	char			space[128];
   1847     } dls;
   1848 
   1849     BZERO(&arpreq, sizeof(arpreq));
   1850 
   1851     /*
   1852      * Get the hardware address of an interface on the same subnet
   1853      * as our local address.
   1854      */
   1855     if (!get_ether_addr(hisaddr, &dls.sdl)) {
   1856 	error("%s: Cannot determine ethernet address for proxy ARP", __func__);
   1857 	return 0;
   1858     }
   1859 
   1860     arpreq.arp_ha.sa_len = sizeof(struct sockaddr);
   1861     arpreq.arp_ha.sa_family = AF_UNSPEC;
   1862     BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen);
   1863     SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
   1864     ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
   1865     arpreq.arp_flags = ATF_PERM | ATF_PUBL;
   1866     if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
   1867 	error("%s: Couldn't add proxy arp entry: %m", __func__);
   1868 	return 0;
   1869     }
   1870 
   1871     proxy_arp_addr = hisaddr;
   1872     return 1;
   1873 }
   1874 
   1875 /*
   1876  * cifproxyarp - Delete the proxy ARP entry for the peer.
   1877  */
   1878 int
   1879 cifproxyarp(int unit, u_int32_t hisaddr)
   1880 {
   1881     struct arpreq arpreq;
   1882 
   1883     BZERO(&arpreq, sizeof(arpreq));
   1884     SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
   1885     ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
   1886     if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
   1887 	warn("%s: Couldn't delete proxy arp entry: %m", __func__);
   1888 	return 0;
   1889     }
   1890     proxy_arp_addr = 0;
   1891     return 1;
   1892 }
   1893 #endif	/* RTM_VERSION */
   1894 
   1895 
   1896 /*
   1897  * get_ether_addr - get the hardware address of an interface on the
   1898  * the same subnet as ipaddr.
   1899  */
   1900 static int
   1901 get_ether_addr(u_int32_t ipaddr, struct sockaddr_dl *hwaddr)
   1902 {
   1903     u_int32_t ina, mask;
   1904     struct sockaddr_dl *dla;
   1905     struct ifaddrs *ifap, *ifa, *ifp;
   1906 
   1907     /*
   1908      * Scan through looking for an interface with an Internet
   1909      * address on the same subnet as `ipaddr'.
   1910      */
   1911     if (getifaddrs(&ifap) != 0) {
   1912 	error("%s: getifaddrs: %m", __func__);
   1913 	return 0;
   1914     }
   1915 
   1916     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
   1917 	if (ifa->ifa_addr->sa_family != AF_INET)
   1918 	    continue;
   1919 	ina = ((struct sockaddr_in *) ifa->ifa_addr)->sin_addr.s_addr;
   1920 	/*
   1921 	 * Check that the interface is up, and not point-to-point
   1922 	 * or loopback.
   1923 	 */
   1924 	if ((ifa->ifa_flags &
   1925 	     (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
   1926 	     != (IFF_UP|IFF_BROADCAST))
   1927 	    continue;
   1928 	/*
   1929 	 * Get its netmask and check that it's on the right subnet.
   1930 	 */
   1931 	mask = ((struct sockaddr_in *) ifa->ifa_netmask)->sin_addr.s_addr;
   1932 	if ((ipaddr & mask) != (ina & mask))
   1933 	    continue;
   1934 	break;
   1935     }
   1936 
   1937     if (!ifa) {
   1938 	freeifaddrs(ifap);
   1939 	return 0;
   1940     }
   1941     info("found interface %s for proxy arp", ifa->ifa_name);
   1942 
   1943     ifp = ifa;
   1944 
   1945     /*
   1946      * Now scan through again looking for a link-level address
   1947      * for this interface.
   1948      */
   1949     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
   1950 	if (strcmp(ifp->ifa_name, ifa->ifa_name) != 0)
   1951 	    continue;
   1952 	if (ifa->ifa_addr->sa_family != AF_LINK)
   1953 	    continue;
   1954 	/*
   1955 	 * Found the link-level address - copy it out
   1956 	 */
   1957 	dla = (struct sockaddr_dl *) ifa->ifa_addr;
   1958 	BCOPY(dla, hwaddr, dla->sdl_len);
   1959 	freeifaddrs(ifap);
   1960 	return 1;
   1961     }
   1962 
   1963     freeifaddrs(ifap);
   1964     return 0;
   1965 }
   1966 
   1967 /*
   1968  * get_if_hwaddr - get the hardware address for the specified
   1969  * network interface device.
   1970  */
   1971 int
   1972 get_if_hwaddr(u_char *addr, char *name)
   1973 {
   1974 
   1975 #define IFREQ_SAFE (sizeof(struct ifreq) + sizeof(struct sockaddr_dl))
   1976     /* XXX sockaddr_dl is larger than the sockaddr in struct ifreq! */
   1977     union {				/* XXX */
   1978     	struct ifreq _ifreq;		/* XXX */
   1979 	char _X[IFREQ_SAFE]; 		/* XXX */
   1980     } _ifreq_dontsmashstack = {0};	/* XXX */
   1981 #define ifreq_xxx _ifreq_dontsmashstack._ifreq			/* XXX */
   1982 
   1983     struct sockaddr_dl *sdl = (struct sockaddr_dl *) &ifreq_xxx.ifr_addr;
   1984     int fd;
   1985 
   1986     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
   1987 	return 0;
   1988     sdl->sdl_family = AF_LINK;
   1989     (void)strlcpy(ifreq_xxx.ifr_name, name, sizeof(ifreq_xxx.ifr_name));
   1990     if (ioctl(fd, SIOCGIFADDR, &ifreq_xxx) == -1) {
   1991 	(void)close(fd);
   1992 	return 0;
   1993     }
   1994     (void)close(fd);
   1995     (void)memcpy(addr, LLADDR(sdl), sdl->sdl_alen);
   1996     return sdl->sdl_nlen;
   1997 }
   1998 
   1999 /*
   2000  * get_first_ether_hwaddr - get the hardware address for the first
   2001  * ethernet-style interface on this system.
   2002  */
   2003 int
   2004 get_first_ether_hwaddr(u_char *addr)
   2005 {
   2006 	struct if_nameindex *if_ni, *i;
   2007 	struct ifreq ifreq;
   2008 	int ret, sock_fd;
   2009 
   2010 	sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
   2011 	if (sock_fd < 0)
   2012 		return -1;
   2013 
   2014 	if_ni = if_nameindex();
   2015 	if (!if_ni) {
   2016 		close(sock_fd);
   2017 		return -1;
   2018 	}
   2019 
   2020 	ret = -1;
   2021 
   2022 	for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
   2023 		struct sockaddr_dl *sdl = (struct sockaddr_dl *)
   2024 		    &ifreq.ifr_addr;
   2025 		sdl->sdl_family = AF_LINK;
   2026 		strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
   2027 		ret = ioctl(sock_fd, SIOCGIFADDR, &ifreq);
   2028 		if (ret >= 0 && sdl->sdl_family == AF_LINK) {
   2029 			memcpy(addr, LLADDR(sdl), sdl->sdl_alen);
   2030 			break;
   2031 		}
   2032 		ret = -1;
   2033 	}
   2034 
   2035 	if_freenameindex(if_ni);
   2036 	close(sock_fd);
   2037 
   2038 	return ret;
   2039 }
   2040 
   2041 /*
   2042  * Return user specified netmask, modified by any mask we might determine
   2043  * for address `addr' (in network byte order).
   2044  * Here we scan through the system's list of interfaces, looking for
   2045  * any non-point-to-point interfaces which might appear to be on the same
   2046  * network as `addr'.  If we find any, we OR in their netmask to the
   2047  * user-specified netmask.
   2048  */
   2049 u_int32_t
   2050 GetMask(u_int32_t addr)
   2051 {
   2052     u_int32_t mask, nmask, ina;
   2053     struct ifaddrs *ifap, *ifa;
   2054 
   2055     addr = ntohl(addr);
   2056     if (IN_CLASSA(addr))	/* determine network mask for address class */
   2057 	nmask = IN_CLASSA_NET;
   2058     else if (IN_CLASSB(addr))
   2059 	nmask = IN_CLASSB_NET;
   2060     else
   2061 	nmask = IN_CLASSC_NET;
   2062     /* class D nets are disallowed by bad_ip_adrs */
   2063     mask = netmask | htonl(nmask);
   2064 
   2065     /*
   2066      * Scan through the system's network interfaces.
   2067      */
   2068     if (getifaddrs(&ifap) != 0) {
   2069 	warn("%s: getifaddrs: %m", __func__);
   2070 	return 0;
   2071     }
   2072 
   2073     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
   2074 	/*
   2075 	 * Check the interface's internet address.
   2076 	 */
   2077 	if (ifa->ifa_addr->sa_family != AF_INET)
   2078 	    continue;
   2079 	ina = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
   2080 	if ((ntohl(ina) & nmask) != (addr & nmask))
   2081 	    continue;
   2082 	/*
   2083 	 * Check that the interface is up, and not point-to-point or loopback.
   2084 	 */
   2085 	if ((ifa->ifa_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) != IFF_UP)
   2086 	    continue;
   2087 	/*
   2088 	 * Get its netmask and OR it into our mask.
   2089 	 */
   2090 	mask |= ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr;
   2091     }
   2092 
   2093     freeifaddrs(ifap);
   2094     return mask;
   2095 }
   2096 
   2097 /*
   2098  * have_route_to - determine if the system has any route to
   2099  * a given IP address.
   2100  * For demand mode to work properly, we have to ignore routes
   2101  * through our own interface.
   2102  */
   2103 int have_route_to(u_int32_t addr)
   2104 {
   2105     return -1;
   2106 }
   2107 
   2108 /*
   2109  * Use the hostid as part of the random number seed.
   2110  */
   2111 int
   2112 get_host_seed(void)
   2113 {
   2114     return gethostid();
   2115 }
   2116 
   2117 #if 0
   2118 /*
   2119  * lock - create a lock file for the named lock device
   2120  */
   2121 #define	LOCK_PREFIX	"/var/spool/lock/LCK.."
   2122 
   2123 static char *lock_file;		/* name of lock file created */
   2124 
   2125 int
   2126 lock(char *dev)
   2127 {
   2128     char hdb_lock_buffer[12];
   2129     int fd, pid, n;
   2130     char *p;
   2131     size_t l;
   2132 
   2133     if ((p = strrchr(dev, '/')) != NULL)
   2134 	dev = p + 1;
   2135     l = strlen(LOCK_PREFIX) + strlen(dev) + 1;
   2136     lock_file = malloc(l);
   2137     if (lock_file == NULL)
   2138 	novm("lock file name");
   2139     slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
   2140 
   2141     while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
   2142 	if (errno == EEXIST
   2143 	    && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
   2144 	    /* Read the lock file to find out who has the device locked */
   2145 	    n = read(fd, hdb_lock_buffer, 11);
   2146 	    if (n <= 0) {
   2147 		error("%s: Can't read pid from lock file %s", __func__,
   2148 		    lock_file);
   2149 		close(fd);
   2150 	    } else {
   2151 		hdb_lock_buffer[n] = 0;
   2152 		pid = atoi(hdb_lock_buffer);
   2153 		if (kill(pid, 0) == -1 && errno == ESRCH) {
   2154 		    /* pid no longer exists - remove the lock file */
   2155 		    if (unlink(lock_file) == 0) {
   2156 			close(fd);
   2157 			notice("%s: Removed stale lock on %s (pid %d)",
   2158 			    __func__, dev, pid);
   2159 			continue;
   2160 		    } else
   2161 			warn("%s: Couldn't remove stale lock on %s", __func__,
   2162 			    dev);
   2163 		} else
   2164 		    notice("%s: Device %s is locked by pid %d", __func__,
   2165 			   dev, pid);
   2166 	    }
   2167 	    close(fd);
   2168 	} else
   2169 	    error("%s: Can't create lock file %s: %m", __func__, lock_file);
   2170 	free(lock_file);
   2171 	lock_file = NULL;
   2172 	return -1;
   2173     }
   2174 
   2175     slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%10d\n", getpid());
   2176     write(fd, hdb_lock_buffer, 11);
   2177 
   2178     close(fd);
   2179     return 0;
   2180 }
   2181 
   2182 /*
   2183  * unlock - remove our lockfile
   2184  */
   2185 void
   2186 unlock(void)
   2187 {
   2188     if (lock_file) {
   2189 	unlink(lock_file);
   2190 	free(lock_file);
   2191 	lock_file = NULL;
   2192     }
   2193 }
   2194 #endif
   2195 
   2196 
   2197 /********************************************************************
   2198  *
   2199  * get_time - Get current time, monotonic if possible.
   2200  */
   2201 int
   2202 ppp_get_time(struct timeval *tv)
   2203 {
   2204     return gettimeofday(tv, NULL);
   2205 }
   2206