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
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
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
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
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
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
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>
78 #include <sys/utsname.h>
79 #include <sys/sysmacros.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. */
102 #define MAX_ADDR_LEN 7
105 #if !defined(__GLIBC__) || __GLIBC__ >= 2
106 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
108 #include <net/if_arp.h>
109 #include <net/route.h>
110 #include <netinet/if_ether.h>
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>
118 #include <netinet/in.h>
119 #include <arpa/inet.h>
121 #include <linux/ppp_defs.h>
122 #include <linux/if_ppp.h>
130 #if __GLIBC__ >= 2 && \
131 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
132 #include <netipx/ipx.h>
134 #include <linux/ipx.h>
136 #endif /* IPX_CHANGE */
139 #include <pcap-bpf.h>
140 #include <linux/filter.h>
141 #endif /* PPP_FILTER */
144 #include <sys/locks.h>
150 * This is in linux/include/net/ipv6.h.
154 struct in6_addr ifr6_addr;
155 __u32 ifr6_prefixlen;
156 unsigned int ifr6_ifindex;
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]); \
166 static const eui64_t nulleui64;
169 /* We can get an EIO error on an ioctl if the modem has hung up */
170 #define ok_error(num) ((num)==EIO)
172 static int tty_disc = N_TTY; /* The TTY discipline */
173 static int ppp_disc = N_PPP; /* The PPP discpline */
174 static int initfdflags = -1; /* Initial file descriptor flags for fd */
175 static int ppp_fd = -1; /* fd which is set to PPP discipline */
176 static int sock_fd = -1; /* socket for doing interface ioctls */
177 static int slave_fd = -1; /* pty for old-style demand mode, slave */
178 static int master_fd = -1; /* pty for old-style demand mode, master */
180 static int sock6_fd = -1;
184 * For the old-style kernel driver, this is the same as ppp_fd.
185 * For the new-style driver, it is the fd of an instance of /dev/ppp
186 * which is attached to the ppp unit and is used for controlling it.
188 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
190 static int chindex; /* channel index (new style driver) */
192 static fd_set in_fds; /* set of fds that wait_input waits for */
193 static int max_in_fd; /* highest fd set in in_fds */
195 static int has_proxy_arp = 0;
196 static int driver_version = 0;
197 static int driver_modification = 0;
198 static int driver_patch = 0;
199 static int driver_is_old = 0;
200 static int restore_term = 0; /* 1 => we've munged the terminal */
201 static struct termios inittermios; /* Initial TTY termios */
203 int new_style_driver = 0;
205 static char loop_name[20];
206 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
208 static int if_is_up; /* Interface has been marked up */
209 static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
210 static int have_default_route; /* Gateway for default route added */
211 static int have_default_route6; /* Gateway for default IPv6 route added */
212 static struct rtentry old_def_rt; /* Old default route */
213 static int default_rt_repl_rest; /* replace and restore old default rt */
214 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
215 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
216 static u_int32_t our_old_addr; /* for detecting address changes */
217 static int dynaddr_set; /* 1 if ip_dynaddr set */
218 static int looped; /* 1 if using loop */
219 static int link_mtu; /* mtu for the link (not bundle) */
221 static struct utsname utsname; /* for the kernel version */
222 static int kernel_version;
223 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
227 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
228 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
229 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
231 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
233 /* Prototypes for procedures local to this file. */
234 static int modify_flags(int fd, int clear_bits, int set_bits);
235 static int translate_speed (int bps);
236 static int baud_rate_of (int speed);
237 static void close_route_table (void);
238 static int open_route_table (void);
239 static int read_route_table (struct rtentry *rt);
240 static int defaultroute_exists (struct rtentry *rt, int metric);
241 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
242 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
243 char *name, int namelen);
244 static void decode_version (char *buf, int *version, int *mod, int *patch);
245 static int set_kdebugflag(int level);
246 static int ppp_registered(void);
247 static int make_ppp_unit(void);
248 static int setifstate (int u, int state);
250 extern u_char inpacket_buf[]; /* borrowed from main.c */
252 extern int dfl_route_metric;
255 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
259 #define SET_SA_FAMILY(addr, family) \
260 memset ((char *) &(addr), '\0', sizeof(addr)); \
261 addr.sa_family = (family);
264 * Determine if the PPP connection should still be present.
269 /* new_fd is the fd of a tty */
270 static void set_ppp_fd (int new_fd)
273 if (!new_style_driver)
277 static int still_ppp(void)
279 if (new_style_driver)
280 return !hungup && ppp_fd >= 0;
281 if (!hungup || ppp_fd == slave_fd)
284 set_ppp_fd(slave_fd);
291 * modify_flags - set and clear flag bits controlling the kernel
294 static int modify_flags(int fd, int clear_bits, int set_bits)
298 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
300 flags = (flags & ~clear_bits) | set_bits;
301 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
308 error("Failed to set PPP kernel option flags: %m");
312 /********************************************************************
314 * sys_init - System-dependent initialization.
319 /* Get an internet socket for doing socket ioctls. */
320 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
322 fatal("Couldn't create IP socket: %m(%d)", errno);
325 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
327 sock6_fd = -errno; /* save errno for later */
334 /********************************************************************
336 * sys_cleanup - restore any system state we modified before exiting:
337 * mark the interface down, delete default route and/or proxy arp entry.
338 * This shouldn't call die() because it's called from die().
341 void sys_cleanup(void)
344 * Take down the device
354 * Delete any routes through the device.
356 if (have_default_route)
357 cifdefaultroute(0, 0, 0);
359 if (have_default_route6)
360 cif6defaultroute(0, nulleui64, nulleui64);
364 cifproxyarp(0, proxy_arp_addr);
367 /********************************************************************
369 * sys_close - Clean up in a child process before execing.
374 if (new_style_driver && ppp_dev_fd >= 0)
388 /********************************************************************
390 * set_kdebugflag - Define the debugging level for the kernel
393 static int set_kdebugflag (int requested_level)
397 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
398 if ( ! ok_error (errno) )
399 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
405 /********************************************************************
407 * tty_establish_ppp - Turn the serial port into a ppp interface.
410 int tty_establish_ppp (int tty_fd)
415 * Ensure that the tty device is in exclusive mode.
417 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
418 if ( ! ok_error ( errno ))
419 warn("Couldn't make tty exclusive: %m");
422 * Demand mode - prime the old ppp device to relinquish the unit.
424 if (!new_style_driver && looped
425 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
426 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
430 * Set the current tty to the PPP discpline
434 #define N_SYNC_PPP 14
436 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
437 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
438 if ( ! ok_error (errno) ) {
439 error("Couldn't set tty to PPP discipline: %m");
444 ret_fd = generic_establish_ppp(tty_fd);
446 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
447 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
451 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
452 (kdebugflag * SC_DEBUG) & SC_LOGB);
454 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
455 warn("Couldn't reset tty to normal line discipline: %m");
461 /********************************************************************
463 * generic_establish_ppp - Turn the fd into a ppp interface.
465 int generic_establish_ppp (int fd)
469 if (new_style_driver) {
472 /* If a ppp_fd is already open, close it first */
479 /* Open an instance of /dev/ppp and connect the channel to it */
480 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
481 error("Couldn't get channel number: %m");
484 dbglog("using channel %d", chindex);
485 fd = open("/dev/ppp", O_RDWR);
487 error("Couldn't reopen /dev/ppp: %m");
490 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
491 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
492 error("Couldn't attach to channel %d: %m", chindex);
495 flags = fcntl(fd, F_GETFL);
496 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
497 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
502 if (!looped && !multilink) {
504 * Create a new PPP unit.
506 if (make_ppp_unit() < 0)
511 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
515 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
516 error("Couldn't attach to PPP unit %d: %m", ifunit);
523 * Old-style driver: find out which interface we were given.
526 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
527 if (ok_error (errno))
529 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
531 /* Check that we got the same unit again. */
532 if (looped && x != ifunit)
533 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
537 * Fetch the initial file flags and reset blocking mode on the file.
539 initfdflags = fcntl(fd, F_GETFL);
540 if (initfdflags == -1 ||
541 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
542 if ( ! ok_error (errno))
543 warn("Couldn't set device to non-blocking mode: %m");
548 * Enable debug in the driver if requested.
551 set_kdebugflag (kdebugflag);
563 /********************************************************************
565 * tty_disestablish_ppp - Restore the serial port to normal operation.
566 * This shouldn't call die() because it's called from die().
569 void tty_disestablish_ppp(int tty_fd)
573 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
575 if (tcflush(tty_fd, TCIOFLUSH) < 0)
577 warn("tcflush failed: %m");
581 * Restore the previous line discipline
583 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
584 if ( ! ok_error (errno))
585 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
588 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
589 if ( ! ok_error (errno))
590 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
593 /* Reset non-blocking mode on fd. */
594 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
595 if ( ! ok_error (errno))
596 warn("Couldn't restore device fd flags: %m");
602 generic_disestablish_ppp(tty_fd);
605 /********************************************************************
607 * generic_disestablish_ppp - Restore device components to normal
608 * operation, and reconnect the ppp unit to the loopback if in demand
609 * mode. This shouldn't call die() because it's called from die().
611 void generic_disestablish_ppp(int dev_fd)
613 if (new_style_driver) {
617 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
619 } else if (!doing_multilink && ppp_dev_fd >= 0) {
621 remove_fd(ppp_dev_fd);
625 /* old-style driver */
627 set_ppp_fd(slave_fd);
634 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
635 * Assumes new_style_driver.
637 static int make_ppp_unit(void)
641 if (ppp_dev_fd >= 0) {
642 dbglog("in make_ppp_unit, already had /dev/ppp open?");
645 ppp_dev_fd = open("/dev/ppp", O_RDWR);
647 fatal("Couldn't open /dev/ppp: %m");
648 flags = fcntl(ppp_dev_fd, F_GETFL);
650 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
651 warn("Couldn't set /dev/ppp to nonblock: %m");
654 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
655 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
656 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
658 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
661 error("Couldn't create new ppp unit: %m");
663 if (x == 0 && req_ifname[0] != '\0') {
665 char t[MAXIFNAMELEN];
666 memset(&ifr, 0, sizeof(struct ifreq));
667 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
668 strlcpy(ifr.ifr_name, t, IF_NAMESIZE);
669 strlcpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE);
670 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
672 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
674 info("Renamed interface %s to %s", t, req_ifname);
681 * cfg_bundle - configure the existing bundle.
682 * Used in demand mode.
684 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
686 if (!new_style_driver)
689 /* set the mrru, mtu and flags */
690 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
691 error("Couldn't set MRRU: %m");
693 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
694 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
695 | (mrru? SC_MULTILINK: 0)));
697 /* connect up the channel */
698 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
699 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
704 * make_new_bundle - create a new PPP unit (i.e. a bundle)
705 * and connect our channel to it. This should only get called
706 * if `multilink' was set at the time establish_ppp was called.
707 * In demand mode this uses our existing bundle instead of making
710 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
712 if (!new_style_driver)
715 /* make us a ppp unit */
716 if (make_ppp_unit() < 0)
719 /* set the mrru and flags */
720 cfg_bundle(mrru, mtru, rssn, tssn);
724 * bundle_attach - attach our link to a given PPP unit.
725 * We assume the unit is controlled by another pppd.
727 int bundle_attach(int ifnum)
731 if (!new_style_driver)
734 master_fd = open("/dev/ppp", O_RDWR);
736 fatal("Couldn't open /dev/ppp: %m");
737 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
738 if (errno == ENXIO) {
740 return 0; /* doesn't still exist */
742 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
744 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
745 fatal("Couldn't connect to interface unit %d: %m", ifnum);
746 modify_flags(master_fd, 0, SC_MULTILINK);
754 * destroy_bundle - tell the driver to destroy our bundle.
756 void destroy_bundle(void)
758 if (ppp_dev_fd >= 0) {
760 remove_fd(ppp_dev_fd);
765 /********************************************************************
767 * clean_check - Fetch the flags for the device and generate
768 * appropriate error messages.
770 void clean_check(void)
776 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
778 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
780 s = "all had bit 7 set to 1";
784 s = "all had bit 7 set to 0";
788 s = "all had odd parity";
792 s = "all had even parity";
797 warn("Receive serial link is not 8-bit clean:");
798 warn("Problem: %s", s);
806 * List of valid speeds.
810 int speed_int, speed_val;
891 { 1000000, B1000000 },
894 { 1152000, B1152000 },
897 { 1500000, B1500000 },
900 { 2000000, B2000000 },
903 { 2500000, B2500000 },
906 { 3000000, B3000000 },
909 { 3500000, B3500000 },
912 { 4000000, B4000000 },
917 /********************************************************************
919 * Translate from bits/second to a speed_t.
922 static int translate_speed (int bps)
924 struct speed *speedp;
927 for (speedp = speeds; speedp->speed_int; speedp++) {
928 if (bps == speedp->speed_int)
929 return speedp->speed_val;
931 warn("speed %d not supported", bps);
936 /********************************************************************
938 * Translate from a speed_t to bits/second.
941 static int baud_rate_of (int speed)
943 struct speed *speedp;
946 for (speedp = speeds; speedp->speed_int; speedp++) {
947 if (speed == speedp->speed_val)
948 return speedp->speed_int;
954 /********************************************************************
956 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
957 * at the requested speed, etc. If `local' is true, set CLOCAL
958 * regardless of whether the modem option was specified.
961 void set_up_tty(int tty_fd, int local)
967 if (tcgetattr(tty_fd, &tios) < 0) {
968 if (!ok_error(errno))
969 fatal("tcgetattr: %m (line %d)", __LINE__);
976 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
977 tios.c_cflag |= CS8 | CREAD | HUPCL;
979 tios.c_iflag = IGNBRK | IGNPAR;
983 tios.c_cc[VTIME] = 0;
986 tios.c_cflag ^= (CLOCAL | HUPCL);
990 tios.c_cflag |= CRTSCTS;
994 tios.c_iflag |= IXON | IXOFF;
995 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
996 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1000 tios.c_cflag &= ~CRTSCTS;
1008 tios.c_cflag |= CSTOPB;
1010 speed = translate_speed(inspeed);
1012 cfsetospeed (&tios, speed);
1013 cfsetispeed (&tios, speed);
1016 * We can't proceed if the serial port speed is B0,
1017 * since that implies that the serial port is disabled.
1020 speed = cfgetospeed(&tios);
1022 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1025 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1027 fatal("tcsetattr: %m (line %d)", __LINE__);
1029 baud_rate = baud_rate_of(speed);
1033 /********************************************************************
1035 * setdtr - control the DTR line on the serial port.
1036 * This is called from die(), so it shouldn't call die().
1039 void setdtr (int tty_fd, int on)
1041 int modembits = TIOCM_DTR;
1043 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1046 /********************************************************************
1048 * restore_tty - restore the terminal to the saved settings.
1051 void restore_tty (int tty_fd)
1056 * Turn off echoing, because otherwise we can get into
1057 * a loop with the tty and the modem echoing to each other.
1058 * We presume we are the sole user of this tty device, so
1059 * when we close it, it will revert to its defaults anyway.
1061 if (!default_device)
1062 inittermios.c_lflag &= ~(ECHO | ECHONL);
1064 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1065 if (! ok_error (errno))
1066 warn("tcsetattr: %m (line %d)", __LINE__);
1071 /********************************************************************
1073 * output - Output PPP packet.
1076 void output (int unit, unsigned char *p, int len)
1081 dump_packet("sent", p, len);
1082 if (snoop_send_hook) snoop_send_hook(p, len);
1084 if (len < PPP_HDRLEN)
1086 if (new_style_driver) {
1089 proto = (p[0] << 8) + p[1];
1090 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1093 if (write(fd, p, len) < 0) {
1094 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1095 || errno == ENXIO || errno == EIO || errno == EINTR)
1096 warn("write: warning: %m (%d)", errno);
1098 error("write: %m (%d)", errno);
1102 /********************************************************************
1104 * wait_input - wait until there is data available,
1105 * for the length of time specified by *timo (indefinite
1109 void wait_input(struct timeval *timo)
1116 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1117 if (n < 0 && errno != EINTR)
1118 fatal("select: %m");
1122 * add_fd - add an fd to the set that wait_input waits for.
1126 if (fd >= FD_SETSIZE)
1127 fatal("internal error: file descriptor too large (%d)", fd);
1128 FD_SET(fd, &in_fds);
1134 * remove_fd - remove an fd from the set that wait_input waits for.
1136 void remove_fd(int fd)
1138 FD_CLR(fd, &in_fds);
1142 /********************************************************************
1144 * read_packet - get a PPP packet from the serial device.
1147 int read_packet (unsigned char *buf)
1151 len = PPP_MRU + PPP_HDRLEN;
1152 if (new_style_driver) {
1153 *buf++ = PPP_ALLSTATIONS;
1159 nr = read(ppp_fd, buf, len);
1160 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1161 && errno != EIO && errno != EINTR)
1163 if (nr < 0 && errno == ENXIO)
1166 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1167 /* N.B. we read ppp_fd first since LCP packets come in there. */
1168 nr = read(ppp_dev_fd, buf, len);
1169 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1170 && errno != EIO && errno != EINTR)
1171 error("read /dev/ppp: %m");
1172 if (nr < 0 && errno == ENXIO)
1174 if (nr == 0 && doing_multilink) {
1175 remove_fd(ppp_dev_fd);
1179 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1181 return (new_style_driver && nr > 0)? nr+2: nr;
1184 /********************************************************************
1186 * get_loop_output - get outgoing packets from the ppp device,
1187 * and detect when we want to bring the real link up.
1188 * Return value is 1 if we need to bring up the link, 0 otherwise.
1191 get_loop_output(void)
1196 if (new_style_driver) {
1197 while ((n = read_packet(inpacket_buf)) > 0)
1198 if (loop_frame(inpacket_buf, n))
1203 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1204 if (loop_chars(inbuf, n))
1208 fatal("eof on loopback");
1210 if (errno != EWOULDBLOCK && errno != EAGAIN)
1211 fatal("read from loopback: %m(%d)", errno);
1217 * netif_set_mtu - set the MTU on the PPP network interface.
1220 netif_set_mtu(int unit, int mtu)
1224 memset (&ifr, '\0', sizeof (ifr));
1225 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1228 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1229 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1233 * netif_get_mtu - get the MTU on the PPP network interface.
1236 netif_get_mtu(int unit)
1240 memset (&ifr, '\0', sizeof (ifr));
1241 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1243 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1244 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1250 /********************************************************************
1252 * tty_send_config - configure the transmit characteristics of
1253 * the ppp interface.
1256 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1263 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1264 if (errno != EIO && errno != ENOTTY)
1265 error("Couldn't set transmit async character map: %m");
1270 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1271 | (sync_serial? SC_SYNC: 0);
1272 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1275 /********************************************************************
1277 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1280 void tty_set_xaccm (ext_accm accm)
1284 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1285 if ( ! ok_error (errno))
1286 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1290 /********************************************************************
1292 * tty_recv_config - configure the receive-side characteristics of
1293 * the ppp interface.
1296 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1299 * If we were called because the link has gone down then there is nothing
1300 * which may be done. Just return without incident.
1305 * Set the receiver parameters
1307 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1308 if (errno != EIO && errno != ENOTTY)
1309 error("Couldn't set channel receive MRU: %m");
1311 if (new_style_driver && ppp_dev_fd >= 0
1312 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1313 error("Couldn't set MRU in generic PPP layer: %m");
1315 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1316 if (errno != EIO && errno != ENOTTY)
1317 error("Couldn't set channel receive asyncmap: %m");
1321 /********************************************************************
1323 * ccp_test - ask kernel whether a given compression method
1324 * is acceptable for use.
1328 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1330 struct ppp_option_data data;
1332 memset (&data, '\0', sizeof (data));
1334 data.length = opt_len;
1335 data.transmit = for_transmit;
1337 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1340 return (errno == ENOBUFS)? 0: -1;
1343 /********************************************************************
1345 * ccp_flags_set - inform kernel about the current state of CCP.
1348 void ccp_flags_set (int unit, int isopen, int isup)
1352 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1353 if (still_ppp() && ppp_dev_fd >= 0)
1354 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1359 * set_filters - set the active and pass filters in the kernel driver.
1361 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1363 struct sock_fprog fp;
1365 fp.len = pass->bf_len;
1366 fp.filter = (struct sock_filter *) pass->bf_insns;
1367 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1368 if (errno == ENOTTY)
1369 warn("kernel does not support PPP filtering");
1371 error("Couldn't set pass-filter in kernel: %m");
1374 fp.len = active->bf_len;
1375 fp.filter = (struct sock_filter *) active->bf_insns;
1376 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1377 error("Couldn't set active-filter in kernel: %m");
1382 #endif /* PPP_FILTER */
1384 /********************************************************************
1386 * get_idle_time - return how long the link has been idle.
1389 get_idle_time(int u, struct ppp_idle *ip)
1391 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1394 /********************************************************************
1396 * get_ppp_stats - return statistics for the link.
1399 get_ppp_stats(int u, struct pppd_stats *stats)
1401 struct ifpppstatsreq req;
1403 memset (&req, 0, sizeof (req));
1405 req.stats_ptr = (caddr_t) &req.stats;
1406 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1407 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1408 error("Couldn't get PPP statistics: %m");
1411 stats->bytes_in = req.stats.p.ppp_ibytes;
1412 stats->bytes_out = req.stats.p.ppp_obytes;
1413 stats->pkts_in = req.stats.p.ppp_ipackets;
1414 stats->pkts_out = req.stats.p.ppp_opackets;
1418 /********************************************************************
1420 * ccp_fatal_error - returns 1 if decompression was disabled as a
1421 * result of an error detected after decompression of a packet,
1422 * 0 otherwise. This is necessary because of patent nonsense.
1425 int ccp_fatal_error (int unit)
1429 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1430 error("Couldn't read compression error flags: %m");
1433 return flags & SC_DC_FERROR;
1436 /********************************************************************
1438 * path_to_procfs - find the path to the proc file system mount point
1440 static char proc_path[MAXPATHLEN];
1441 static int proc_path_len;
1443 static char *path_to_procfs(const char *tail)
1445 struct mntent *mntent;
1448 if (proc_path_len == 0) {
1449 /* Default the mount location of /proc */
1450 strlcpy (proc_path, "/proc", sizeof(proc_path));
1452 fp = fopen(MOUNTED, "r");
1454 while ((mntent = getmntent(fp)) != NULL) {
1455 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1457 if (strcmp(mntent->mnt_type, "proc") == 0) {
1458 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1459 proc_path_len = strlen(proc_path);
1467 strlcpy(proc_path + proc_path_len, tail,
1468 sizeof(proc_path) - proc_path_len);
1473 * /proc/net/route parsing stuff.
1475 #define ROUTE_MAX_COLS 12
1476 FILE *route_fd = (FILE *) 0;
1477 static char route_buffer[512];
1478 static int route_dev_col, route_dest_col, route_gw_col;
1479 static int route_flags_col, route_metric_col, route_mask_col;
1480 static int route_num_cols;
1482 static int open_route_table (void);
1483 static void close_route_table (void);
1484 static int read_route_table (struct rtentry *rt);
1486 /********************************************************************
1488 * close_route_table - close the interface to the route table
1491 static void close_route_table (void)
1493 if (route_fd != (FILE *) 0) {
1495 route_fd = (FILE *) 0;
1499 /********************************************************************
1501 * open_route_table - open the interface to the route table
1503 static char route_delims[] = " \t\n";
1505 static int open_route_table (void)
1509 close_route_table();
1511 path = path_to_procfs("/net/route");
1512 route_fd = fopen (path, "r");
1513 if (route_fd == NULL) {
1514 error("can't open routing table %s: %m", path);
1518 route_dev_col = 0; /* default to usual columns */
1521 route_flags_col = 3;
1522 route_metric_col = 6;
1526 /* parse header line */
1527 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1528 char *p = route_buffer, *q;
1530 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1532 if ((q = strtok(p, route_delims)) == 0)
1534 if (strcasecmp(q, "iface") == 0)
1535 route_dev_col = col;
1536 else if (strcasecmp(q, "destination") == 0)
1537 route_dest_col = col;
1538 else if (strcasecmp(q, "gateway") == 0)
1540 else if (strcasecmp(q, "flags") == 0)
1541 route_flags_col = col;
1542 else if (strcasecmp(q, "mask") == 0)
1543 route_mask_col = col;
1546 if (used && col >= route_num_cols)
1547 route_num_cols = col + 1;
1555 /********************************************************************
1557 * read_route_table - read the next entry from the route table
1560 static int read_route_table(struct rtentry *rt)
1562 char *cols[ROUTE_MAX_COLS], *p;
1565 memset (rt, '\0', sizeof (struct rtentry));
1567 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1571 for (col = 0; col < route_num_cols; ++col) {
1572 cols[col] = strtok(p, route_delims);
1573 if (cols[col] == NULL)
1574 return 0; /* didn't get enough columns */
1578 SET_SA_FAMILY (rt->rt_dst, AF_INET);
1579 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
1581 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1582 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1583 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1585 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1586 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
1587 rt->rt_dev = cols[route_dev_col];
1592 /********************************************************************
1594 * defaultroute_exists - determine if there is a default route
1595 * with the given metric (or negative for any)
1598 static int defaultroute_exists (struct rtentry *rt, int metric)
1602 if (!open_route_table())
1605 while (read_route_table(rt) != 0) {
1606 if ((rt->rt_flags & RTF_UP) == 0)
1609 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1611 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1612 || rt->rt_metric == metric)) {
1618 close_route_table();
1623 * have_route_to - determine if the system has any route to
1624 * a given IP address. `addr' is in network byte order.
1625 * Return value is 1 if yes, 0 if no, -1 if don't know.
1626 * For demand mode to work properly, we have to ignore routes
1627 * through our own interface.
1629 int have_route_to(u_int32_t addr)
1634 if (!open_route_table())
1635 return -1; /* don't know */
1637 while (read_route_table(&rt)) {
1638 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1640 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1646 close_route_table();
1650 /********************************************************************
1652 * sifdefaultroute - assign a default route through the address given.
1654 * If the global default_rt_repl_rest flag is set, then this function
1655 * already replaced the original system defaultroute with some other
1656 * route and it should just replace the current defaultroute with
1657 * another one, without saving the current route. Use: demand mode,
1658 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
1659 * and then changes the temporary addresses to the addresses for the real
1660 * ppp connection when it has come up.
1663 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
1665 struct rtentry rt, tmp_rt;
1666 struct rtentry *del_rt = NULL;
1668 if (default_rt_repl_rest) {
1669 /* We have already replaced the original defaultroute, if we
1670 * are called again, we will delete the current default route
1671 * and set the new default route in this function.
1672 * - this is normally only the case the doing demand: */
1673 if (defaultroute_exists(&tmp_rt, -1))
1675 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
1676 strcmp( old_def_rt.rt_dev, ifname) != 0) {
1678 * We did not yet replace an existing default route, let's
1679 * check if we should save and replace a default route:
1681 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
1683 if (old_gateway != gateway) {
1685 error("not replacing default route to %s [%I]",
1686 old_def_rt.rt_dev, old_gateway);
1689 /* we need to copy rt_dev because we need it permanent too: */
1690 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
1691 strcpy(tmp_dev, old_def_rt.rt_dev);
1692 old_def_rt.rt_dev = tmp_dev;
1694 notice("replacing old default route to %s [%I]",
1695 old_def_rt.rt_dev, old_gateway);
1696 default_rt_repl_rest = 1;
1697 del_rt = &old_def_rt;
1702 memset (&rt, 0, sizeof (rt));
1703 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1706 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1708 if (kernel_version > KVERSION(2,1,0)) {
1709 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1710 SIN_ADDR(rt.rt_genmask) = 0L;
1713 rt.rt_flags = RTF_UP;
1714 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1715 if ( ! ok_error ( errno ))
1716 error("default route ioctl(SIOCADDRT): %m");
1719 if (default_rt_repl_rest && del_rt)
1720 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
1721 if ( ! ok_error ( errno ))
1722 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
1726 have_default_route = 1;
1730 /********************************************************************
1732 * cifdefaultroute - delete a default route through the address given.
1735 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1739 have_default_route = 0;
1741 memset (&rt, '\0', sizeof (rt));
1742 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1743 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1748 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1750 if (kernel_version > KVERSION(2,1,0)) {
1751 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1752 SIN_ADDR(rt.rt_genmask) = 0L;
1755 rt.rt_flags = RTF_UP;
1756 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1758 if ( ! ok_error ( errno ))
1759 error("default route ioctl(SIOCDELRT): %m");
1763 if (default_rt_repl_rest) {
1764 notice("restoring old default route to %s [%I]",
1765 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
1766 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
1767 if ( ! ok_error ( errno ))
1768 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
1771 default_rt_repl_rest = 0;
1779 * /proc/net/ipv6_route parsing stuff.
1781 static int route_dest_plen_col;
1782 static int open_route6_table (void);
1783 static int read_route6_table (struct in6_rtmsg *rt);
1785 /********************************************************************
1787 * open_route6_table - open the interface to the route table
1789 static int open_route6_table (void)
1793 close_route_table();
1795 path = path_to_procfs("/net/ipv6_route");
1796 route_fd = fopen (path, "r");
1797 if (route_fd == NULL) {
1798 error("can't open routing table %s: %m", path);
1802 /* default to usual columns */
1804 route_dest_plen_col = 1;
1806 route_metric_col = 5;
1807 route_flags_col = 8;
1809 route_num_cols = 10;
1814 /********************************************************************
1816 * read_route6_table - read the next entry from the route table
1819 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
1826 for (i = 0; i < 4; i++) {
1827 memcpy(hex8, s + 8*i, 8);
1828 v = strtoul(hex8, NULL, 16);
1829 addr->s6_addr32[i] = v;
1833 static int read_route6_table(struct in6_rtmsg *rt)
1835 char *cols[ROUTE_MAX_COLS], *p;
1838 memset (rt, '\0', sizeof (struct in6_rtmsg));
1840 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1844 for (col = 0; col < route_num_cols; ++col) {
1845 cols[col] = strtok(p, route_delims);
1846 if (cols[col] == NULL)
1847 return 0; /* didn't get enough columns */
1851 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
1852 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
1853 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
1855 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
1856 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
1857 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
1862 /********************************************************************
1864 * defaultroute6_exists - determine if there is a default route
1867 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
1871 if (!open_route6_table())
1874 while (read_route6_table(rt) != 0) {
1875 if ((rt->rtmsg_flags & RTF_UP) == 0)
1878 if (rt->rtmsg_dst_len != 0)
1880 if (rt->rtmsg_dst.s6_addr32[0] == 0L
1881 && rt->rtmsg_dst.s6_addr32[1] == 0L
1882 && rt->rtmsg_dst.s6_addr32[2] == 0L
1883 && rt->rtmsg_dst.s6_addr32[3] == 0L
1884 && (metric < 0 || rt->rtmsg_metric == metric)) {
1890 close_route_table();
1894 /********************************************************************
1896 * sif6defaultroute - assign a default route through the address given.
1898 * If the global default_rt_repl_rest flag is set, then this function
1899 * already replaced the original system defaultroute with some other
1900 * route and it should just replace the current defaultroute with
1901 * another one, without saving the current route. Use: demand mode,
1902 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
1903 * and then changes the temporary addresses to the addresses for the real
1904 * ppp connection when it has come up.
1907 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
1909 struct in6_rtmsg rt;
1910 char buf[IF_NAMESIZE];
1912 if (defaultroute6_exists(&rt, dfl_route_metric) &&
1913 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
1914 if (rt.rtmsg_flags & RTF_GATEWAY)
1915 error("not replacing existing default route via gateway");
1917 error("not replacing existing default route through %s",
1918 if_indextoname(rt.rtmsg_ifindex, buf));
1922 memset (&rt, 0, sizeof (rt));
1924 rt.rtmsg_ifindex = if_nametoindex(ifname);
1925 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1926 rt.rtmsg_dst_len = 0;
1928 rt.rtmsg_flags = RTF_UP;
1929 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
1930 if ( ! ok_error ( errno ))
1931 error("default route ioctl(SIOCADDRT): %m");
1935 have_default_route6 = 1;
1939 /********************************************************************
1941 * cif6defaultroute - delete a default route through the address given.
1944 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
1946 struct in6_rtmsg rt;
1948 have_default_route6 = 0;
1950 memset (&rt, '\0', sizeof (rt));
1952 rt.rtmsg_ifindex = if_nametoindex(ifname);
1953 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1954 rt.rtmsg_dst_len = 0;
1956 rt.rtmsg_flags = RTF_UP;
1957 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1959 if ( ! ok_error ( errno ))
1960 error("default route ioctl(SIOCDELRT): %m");
1969 /********************************************************************
1971 * sifproxyarp - Make a proxy ARP entry for the peer.
1974 int sifproxyarp (int unit, u_int32_t his_adr)
1976 struct arpreq arpreq;
1979 if (has_proxy_arp == 0) {
1980 memset (&arpreq, '\0', sizeof(arpreq));
1982 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1983 SIN_ADDR(arpreq.arp_pa) = his_adr;
1984 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1986 * Get the hardware address of an interface on the same subnet
1987 * as our local address.
1989 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1990 sizeof(proxy_arp_dev))) {
1991 error("Cannot determine ethernet address for proxy ARP");
1994 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1996 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1997 if ( ! ok_error ( errno ))
1998 error("ioctl(SIOCSARP): %m");
2001 proxy_arp_addr = his_adr;
2005 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2006 if (forw_path != 0) {
2007 int fd = open(forw_path, O_WRONLY);
2009 if (write(fd, "1", 1) != 1)
2010 error("Couldn't enable IP forwarding: %m");
2020 /********************************************************************
2022 * cifproxyarp - Delete the proxy ARP entry for the peer.
2025 int cifproxyarp (int unit, u_int32_t his_adr)
2027 struct arpreq arpreq;
2029 if (has_proxy_arp) {
2031 memset (&arpreq, '\0', sizeof(arpreq));
2032 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2033 SIN_ADDR(arpreq.arp_pa) = his_adr;
2034 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2035 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2037 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2038 if ( ! ok_error ( errno ))
2039 warn("ioctl(SIOCDARP): %m");
2046 /********************************************************************
2048 * get_ether_addr - get the hardware address of an interface on the
2049 * the same subnet as ipaddr.
2052 static int get_ether_addr (u_int32_t ipaddr,
2053 struct sockaddr *hwaddr,
2054 char *name, int namelen)
2056 struct ifreq *ifr, *ifend;
2057 u_int32_t ina, mask;
2059 struct ifreq ifreq, bestifreq;
2061 struct ifreq ifs[MAX_IFS];
2063 u_int32_t bestmask=0;
2064 int found_interface = 0;
2066 ifc.ifc_len = sizeof(ifs);
2068 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2069 if ( ! ok_error ( errno ))
2070 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2075 * Scan through looking for an interface with an Internet
2076 * address on the same subnet as `ipaddr'.
2078 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2079 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2080 if (ifr->ifr_addr.sa_family == AF_INET) {
2081 ina = SIN_ADDR(ifr->ifr_addr);
2082 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2084 * Check that the interface is up, and not point-to-point
2087 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2090 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2093 * Get its netmask and check that it's on the right subnet.
2095 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2098 mask = SIN_ADDR(ifreq.ifr_addr);
2100 if (((ipaddr ^ ina) & mask) != 0)
2101 continue; /* no match */
2103 if (mask >= bestmask) {
2104 /* Compare using >= instead of > -- it is possible for
2105 an interface to have a netmask of 0.0.0.0 */
2106 found_interface = 1;
2113 if (!found_interface) return 0;
2115 strlcpy(name, bestifreq.ifr_name, namelen);
2117 /* trim off the :1 in eth0:1 */
2118 aliasp = strchr(name, ':');
2122 info("found interface %s for proxy arp", name);
2124 * Now get the hardware address.
2126 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2127 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2128 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2133 &bestifreq.ifr_hwaddr,
2134 sizeof (struct sockaddr));
2140 * get_if_hwaddr - get the hardware address for the specified
2141 * network interface device.
2144 get_if_hwaddr(u_char *addr, char *name)
2149 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2152 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2153 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2154 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2157 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2162 * get_first_ether_hwaddr - get the hardware address for the first
2163 * ethernet-style interface on this system.
2166 get_first_ether_hwaddr(u_char *addr)
2168 struct if_nameindex *if_ni, *i;
2172 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2176 if_ni = if_nameindex();
2184 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2185 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2186 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2187 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2188 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2189 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2195 if_freenameindex(if_ni);
2201 /********************************************************************
2203 * Return user specified netmask, modified by any mask we might determine
2204 * for address `addr' (in network byte order).
2205 * Here we scan through the system's list of interfaces, looking for
2206 * any non-point-to-point interfaces which might appear to be on the same
2207 * network as `addr'. If we find any, we OR in their netmask to the
2208 * user-specified netmask.
2211 u_int32_t GetMask (u_int32_t addr)
2213 u_int32_t mask, nmask, ina;
2214 struct ifreq *ifr, *ifend, ifreq;
2216 struct ifreq ifs[MAX_IFS];
2220 if (IN_CLASSA(addr)) /* determine network mask for address class */
2221 nmask = IN_CLASSA_NET;
2222 else if (IN_CLASSB(addr))
2223 nmask = IN_CLASSB_NET;
2225 nmask = IN_CLASSC_NET;
2227 /* class D nets are disallowed by bad_ip_adrs */
2228 mask = netmask | htonl(nmask);
2230 * Scan through the system's network interfaces.
2232 ifc.ifc_len = sizeof(ifs);
2234 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2235 if ( ! ok_error ( errno ))
2236 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2240 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2241 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2243 * Check the interface's internet address.
2245 if (ifr->ifr_addr.sa_family != AF_INET)
2247 ina = SIN_ADDR(ifr->ifr_addr);
2248 if (((ntohl(ina) ^ addr) & nmask) != 0)
2251 * Check that the interface is up, and not point-to-point nor loopback.
2253 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2254 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2257 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2260 * Get its netmask and OR it into our mask.
2262 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2264 mask |= SIN_ADDR(ifreq.ifr_addr);
2270 /********************************************************************
2272 * Internal routine to decode the version.modification.patch level
2275 static void decode_version (char *buf, int *version,
2276 int *modification, int *patch)
2280 *version = (int) strtoul (buf, &endp, 10);
2284 if (endp != buf && *endp == '.') {
2286 *modification = (int) strtoul (buf, &endp, 10);
2287 if (endp != buf && *endp == '.') {
2289 *patch = (int) strtoul (buf, &buf, 10);
2294 /********************************************************************
2296 * Procedure to determine if the PPP line discipline is registered.
2300 ppp_registered(void)
2308 * We used to open the serial device and set it to the ppp line
2309 * discipline here, in order to create a ppp unit. But that is
2310 * not a good idea - the user might have specified a device that
2311 * they can't open (permission, or maybe it doesn't really exist).
2312 * So we grab a pty master/slave pair and use that.
2314 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2315 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2320 * Try to put the device into the PPP discipline.
2322 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2323 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2332 /********************************************************************
2334 * ppp_available - check whether the system has any ppp interfaces
2335 * (in fact we check whether we can do an ioctl on ppp0).
2338 int ppp_available(void)
2343 int my_version, my_modification, my_patch;
2344 int osmaj, osmin, ospatch;
2346 /* get the kernel version now, since we are called before sys_init */
2348 osmaj = osmin = ospatch = 0;
2349 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2350 kernel_version = KVERSION(osmaj, osmin, ospatch);
2352 fd = open("/dev/ppp", O_RDWR);
2354 new_style_driver = 1;
2356 /* XXX should get from driver */
2358 driver_modification = 4;
2364 if (kernel_version >= KVERSION(2,3,13)) {
2365 error("Couldn't open the /dev/ppp device: %m");
2366 if (errno == ENOENT)
2368 "You need to create the /dev/ppp device node by\n"
2369 "executing the following command as root:\n"
2370 " mknod /dev/ppp c 108 0\n";
2371 else if (errno == ENODEV || errno == ENXIO)
2373 "Please load the ppp_generic kernel module.\n";
2377 /* we are running on a really really old kernel */
2379 "This system lacks kernel support for PPP. This could be because\n"
2380 "the PPP kernel module could not be loaded, or because PPP was not\n"
2381 "included in the kernel configuration. If PPP was included as a\n"
2382 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2383 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2384 "See README.linux file in the ppp distribution for more details.\n";
2387 * Open a socket for doing the ioctl operations.
2389 s = socket(AF_INET, SOCK_DGRAM, 0);
2393 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2394 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2396 * If the device did not exist then attempt to create one by putting the
2397 * current tty into the PPP discipline. If this works then obtain the
2398 * flags for the device again.
2401 if (ppp_registered()) {
2402 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2403 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2407 * Ensure that the hardware address is for PPP and not something else
2410 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2412 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2416 * This is the PPP device. Validate the version of the driver at this
2417 * point to ensure that this program will work with the driver.
2420 char abBuffer [1024];
2422 ifr.ifr_data = abBuffer;
2423 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2425 error("Couldn't read driver version: %m");
2427 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2430 decode_version(abBuffer,
2432 &driver_modification,
2435 * Validate the version of the driver against the version that we used.
2437 decode_version(VERSION,
2442 /* The version numbers must match */
2443 if (driver_version != my_version)
2446 /* The modification levels must be legal */
2447 if (driver_modification < 3) {
2448 if (driver_modification >= 2) {
2449 /* we can cope with 2.2.0 and above */
2457 slprintf(route_buffer, sizeof(route_buffer),
2458 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2459 driver_version, driver_modification, driver_patch);
2461 no_ppp_msg = route_buffer;
2469 #ifndef HAVE_LOGWTMP
2470 /********************************************************************
2472 * Update the wtmp file with the appropriate user name and tty device.
2475 void logwtmp (const char *line, const char *name, const char *host)
2477 struct utmp ut, *utp;
2478 pid_t mypid = getpid();
2484 * Update the signon database for users.
2485 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2487 utmpname(_PATH_UTMP);
2489 while ((utp = getutent()) && (utp->ut_pid != mypid))
2493 memcpy(&ut, utp, sizeof(ut));
2495 /* some gettys/telnetds don't initialize utmp... */
2496 memset(&ut, 0, sizeof(ut));
2498 if (ut.ut_id[0] == 0)
2499 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2501 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2502 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2506 ut.ut_type = USER_PROCESS;
2509 /* Insert the host name if one is supplied */
2511 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2513 /* Insert the IP address of the remote system if IP is enabled */
2514 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2515 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2516 sizeof(ut.ut_addr));
2518 /* CL: Makes sure that the logout works */
2519 if (*host == 0 && *name==0)
2525 * Update the wtmp file.
2528 updwtmp(_PATH_WTMP, &ut);
2530 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2532 flock(wtmp, LOCK_EX);
2534 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2535 warn("error writing %s: %m", _PATH_WTMP);
2537 flock(wtmp, LOCK_UN);
2543 #endif /* HAVE_LOGWTMP */
2545 /********************************************************************
2547 * sifvjcomp - config tcp header compression
2550 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2555 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2556 error("Couldn't set up TCP header compression: %m");
2561 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2562 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2567 /********************************************************************
2569 * sifup - Config the interface up and enable IP packets to pass.
2576 if ((ret = setifstate(u, 1)))
2582 /********************************************************************
2584 * sifdown - Disable the indicated protocol and config the interface
2585 * down if there are no remaining protocols.
2590 if (if_is_up && --if_is_up > 0)
2598 return setifstate(u, 0);
2602 /********************************************************************
2604 * sif6up - Config the interface up for IPv6
2611 if ((ret = setifstate(u, 1)))
2617 /********************************************************************
2619 * sif6down - Disable the IPv6CP protocol and config the interface
2620 * down if there are no remaining protocols.
2623 int sif6down (int u)
2630 return setifstate(u, 0);
2634 /********************************************************************
2636 * setifstate - Config the interface up or down
2639 static int setifstate (int u, int state)
2643 memset (&ifr, '\0', sizeof (ifr));
2644 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2645 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2646 if (! ok_error (errno))
2647 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2652 ifr.ifr_flags |= IFF_UP;
2654 ifr.ifr_flags &= ~IFF_UP;
2655 ifr.ifr_flags |= IFF_POINTOPOINT;
2656 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2657 if (! ok_error (errno))
2658 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2664 /********************************************************************
2666 * sifaddr - Config the interface IP addresses and netmask.
2669 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2675 memset (&ifr, '\0', sizeof (ifr));
2676 memset (&rt, '\0', sizeof (rt));
2678 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2679 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2680 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2682 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2684 * Set our IP address
2686 SIN_ADDR(ifr.ifr_addr) = our_adr;
2687 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2688 if (errno != EEXIST) {
2689 if (! ok_error (errno))
2690 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2693 warn("ioctl(SIOCSIFADDR): Address already exists");
2698 * Set the gateway address
2701 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2702 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2703 if (! ok_error (errno))
2704 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2710 * For recent kernels, force the netmask to 255.255.255.255.
2712 if (kernel_version >= KVERSION(2,1,16))
2714 if (net_mask != 0) {
2715 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2716 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2717 if (! ok_error (errno))
2718 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2723 * Add the device route
2725 if (kernel_version < KVERSION(2,1,16)) {
2726 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2727 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2730 SIN_ADDR(rt.rt_gateway) = 0L;
2731 SIN_ADDR(rt.rt_dst) = his_adr;
2732 rt.rt_flags = RTF_UP | RTF_HOST;
2734 if (kernel_version > KVERSION(2,1,0)) {
2735 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2736 SIN_ADDR(rt.rt_genmask) = -1L;
2739 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2740 if (! ok_error (errno))
2741 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2746 /* set ip_dynaddr in demand mode if address changes */
2747 if (demand && tune_kernel && !dynaddr_set
2748 && our_old_addr && our_old_addr != our_adr) {
2749 /* set ip_dynaddr if possible */
2753 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2754 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2755 if (write(fd, "1", 1) != 1)
2756 error("Couldn't enable dynamic IP addressing: %m");
2759 dynaddr_set = 1; /* only 1 attempt */
2766 /********************************************************************
2768 * cifaddr - Clear the interface IP addresses, and delete routes
2769 * through the interface if possible.
2772 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2776 if (kernel_version < KVERSION(2,1,16)) {
2778 * Delete the route through the device
2781 memset (&rt, '\0', sizeof (rt));
2783 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2784 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2787 SIN_ADDR(rt.rt_gateway) = 0;
2788 SIN_ADDR(rt.rt_dst) = his_adr;
2789 rt.rt_flags = RTF_UP | RTF_HOST;
2791 if (kernel_version > KVERSION(2,1,0)) {
2792 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2793 SIN_ADDR(rt.rt_genmask) = -1L;
2796 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2797 if (still_ppp() && ! ok_error (errno))
2798 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2803 /* This way it is possible to have an IPX-only or IPv6-only interface */
2804 memset(&ifr, 0, sizeof(ifr));
2805 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2806 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2808 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2809 if (! ok_error (errno)) {
2810 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2815 our_old_addr = our_adr;
2821 /********************************************************************
2823 * sif6addr - Config the interface with an IPv6 link-local address
2825 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2827 struct in6_ifreq ifr6;
2829 struct in6_rtmsg rt6;
2833 error("IPv6 socket creation failed: %m");
2836 memset(&ifr, 0, sizeof (ifr));
2837 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2838 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2839 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2843 /* Local interface */
2844 memset(&ifr6, 0, sizeof(ifr6));
2845 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2846 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2847 ifr6.ifr6_prefixlen = 128;
2849 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2850 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2854 /* Route to remote host */
2855 memset(&rt6, 0, sizeof(rt6));
2856 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2857 rt6.rtmsg_flags = RTF_UP;
2858 rt6.rtmsg_dst_len = 128;
2859 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2860 rt6.rtmsg_metric = 1;
2862 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2863 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2871 /********************************************************************
2873 * cif6addr - Remove IPv6 address from interface
2875 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2878 struct in6_ifreq ifr6;
2882 error("IPv6 socket creation failed: %m");
2885 memset(&ifr, 0, sizeof(ifr));
2886 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2887 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2888 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2892 memset(&ifr6, 0, sizeof(ifr6));
2893 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2894 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2895 ifr6.ifr6_prefixlen = 128;
2897 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2898 if (errno != EADDRNOTAVAIL) {
2899 if (! ok_error (errno))
2900 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2903 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2912 * get_pty - get a pty master/slave pair and chown the slave side
2913 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2916 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
2918 int i, mfd, sfd = -1;
2920 struct termios tios;
2924 * Try the unix98 way first.
2926 mfd = open("/dev/ptmx", O_RDWR);
2929 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2930 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2931 chmod(pty_name, S_IRUSR | S_IWUSR);
2934 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2935 warn("Couldn't unlock pty slave %s: %m", pty_name);
2937 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2939 warn("Couldn't open pty slave %s: %m", pty_name);
2944 #endif /* TIOCGPTN */
2947 /* the old way - scan through the pty name space */
2948 for (i = 0; i < 64; ++i) {
2949 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2950 'p' + i / 16, i % 16);
2951 mfd = open(pty_name, O_RDWR, 0);
2954 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2956 fchown(sfd, uid, -1);
2957 fchmod(sfd, S_IRUSR | S_IWUSR);
2968 strlcpy(slave_name, pty_name, 16);
2971 if (tcgetattr(sfd, &tios) == 0) {
2972 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2973 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2974 tios.c_iflag = IGNPAR;
2977 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2978 warn("couldn't set attributes on pty: %m");
2980 warn("couldn't get attributes on pty: %m");
2985 /********************************************************************
2987 * open_loopback - open the device we use for getting packets
2988 * in demand mode. Under Linux, we use a pty master/slave pair.
2991 open_ppp_loopback(void)
2996 if (new_style_driver) {
2997 /* allocate ourselves a ppp unit */
2998 if (make_ppp_unit() < 0)
3000 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3001 set_kdebugflag(kdebugflag);
3006 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3007 fatal("No free pty for loopback");
3009 set_ppp_fd(slave_fd);
3011 flags = fcntl(master_fd, F_GETFL);
3013 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3014 warn("couldn't set master loopback to nonblock: %m");
3016 flags = fcntl(ppp_fd, F_GETFL);
3018 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3019 warn("couldn't set slave loopback to nonblock: %m");
3021 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3022 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3024 * Find out which interface we were given.
3026 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3027 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3029 * Enable debug in the driver if requested.
3031 set_kdebugflag (kdebugflag);
3036 /********************************************************************
3038 * sifnpmode - Set the mode for handling packets for a given NP.
3042 sifnpmode(int u, int proto, enum NPmode mode)
3046 npi.protocol = proto;
3048 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3049 if (! ok_error (errno))
3050 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3057 /********************************************************************
3059 * sipxfaddr - Config the interface IPX networknumber
3062 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
3069 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3071 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3073 if (! ok_error (errno))
3074 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3078 memset (&ifr, '\0', sizeof (ifr));
3079 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3081 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
3082 sipx->sipx_family = AF_IPX;
3083 sipx->sipx_port = 0;
3084 sipx->sipx_network = htonl (network);
3085 sipx->sipx_type = IPX_FRAME_ETHERII;
3086 sipx->sipx_action = IPX_CRTITF;
3088 * Set the IPX device
3090 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3092 if (errno != EEXIST) {
3093 if (! ok_error (errno))
3094 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
3097 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
3106 /********************************************************************
3108 * cipxfaddr - Clear the information for the IPX network. The IPX routes
3109 * are removed and the device is no longer able to pass IPX
3113 int cipxfaddr (int unit)
3120 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3122 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3124 if (! ok_error (errno))
3125 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3129 memset (&ifr, '\0', sizeof (ifr));
3130 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3132 sipx->sipx_type = IPX_FRAME_ETHERII;
3133 sipx->sipx_action = IPX_DLTITF;
3134 sipx->sipx_family = AF_IPX;
3136 * Set the IPX device
3138 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3139 if (! ok_error (errno))
3140 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
3150 * Use the hostname as part of the random number seed.
3159 for (p = hostname; *p != 0; ++p)
3164 /********************************************************************
3166 * sys_check_options - check the options that the user specified
3170 sys_check_options(void)
3174 * Disable the IPX protocol if the support is not present in the kernel.
3178 if (ipxcp_protent.enabled_flag) {
3179 struct stat stat_buf;
3180 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
3181 && (path = path_to_procfs("/net/ipx_interface")) == NULL)
3182 || lstat(path, &stat_buf) < 0) {
3183 error("IPX support is not present in the kernel\n");
3184 ipxcp_protent.enabled_flag = 0;
3188 if (demand && driver_is_old) {
3189 option_error("demand dialling is not supported by kernel driver "
3190 "version %d.%d.%d", driver_version, driver_modification,
3194 if (multilink && !new_style_driver) {
3195 warn("Warning: multilink is not supported by the kernel driver");
3201 /********************************************************************
3203 * get_time - Get current time, monotonic if possible.
3206 get_time(struct timeval *tv)
3208 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3209 * Runtime checking makes it safe. */
3210 #ifndef CLOCK_MONOTONIC
3211 #define CLOCK_MONOTONIC 1
3213 static int monotonic = -1;
3218 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3222 tv->tv_sec = ts.tv_sec;
3223 tv->tv_usec = ts.tv_nsec / 1000;
3226 } else if (monotonic > 0)
3230 warn("Couldn't use monotonic clock source: %m");
3233 return gettimeofday(tv, NULL);