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 u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
213 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
214 static u_int32_t our_old_addr; /* for detecting address changes */
215 static int dynaddr_set; /* 1 if ip_dynaddr set */
216 static int looped; /* 1 if using loop */
217 static int link_mtu; /* mtu for the link (not bundle) */
219 static struct utsname utsname; /* for the kernel version */
220 static int kernel_version;
221 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
225 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
226 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
227 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
229 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
231 /* Prototypes for procedures local to this file. */
232 static int modify_flags(int fd, int clear_bits, int set_bits);
233 static int translate_speed (int bps);
234 static int baud_rate_of (int speed);
235 static void close_route_table (void);
236 static int open_route_table (void);
237 static int read_route_table (struct rtentry *rt);
238 static int defaultroute_exists (struct rtentry *rt, int metric);
239 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
240 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
241 char *name, int namelen);
242 static void decode_version (char *buf, int *version, int *mod, int *patch);
243 static int set_kdebugflag(int level);
244 static int ppp_registered(void);
245 static int make_ppp_unit(void);
246 static int setifstate (int u, int state);
248 extern u_char inpacket_buf[]; /* borrowed from main.c */
250 extern int dfl_route_metric;
253 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
257 #define SET_SA_FAMILY(addr, family) \
258 memset ((char *) &(addr), '\0', sizeof(addr)); \
259 addr.sa_family = (family);
262 * Determine if the PPP connection should still be present.
267 /* new_fd is the fd of a tty */
268 static void set_ppp_fd (int new_fd)
271 if (!new_style_driver)
275 static int still_ppp(void)
277 if (new_style_driver)
278 return !hungup && ppp_fd >= 0;
279 if (!hungup || ppp_fd == slave_fd)
282 set_ppp_fd(slave_fd);
289 * modify_flags - set and clear flag bits controlling the kernel
292 static int modify_flags(int fd, int clear_bits, int set_bits)
296 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
298 flags = (flags & ~clear_bits) | set_bits;
299 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
306 error("Failed to set PPP kernel option flags: %m");
310 /********************************************************************
312 * sys_init - System-dependent initialization.
317 /* Get an internet socket for doing socket ioctls. */
318 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
320 fatal("Couldn't create IP socket: %m(%d)", errno);
323 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
325 sock6_fd = -errno; /* save errno for later */
332 /********************************************************************
334 * sys_cleanup - restore any system state we modified before exiting:
335 * mark the interface down, delete default route and/or proxy arp entry.
336 * This shouldn't call die() because it's called from die().
339 void sys_cleanup(void)
342 * Take down the device
352 * Delete any routes through the device.
354 if (have_default_route)
355 cifdefaultroute(0, 0, 0);
357 if (have_default_route6)
358 cif6defaultroute(0, nulleui64, nulleui64);
362 cifproxyarp(0, proxy_arp_addr);
365 /********************************************************************
367 * sys_close - Clean up in a child process before execing.
372 if (new_style_driver && ppp_dev_fd >= 0)
386 /********************************************************************
388 * set_kdebugflag - Define the debugging level for the kernel
391 static int set_kdebugflag (int requested_level)
395 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
396 if ( ! ok_error (errno) )
397 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
403 /********************************************************************
405 * tty_establish_ppp - Turn the serial port into a ppp interface.
408 int tty_establish_ppp (int tty_fd)
413 * Ensure that the tty device is in exclusive mode.
415 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
416 if ( ! ok_error ( errno ))
417 warn("Couldn't make tty exclusive: %m");
420 * Demand mode - prime the old ppp device to relinquish the unit.
422 if (!new_style_driver && looped
423 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
424 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
428 * Set the current tty to the PPP discpline
432 #define N_SYNC_PPP 14
434 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
435 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
436 if ( ! ok_error (errno) ) {
437 error("Couldn't set tty to PPP discipline: %m");
442 ret_fd = generic_establish_ppp(tty_fd);
444 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
445 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
449 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
450 (kdebugflag * SC_DEBUG) & SC_LOGB);
452 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
453 warn("Couldn't reset tty to normal line discipline: %m");
459 /********************************************************************
461 * generic_establish_ppp - Turn the fd into a ppp interface.
463 int generic_establish_ppp (int fd)
467 if (new_style_driver) {
470 /* Open an instance of /dev/ppp and connect the channel to it */
471 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
472 error("Couldn't get channel number: %m");
475 dbglog("using channel %d", chindex);
476 fd = open("/dev/ppp", O_RDWR);
478 error("Couldn't reopen /dev/ppp: %m");
481 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
482 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
483 error("Couldn't attach to channel %d: %m", chindex);
486 flags = fcntl(fd, F_GETFL);
487 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
488 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
493 if (!looped && !multilink) {
495 * Create a new PPP unit.
497 if (make_ppp_unit() < 0)
502 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
506 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
507 error("Couldn't attach to PPP unit %d: %m", ifunit);
514 * Old-style driver: find out which interface we were given.
517 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
518 if (ok_error (errno))
520 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
522 /* Check that we got the same unit again. */
523 if (looped && x != ifunit)
524 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
528 * Fetch the initial file flags and reset blocking mode on the file.
530 initfdflags = fcntl(fd, F_GETFL);
531 if (initfdflags == -1 ||
532 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
533 if ( ! ok_error (errno))
534 warn("Couldn't set device to non-blocking mode: %m");
539 * Enable debug in the driver if requested.
542 set_kdebugflag (kdebugflag);
554 /********************************************************************
556 * tty_disestablish_ppp - Restore the serial port to normal operation.
557 * This shouldn't call die() because it's called from die().
560 void tty_disestablish_ppp(int tty_fd)
564 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
566 if (tcflush(tty_fd, TCIOFLUSH) < 0)
568 warn("tcflush failed: %m");
572 * Restore the previous line discipline
574 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
575 if ( ! ok_error (errno))
576 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
579 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
580 if ( ! ok_error (errno))
581 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
584 /* Reset non-blocking mode on fd. */
585 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
586 if ( ! ok_error (errno))
587 warn("Couldn't restore device fd flags: %m");
593 generic_disestablish_ppp(tty_fd);
596 /********************************************************************
598 * generic_disestablish_ppp - Restore device components to normal
599 * operation, and reconnect the ppp unit to the loopback if in demand
600 * mode. This shouldn't call die() because it's called from die().
602 void generic_disestablish_ppp(int dev_fd)
604 if (new_style_driver) {
608 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
610 } else if (!doing_multilink && ppp_dev_fd >= 0) {
612 remove_fd(ppp_dev_fd);
616 /* old-style driver */
618 set_ppp_fd(slave_fd);
625 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
626 * Assumes new_style_driver.
628 static int make_ppp_unit(void)
632 if (ppp_dev_fd >= 0) {
633 dbglog("in make_ppp_unit, already had /dev/ppp open?");
636 ppp_dev_fd = open("/dev/ppp", O_RDWR);
638 fatal("Couldn't open /dev/ppp: %m");
639 flags = fcntl(ppp_dev_fd, F_GETFL);
641 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
642 warn("Couldn't set /dev/ppp to nonblock: %m");
645 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
646 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
647 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
649 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
652 error("Couldn't create new ppp unit: %m");
654 if (x == 0 && req_ifname[0] != '\0') {
656 char t[MAXIFNAMELEN];
657 memset(&ifr, 0, sizeof(struct ifreq));
658 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
659 strlcpy(ifr.ifr_name, t, IF_NAMESIZE);
660 strlcpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE);
661 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
663 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
665 info("Renamed interface %s to %s", t, req_ifname);
672 * cfg_bundle - configure the existing bundle.
673 * Used in demand mode.
675 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
677 if (!new_style_driver)
680 /* set the mrru, mtu and flags */
681 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
682 error("Couldn't set MRRU: %m");
684 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
685 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
686 | (mrru? SC_MULTILINK: 0)));
688 /* connect up the channel */
689 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
690 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
695 * make_new_bundle - create a new PPP unit (i.e. a bundle)
696 * and connect our channel to it. This should only get called
697 * if `multilink' was set at the time establish_ppp was called.
698 * In demand mode this uses our existing bundle instead of making
701 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
703 if (!new_style_driver)
706 /* make us a ppp unit */
707 if (make_ppp_unit() < 0)
710 /* set the mrru and flags */
711 cfg_bundle(mrru, mtru, rssn, tssn);
715 * bundle_attach - attach our link to a given PPP unit.
716 * We assume the unit is controlled by another pppd.
718 int bundle_attach(int ifnum)
722 if (!new_style_driver)
725 master_fd = open("/dev/ppp", O_RDWR);
727 fatal("Couldn't open /dev/ppp: %m");
728 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
729 if (errno == ENXIO) {
731 return 0; /* doesn't still exist */
733 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
735 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
736 fatal("Couldn't connect to interface unit %d: %m", ifnum);
737 modify_flags(master_fd, 0, SC_MULTILINK);
745 * destroy_bundle - tell the driver to destroy our bundle.
747 void destroy_bundle(void)
749 if (ppp_dev_fd >= 0) {
751 remove_fd(ppp_dev_fd);
756 /********************************************************************
758 * clean_check - Fetch the flags for the device and generate
759 * appropriate error messages.
761 void clean_check(void)
767 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
769 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
771 s = "all had bit 7 set to 1";
775 s = "all had bit 7 set to 0";
779 s = "all had odd parity";
783 s = "all had even parity";
788 warn("Receive serial link is not 8-bit clean:");
789 warn("Problem: %s", s);
797 * List of valid speeds.
801 int speed_int, speed_val;
882 { 1000000, B1000000 },
885 { 1152000, B1152000 },
888 { 1500000, B1500000 },
891 { 2000000, B2000000 },
894 { 2500000, B2500000 },
897 { 3000000, B3000000 },
900 { 3500000, B3500000 },
903 { 4000000, B4000000 },
908 /********************************************************************
910 * Translate from bits/second to a speed_t.
913 static int translate_speed (int bps)
915 struct speed *speedp;
918 for (speedp = speeds; speedp->speed_int; speedp++) {
919 if (bps == speedp->speed_int)
920 return speedp->speed_val;
922 warn("speed %d not supported", bps);
927 /********************************************************************
929 * Translate from a speed_t to bits/second.
932 static int baud_rate_of (int speed)
934 struct speed *speedp;
937 for (speedp = speeds; speedp->speed_int; speedp++) {
938 if (speed == speedp->speed_val)
939 return speedp->speed_int;
945 /********************************************************************
947 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
948 * at the requested speed, etc. If `local' is true, set CLOCAL
949 * regardless of whether the modem option was specified.
952 void set_up_tty(int tty_fd, int local)
958 if (tcgetattr(tty_fd, &tios) < 0) {
959 if (!ok_error(errno))
960 fatal("tcgetattr: %m (line %d)", __LINE__);
967 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
968 tios.c_cflag |= CS8 | CREAD | HUPCL;
970 tios.c_iflag = IGNBRK | IGNPAR;
974 tios.c_cc[VTIME] = 0;
977 tios.c_cflag ^= (CLOCAL | HUPCL);
981 tios.c_cflag |= CRTSCTS;
985 tios.c_iflag |= IXON | IXOFF;
986 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
987 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
991 tios.c_cflag &= ~CRTSCTS;
999 tios.c_cflag |= CSTOPB;
1001 speed = translate_speed(inspeed);
1003 cfsetospeed (&tios, speed);
1004 cfsetispeed (&tios, speed);
1007 * We can't proceed if the serial port speed is B0,
1008 * since that implies that the serial port is disabled.
1011 speed = cfgetospeed(&tios);
1013 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1016 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1018 fatal("tcsetattr: %m (line %d)", __LINE__);
1020 baud_rate = baud_rate_of(speed);
1024 /********************************************************************
1026 * setdtr - control the DTR line on the serial port.
1027 * This is called from die(), so it shouldn't call die().
1030 void setdtr (int tty_fd, int on)
1032 int modembits = TIOCM_DTR;
1034 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1037 /********************************************************************
1039 * restore_tty - restore the terminal to the saved settings.
1042 void restore_tty (int tty_fd)
1047 * Turn off echoing, because otherwise we can get into
1048 * a loop with the tty and the modem echoing to each other.
1049 * We presume we are the sole user of this tty device, so
1050 * when we close it, it will revert to its defaults anyway.
1052 if (!default_device)
1053 inittermios.c_lflag &= ~(ECHO | ECHONL);
1055 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1056 if (! ok_error (errno))
1057 warn("tcsetattr: %m (line %d)", __LINE__);
1062 /********************************************************************
1064 * output - Output PPP packet.
1067 void output (int unit, unsigned char *p, int len)
1072 dump_packet("sent", p, len);
1073 if (snoop_send_hook) snoop_send_hook(p, len);
1075 if (len < PPP_HDRLEN)
1077 if (new_style_driver) {
1080 proto = (p[0] << 8) + p[1];
1081 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1084 if (write(fd, p, len) < 0) {
1085 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1086 || errno == ENXIO || errno == EIO || errno == EINTR)
1087 warn("write: warning: %m (%d)", errno);
1089 error("write: %m (%d)", errno);
1093 /********************************************************************
1095 * wait_input - wait until there is data available,
1096 * for the length of time specified by *timo (indefinite
1100 void wait_input(struct timeval *timo)
1107 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1108 if (n < 0 && errno != EINTR)
1109 fatal("select: %m");
1113 * add_fd - add an fd to the set that wait_input waits for.
1117 if (fd >= FD_SETSIZE)
1118 fatal("internal error: file descriptor too large (%d)", fd);
1119 FD_SET(fd, &in_fds);
1125 * remove_fd - remove an fd from the set that wait_input waits for.
1127 void remove_fd(int fd)
1129 FD_CLR(fd, &in_fds);
1133 /********************************************************************
1135 * read_packet - get a PPP packet from the serial device.
1138 int read_packet (unsigned char *buf)
1142 len = PPP_MRU + PPP_HDRLEN;
1143 if (new_style_driver) {
1144 *buf++ = PPP_ALLSTATIONS;
1150 nr = read(ppp_fd, buf, len);
1151 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1152 && errno != EIO && errno != EINTR)
1154 if (nr < 0 && errno == ENXIO)
1157 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1158 /* N.B. we read ppp_fd first since LCP packets come in there. */
1159 nr = read(ppp_dev_fd, buf, len);
1160 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1161 && errno != EIO && errno != EINTR)
1162 error("read /dev/ppp: %m");
1163 if (nr < 0 && errno == ENXIO)
1165 if (nr == 0 && doing_multilink) {
1166 remove_fd(ppp_dev_fd);
1170 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1172 return (new_style_driver && nr > 0)? nr+2: nr;
1175 /********************************************************************
1177 * get_loop_output - get outgoing packets from the ppp device,
1178 * and detect when we want to bring the real link up.
1179 * Return value is 1 if we need to bring up the link, 0 otherwise.
1182 get_loop_output(void)
1187 if (new_style_driver) {
1188 while ((n = read_packet(inpacket_buf)) > 0)
1189 if (loop_frame(inpacket_buf, n))
1194 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1195 if (loop_chars(inbuf, n))
1199 fatal("eof on loopback");
1201 if (errno != EWOULDBLOCK && errno != EAGAIN)
1202 fatal("read from loopback: %m(%d)", errno);
1208 * netif_set_mtu - set the MTU on the PPP network interface.
1211 netif_set_mtu(int unit, int mtu)
1215 memset (&ifr, '\0', sizeof (ifr));
1216 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1219 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1220 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1224 * netif_get_mtu - get the MTU on the PPP network interface.
1227 netif_get_mtu(int unit)
1231 memset (&ifr, '\0', sizeof (ifr));
1232 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1234 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1235 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1241 /********************************************************************
1243 * tty_send_config - configure the transmit characteristics of
1244 * the ppp interface.
1247 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1254 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1255 if (errno != EIO && errno != ENOTTY)
1256 error("Couldn't set transmit async character map: %m");
1261 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1262 | (sync_serial? SC_SYNC: 0);
1263 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1266 /********************************************************************
1268 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1271 void tty_set_xaccm (ext_accm accm)
1275 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1276 if ( ! ok_error (errno))
1277 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1281 /********************************************************************
1283 * tty_recv_config - configure the receive-side characteristics of
1284 * the ppp interface.
1287 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1290 * If we were called because the link has gone down then there is nothing
1291 * which may be done. Just return without incident.
1296 * Set the receiver parameters
1298 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1299 if (errno != EIO && errno != ENOTTY)
1300 error("Couldn't set channel receive MRU: %m");
1302 if (new_style_driver && ppp_dev_fd >= 0
1303 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1304 error("Couldn't set MRU in generic PPP layer: %m");
1306 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1307 if (errno != EIO && errno != ENOTTY)
1308 error("Couldn't set channel receive asyncmap: %m");
1312 /********************************************************************
1314 * ccp_test - ask kernel whether a given compression method
1315 * is acceptable for use.
1319 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1321 struct ppp_option_data data;
1323 memset (&data, '\0', sizeof (data));
1325 data.length = opt_len;
1326 data.transmit = for_transmit;
1328 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1331 return (errno == ENOBUFS)? 0: -1;
1334 /********************************************************************
1336 * ccp_flags_set - inform kernel about the current state of CCP.
1339 void ccp_flags_set (int unit, int isopen, int isup)
1343 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1344 if (still_ppp() && ppp_dev_fd >= 0)
1345 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1350 * set_filters - set the active and pass filters in the kernel driver.
1352 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1354 struct sock_fprog fp;
1356 fp.len = pass->bf_len;
1357 fp.filter = (struct sock_filter *) pass->bf_insns;
1358 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1359 if (errno == ENOTTY)
1360 warn("kernel does not support PPP filtering");
1362 error("Couldn't set pass-filter in kernel: %m");
1365 fp.len = active->bf_len;
1366 fp.filter = (struct sock_filter *) active->bf_insns;
1367 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1368 error("Couldn't set active-filter in kernel: %m");
1373 #endif /* PPP_FILTER */
1375 /********************************************************************
1377 * get_idle_time - return how long the link has been idle.
1380 get_idle_time(int u, struct ppp_idle *ip)
1382 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1385 /********************************************************************
1387 * get_ppp_stats - return statistics for the link.
1390 get_ppp_stats(int u, struct pppd_stats *stats)
1392 struct ifpppstatsreq req;
1394 memset (&req, 0, sizeof (req));
1396 req.stats_ptr = (caddr_t) &req.stats;
1397 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1398 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1399 error("Couldn't get PPP statistics: %m");
1402 stats->bytes_in = req.stats.p.ppp_ibytes;
1403 stats->bytes_out = req.stats.p.ppp_obytes;
1404 stats->pkts_in = req.stats.p.ppp_ipackets;
1405 stats->pkts_out = req.stats.p.ppp_opackets;
1409 /********************************************************************
1411 * ccp_fatal_error - returns 1 if decompression was disabled as a
1412 * result of an error detected after decompression of a packet,
1413 * 0 otherwise. This is necessary because of patent nonsense.
1416 int ccp_fatal_error (int unit)
1420 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1421 error("Couldn't read compression error flags: %m");
1424 return flags & SC_DC_FERROR;
1427 /********************************************************************
1429 * path_to_procfs - find the path to the proc file system mount point
1431 static char proc_path[MAXPATHLEN];
1432 static int proc_path_len;
1434 static char *path_to_procfs(const char *tail)
1436 struct mntent *mntent;
1439 if (proc_path_len == 0) {
1440 /* Default the mount location of /proc */
1441 strlcpy (proc_path, "/proc", sizeof(proc_path));
1443 fp = fopen(MOUNTED, "r");
1445 while ((mntent = getmntent(fp)) != NULL) {
1446 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1448 if (strcmp(mntent->mnt_type, "proc") == 0) {
1449 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1450 proc_path_len = strlen(proc_path);
1458 strlcpy(proc_path + proc_path_len, tail,
1459 sizeof(proc_path) - proc_path_len);
1464 * /proc/net/route parsing stuff.
1466 #define ROUTE_MAX_COLS 12
1467 FILE *route_fd = (FILE *) 0;
1468 static char route_buffer[512];
1469 static int route_dev_col, route_dest_col, route_gw_col;
1470 static int route_flags_col, route_metric_col, route_mask_col;
1471 static int route_num_cols;
1473 static int open_route_table (void);
1474 static void close_route_table (void);
1475 static int read_route_table (struct rtentry *rt);
1477 /********************************************************************
1479 * close_route_table - close the interface to the route table
1482 static void close_route_table (void)
1484 if (route_fd != (FILE *) 0) {
1486 route_fd = (FILE *) 0;
1490 /********************************************************************
1492 * open_route_table - open the interface to the route table
1494 static char route_delims[] = " \t\n";
1496 static int open_route_table (void)
1500 close_route_table();
1502 path = path_to_procfs("/net/route");
1503 route_fd = fopen (path, "r");
1504 if (route_fd == NULL) {
1505 error("can't open routing table %s: %m", path);
1509 route_dev_col = 0; /* default to usual columns */
1512 route_flags_col = 3;
1513 route_metric_col = 6;
1517 /* parse header line */
1518 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1519 char *p = route_buffer, *q;
1521 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1523 if ((q = strtok(p, route_delims)) == 0)
1525 if (strcasecmp(q, "iface") == 0)
1526 route_dev_col = col;
1527 else if (strcasecmp(q, "destination") == 0)
1528 route_dest_col = col;
1529 else if (strcasecmp(q, "gateway") == 0)
1531 else if (strcasecmp(q, "flags") == 0)
1532 route_flags_col = col;
1533 else if (strcasecmp(q, "mask") == 0)
1534 route_mask_col = col;
1537 if (used && col >= route_num_cols)
1538 route_num_cols = col + 1;
1546 /********************************************************************
1548 * read_route_table - read the next entry from the route table
1551 static int read_route_table(struct rtentry *rt)
1553 char *cols[ROUTE_MAX_COLS], *p;
1556 memset (rt, '\0', sizeof (struct rtentry));
1558 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1562 for (col = 0; col < route_num_cols; ++col) {
1563 cols[col] = strtok(p, route_delims);
1564 if (cols[col] == NULL)
1565 return 0; /* didn't get enough columns */
1569 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1570 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1571 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1573 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1574 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
1575 rt->rt_dev = cols[route_dev_col];
1580 /********************************************************************
1582 * defaultroute_exists - determine if there is a default route
1583 * with the given metric (or negative for any)
1586 static int defaultroute_exists (struct rtentry *rt, int metric)
1590 if (!open_route_table())
1593 while (read_route_table(rt) != 0) {
1594 if ((rt->rt_flags & RTF_UP) == 0)
1597 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1599 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1600 || rt->rt_metric == metric)) {
1606 close_route_table();
1611 * have_route_to - determine if the system has any route to
1612 * a given IP address. `addr' is in network byte order.
1613 * Return value is 1 if yes, 0 if no, -1 if don't know.
1614 * For demand mode to work properly, we have to ignore routes
1615 * through our own interface.
1617 int have_route_to(u_int32_t addr)
1622 if (!open_route_table())
1623 return -1; /* don't know */
1625 while (read_route_table(&rt)) {
1626 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1628 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1634 close_route_table();
1638 /********************************************************************
1640 * sifdefaultroute - assign a default route through the address given.
1643 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1647 if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) {
1648 if (rt.rt_flags & RTF_GATEWAY)
1649 error("not replacing existing default route via %I with metric %d",
1650 SIN_ADDR(rt.rt_gateway), dfl_route_metric);
1652 error("not replacing existing default route through %s with metric %d",
1653 rt.rt_dev, dfl_route_metric);
1657 memset (&rt, 0, sizeof (rt));
1658 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1661 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1663 if (kernel_version > KVERSION(2,1,0)) {
1664 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1665 SIN_ADDR(rt.rt_genmask) = 0L;
1668 rt.rt_flags = RTF_UP;
1669 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1670 if ( ! ok_error ( errno ))
1671 error("default route ioctl(SIOCADDRT): %m");
1675 have_default_route = 1;
1679 /********************************************************************
1681 * cifdefaultroute - delete a default route through the address given.
1684 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1688 have_default_route = 0;
1690 memset (&rt, '\0', sizeof (rt));
1691 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1692 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1697 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1699 if (kernel_version > KVERSION(2,1,0)) {
1700 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1701 SIN_ADDR(rt.rt_genmask) = 0L;
1704 rt.rt_flags = RTF_UP;
1705 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1707 if ( ! ok_error ( errno ))
1708 error("default route ioctl(SIOCDELRT): %m");
1718 * /proc/net/ipv6_route parsing stuff.
1720 static int route_dest_plen_col;
1721 static int open_route6_table (void);
1722 static int read_route6_table (struct in6_rtmsg *rt);
1724 /********************************************************************
1726 * open_route6_table - open the interface to the route table
1728 static int open_route6_table (void)
1732 close_route_table();
1734 path = path_to_procfs("/net/ipv6_route");
1735 route_fd = fopen (path, "r");
1736 if (route_fd == NULL) {
1737 error("can't open routing table %s: %m", path);
1741 /* default to usual columns */
1743 route_dest_plen_col = 1;
1745 route_metric_col = 5;
1746 route_flags_col = 8;
1748 route_num_cols = 10;
1753 /********************************************************************
1755 * read_route6_table - read the next entry from the route table
1758 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
1765 for (i = 0; i < 4; i++) {
1766 memcpy(hex8, s + 8*i, 8);
1767 v = strtoul(hex8, NULL, 16);
1768 addr->s6_addr32[i] = v;
1772 static int read_route6_table(struct in6_rtmsg *rt)
1774 char *cols[ROUTE_MAX_COLS], *p;
1777 memset (rt, '\0', sizeof (struct in6_rtmsg));
1779 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1783 for (col = 0; col < route_num_cols; ++col) {
1784 cols[col] = strtok(p, route_delims);
1785 if (cols[col] == NULL)
1786 return 0; /* didn't get enough columns */
1790 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
1791 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
1792 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
1794 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
1795 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
1796 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
1801 /********************************************************************
1803 * defaultroute6_exists - determine if there is a default route
1806 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
1810 if (!open_route6_table())
1813 while (read_route6_table(rt) != 0) {
1814 if ((rt->rtmsg_flags & RTF_UP) == 0)
1817 if (rt->rtmsg_dst_len != 0)
1819 if (rt->rtmsg_dst.s6_addr32[0] == 0L
1820 && rt->rtmsg_dst.s6_addr32[1] == 0L
1821 && rt->rtmsg_dst.s6_addr32[2] == 0L
1822 && rt->rtmsg_dst.s6_addr32[3] == 0L
1823 && (metric < 0 || rt->rtmsg_metric == metric)) {
1829 close_route_table();
1833 /********************************************************************
1835 * sif6defaultroute - assign a default route through the address given.
1837 * If the global default_rt_repl_rest flag is set, then this function
1838 * already replaced the original system defaultroute with some other
1839 * route and it should just replace the current defaultroute with
1840 * another one, without saving the current route. Use: demand mode,
1841 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
1842 * and then changes the temporary addresses to the addresses for the real
1843 * ppp connection when it has come up.
1846 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
1848 struct in6_rtmsg rt;
1849 char buf[IF_NAMESIZE];
1851 if (defaultroute6_exists(&rt, dfl_route_metric) &&
1852 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
1853 if (rt.rtmsg_flags & RTF_GATEWAY)
1854 error("not replacing existing default route via gateway");
1856 error("not replacing existing default route through %s",
1857 if_indextoname(rt.rtmsg_ifindex, buf));
1861 memset (&rt, 0, sizeof (rt));
1863 rt.rtmsg_ifindex = if_nametoindex(ifname);
1864 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1865 rt.rtmsg_dst_len = 0;
1867 rt.rtmsg_flags = RTF_UP;
1868 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
1869 if ( ! ok_error ( errno ))
1870 error("default route ioctl(SIOCADDRT): %m");
1874 have_default_route6 = 1;
1878 /********************************************************************
1880 * cif6defaultroute - delete a default route through the address given.
1883 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
1885 struct in6_rtmsg rt;
1887 have_default_route6 = 0;
1889 memset (&rt, '\0', sizeof (rt));
1891 rt.rtmsg_ifindex = if_nametoindex(ifname);
1892 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1893 rt.rtmsg_dst_len = 0;
1895 rt.rtmsg_flags = RTF_UP;
1896 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1898 if ( ! ok_error ( errno ))
1899 error("default route ioctl(SIOCDELRT): %m");
1908 /********************************************************************
1910 * sifproxyarp - Make a proxy ARP entry for the peer.
1913 int sifproxyarp (int unit, u_int32_t his_adr)
1915 struct arpreq arpreq;
1918 if (has_proxy_arp == 0) {
1919 memset (&arpreq, '\0', sizeof(arpreq));
1921 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1922 SIN_ADDR(arpreq.arp_pa) = his_adr;
1923 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1925 * Get the hardware address of an interface on the same subnet
1926 * as our local address.
1928 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1929 sizeof(proxy_arp_dev))) {
1930 error("Cannot determine ethernet address for proxy ARP");
1933 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1935 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1936 if ( ! ok_error ( errno ))
1937 error("ioctl(SIOCSARP): %m");
1940 proxy_arp_addr = his_adr;
1944 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1945 if (forw_path != 0) {
1946 int fd = open(forw_path, O_WRONLY);
1948 if (write(fd, "1", 1) != 1)
1949 error("Couldn't enable IP forwarding: %m");
1959 /********************************************************************
1961 * cifproxyarp - Delete the proxy ARP entry for the peer.
1964 int cifproxyarp (int unit, u_int32_t his_adr)
1966 struct arpreq arpreq;
1968 if (has_proxy_arp) {
1970 memset (&arpreq, '\0', sizeof(arpreq));
1971 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1972 SIN_ADDR(arpreq.arp_pa) = his_adr;
1973 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1974 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1976 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1977 if ( ! ok_error ( errno ))
1978 warn("ioctl(SIOCDARP): %m");
1985 /********************************************************************
1987 * get_ether_addr - get the hardware address of an interface on the
1988 * the same subnet as ipaddr.
1991 static int get_ether_addr (u_int32_t ipaddr,
1992 struct sockaddr *hwaddr,
1993 char *name, int namelen)
1995 struct ifreq *ifr, *ifend;
1996 u_int32_t ina, mask;
1998 struct ifreq ifreq, bestifreq;
2000 struct ifreq ifs[MAX_IFS];
2002 u_int32_t bestmask=0;
2003 int found_interface = 0;
2005 ifc.ifc_len = sizeof(ifs);
2007 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2008 if ( ! ok_error ( errno ))
2009 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2014 * Scan through looking for an interface with an Internet
2015 * address on the same subnet as `ipaddr'.
2017 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2018 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2019 if (ifr->ifr_addr.sa_family == AF_INET) {
2020 ina = SIN_ADDR(ifr->ifr_addr);
2021 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2023 * Check that the interface is up, and not point-to-point
2026 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2029 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2032 * Get its netmask and check that it's on the right subnet.
2034 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2037 mask = SIN_ADDR(ifreq.ifr_addr);
2039 if (((ipaddr ^ ina) & mask) != 0)
2040 continue; /* no match */
2042 if (mask >= bestmask) {
2043 /* Compare using >= instead of > -- it is possible for
2044 an interface to have a netmask of 0.0.0.0 */
2045 found_interface = 1;
2052 if (!found_interface) return 0;
2054 strlcpy(name, bestifreq.ifr_name, namelen);
2056 /* trim off the :1 in eth0:1 */
2057 aliasp = strchr(name, ':');
2061 info("found interface %s for proxy arp", name);
2063 * Now get the hardware address.
2065 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2066 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2067 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2072 &bestifreq.ifr_hwaddr,
2073 sizeof (struct sockaddr));
2079 * get_if_hwaddr - get the hardware address for the specified
2080 * network interface device.
2083 get_if_hwaddr(u_char *addr, char *name)
2088 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2091 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2092 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2093 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2096 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2101 * get_first_ethernet - return the name of the first ethernet-style
2102 * interface on this system.
2104 static char first_ether_name[IF_NAMESIZE];
2106 get_first_ethernet(void)
2108 struct if_nameindex *if_ni, *i;
2112 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2116 if_ni = if_nameindex();
2122 first_ether_name[0] = 0;
2124 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2125 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2126 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2127 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2128 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2129 strlcpy(first_ether_name, i->if_name, sizeof(first_ether_name));
2134 if_freenameindex(if_ni);
2137 if (!first_ether_name[0])
2140 return first_ether_name;
2143 /********************************************************************
2145 * Return user specified netmask, modified by any mask we might determine
2146 * for address `addr' (in network byte order).
2147 * Here we scan through the system's list of interfaces, looking for
2148 * any non-point-to-point interfaces which might appear to be on the same
2149 * network as `addr'. If we find any, we OR in their netmask to the
2150 * user-specified netmask.
2153 u_int32_t GetMask (u_int32_t addr)
2155 u_int32_t mask, nmask, ina;
2156 struct ifreq *ifr, *ifend, ifreq;
2158 struct ifreq ifs[MAX_IFS];
2162 if (IN_CLASSA(addr)) /* determine network mask for address class */
2163 nmask = IN_CLASSA_NET;
2164 else if (IN_CLASSB(addr))
2165 nmask = IN_CLASSB_NET;
2167 nmask = IN_CLASSC_NET;
2169 /* class D nets are disallowed by bad_ip_adrs */
2170 mask = netmask | htonl(nmask);
2172 * Scan through the system's network interfaces.
2174 ifc.ifc_len = sizeof(ifs);
2176 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2177 if ( ! ok_error ( errno ))
2178 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2182 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2183 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2185 * Check the interface's internet address.
2187 if (ifr->ifr_addr.sa_family != AF_INET)
2189 ina = SIN_ADDR(ifr->ifr_addr);
2190 if (((ntohl(ina) ^ addr) & nmask) != 0)
2193 * Check that the interface is up, and not point-to-point nor loopback.
2195 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2196 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2199 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2202 * Get its netmask and OR it into our mask.
2204 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2206 mask |= SIN_ADDR(ifreq.ifr_addr);
2212 /********************************************************************
2214 * Internal routine to decode the version.modification.patch level
2217 static void decode_version (char *buf, int *version,
2218 int *modification, int *patch)
2222 *version = (int) strtoul (buf, &endp, 10);
2226 if (endp != buf && *endp == '.') {
2228 *modification = (int) strtoul (buf, &endp, 10);
2229 if (endp != buf && *endp == '.') {
2231 *patch = (int) strtoul (buf, &buf, 10);
2236 /********************************************************************
2238 * Procedure to determine if the PPP line discipline is registered.
2242 ppp_registered(void)
2250 * We used to open the serial device and set it to the ppp line
2251 * discipline here, in order to create a ppp unit. But that is
2252 * not a good idea - the user might have specified a device that
2253 * they can't open (permission, or maybe it doesn't really exist).
2254 * So we grab a pty master/slave pair and use that.
2256 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2257 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2262 * Try to put the device into the PPP discipline.
2264 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2265 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2274 /********************************************************************
2276 * ppp_available - check whether the system has any ppp interfaces
2277 * (in fact we check whether we can do an ioctl on ppp0).
2280 int ppp_available(void)
2285 int my_version, my_modification, my_patch;
2286 int osmaj, osmin, ospatch;
2288 /* get the kernel version now, since we are called before sys_init */
2290 osmaj = osmin = ospatch = 0;
2291 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2292 kernel_version = KVERSION(osmaj, osmin, ospatch);
2294 fd = open("/dev/ppp", O_RDWR);
2296 new_style_driver = 1;
2298 /* XXX should get from driver */
2300 driver_modification = 4;
2306 if (kernel_version >= KVERSION(2,3,13)) {
2307 error("Couldn't open the /dev/ppp device: %m");
2308 if (errno == ENOENT)
2310 "You need to create the /dev/ppp device node by\n"
2311 "executing the following command as root:\n"
2312 " mknod /dev/ppp c 108 0\n";
2313 else if (errno == ENODEV || errno == ENXIO)
2315 "Please load the ppp_generic kernel module.\n";
2319 /* we are running on a really really old kernel */
2321 "This system lacks kernel support for PPP. This could be because\n"
2322 "the PPP kernel module could not be loaded, or because PPP was not\n"
2323 "included in the kernel configuration. If PPP was included as a\n"
2324 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2325 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2326 "See README.linux file in the ppp distribution for more details.\n";
2329 * Open a socket for doing the ioctl operations.
2331 s = socket(AF_INET, SOCK_DGRAM, 0);
2335 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2336 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2338 * If the device did not exist then attempt to create one by putting the
2339 * current tty into the PPP discipline. If this works then obtain the
2340 * flags for the device again.
2343 if (ppp_registered()) {
2344 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2345 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2349 * Ensure that the hardware address is for PPP and not something else
2352 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2354 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2358 * This is the PPP device. Validate the version of the driver at this
2359 * point to ensure that this program will work with the driver.
2362 char abBuffer [1024];
2364 ifr.ifr_data = abBuffer;
2365 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2367 error("Couldn't read driver version: %m");
2369 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2372 decode_version(abBuffer,
2374 &driver_modification,
2377 * Validate the version of the driver against the version that we used.
2379 decode_version(VERSION,
2384 /* The version numbers must match */
2385 if (driver_version != my_version)
2388 /* The modification levels must be legal */
2389 if (driver_modification < 3) {
2390 if (driver_modification >= 2) {
2391 /* we can cope with 2.2.0 and above */
2399 slprintf(route_buffer, sizeof(route_buffer),
2400 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2401 driver_version, driver_modification, driver_patch);
2403 no_ppp_msg = route_buffer;
2411 #ifndef HAVE_LOGWTMP
2412 /********************************************************************
2414 * Update the wtmp file with the appropriate user name and tty device.
2417 void logwtmp (const char *line, const char *name, const char *host)
2419 struct utmp ut, *utp;
2420 pid_t mypid = getpid();
2426 * Update the signon database for users.
2427 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2429 utmpname(_PATH_UTMP);
2431 while ((utp = getutent()) && (utp->ut_pid != mypid))
2435 memcpy(&ut, utp, sizeof(ut));
2437 /* some gettys/telnetds don't initialize utmp... */
2438 memset(&ut, 0, sizeof(ut));
2440 if (ut.ut_id[0] == 0)
2441 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2443 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2444 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2448 ut.ut_type = USER_PROCESS;
2451 /* Insert the host name if one is supplied */
2453 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2455 /* Insert the IP address of the remote system if IP is enabled */
2456 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2457 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2458 sizeof(ut.ut_addr));
2460 /* CL: Makes sure that the logout works */
2461 if (*host == 0 && *name==0)
2467 * Update the wtmp file.
2470 updwtmp(_PATH_WTMP, &ut);
2472 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2474 flock(wtmp, LOCK_EX);
2476 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2477 warn("error writing %s: %m", _PATH_WTMP);
2479 flock(wtmp, LOCK_UN);
2485 #endif /* HAVE_LOGWTMP */
2487 /********************************************************************
2489 * sifvjcomp - config tcp header compression
2492 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2497 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2498 error("Couldn't set up TCP header compression: %m");
2503 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2504 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2509 /********************************************************************
2511 * sifup - Config the interface up and enable IP packets to pass.
2518 if ((ret = setifstate(u, 1)))
2524 /********************************************************************
2526 * sifdown - Disable the indicated protocol and config the interface
2527 * down if there are no remaining protocols.
2532 if (if_is_up && --if_is_up > 0)
2540 return setifstate(u, 0);
2544 /********************************************************************
2546 * sif6up - Config the interface up for IPv6
2553 if ((ret = setifstate(u, 1)))
2559 /********************************************************************
2561 * sif6down - Disable the IPv6CP protocol and config the interface
2562 * down if there are no remaining protocols.
2565 int sif6down (int u)
2572 return setifstate(u, 0);
2576 /********************************************************************
2578 * setifstate - Config the interface up or down
2581 static int setifstate (int u, int state)
2585 memset (&ifr, '\0', sizeof (ifr));
2586 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2587 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2588 if (! ok_error (errno))
2589 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2594 ifr.ifr_flags |= IFF_UP;
2596 ifr.ifr_flags &= ~IFF_UP;
2597 ifr.ifr_flags |= IFF_POINTOPOINT;
2598 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2599 if (! ok_error (errno))
2600 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2606 /********************************************************************
2608 * sifaddr - Config the interface IP addresses and netmask.
2611 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2617 memset (&ifr, '\0', sizeof (ifr));
2618 memset (&rt, '\0', sizeof (rt));
2620 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2621 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2622 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2624 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2626 * Set our IP address
2628 SIN_ADDR(ifr.ifr_addr) = our_adr;
2629 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2630 if (errno != EEXIST) {
2631 if (! ok_error (errno))
2632 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2635 warn("ioctl(SIOCSIFADDR): Address already exists");
2640 * Set the gateway address
2643 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2644 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2645 if (! ok_error (errno))
2646 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2652 * For recent kernels, force the netmask to 255.255.255.255.
2654 if (kernel_version >= KVERSION(2,1,16))
2656 if (net_mask != 0) {
2657 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2658 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2659 if (! ok_error (errno))
2660 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2665 * Add the device route
2667 if (kernel_version < KVERSION(2,1,16)) {
2668 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2669 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2672 SIN_ADDR(rt.rt_gateway) = 0L;
2673 SIN_ADDR(rt.rt_dst) = his_adr;
2674 rt.rt_flags = RTF_UP | RTF_HOST;
2676 if (kernel_version > KVERSION(2,1,0)) {
2677 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2678 SIN_ADDR(rt.rt_genmask) = -1L;
2681 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2682 if (! ok_error (errno))
2683 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2688 /* set ip_dynaddr in demand mode if address changes */
2689 if (demand && tune_kernel && !dynaddr_set
2690 && our_old_addr && our_old_addr != our_adr) {
2691 /* set ip_dynaddr if possible */
2695 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2696 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2697 if (write(fd, "1", 1) != 1)
2698 error("Couldn't enable dynamic IP addressing: %m");
2701 dynaddr_set = 1; /* only 1 attempt */
2708 /********************************************************************
2710 * cifaddr - Clear the interface IP addresses, and delete routes
2711 * through the interface if possible.
2714 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2718 if (kernel_version < KVERSION(2,1,16)) {
2720 * Delete the route through the device
2723 memset (&rt, '\0', sizeof (rt));
2725 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2726 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2729 SIN_ADDR(rt.rt_gateway) = 0;
2730 SIN_ADDR(rt.rt_dst) = his_adr;
2731 rt.rt_flags = RTF_UP | RTF_HOST;
2733 if (kernel_version > KVERSION(2,1,0)) {
2734 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2735 SIN_ADDR(rt.rt_genmask) = -1L;
2738 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2739 if (still_ppp() && ! ok_error (errno))
2740 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2745 /* This way it is possible to have an IPX-only or IPv6-only interface */
2746 memset(&ifr, 0, sizeof(ifr));
2747 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2748 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2750 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2751 if (! ok_error (errno)) {
2752 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2757 our_old_addr = our_adr;
2763 /********************************************************************
2765 * sif6addr - Config the interface with an IPv6 link-local address
2767 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2769 struct in6_ifreq ifr6;
2771 struct in6_rtmsg rt6;
2775 error("IPv6 socket creation failed: %m");
2778 memset(&ifr, 0, sizeof (ifr));
2779 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2780 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2781 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2785 /* Local interface */
2786 memset(&ifr6, 0, sizeof(ifr6));
2787 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2788 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2789 ifr6.ifr6_prefixlen = 128;
2791 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2792 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2796 /* Route to remote host */
2797 memset(&rt6, 0, sizeof(rt6));
2798 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2799 rt6.rtmsg_flags = RTF_UP;
2800 rt6.rtmsg_dst_len = 128;
2801 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2802 rt6.rtmsg_metric = 1;
2804 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2805 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2813 /********************************************************************
2815 * cif6addr - Remove IPv6 address from interface
2817 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2820 struct in6_ifreq ifr6;
2824 error("IPv6 socket creation failed: %m");
2827 memset(&ifr, 0, sizeof(ifr));
2828 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2829 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2830 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2834 memset(&ifr6, 0, sizeof(ifr6));
2835 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2836 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2837 ifr6.ifr6_prefixlen = 128;
2839 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2840 if (errno != EADDRNOTAVAIL) {
2841 if (! ok_error (errno))
2842 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2845 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2854 * get_pty - get a pty master/slave pair and chown the slave side
2855 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2858 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
2860 int i, mfd, sfd = -1;
2862 struct termios tios;
2866 * Try the unix98 way first.
2868 mfd = open("/dev/ptmx", O_RDWR);
2871 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2872 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2873 chmod(pty_name, S_IRUSR | S_IWUSR);
2876 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2877 warn("Couldn't unlock pty slave %s: %m", pty_name);
2879 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2881 warn("Couldn't open pty slave %s: %m", pty_name);
2886 #endif /* TIOCGPTN */
2889 /* the old way - scan through the pty name space */
2890 for (i = 0; i < 64; ++i) {
2891 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2892 'p' + i / 16, i % 16);
2893 mfd = open(pty_name, O_RDWR, 0);
2896 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2898 fchown(sfd, uid, -1);
2899 fchmod(sfd, S_IRUSR | S_IWUSR);
2910 strlcpy(slave_name, pty_name, 16);
2913 if (tcgetattr(sfd, &tios) == 0) {
2914 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2915 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2916 tios.c_iflag = IGNPAR;
2919 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2920 warn("couldn't set attributes on pty: %m");
2922 warn("couldn't get attributes on pty: %m");
2927 /********************************************************************
2929 * open_loopback - open the device we use for getting packets
2930 * in demand mode. Under Linux, we use a pty master/slave pair.
2933 open_ppp_loopback(void)
2938 if (new_style_driver) {
2939 /* allocate ourselves a ppp unit */
2940 if (make_ppp_unit() < 0)
2942 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2943 set_kdebugflag(kdebugflag);
2948 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2949 fatal("No free pty for loopback");
2951 set_ppp_fd(slave_fd);
2953 flags = fcntl(master_fd, F_GETFL);
2955 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2956 warn("couldn't set master loopback to nonblock: %m");
2958 flags = fcntl(ppp_fd, F_GETFL);
2960 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2961 warn("couldn't set slave loopback to nonblock: %m");
2963 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2964 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2966 * Find out which interface we were given.
2968 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2969 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2971 * Enable debug in the driver if requested.
2973 set_kdebugflag (kdebugflag);
2978 /********************************************************************
2980 * sifnpmode - Set the mode for handling packets for a given NP.
2984 sifnpmode(int u, int proto, enum NPmode mode)
2988 npi.protocol = proto;
2990 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2991 if (! ok_error (errno))
2992 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2999 /********************************************************************
3001 * sipxfaddr - Config the interface IPX networknumber
3004 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
3011 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3013 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3015 if (! ok_error (errno))
3016 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3020 memset (&ifr, '\0', sizeof (ifr));
3021 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3023 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
3024 sipx->sipx_family = AF_IPX;
3025 sipx->sipx_port = 0;
3026 sipx->sipx_network = htonl (network);
3027 sipx->sipx_type = IPX_FRAME_ETHERII;
3028 sipx->sipx_action = IPX_CRTITF;
3030 * Set the IPX device
3032 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3034 if (errno != EEXIST) {
3035 if (! ok_error (errno))
3036 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
3039 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
3048 /********************************************************************
3050 * cipxfaddr - Clear the information for the IPX network. The IPX routes
3051 * are removed and the device is no longer able to pass IPX
3055 int cipxfaddr (int unit)
3062 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3064 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3066 if (! ok_error (errno))
3067 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3071 memset (&ifr, '\0', sizeof (ifr));
3072 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3074 sipx->sipx_type = IPX_FRAME_ETHERII;
3075 sipx->sipx_action = IPX_DLTITF;
3076 sipx->sipx_family = AF_IPX;
3078 * Set the IPX device
3080 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3081 if (! ok_error (errno))
3082 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
3092 * Use the hostname as part of the random number seed.
3101 for (p = hostname; *p != 0; ++p)
3106 /********************************************************************
3108 * sys_check_options - check the options that the user specified
3112 sys_check_options(void)
3116 * Disable the IPX protocol if the support is not present in the kernel.
3120 if (ipxcp_protent.enabled_flag) {
3121 struct stat stat_buf;
3122 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
3123 && (path = path_to_procfs("/net/ipx_interface")) == NULL)
3124 || lstat(path, &stat_buf) < 0) {
3125 error("IPX support is not present in the kernel\n");
3126 ipxcp_protent.enabled_flag = 0;
3130 if (demand && driver_is_old) {
3131 option_error("demand dialling is not supported by kernel driver "
3132 "version %d.%d.%d", driver_version, driver_modification,
3136 if (multilink && !new_style_driver) {
3137 warn("Warning: multilink is not supported by the kernel driver");
3145 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
3147 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
3148 * that the system has a properly configured Ethernet interface for this
3149 * function to return non-zero.
3152 ether_to_eui64(eui64_t *p_eui64)
3156 const unsigned char *ptr;
3158 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
3161 warn("could not open IPv6 socket");
3165 strcpy(ifr.ifr_name, "eth0");
3166 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
3169 warn("could not obtain hardware address for eth0");
3175 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
3177 ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data;
3178 p_eui64->e8[0] = ptr[0] | 0x02;
3179 p_eui64->e8[1] = ptr[1];
3180 p_eui64->e8[2] = ptr[2];
3181 p_eui64->e8[3] = 0xFF;
3182 p_eui64->e8[4] = 0xFE;
3183 p_eui64->e8[5] = ptr[3];
3184 p_eui64->e8[6] = ptr[4];
3185 p_eui64->e8[7] = ptr[5];
3191 /********************************************************************
3193 * get_time - Get current time, monotonic if possible.
3196 get_time(struct timeval *tv)
3198 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3199 * Runtime checking makes it safe. */
3200 #ifndef CLOCK_MONOTONIC
3201 #define CLOCK_MONOTONIC 1
3203 static int monotonic = -1;
3208 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3212 tv->tv_sec = ts.tv_sec;
3213 tv->tv_usec = ts.tv_nsec / 1000;
3216 } else if (monotonic > 0)
3220 warn("Couldn't use monotonic clock source: %m");
3223 return gettimeofday(tv, NULL);