dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / pppd / pppd / sys-linux.c
blob1c7bad30cc0870142d5738cdb73025aa0d1543e5
1 /*
2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
5 * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. The name(s) of the authors of this software must not be used to
15 * endorse or promote products derived from this software without
16 * prior written permission.
18 * 3. Redistributions of any form whatsoever must retain the following
19 * acknowledgment:
20 * "This product includes software developed by Paul Mackerras
21 * <paulus@samba.org>".
23 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
24 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
25 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
26 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
29 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 * Derived from main.c and pppd.h, which are:
33 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
47 * 3. The name "Carnegie Mellon University" must not be used to
48 * endorse or promote products derived from this software without
49 * prior written permission. For permission or any legal
50 * details, please contact
51 * Office of Technology Transfer
52 * Carnegie Mellon University
53 * 5000 Forbes Avenue
54 * Pittsburgh, PA 15213-3890
55 * (412) 268-4387, fax: (412) 268-7395
56 * tech-transfer@andrew.cmu.edu
58 * 4. Redistributions of any form whatsoever must retain the following
59 * acknowledgment:
60 * "This product includes software developed by Computing Services
61 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
63 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
64 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
65 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
66 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
67 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
68 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
69 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
72 #include <sys/ioctl.h>
73 #include <sys/types.h>
74 #include <sys/socket.h>
75 #include <sys/time.h>
76 #include <sys/errno.h>
77 #include <sys/file.h>
78 #include <sys/stat.h>
79 #include <sys/utsname.h>
80 #include <sys/sysmacros.h>
82 #include <stdio.h>
83 #include <stdlib.h>
84 #include <syslog.h>
85 #include <string.h>
86 #include <time.h>
87 #include <memory.h>
88 #include <utmp.h>
89 #include <mntent.h>
90 #include <signal.h>
91 #include <fcntl.h>
92 #include <ctype.h>
93 #include <termios.h>
94 #include <unistd.h>
96 /* This is in netdevice.h. However, this compile will fail miserably if
97 you attempt to include netdevice.h because it has so many references
98 to __memcpy functions which it should not attempt to do. So, since I
99 really don't use it, but it must be defined, define it now. */
101 #ifndef MAX_ADDR_LEN
102 #define MAX_ADDR_LEN 7
103 #endif
105 #if __GLIBC__ >= 2
106 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
107 #include <net/if.h>
108 #include <net/if_arp.h>
109 #include <net/route.h>
110 #include <netinet/if_ether.h>
111 #else
112 #include <linux/types.h>
113 #include <linux/if.h>
114 #include <linux/if_arp.h>
115 #include <linux/route.h>
116 #include <linux/if_ether.h>
117 #endif
118 #include <netinet/in.h>
119 #include <arpa/inet.h>
121 #include <linux/ppp_defs.h>
122 #include <linux/if_ppp.h>
124 #include "pppd.h"
125 #include "fsm.h"
126 #include "ipcp.h"
128 #ifdef IPX_CHANGE
129 #include "ipxcp.h"
130 #if __GLIBC__ >= 2 && \
131 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
132 #include <netipx/ipx.h>
133 #else
134 #include <linux/ipx.h>
135 #endif
136 #endif /* IPX_CHANGE */
138 #ifdef PPP_FILTER
139 #include <pcap-bpf.h>
140 #include <linux/filter.h>
141 #endif /* PPP_FILTER */
143 #ifdef LOCKLIB
144 #include <sys/locks.h>
145 #endif
147 #ifdef INET6
148 #ifndef _LINUX_IN6_H
150 * This is in linux/include/net/ipv6.h.
153 struct in6_ifreq {
154 struct in6_addr ifr6_addr;
155 __u32 ifr6_prefixlen;
156 unsigned int ifr6_ifindex;
158 #endif
160 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
161 memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \
162 sin6.s6_addr16[0] = htons(0xfe80); \
163 eui64_copy(eui64, sin6.s6_addr32[2]); \
164 } while (0)
166 #endif /* INET6 */
168 /* We can get an EIO error on an ioctl if the modem has hung up */
169 #define ok_error(num) ((num)==EIO)
171 static int tty_disc = N_TTY; /* The TTY discipline */
172 static int ppp_disc = N_PPP; /* The PPP discpline */
173 static int initfdflags = -1; /* Initial file descriptor flags for fd */
174 static int ppp_fd = -1; /* fd which is set to PPP discipline */
175 static int sock_fd = -1; /* socket for doing interface ioctls */
176 static int slave_fd = -1; /* pty for old-style demand mode, slave */
177 static int master_fd = -1; /* pty for old-style demand mode, master */
178 #ifdef INET6
179 static int sock6_fd = -1;
180 #endif /* INET6 */
183 * For the old-style kernel driver, this is the same as ppp_fd.
184 * For the new-style driver, it is the fd of an instance of /dev/ppp
185 * which is attached to the ppp unit and is used for controlling it.
187 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
189 static int chindex; /* channel index (new style driver) */
191 static fd_set in_fds; /* set of fds that wait_input waits for */
192 static int max_in_fd; /* highest fd set in in_fds */
194 static int has_proxy_arp = 0;
195 static int driver_version = 0;
196 static int driver_modification = 0;
197 static int driver_patch = 0;
198 static int driver_is_old = 0;
199 static int restore_term = 0; /* 1 => we've munged the terminal */
200 static struct termios inittermios; /* Initial TTY termios */
202 int new_style_driver = 0;
204 static char loop_name[20];
205 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
207 static int if_is_up; /* Interface has been marked up */
208 static int have_default_route; /* Gateway for default route added */
209 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
210 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
211 static u_int32_t our_old_addr; /* for detecting address changes */
212 static int dynaddr_set; /* 1 if ip_dynaddr set */
213 static int looped; /* 1 if using loop */
214 static int link_mtu; /* mtu for the link (not bundle) */
216 static struct utsname utsname; /* for the kernel version */
217 static int kernel_version;
218 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
220 #define MAX_IFS 100
222 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
223 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
224 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
226 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
228 /* Prototypes for procedures local to this file. */
229 static int modify_flags(int fd, int clear_bits, int set_bits);
230 static int translate_speed (int bps);
231 static int baud_rate_of (int speed);
232 static void close_route_table (void);
233 static int open_route_table (void);
234 static int read_route_table (struct rtentry *rt);
235 static int defaultroute_exists (struct rtentry *rt);
236 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
237 char *name, int namelen);
238 static void decode_version (char *buf, int *version, int *mod, int *patch);
239 static int set_kdebugflag(int level);
240 static int ppp_registered(void);
241 static int make_ppp_unit(void);
243 extern u_char inpacket_buf[]; /* borrowed from main.c */
246 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
247 * if it exists.
250 #define SET_SA_FAMILY(addr, family) \
251 memset ((char *) &(addr), '\0', sizeof(addr)); \
252 addr.sa_family = (family);
255 * Determine if the PPP connection should still be present.
258 extern int hungup;
260 /* new_fd is the fd of a tty */
261 static void set_ppp_fd (int new_fd)
263 ppp_fd = new_fd;
264 if (!new_style_driver)
265 ppp_dev_fd = new_fd;
268 static int still_ppp(void)
270 if (new_style_driver)
271 return !hungup && ppp_fd >= 0;
272 if (!hungup || ppp_fd == slave_fd)
273 return 1;
274 if (slave_fd >= 0) {
275 set_ppp_fd(slave_fd);
276 return 1;
278 return 0;
282 * modify_flags - set and clear flag bits controlling the kernel
283 * PPP driver.
285 static int modify_flags(int fd, int clear_bits, int set_bits)
287 int flags;
289 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
290 goto err;
291 flags = (flags & ~clear_bits) | set_bits;
292 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
293 goto err;
295 return 0;
297 err:
298 if (errno != EIO)
299 error("Failed to set PPP kernel option flags: %m");
300 return -1;
303 /********************************************************************
305 * sys_init - System-dependent initialization.
308 void sys_init(void)
310 /* Get an internet socket for doing socket ioctls. */
311 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
312 if (sock_fd < 0)
313 fatal("Couldn't create IP socket: %m(%d)", errno);
315 #ifdef INET6
316 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
317 if (sock6_fd < 0)
318 sock6_fd = -errno; /* save errno for later */
319 #endif
321 FD_ZERO(&in_fds);
322 max_in_fd = 0;
325 /********************************************************************
327 * sys_cleanup - restore any system state we modified before exiting:
328 * mark the interface down, delete default route and/or proxy arp entry.
329 * This shouldn't call die() because it's called from die().
332 void sys_cleanup(void)
335 * Take down the device
337 if (if_is_up) {
338 if_is_up = 0;
339 sifdown(0);
342 * Delete any routes through the device.
344 if (have_default_route)
345 cifdefaultroute(0, 0, 0);
347 if (has_proxy_arp)
348 cifproxyarp(0, proxy_arp_addr);
351 /********************************************************************
353 * sys_close - Clean up in a child process before execing.
355 void
356 sys_close(void)
358 if (new_style_driver && ppp_dev_fd >= 0)
359 close(ppp_dev_fd);
360 if (sock_fd >= 0)
361 close(sock_fd);
362 #ifdef INET6
363 if (sock6_fd >= 0)
364 close(sock6_fd);
365 #endif
366 if (slave_fd >= 0)
367 close(slave_fd);
368 if (master_fd >= 0)
369 close(master_fd);
372 /********************************************************************
374 * set_kdebugflag - Define the debugging level for the kernel
377 static int set_kdebugflag (int requested_level)
379 if (ppp_dev_fd < 0)
380 return 1;
381 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
382 if ( ! ok_error (errno) )
383 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
384 return (0);
386 return (1);
389 /********************************************************************
391 * tty_establish_ppp - Turn the serial port into a ppp interface.
394 int tty_establish_ppp (int tty_fd)
396 int ret_fd;
399 * Ensure that the tty device is in exclusive mode.
401 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
402 if ( ! ok_error ( errno ))
403 warn("Couldn't make tty exclusive: %m");
406 * Demand mode - prime the old ppp device to relinquish the unit.
408 if (!new_style_driver && looped
409 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
410 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
411 return -1;
414 * Set the current tty to the PPP discpline
417 #ifndef N_SYNC_PPP
418 #define N_SYNC_PPP 14
419 #endif
420 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
421 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
422 if ( ! ok_error (errno) ) {
423 error("Couldn't set tty to PPP discipline: %m");
424 return -1;
428 ret_fd = generic_establish_ppp(tty_fd);
430 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
431 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
432 | SC_LOG_FLUSH)
434 if (ret_fd >= 0) {
435 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
436 (kdebugflag * SC_DEBUG) & SC_LOGB);
437 } else {
438 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
439 warn("Couldn't reset tty to normal line discipline: %m");
442 return ret_fd;
445 /********************************************************************
447 * generic_establish_ppp - Turn the fd into a ppp interface.
449 int generic_establish_ppp (int fd)
451 int x;
453 if (new_style_driver) {
454 int flags;
456 /* if a ppp_fd is already open, close it first */
457 if(ppp_fd > 0) {
458 close(ppp_fd);
459 remove_fd(ppp_fd);
460 ppp_fd = -1;
463 /* Open an instance of /dev/ppp and connect the channel to it */
464 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
465 error("Couldn't get channel number: %m");
466 goto err;
468 dbglog("using channel %d", chindex);
469 fd = open("/dev/ppp", O_RDWR);
470 if (fd < 0) {
471 error("Couldn't reopen /dev/ppp: %m");
472 goto err;
474 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
475 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
476 error("Couldn't attach to channel %d: %m", chindex);
477 goto err_close;
479 flags = fcntl(fd, F_GETFL);
480 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
481 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
482 set_ppp_fd(fd);
484 if (!looped)
485 ifunit = -1;
486 if (!looped && !multilink) {
488 * Create a new PPP unit.
490 if (make_ppp_unit() < 0)
491 goto err_close;
494 if (looped)
495 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
497 if (!multilink) {
498 add_fd(ppp_dev_fd);
499 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
500 error("Couldn't attach to PPP unit %d: %m", ifunit);
501 goto err_close;
505 } else {
507 * Old-style driver: find out which interface we were given.
509 set_ppp_fd (fd);
510 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
511 if (ok_error (errno))
512 goto err;
513 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
515 /* Check that we got the same unit again. */
516 if (looped && x != ifunit)
517 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
518 ifunit = x;
521 * Fetch the initial file flags and reset blocking mode on the file.
523 initfdflags = fcntl(fd, F_GETFL);
524 if (initfdflags == -1 ||
525 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
526 if ( ! ok_error (errno))
527 warn("Couldn't set device to non-blocking mode: %m");
532 * Enable debug in the driver if requested.
534 if (!looped)
535 set_kdebugflag (kdebugflag);
537 looped = 0;
539 return ppp_fd;
541 err_close:
542 close(fd);
543 err:
544 return -1;
547 /********************************************************************
549 * tty_disestablish_ppp - Restore the serial port to normal operation.
550 * This shouldn't call die() because it's called from die().
553 void tty_disestablish_ppp(int tty_fd)
555 if (!hungup) {
557 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
559 if (tcflush(tty_fd, TCIOFLUSH) < 0)
561 warn("tcflush failed: %m");
562 goto flushfailed;
565 * Restore the previous line discipline
567 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
568 if ( ! ok_error (errno))
569 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
572 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
573 if ( ! ok_error (errno))
574 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
577 /* Reset non-blocking mode on fd. */
578 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
579 if ( ! ok_error (errno))
580 warn("Couldn't restore device fd flags: %m");
583 flushfailed:
584 initfdflags = -1;
586 generic_disestablish_ppp(tty_fd);
589 /********************************************************************
591 * generic_disestablish_ppp - Restore device components to normal
592 * operation, and reconnect the ppp unit to the loopback if in demand
593 * mode. This shouldn't call die() because it's called from die().
595 void generic_disestablish_ppp(int dev_fd)
597 if (new_style_driver) {
598 close(ppp_fd);
599 ppp_fd = -1;
600 if (demand) {
601 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
602 looped = 1;
603 } else if (!doing_multilink && ppp_dev_fd >= 0) {
604 close(ppp_dev_fd);
605 remove_fd(ppp_dev_fd);
606 ppp_dev_fd = -1;
608 } else {
609 /* old-style driver */
610 if (demand)
611 set_ppp_fd(slave_fd);
612 else
613 ppp_dev_fd = -1;
618 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
619 * Assumes new_style_driver.
621 static int make_ppp_unit()
623 int x, flags;
625 if (ppp_dev_fd >= 0) {
626 dbglog("in make_ppp_unit, already had /dev/ppp open?");
627 close(ppp_dev_fd);
629 ppp_dev_fd = open("/dev/ppp", O_RDWR);
630 if (ppp_dev_fd < 0)
631 fatal("Couldn't open /dev/ppp: %m");
632 flags = fcntl(ppp_dev_fd, F_GETFL);
633 if (flags == -1
634 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
635 warn("Couldn't set /dev/ppp to nonblock: %m");
637 ifunit = (req_unit >= 0) ? req_unit : req_minunit;
638 do {
639 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
640 if (x < 0 && errno == EEXIST) {
641 warn("Couldn't allocate PPP unit %d as it is already in use", ifunit);
642 ifunit = (req_unit >= 0) ? -1 : ++req_minunit;
643 } else break;
644 } while (ifunit < MAXUNIT);
646 if (x < 0)
647 error("Couldn't create new ppp unit: %m");
648 return x;
652 * cfg_bundle - configure the existing bundle.
653 * Used in demand mode.
655 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
657 if (!new_style_driver)
658 return;
660 /* set the mrru, mtu and flags */
661 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
662 error("Couldn't set MRRU: %m");
664 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
665 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
666 | (mrru? SC_MULTILINK: 0)));
668 /* connect up the channel */
669 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
670 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
671 add_fd(ppp_dev_fd);
675 * make_new_bundle - create a new PPP unit (i.e. a bundle)
676 * and connect our channel to it. This should only get called
677 * if `multilink' was set at the time establish_ppp was called.
678 * In demand mode this uses our existing bundle instead of making
679 * a new one.
681 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
683 if (!new_style_driver)
684 return;
686 /* make us a ppp unit */
687 if (make_ppp_unit() < 0)
688 die(1);
690 /* set the mrru and flags */
691 cfg_bundle(mrru, mtru, rssn, tssn);
695 * bundle_attach - attach our link to a given PPP unit.
696 * We assume the unit is controlled by another pppd.
698 int bundle_attach(int ifnum)
700 int master_fd;
702 if (!new_style_driver)
703 return -1;
705 master_fd = open("/dev/ppp", O_RDWR);
706 if (master_fd < 0)
707 fatal("Couldn't open /dev/ppp: %m");
708 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
709 if (errno == ENXIO) {
710 close(master_fd);
711 return 0; /* doesn't still exist */
713 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
715 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
716 fatal("Couldn't connect to interface unit %d: %m", ifnum);
717 modify_flags(master_fd, 0, SC_MULTILINK);
718 close(master_fd);
720 ifunit = ifnum;
721 return 1;
725 * destroy_bundle - tell the driver to destroy our bundle.
727 void destroy_bundle(void)
729 if (ppp_dev_fd >= 0) {
730 close(ppp_dev_fd);
731 remove_fd(ppp_dev_fd);
732 ppp_dev_fd = -1;
736 /********************************************************************
738 * clean_check - Fetch the flags for the device and generate
739 * appropriate error messages.
741 void clean_check(void)
743 int x;
744 char *s;
746 if (still_ppp()) {
747 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
748 s = NULL;
749 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
750 case SC_RCV_B7_0:
751 s = "all had bit 7 set to 1";
752 break;
754 case SC_RCV_B7_1:
755 s = "all had bit 7 set to 0";
756 break;
758 case SC_RCV_EVNP:
759 s = "all had odd parity";
760 break;
762 case SC_RCV_ODDP:
763 s = "all had even parity";
764 break;
767 if (s != NULL) {
768 warn("Receive serial link is not 8-bit clean:");
769 warn("Problem: %s", s);
777 * List of valid speeds.
780 struct speed {
781 int speed_int, speed_val;
782 } speeds[] = {
783 #ifdef B50
784 { 50, B50 },
785 #endif
786 #ifdef B75
787 { 75, B75 },
788 #endif
789 #ifdef B110
790 { 110, B110 },
791 #endif
792 #ifdef B134
793 { 134, B134 },
794 #endif
795 #ifdef B150
796 { 150, B150 },
797 #endif
798 #ifdef B200
799 { 200, B200 },
800 #endif
801 #ifdef B300
802 { 300, B300 },
803 #endif
804 #ifdef B600
805 { 600, B600 },
806 #endif
807 #ifdef B1200
808 { 1200, B1200 },
809 #endif
810 #ifdef B1800
811 { 1800, B1800 },
812 #endif
813 #ifdef B2000
814 { 2000, B2000 },
815 #endif
816 #ifdef B2400
817 { 2400, B2400 },
818 #endif
819 #ifdef B3600
820 { 3600, B3600 },
821 #endif
822 #ifdef B4800
823 { 4800, B4800 },
824 #endif
825 #ifdef B7200
826 { 7200, B7200 },
827 #endif
828 #ifdef B9600
829 { 9600, B9600 },
830 #endif
831 #ifdef B19200
832 { 19200, B19200 },
833 #endif
834 #ifdef B38400
835 { 38400, B38400 },
836 #endif
837 #ifdef B57600
838 { 57600, B57600 },
839 #endif
840 #ifdef B76800
841 { 76800, B76800 },
842 #endif
843 #ifdef B115200
844 { 115200, B115200 },
845 #endif
846 #ifdef EXTA
847 { 19200, EXTA },
848 #endif
849 #ifdef EXTB
850 { 38400, EXTB },
851 #endif
852 #ifdef B230400
853 { 230400, B230400 },
854 #endif
855 #ifdef B460800
856 { 460800, B460800 },
857 #endif
858 #ifdef B921600
859 { 921600, B921600 },
860 #endif
861 #ifdef B1000000
862 { 1000000, B1000000 },
863 #endif
864 #ifdef B1152000
865 { 1152000, B1152000 },
866 #endif
867 #ifdef B1500000
868 { 1500000, B1500000 },
869 #endif
870 #ifdef B2000000
871 { 2000000, B2000000 },
872 #endif
873 #ifdef B2500000
874 { 2500000, B2500000 },
875 #endif
876 #ifdef B3000000
877 { 3000000, B3000000 },
878 #endif
879 #ifdef B3500000
880 { 3500000, B3500000 },
881 #endif
882 #ifdef B4000000
883 { 4000000, B4000000 },
884 #endif
885 { 0, 0 }
888 /********************************************************************
890 * Translate from bits/second to a speed_t.
893 static int translate_speed (int bps)
895 struct speed *speedp;
897 if (bps != 0) {
898 for (speedp = speeds; speedp->speed_int; speedp++) {
899 if (bps == speedp->speed_int)
900 return speedp->speed_val;
902 warn("speed %d not supported", bps);
904 return 0;
907 /********************************************************************
909 * Translate from a speed_t to bits/second.
912 static int baud_rate_of (int speed)
914 struct speed *speedp;
916 if (speed != 0) {
917 for (speedp = speeds; speedp->speed_int; speedp++) {
918 if (speed == speedp->speed_val)
919 return speedp->speed_int;
922 return 0;
925 /********************************************************************
927 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
928 * at the requested speed, etc. If `local' is true, set CLOCAL
929 * regardless of whether the modem option was specified.
932 void set_up_tty(int tty_fd, int local)
934 int speed;
935 struct termios tios;
937 setdtr(tty_fd, 1);
938 if (tcgetattr(tty_fd, &tios) < 0) {
939 if (!ok_error(errno))
940 fatal("tcgetattr: %m (line %d)", __LINE__);
941 return;
944 if (!restore_term)
945 inittermios = tios;
947 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
948 tios.c_cflag |= CS8 | CREAD | HUPCL;
950 tios.c_iflag = IGNBRK | IGNPAR;
951 tios.c_oflag = 0;
952 tios.c_lflag = 0;
953 tios.c_cc[VMIN] = 1;
954 tios.c_cc[VTIME] = 0;
956 if (local || !modem)
957 tios.c_cflag ^= (CLOCAL | HUPCL);
959 switch (crtscts) {
960 case 1:
961 tios.c_cflag |= CRTSCTS;
962 break;
964 case -2:
965 tios.c_iflag |= IXON | IXOFF;
966 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
967 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
968 break;
970 case -1:
971 tios.c_cflag &= ~CRTSCTS;
972 break;
974 default:
975 break;
978 speed = translate_speed(inspeed);
979 if (speed) {
980 cfsetospeed (&tios, speed);
981 cfsetispeed (&tios, speed);
984 * We can't proceed if the serial port speed is B0,
985 * since that implies that the serial port is disabled.
987 else {
988 speed = cfgetospeed(&tios);
989 if (speed == B0)
990 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
993 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
994 if (errno != EINTR)
995 fatal("tcsetattr: %m (line %d)", __LINE__);
997 baud_rate = baud_rate_of(speed);
998 restore_term = 1;
1001 /********************************************************************
1003 * setdtr - control the DTR line on the serial port.
1004 * This is called from die(), so it shouldn't call die().
1007 void setdtr (int tty_fd, int on)
1009 int modembits = TIOCM_DTR;
1011 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1014 /********************************************************************
1016 * restore_tty - restore the terminal to the saved settings.
1019 void restore_tty (int tty_fd)
1021 if (restore_term) {
1022 restore_term = 0;
1024 * Turn off echoing, because otherwise we can get into
1025 * a loop with the tty and the modem echoing to each other.
1026 * We presume we are the sole user of this tty device, so
1027 * when we close it, it will revert to its defaults anyway.
1029 if (!default_device)
1030 inittermios.c_lflag &= ~(ECHO | ECHONL);
1032 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1033 if (! ok_error (errno))
1034 warn("tcsetattr: %m (line %d)", __LINE__);
1039 /********************************************************************
1041 * output - Output PPP packet.
1044 void output (int unit, unsigned char *p, int len)
1046 int fd = ppp_fd;
1047 int proto;
1049 dump_packet("sent", p, len);
1050 if (snoop_send_hook) snoop_send_hook(p, len);
1052 if (len < PPP_HDRLEN)
1053 return;
1054 if (new_style_driver) {
1055 p += 2;
1056 len -= 2;
1057 proto = (p[0] << 8) + p[1];
1058 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1059 fd = ppp_dev_fd;
1061 if (write(fd, p, len) < 0) {
1062 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1063 || errno == ENXIO || errno == EIO || errno == EINTR)
1064 warn("write: warning: %m (%d)", errno);
1065 else
1066 error("write: %m (%d)", errno);
1070 /********************************************************************
1072 * wait_input - wait until there is data available,
1073 * for the length of time specified by *timo (indefinite
1074 * if timo is NULL).
1077 void wait_input(struct timeval *timo)
1079 fd_set ready, exc;
1080 int n;
1082 ready = in_fds;
1083 exc = in_fds;
1084 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1085 if (n < 0 && errno != EINTR)
1086 fatal("select: %m");
1090 * add_fd - add an fd to the set that wait_input waits for.
1092 void add_fd(int fd)
1094 if (fd >= FD_SETSIZE)
1095 fatal("internal error: file descriptor too large (%d)", fd);
1096 FD_SET(fd, &in_fds);
1097 if (fd > max_in_fd)
1098 max_in_fd = fd;
1102 * remove_fd - remove an fd from the set that wait_input waits for.
1104 void remove_fd(int fd)
1106 FD_CLR(fd, &in_fds);
1110 /********************************************************************
1112 * read_packet - get a PPP packet from the serial device.
1115 int read_packet (unsigned char *buf)
1117 int len, nr;
1119 len = PPP_MRU + PPP_HDRLEN;
1120 if (new_style_driver) {
1121 *buf++ = PPP_ALLSTATIONS;
1122 *buf++ = PPP_UI;
1123 len -= 2;
1125 nr = -1;
1126 if (ppp_fd >= 0) {
1127 nr = read(ppp_fd, buf, len);
1128 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1129 && errno != EIO && errno != EINTR)
1130 error("read: %m");
1131 if (nr < 0 && errno == ENXIO)
1132 return 0;
1134 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1135 /* N.B. we read ppp_fd first since LCP packets come in there. */
1136 nr = read(ppp_dev_fd, buf, len);
1137 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1138 && errno != EIO && errno != EINTR)
1139 error("read /dev/ppp: %m");
1140 if (nr < 0 && errno == ENXIO)
1141 nr = 0;
1142 if (nr == 0 && doing_multilink) {
1143 remove_fd(ppp_dev_fd);
1144 bundle_eof = 1;
1147 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1148 nr = 0;
1149 return (new_style_driver && nr > 0)? nr+2: nr;
1152 /********************************************************************
1154 * get_loop_output - get outgoing packets from the ppp device,
1155 * and detect when we want to bring the real link up.
1156 * Return value is 1 if we need to bring up the link, 0 otherwise.
1159 get_loop_output(void)
1161 int rv = 0;
1162 int n;
1164 if (new_style_driver) {
1165 while ((n = read_packet(inpacket_buf)) > 0)
1166 if (loop_frame(inpacket_buf, n))
1167 rv = 1;
1168 return rv;
1171 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1172 if (loop_chars(inbuf, n))
1173 rv = 1;
1175 if (n == 0)
1176 fatal("eof on loopback");
1178 if (errno != EWOULDBLOCK && errno != EAGAIN)
1179 fatal("read from loopback: %m(%d)", errno);
1181 return rv;
1185 * netif_set_mtu - set the MTU on the PPP network interface.
1187 void
1188 netif_set_mtu(int unit, int mtu)
1190 struct ifreq ifr;
1192 memset (&ifr, '\0', sizeof (ifr));
1193 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1194 ifr.ifr_mtu = mtu;
1196 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1197 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1201 * netif_get_mtu - get the MTU on the PPP network interface.
1204 netif_get_mtu(int unit)
1206 struct ifreq ifr;
1208 memset (&ifr, '\0', sizeof (ifr));
1209 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1211 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1212 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1213 return 0;
1215 return ifr.ifr_mtu;
1218 /********************************************************************
1220 * tty_send_config - configure the transmit characteristics of
1221 * the ppp interface.
1224 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1226 int x;
1228 if (!still_ppp())
1229 return;
1230 link_mtu = mtu;
1231 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1232 if (errno != EIO && errno != ENOTTY)
1233 error("Couldn't set transmit async character map: %m");
1234 ++error_count;
1235 return;
1238 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1239 | (sync_serial? SC_SYNC: 0);
1240 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1243 /********************************************************************
1245 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1248 void tty_set_xaccm (ext_accm accm)
1250 if (!still_ppp())
1251 return;
1252 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1253 if ( ! ok_error (errno))
1254 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1258 /********************************************************************
1260 * tty_recv_config - configure the receive-side characteristics of
1261 * the ppp interface.
1264 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1267 * If we were called because the link has gone down then there is nothing
1268 * which may be done. Just return without incident.
1270 if (!still_ppp())
1271 return;
1273 * Set the receiver parameters
1275 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1276 if (errno != EIO && errno != ENOTTY)
1277 error("Couldn't set channel receive MRU: %m");
1279 if (new_style_driver && ppp_dev_fd >= 0
1280 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1281 error("Couldn't set MRU in generic PPP layer: %m");
1283 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1284 if (errno != EIO && errno != ENOTTY)
1285 error("Couldn't set channel receive asyncmap: %m");
1289 /********************************************************************
1291 * ccp_test - ask kernel whether a given compression method
1292 * is acceptable for use.
1296 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1298 struct ppp_option_data data;
1300 memset (&data, '\0', sizeof (data));
1301 data.ptr = opt_ptr;
1302 data.length = opt_len;
1303 data.transmit = for_transmit;
1305 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1306 return 1;
1308 return (errno == ENOBUFS)? 0: -1;
1311 /********************************************************************
1313 * ccp_flags_set - inform kernel about the current state of CCP.
1316 void ccp_flags_set (int unit, int isopen, int isup)
1318 int x;
1320 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1321 if (still_ppp() && ppp_dev_fd >= 0)
1322 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1325 #ifdef PPP_FILTER
1327 * set_filters - set the active and pass filters in the kernel driver.
1329 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1331 struct sock_fprog fp;
1333 fp.len = pass->bf_len;
1334 fp.filter = (struct sock_filter *) pass->bf_insns;
1335 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1336 if (errno == ENOTTY)
1337 warn("kernel does not support PPP filtering");
1338 else
1339 error("Couldn't set pass-filter in kernel: %m");
1340 return 0;
1342 fp.len = active->bf_len;
1343 fp.filter = (struct sock_filter *) active->bf_insns;
1344 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1345 error("Couldn't set active-filter in kernel: %m");
1346 return 0;
1348 return 1;
1350 #endif /* PPP_FILTER */
1352 /********************************************************************
1354 * get_idle_time - return how long the link has been idle.
1357 get_idle_time(u, ip)
1358 int u;
1359 struct ppp_idle *ip;
1361 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1364 /********************************************************************
1366 * get_ppp_stats - return statistics for the link.
1369 get_ppp_stats(u, stats)
1370 int u;
1371 struct pppd_stats *stats;
1373 struct ifpppstatsreq req;
1375 memset (&req, 0, sizeof (req));
1377 req.stats_ptr = (caddr_t) &req.stats;
1378 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1379 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1380 error("Couldn't get PPP statistics: %m");
1381 return 0;
1383 stats->bytes_in = req.stats.p.ppp_ibytes;
1384 stats->bytes_out = req.stats.p.ppp_obytes;
1385 stats->pkts_in = req.stats.p.ppp_ipackets;
1386 stats->pkts_out = req.stats.p.ppp_opackets;
1387 return 1;
1390 /********************************************************************
1392 * ccp_fatal_error - returns 1 if decompression was disabled as a
1393 * result of an error detected after decompression of a packet,
1394 * 0 otherwise. This is necessary because of patent nonsense.
1397 int ccp_fatal_error (int unit)
1399 int flags;
1401 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1402 error("Couldn't read compression error flags: %m");
1403 flags = 0;
1405 return flags & SC_DC_FERROR;
1408 /********************************************************************
1410 * path_to_procfs - find the path to the proc file system mount point
1412 static char proc_path[MAXPATHLEN];
1413 static int proc_path_len;
1415 static char *path_to_procfs(const char *tail)
1417 struct mntent *mntent;
1418 FILE *fp;
1420 if (proc_path_len == 0) {
1421 /* Default the mount location of /proc */
1422 strlcpy (proc_path, "/proc", sizeof(proc_path));
1423 proc_path_len = 5;
1424 fp = fopen(MOUNTED, "r");
1425 if (fp != NULL) {
1426 while ((mntent = getmntent(fp)) != NULL) {
1427 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1428 continue;
1429 if (strcmp(mntent->mnt_type, "proc") == 0) {
1430 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1431 proc_path_len = strlen(proc_path);
1432 break;
1435 fclose (fp);
1439 strlcpy(proc_path + proc_path_len, tail,
1440 sizeof(proc_path) - proc_path_len);
1441 return proc_path;
1445 * /proc/net/route parsing stuff.
1447 #define ROUTE_MAX_COLS 12
1448 FILE *route_fd = (FILE *) 0;
1449 static char route_buffer[512];
1450 static int route_dev_col, route_dest_col, route_gw_col;
1451 static int route_flags_col, route_mask_col;
1452 static int route_num_cols;
1454 static int open_route_table (void);
1455 static void close_route_table (void);
1456 static int read_route_table (struct rtentry *rt);
1458 /********************************************************************
1460 * close_route_table - close the interface to the route table
1463 static void close_route_table (void)
1465 if (route_fd != (FILE *) 0) {
1466 fclose (route_fd);
1467 route_fd = (FILE *) 0;
1471 /********************************************************************
1473 * open_route_table - open the interface to the route table
1475 static char route_delims[] = " \t\n";
1477 static int open_route_table (void)
1479 char *path;
1481 close_route_table();
1483 path = path_to_procfs("/net/route");
1484 route_fd = fopen (path, "r");
1485 if (route_fd == NULL) {
1486 error("can't open routing table %s: %m", path);
1487 return 0;
1490 route_dev_col = 0; /* default to usual columns */
1491 route_dest_col = 1;
1492 route_gw_col = 2;
1493 route_flags_col = 3;
1494 route_mask_col = 7;
1495 route_num_cols = 8;
1497 /* parse header line */
1498 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1499 char *p = route_buffer, *q;
1500 int col;
1501 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1502 int used = 1;
1503 if ((q = strtok(p, route_delims)) == 0)
1504 break;
1505 if (strcasecmp(q, "iface") == 0)
1506 route_dev_col = col;
1507 else if (strcasecmp(q, "destination") == 0)
1508 route_dest_col = col;
1509 else if (strcasecmp(q, "gateway") == 0)
1510 route_gw_col = col;
1511 else if (strcasecmp(q, "flags") == 0)
1512 route_flags_col = col;
1513 else if (strcasecmp(q, "mask") == 0)
1514 route_mask_col = col;
1515 else
1516 used = 0;
1517 if (used && col >= route_num_cols)
1518 route_num_cols = col + 1;
1519 p = NULL;
1523 return 1;
1526 /********************************************************************
1528 * read_route_table - read the next entry from the route table
1531 static int read_route_table(struct rtentry *rt)
1533 char *cols[ROUTE_MAX_COLS], *p;
1534 int col;
1536 memset (rt, '\0', sizeof (struct rtentry));
1538 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1539 return 0;
1541 p = route_buffer;
1542 for (col = 0; col < route_num_cols; ++col) {
1543 cols[col] = strtok(p, route_delims);
1544 if (cols[col] == NULL)
1545 return 0; /* didn't get enough columns */
1546 p = NULL;
1549 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1550 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1551 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1553 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1554 rt->rt_dev = cols[route_dev_col];
1556 return 1;
1559 /********************************************************************
1561 * defaultroute_exists - determine if there is a default route
1564 static int defaultroute_exists (struct rtentry *rt)
1566 int result = 0;
1568 if (!open_route_table())
1569 return 0;
1571 while (read_route_table(rt) != 0) {
1572 if ((rt->rt_flags & RTF_UP) == 0)
1573 continue;
1575 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1576 continue;
1577 if (SIN_ADDR(rt->rt_dst) == 0L) {
1578 result = 1;
1579 break;
1583 close_route_table();
1584 return result;
1588 * have_route_to - determine if the system has any route to
1589 * a given IP address. `addr' is in network byte order.
1590 * Return value is 1 if yes, 0 if no, -1 if don't know.
1591 * For demand mode to work properly, we have to ignore routes
1592 * through our own interface.
1594 int have_route_to(u_int32_t addr)
1596 struct rtentry rt;
1597 int result = 0;
1599 if (!open_route_table())
1600 return -1; /* don't know */
1602 while (read_route_table(&rt)) {
1603 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1604 continue;
1605 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1606 result = 1;
1607 break;
1611 close_route_table();
1612 return result;
1615 /********************************************************************
1617 * sifdefaultroute - assign a default route through the address given.
1620 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1622 struct rtentry rt;
1624 if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1625 if (rt.rt_flags & RTF_GATEWAY)
1626 error("not replacing existing default route via %I",
1627 SIN_ADDR(rt.rt_gateway));
1628 else
1629 error("not replacing existing default route through %s",
1630 rt.rt_dev);
1631 return 0;
1634 memset (&rt, 0, sizeof (rt));
1635 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1637 SET_SA_FAMILY(rt.rt_gateway, AF_INET);
1638 SIN_ADDR(rt.rt_gateway) = gateway;
1640 rt.rt_dev = ifname;
1642 if (kernel_version > KVERSION(2,1,0)) {
1643 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1644 SIN_ADDR(rt.rt_genmask) = 0L;
1647 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1648 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1649 if ( ! ok_error ( errno ))
1650 error("default route ioctl(SIOCADDRT): %m");
1651 return 0;
1654 have_default_route = 1;
1655 return 1;
1658 /********************************************************************
1660 * cifdefaultroute - delete a default route through the address given.
1663 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1665 struct rtentry rt;
1667 have_default_route = 0;
1669 memset (&rt, '\0', sizeof (rt));
1670 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1671 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1673 rt.rt_dev = ifname;
1675 if (kernel_version > KVERSION(2,1,0)) {
1676 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1677 SIN_ADDR(rt.rt_genmask) = 0L;
1680 rt.rt_flags = RTF_UP;
1681 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1682 if (still_ppp()) {
1683 if ( ! ok_error ( errno ))
1684 error("default route ioctl(SIOCDELRT): %m");
1685 return 0;
1689 return 1;
1692 /********************************************************************
1694 * sifproxyarp - Make a proxy ARP entry for the peer.
1697 int sifproxyarp (int unit, u_int32_t his_adr)
1699 struct arpreq arpreq;
1700 char *forw_path;
1702 if (has_proxy_arp == 0) {
1703 memset (&arpreq, '\0', sizeof(arpreq));
1705 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1706 SIN_ADDR(arpreq.arp_pa) = his_adr;
1707 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1709 * Get the hardware address of an interface on the same subnet
1710 * as our local address.
1712 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1713 sizeof(proxy_arp_dev))) {
1714 error("Cannot determine ethernet address for proxy ARP");
1715 return 0;
1717 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1719 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1720 if ( ! ok_error ( errno ))
1721 error("ioctl(SIOCSARP): %m");
1722 return 0;
1724 proxy_arp_addr = his_adr;
1725 has_proxy_arp = 1;
1727 if (tune_kernel) {
1728 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1729 if (forw_path != 0) {
1730 int fd = open(forw_path, O_WRONLY);
1731 if (fd >= 0) {
1732 if (write(fd, "1", 1) != 1)
1733 error("Couldn't enable IP forwarding: %m");
1734 close(fd);
1740 return 1;
1743 /********************************************************************
1745 * cifproxyarp - Delete the proxy ARP entry for the peer.
1748 int cifproxyarp (int unit, u_int32_t his_adr)
1750 struct arpreq arpreq;
1752 if (has_proxy_arp) {
1753 has_proxy_arp = 0;
1754 memset (&arpreq, '\0', sizeof(arpreq));
1755 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1756 SIN_ADDR(arpreq.arp_pa) = his_adr;
1757 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1758 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1760 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1761 if ( ! ok_error ( errno ))
1762 warn("ioctl(SIOCDARP): %m");
1763 return 0;
1766 return 1;
1769 /********************************************************************
1771 * get_ether_addr - get the hardware address of an interface on the
1772 * the same subnet as ipaddr.
1775 static int get_ether_addr (u_int32_t ipaddr,
1776 struct sockaddr *hwaddr,
1777 char *name, int namelen)
1779 struct ifreq *ifr, *ifend;
1780 u_int32_t ina, mask;
1781 char *aliasp;
1782 struct ifreq ifreq, bestifreq;
1783 struct ifconf ifc;
1784 struct ifreq ifs[MAX_IFS];
1786 u_int32_t bestmask=0;
1787 int found_interface = 0;
1789 ifc.ifc_len = sizeof(ifs);
1790 ifc.ifc_req = ifs;
1791 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1792 if ( ! ok_error ( errno ))
1793 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1794 return 0;
1798 * Scan through looking for an interface with an Internet
1799 * address on the same subnet as `ipaddr'.
1801 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1802 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1803 if (ifr->ifr_addr.sa_family == AF_INET) {
1804 ina = SIN_ADDR(ifr->ifr_addr);
1805 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1807 * Check that the interface is up, and not point-to-point
1808 * nor loopback.
1810 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1811 continue;
1813 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1814 continue;
1816 * Get its netmask and check that it's on the right subnet.
1818 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1819 continue;
1821 mask = SIN_ADDR(ifreq.ifr_addr);
1823 if (((ipaddr ^ ina) & mask) != 0)
1824 continue; /* no match */
1825 /* matched */
1826 if (mask >= bestmask) {
1827 /* Compare using >= instead of > -- it is possible for
1828 an interface to have a netmask of 0.0.0.0 */
1829 found_interface = 1;
1830 bestifreq = ifreq;
1831 bestmask = mask;
1836 if (!found_interface) return 0;
1838 strlcpy(name, bestifreq.ifr_name, namelen);
1840 /* trim off the :1 in eth0:1 */
1841 aliasp = strchr(name, ':');
1842 if (aliasp != 0)
1843 *aliasp = 0;
1845 info("found interface %s for proxy arp", name);
1847 * Now get the hardware address.
1849 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1850 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1851 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1852 return 0;
1855 memcpy (hwaddr,
1856 &bestifreq.ifr_hwaddr,
1857 sizeof (struct sockaddr));
1859 return 1;
1863 * get_if_hwaddr - get the hardware address for the specified
1864 * network interface device.
1867 get_if_hwaddr(u_char *addr, char *name)
1869 struct ifreq ifreq;
1870 int ret, sock_fd;
1872 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1873 if (sock_fd < 0)
1874 return 0;
1875 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1876 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1877 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1878 close(sock_fd);
1879 if (ret >= 0)
1880 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1881 return ret;
1885 * get_first_ethernet - return the name of the first ethernet-style
1886 * interface on this system.
1888 char *
1889 get_first_ethernet()
1891 return "eth0";
1894 /********************************************************************
1896 * Return user specified netmask, modified by any mask we might determine
1897 * for address `addr' (in network byte order).
1898 * Here we scan through the system's list of interfaces, looking for
1899 * any non-point-to-point interfaces which might appear to be on the same
1900 * network as `addr'. If we find any, we OR in their netmask to the
1901 * user-specified netmask.
1904 u_int32_t GetMask (u_int32_t addr)
1906 u_int32_t mask, nmask, ina;
1907 struct ifreq *ifr, *ifend, ifreq;
1908 struct ifconf ifc;
1909 struct ifreq ifs[MAX_IFS];
1911 addr = ntohl(addr);
1913 if (IN_CLASSA(addr)) /* determine network mask for address class */
1914 nmask = IN_CLASSA_NET;
1915 else if (IN_CLASSB(addr))
1916 nmask = IN_CLASSB_NET;
1917 else
1918 nmask = IN_CLASSC_NET;
1920 /* class D nets are disallowed by bad_ip_adrs */
1921 mask = netmask | htonl(nmask);
1923 * Scan through the system's network interfaces.
1925 ifc.ifc_len = sizeof(ifs);
1926 ifc.ifc_req = ifs;
1927 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1928 if ( ! ok_error ( errno ))
1929 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1930 return mask;
1933 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1934 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1936 * Check the interface's internet address.
1938 if (ifr->ifr_addr.sa_family != AF_INET)
1939 continue;
1940 ina = SIN_ADDR(ifr->ifr_addr);
1941 if (((ntohl(ina) ^ addr) & nmask) != 0)
1942 continue;
1944 * Check that the interface is up, and not point-to-point nor loopback.
1946 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1947 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1948 continue;
1950 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1951 continue;
1953 * Get its netmask and OR it into our mask.
1955 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1956 continue;
1957 mask |= SIN_ADDR(ifreq.ifr_addr);
1958 break;
1960 return mask;
1963 /********************************************************************
1965 * Internal routine to decode the version.modification.patch level
1968 static void decode_version (char *buf, int *version,
1969 int *modification, int *patch)
1971 char *endp;
1973 *version = (int) strtoul (buf, &endp, 10);
1974 *modification = 0;
1975 *patch = 0;
1977 if (endp != buf && *endp == '.') {
1978 buf = endp + 1;
1979 *modification = (int) strtoul (buf, &endp, 10);
1980 if (endp != buf && *endp == '.') {
1981 buf = endp + 1;
1982 *patch = (int) strtoul (buf, &buf, 10);
1987 /********************************************************************
1989 * Procedure to determine if the PPP line discipline is registered.
1992 static int
1993 ppp_registered(void)
1995 int local_fd;
1996 int mfd = -1;
1997 int ret = 0;
1998 char slave[16];
2001 * We used to open the serial device and set it to the ppp line
2002 * discipline here, in order to create a ppp unit. But that is
2003 * not a good idea - the user might have specified a device that
2004 * they can't open (permission, or maybe it doesn't really exist).
2005 * So we grab a pty master/slave pair and use that.
2007 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2008 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2009 return 0;
2013 * Try to put the device into the PPP discipline.
2015 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2016 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2017 } else
2018 ret = 1;
2020 close(local_fd);
2021 close(mfd);
2022 return ret;
2025 /********************************************************************
2027 * ppp_available - check whether the system has any ppp interfaces
2028 * (in fact we check whether we can do an ioctl on ppp0).
2031 int ppp_available(void)
2033 int s, ok, fd, err;
2034 struct ifreq ifr;
2035 int size;
2036 int my_version, my_modification, my_patch;
2037 int osmaj, osmin, ospatch;
2039 /* get the kernel version now, since we are called before sys_init */
2040 uname(&utsname);
2041 osmaj = osmin = ospatch = 0;
2042 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2043 kernel_version = KVERSION(osmaj, osmin, ospatch);
2045 fd = open("/dev/ppp", O_RDWR);
2046 if (fd >= 0) {
2047 new_style_driver = 1;
2049 /* XXX should get from driver */
2050 driver_version = 2;
2051 driver_modification = 4;
2052 driver_patch = 0;
2053 close(fd);
2054 return 1;
2056 err = errno;
2058 if (kernel_version >= KVERSION(2,3,13)) {
2059 error("Couldn't open the /dev/ppp device: %m");
2060 if (errno == ENOENT)
2061 no_ppp_msg =
2062 "You need to create the /dev/ppp device node by\n"
2063 "executing the following command as root:\n"
2064 " mknod /dev/ppp c 108 0\n";
2065 else if (errno == ENODEV || errno == ENXIO)
2066 no_ppp_msg =
2067 "Please load the ppp_generic kernel module.\n";
2068 return 0;
2071 /* we are running on a really really old kernel */
2072 no_ppp_msg =
2073 "This system lacks kernel support for PPP. This could be because\n"
2074 "the PPP kernel module could not be loaded, or because PPP was not\n"
2075 "included in the kernel configuration. If PPP was included as a\n"
2076 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2077 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2078 "See README.linux file in the ppp distribution for more details.\n";
2081 * Open a socket for doing the ioctl operations.
2083 s = socket(AF_INET, SOCK_DGRAM, 0);
2084 if (s < 0)
2085 return 0;
2087 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2088 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2090 * If the device did not exist then attempt to create one by putting the
2091 * current tty into the PPP discipline. If this works then obtain the
2092 * flags for the device again.
2094 if (!ok) {
2095 if (ppp_registered()) {
2096 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2097 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2101 * Ensure that the hardware address is for PPP and not something else
2103 if (ok)
2104 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2106 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2107 ok = 0;
2110 * This is the PPP device. Validate the version of the driver at this
2111 * point to ensure that this program will work with the driver.
2113 if (ok) {
2114 char abBuffer [1024];
2116 ifr.ifr_data = abBuffer;
2117 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2118 if (size < 0) {
2119 error("Couldn't read driver version: %m");
2120 ok = 0;
2121 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2123 } else {
2124 decode_version(abBuffer,
2125 &driver_version,
2126 &driver_modification,
2127 &driver_patch);
2129 * Validate the version of the driver against the version that we used.
2131 decode_version(VERSION,
2132 &my_version,
2133 &my_modification,
2134 &my_patch);
2136 /* The version numbers must match */
2137 if (driver_version != my_version)
2138 ok = 0;
2140 /* The modification levels must be legal */
2141 if (driver_modification < 3) {
2142 if (driver_modification >= 2) {
2143 /* we can cope with 2.2.0 and above */
2144 driver_is_old = 1;
2145 } else {
2146 ok = 0;
2150 close (s);
2151 if (!ok) {
2152 slprintf(route_buffer, sizeof(route_buffer),
2153 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2154 driver_version, driver_modification, driver_patch);
2156 no_ppp_msg = route_buffer;
2160 return ok;
2163 /********************************************************************
2165 * Update the wtmp file with the appropriate user name and tty device.
2168 void logwtmp (const char *line, const char *name, const char *host)
2170 #if 0
2171 struct utmp ut, *utp;
2172 pid_t mypid = getpid();
2173 #if __GLIBC__ < 2
2174 int wtmp;
2175 #endif
2178 * Update the signon database for users.
2179 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2181 utmpname(_PATH_UTMP);
2182 setutent();
2183 while ((utp = getutent()) && (utp->ut_pid != mypid))
2184 /* nothing */;
2186 if (utp)
2187 memcpy(&ut, utp, sizeof(ut));
2188 else
2189 /* some gettys/telnetds don't initialize utmp... */
2190 memset(&ut, 0, sizeof(ut));
2192 if (ut.ut_id[0] == 0)
2193 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2195 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2196 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2198 time(&ut.ut_time);
2200 ut.ut_type = USER_PROCESS;
2201 ut.ut_pid = mypid;
2203 /* Insert the host name if one is supplied */
2204 if (*host)
2205 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2207 /* Insert the IP address of the remote system if IP is enabled */
2208 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2209 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2210 sizeof(ut.ut_addr));
2212 /* CL: Makes sure that the logout works */
2213 if (*host == 0 && *name==0)
2214 ut.ut_host[0]=0;
2216 pututline(&ut);
2217 endutent();
2219 * Update the wtmp file.
2221 #if __GLIBC__ >= 2
2222 updwtmp(_PATH_WTMP, &ut);
2223 #else
2224 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2225 if (wtmp >= 0) {
2226 flock(wtmp, LOCK_EX);
2228 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2229 warn("error writing %s: %m", _PATH_WTMP);
2231 flock(wtmp, LOCK_UN);
2233 close (wtmp);
2235 #endif
2236 #endif
2240 /********************************************************************
2242 * sifvjcomp - config tcp header compression
2245 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2247 u_int x;
2249 if (vjcomp) {
2250 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)
2251 error("Couldn't set up TCP header compression: %m");
2252 vjcomp = 0;
2255 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2256 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2258 return 1;
2261 /********************************************************************
2263 * sifup - Config the interface up and enable IP packets to pass.
2266 int sifup(int u)
2268 struct ifreq ifr;
2270 memset (&ifr, '\0', sizeof (ifr));
2271 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2272 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2273 if (! ok_error (errno))
2274 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2275 return 0;
2278 ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2279 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2280 if (! ok_error (errno))
2281 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2282 return 0;
2284 if_is_up++;
2286 return 1;
2289 /********************************************************************
2291 * sifdown - Disable the indicated protocol and config the interface
2292 * down if there are no remaining protocols.
2295 int sifdown (int u)
2297 struct ifreq ifr;
2299 if (if_is_up && --if_is_up > 0)
2300 return 1;
2302 memset (&ifr, '\0', sizeof (ifr));
2303 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2304 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2305 if (! ok_error (errno))
2306 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2307 return 0;
2310 ifr.ifr_flags &= ~IFF_UP;
2311 ifr.ifr_flags |= IFF_POINTOPOINT;
2312 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2313 if (! ok_error (errno))
2314 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2315 return 0;
2317 return 1;
2320 /********************************************************************
2322 * sifaddr - Config the interface IP addresses and netmask.
2325 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2326 u_int32_t net_mask)
2328 struct ifreq ifr;
2329 struct rtentry rt;
2331 memset (&ifr, '\0', sizeof (ifr));
2332 memset (&rt, '\0', sizeof (rt));
2334 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2335 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2336 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2338 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2340 * Set our IP address
2342 SIN_ADDR(ifr.ifr_addr) = our_adr;
2343 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2344 if (errno != EEXIST) {
2345 if (! ok_error (errno))
2346 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2348 else {
2349 warn("ioctl(SIOCSIFADDR): Address already exists");
2351 return (0);
2354 * Set the gateway address
2356 if (his_adr != 0) {
2357 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2358 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2359 if (! ok_error (errno))
2360 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2361 return (0);
2365 * Set the netmask.
2366 * For recent kernels, force the netmask to 255.255.255.255.
2368 if (kernel_version >= KVERSION(2,1,16))
2369 net_mask = ~0L;
2370 if (net_mask != 0) {
2371 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2372 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2373 if (! ok_error (errno))
2374 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2375 return (0);
2379 * Add the device route
2381 if (kernel_version < KVERSION(2,1,16)) {
2382 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2383 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2384 rt.rt_dev = ifname;
2386 SIN_ADDR(rt.rt_gateway) = 0L;
2387 SIN_ADDR(rt.rt_dst) = his_adr;
2388 rt.rt_flags = RTF_UP | RTF_HOST;
2390 if (kernel_version > KVERSION(2,1,0)) {
2391 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2392 SIN_ADDR(rt.rt_genmask) = -1L;
2395 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2396 if (! ok_error (errno))
2397 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2398 return (0);
2402 /* set ip_dynaddr in demand mode if address changes */
2403 if (demand && tune_kernel && !dynaddr_set
2404 && our_old_addr && our_old_addr != our_adr) {
2405 /* set ip_dynaddr if possible */
2406 char *path;
2407 int fd;
2409 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2410 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2411 if (write(fd, "1", 1) != 1)
2412 error("Couldn't enable dynamic IP addressing: %m");
2413 close(fd);
2415 dynaddr_set = 1; /* only 1 attempt */
2417 our_old_addr = 0;
2419 return 1;
2422 /********************************************************************
2424 * cifaddr - Clear the interface IP addresses, and delete routes
2425 * through the interface if possible.
2428 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2430 struct ifreq ifr;
2432 if (kernel_version < KVERSION(2,1,16)) {
2434 * Delete the route through the device
2436 struct rtentry rt;
2437 memset (&rt, '\0', sizeof (rt));
2439 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2440 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2441 rt.rt_dev = ifname;
2443 SIN_ADDR(rt.rt_gateway) = 0;
2444 SIN_ADDR(rt.rt_dst) = his_adr;
2445 rt.rt_flags = RTF_UP | RTF_HOST;
2447 if (kernel_version > KVERSION(2,1,0)) {
2448 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2449 SIN_ADDR(rt.rt_genmask) = -1L;
2452 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2453 if (still_ppp() && ! ok_error (errno))
2454 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2455 return (0);
2459 /* This way it is possible to have an IPX-only or IPv6-only interface */
2460 memset(&ifr, 0, sizeof(ifr));
2461 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2462 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2464 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2465 if (! ok_error (errno)) {
2466 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2467 return 0;
2471 our_old_addr = our_adr;
2473 return 1;
2476 #ifdef INET6
2477 /********************************************************************
2479 * sif6addr - Config the interface with an IPv6 link-local address
2481 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2483 struct in6_ifreq ifr6;
2484 struct ifreq ifr;
2485 struct in6_rtmsg rt6;
2487 if (sock6_fd < 0) {
2488 errno = -sock6_fd;
2489 error("IPv6 socket creation failed: %m");
2490 return 0;
2492 memset(&ifr, 0, sizeof (ifr));
2493 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2494 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2495 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2496 return 0;
2499 /* Local interface */
2500 memset(&ifr6, 0, sizeof(ifr6));
2501 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2502 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2503 ifr6.ifr6_prefixlen = 10;
2505 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2506 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2507 return 0;
2510 /* Route to remote host */
2511 memset(&rt6, 0, sizeof(rt6));
2512 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2513 rt6.rtmsg_flags = RTF_UP;
2514 rt6.rtmsg_dst_len = 10;
2515 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2516 rt6.rtmsg_metric = 1;
2518 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2519 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2520 return 0;
2523 return 1;
2527 /********************************************************************
2529 * cif6addr - Remove IPv6 address from interface
2531 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2533 struct ifreq ifr;
2534 struct in6_ifreq ifr6;
2536 if (sock6_fd < 0) {
2537 errno = -sock6_fd;
2538 error("IPv6 socket creation failed: %m");
2539 return 0;
2541 memset(&ifr, 0, sizeof(ifr));
2542 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2543 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2544 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2545 return 0;
2548 memset(&ifr6, 0, sizeof(ifr6));
2549 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2550 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2551 ifr6.ifr6_prefixlen = 10;
2553 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2554 if (errno != EADDRNOTAVAIL) {
2555 if (! ok_error (errno))
2556 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2558 else {
2559 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2561 return (0);
2563 return 1;
2565 #endif /* INET6 */
2568 * get_pty - get a pty master/slave pair and chown the slave side
2569 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2572 get_pty(master_fdp, slave_fdp, slave_name, uid)
2573 int *master_fdp;
2574 int *slave_fdp;
2575 char *slave_name;
2576 int uid;
2578 int i, mfd, sfd = -1;
2579 char pty_name[16];
2580 struct termios tios;
2582 #ifdef TIOCGPTN
2584 * Try the unix98 way first.
2586 mfd = open("/dev/ptmx", O_RDWR);
2587 if (mfd >= 0) {
2588 int ptn;
2589 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2590 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2591 chmod(pty_name, S_IRUSR | S_IWUSR);
2592 #ifdef TIOCSPTLCK
2593 ptn = 0;
2594 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2595 warn("Couldn't unlock pty slave %s: %m", pty_name);
2596 #endif
2597 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2598 warn("Couldn't open pty slave %s: %m", pty_name);
2601 #endif /* TIOCGPTN */
2603 if (sfd < 0) {
2604 /* the old way - scan through the pty name space */
2605 for (i = 0; i < 64; ++i) {
2606 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2607 'p' + i / 16, i % 16);
2608 mfd = open(pty_name, O_RDWR, 0);
2609 if (mfd >= 0) {
2610 pty_name[5] = 't';
2611 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2612 if (sfd >= 0) {
2613 fchown(sfd, uid, -1);
2614 fchmod(sfd, S_IRUSR | S_IWUSR);
2615 break;
2617 close(mfd);
2622 if (sfd < 0)
2623 return 0;
2625 strlcpy(slave_name, pty_name, 16);
2626 *master_fdp = mfd;
2627 *slave_fdp = sfd;
2628 if (tcgetattr(sfd, &tios) == 0) {
2629 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2630 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2631 tios.c_iflag = IGNPAR;
2632 tios.c_oflag = 0;
2633 tios.c_lflag = 0;
2634 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2635 warn("couldn't set attributes on pty: %m");
2636 } else
2637 warn("couldn't get attributes on pty: %m");
2639 return 1;
2642 /********************************************************************
2644 * open_loopback - open the device we use for getting packets
2645 * in demand mode. Under Linux, we use a pty master/slave pair.
2648 open_ppp_loopback(void)
2650 int flags;
2652 looped = 1;
2653 if (new_style_driver) {
2654 /* allocate ourselves a ppp unit */
2655 if (make_ppp_unit() < 0)
2656 die(1);
2657 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2658 set_kdebugflag(kdebugflag);
2659 ppp_fd = -1;
2660 return ppp_dev_fd;
2663 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2664 fatal("No free pty for loopback");
2666 set_ppp_fd(slave_fd);
2668 flags = fcntl(master_fd, F_GETFL);
2669 if (flags == -1 ||
2670 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2671 warn("couldn't set master loopback to nonblock: %m");
2673 flags = fcntl(ppp_fd, F_GETFL);
2674 if (flags == -1 ||
2675 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2676 warn("couldn't set slave loopback to nonblock: %m");
2678 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2679 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2681 * Find out which interface we were given.
2683 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2684 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2686 * Enable debug in the driver if requested.
2688 set_kdebugflag (kdebugflag);
2690 return master_fd;
2693 /********************************************************************
2695 * sifnpmode - Set the mode for handling packets for a given NP.
2699 sifnpmode(u, proto, mode)
2700 int u;
2701 int proto;
2702 enum NPmode mode;
2704 struct npioctl npi;
2706 npi.protocol = proto;
2707 npi.mode = mode;
2708 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2709 if (! ok_error (errno))
2710 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2711 return 0;
2713 return 1;
2717 /********************************************************************
2719 * sipxfaddr - Config the interface IPX networknumber
2722 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2724 int result = 1;
2726 #ifdef IPX_CHANGE
2727 int skfd;
2728 struct ifreq ifr;
2729 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2731 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2732 if (skfd < 0) {
2733 if (! ok_error (errno))
2734 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2735 result = 0;
2737 else {
2738 memset (&ifr, '\0', sizeof (ifr));
2739 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2741 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2742 sipx->sipx_family = AF_IPX;
2743 sipx->sipx_port = 0;
2744 sipx->sipx_network = htonl (network);
2745 sipx->sipx_type = IPX_FRAME_ETHERII;
2746 sipx->sipx_action = IPX_CRTITF;
2748 * Set the IPX device
2750 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2751 result = 0;
2752 if (errno != EEXIST) {
2753 if (! ok_error (errno))
2754 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2756 else {
2757 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2760 close (skfd);
2762 #endif
2763 return result;
2766 /********************************************************************
2768 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2769 * are removed and the device is no longer able to pass IPX
2770 * frames.
2773 int cipxfaddr (int unit)
2775 int result = 1;
2777 #ifdef IPX_CHANGE
2778 int skfd;
2779 struct ifreq ifr;
2780 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2782 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2783 if (skfd < 0) {
2784 if (! ok_error (errno))
2785 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2786 result = 0;
2788 else {
2789 memset (&ifr, '\0', sizeof (ifr));
2790 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2792 sipx->sipx_type = IPX_FRAME_ETHERII;
2793 sipx->sipx_action = IPX_DLTITF;
2794 sipx->sipx_family = AF_IPX;
2796 * Set the IPX device
2798 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2799 if (! ok_error (errno))
2800 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2801 result = 0;
2803 close (skfd);
2805 #endif
2806 return result;
2810 * Use the hostname as part of the random number seed.
2813 get_host_seed()
2815 int h;
2816 char *p = hostname;
2818 h = 407;
2819 for (p = hostname; *p != 0; ++p)
2820 h = h * 37 + *p;
2821 return h;
2824 /********************************************************************
2826 * sys_check_options - check the options that the user specified
2830 sys_check_options(void)
2832 #ifdef IPX_CHANGE
2834 * Disable the IPX protocol if the support is not present in the kernel.
2836 char *path;
2838 if (ipxcp_protent.enabled_flag) {
2839 struct stat stat_buf;
2840 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
2841 && (path = path_to_procfs("/net/ipx_interface")) == NULL)
2842 || lstat(path, &stat_buf) < 0) {
2843 error("IPX support is not present in the kernel\n");
2844 ipxcp_protent.enabled_flag = 0;
2847 #endif
2848 if (demand && driver_is_old) {
2849 option_error("demand dialling is not supported by kernel driver "
2850 "version %d.%d.%d", driver_version, driver_modification,
2851 driver_patch);
2852 return 0;
2854 if (multilink && !new_style_driver) {
2855 warn("Warning: multilink is not supported by the kernel driver");
2856 multilink = 0;
2858 return 1;
2861 #ifdef INET6
2863 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2865 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2866 * that the system has a properly configured Ethernet interface for this
2867 * function to return non-zero.
2870 ether_to_eui64(eui64_t *p_eui64)
2872 struct ifreq ifr;
2873 int skfd;
2874 const unsigned char *ptr;
2876 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2877 if(skfd == -1)
2879 warn("could not open IPv6 socket");
2880 return 0;
2883 strcpy(ifr.ifr_name, "eth0");
2884 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2886 close(skfd);
2887 warn("could not obtain hardware address for eth0");
2888 return 0;
2890 close(skfd);
2893 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2895 ptr = ifr.ifr_hwaddr.sa_data;
2896 p_eui64->e8[0] = ptr[0] | 0x02;
2897 p_eui64->e8[1] = ptr[1];
2898 p_eui64->e8[2] = ptr[2];
2899 p_eui64->e8[3] = 0xFF;
2900 p_eui64->e8[4] = 0xFE;
2901 p_eui64->e8[5] = ptr[3];
2902 p_eui64->e8[6] = ptr[4];
2903 p_eui64->e8[7] = ptr[5];
2905 return 1;
2907 #endif