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