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 #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
set_queue_size(const char * fmt,int fd)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
get_flags(int fd)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
set_flags(int fd,int flags)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
sys_init(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
sys_cleanup(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
ppp_sys_close()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
sys_check_options(void)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
ppp_check_kernel_support(void)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
tty_establish_ppp(int fd)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
restore_loop(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
tty_disestablish_ppp(fd)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
cfg_bundle(int mrru,int mtru,int rssn,int tssn)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
make_new_bundle(int mrru,int mtru,int rssn,int tssn)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
bundle_attach(int ifnum)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 */
destroy_bundle(void)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
clean_check(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
set_up_tty(int fd,int local)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
restore_tty(int fd)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
setdtr(int fd,int on)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
sif6addr(int unit,eui64_t our_eui64,eui64_t his_eui64)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
cif6addr(int unit,eui64_t our_eui64,eui64_t his_eui64)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
get_pty(int * master_fdp,int * slave_fdp,char * slave_name,int uid)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
open_ppp_loopback(void)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
output(int unit,u_char * p,int len)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
wait_input(struct timeval * timo)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 */
add_fd(int fd)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 */
remove_fd(int fd)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
read_packet(u_char * buf)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
get_loop_output(void)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
ppp_set_mtu(int unit,int mtu)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
ppp_get_mtu(int unit)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
tty_send_config(int mtu,u_int32_t asyncmap,int pcomp,int accomp)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
tty_set_xaccm(ext_accm accm)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
tty_recv_config(int mru,u_int32_t asyncmap,int pcomp,int accomp)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
ccp_test(int unit,u_char * opt_ptr,int opt_len,int for_transmit)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
ccp_flags_set(int unit,int isopen,int isup)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
ccp_fatal_error(int unit)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
get_idle_time(int u,struct ppp_idle * ip)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
get_ppp_stats(int u,struct pppd_stats * stats)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
set_filters(struct bpf_program * pass_in,struct bpf_program * pass_out,struct bpf_program * active_in,struct bpf_program * active_out)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
sifvjcomp(int u,int vjcomp,int cidcomp,int maxcid)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
sifup(int u)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
sifdown(int u)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
sif6up(int u)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
sif6down(int u)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
setifstate(int u,int state)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
sifnpmode(int u,int proto,enum NPmode mode)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
sifaddr(int u,u_int32_t o,u_int32_t h,u_int32_t m)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
cifaddr(int u,u_int32_t o,u_int32_t h)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
sifdefaultroute(int u,u_int32_t l,u_int32_t g,bool replace)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
cifdefaultroute(int u,u_int32_t l,u_int32_t g)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
dodefaultroute(u_int32_t g,int cmd)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
dodefaultroute6(int u,eui64_t l,eui64_t g,char cmd)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
sif6defaultroute(int u,eui64_t l,eui64_t g)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
cif6defaultroute(int u,eui64_t l,eui64_t g)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
sifproxyarp(int unit,u_int32_t hisaddr)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
cifproxyarp(int unit,u_int32_t hisaddr)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
sifproxyarp(int unit,u_int32_t hisaddr)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
cifproxyarp(int unit,u_int32_t hisaddr)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
get_ether_addr(u_int32_t ipaddr,struct sockaddr_dl * hwaddr)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
get_if_hwaddr(u_char * addr,char * name)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
get_first_ether_hwaddr(u_char * addr)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
GetMask(u_int32_t addr)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 */
have_route_to(u_int32_t addr)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
get_host_seed(void)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
ppp_get_time(struct timeval * tv)2202 ppp_get_time(struct timeval *tv)
2203 {
2204 return gettimeofday(tv, NULL);
2205 }
2206