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
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]); \
168 /* We can get an EIO error on an ioctl if the modem has hung up */
169 #define ok_error(num) ((num)==EIO)
171 static int tty_disc = N_TTY; /* The TTY discipline */
172 static int ppp_disc = N_PPP; /* The PPP discpline */
173 static int initfdflags = -1; /* Initial file descriptor flags for fd */
174 static int ppp_fd = -1; /* fd which is set to PPP discipline */
175 static int sock_fd = -1; /* socket for doing interface ioctls */
176 static int slave_fd = -1; /* pty for old-style demand mode, slave */
177 static int master_fd = -1; /* pty for old-style demand mode, master */
179 static int sock6_fd = -1;
183 * For the old-style kernel driver, this is the same as ppp_fd.
184 * For the new-style driver, it is the fd of an instance of /dev/ppp
185 * which is attached to the ppp unit and is used for controlling it.
187 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
189 static int chindex; /* channel index (new style driver) */
191 static fd_set in_fds; /* set of fds that wait_input waits for */
192 static int max_in_fd; /* highest fd set in in_fds */
194 static int has_proxy_arp = 0;
195 static int driver_version = 0;
196 static int driver_modification = 0;
197 static int driver_patch = 0;
198 static int driver_is_old = 0;
199 static int restore_term = 0; /* 1 => we've munged the terminal */
200 static struct termios inittermios; /* Initial TTY termios */
202 int new_style_driver = 0;
204 static char loop_name[20];
205 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
207 static int if_is_up; /* Interface has been marked up */
208 static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
209 static int have_default_route; /* Gateway for default route added */
210 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
211 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
212 static u_int32_t our_old_addr; /* for detecting address changes */
213 static int dynaddr_set; /* 1 if ip_dynaddr set */
214 static int looped; /* 1 if using loop */
215 static int link_mtu; /* mtu for the link (not bundle) */
217 static struct utsname utsname; /* for the kernel version */
218 static int kernel_version;
219 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
223 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
224 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
225 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
227 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
229 /* Prototypes for procedures local to this file. */
230 static int modify_flags(int fd, int clear_bits, int set_bits);
231 static int translate_speed (int bps);
232 static int baud_rate_of (int speed);
233 static void close_route_table (void);
234 static int open_route_table (void);
235 static int read_route_table (struct rtentry *rt);
236 static int defaultroute_exists (struct rtentry *rt, int metric);
237 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
238 char *name, int namelen);
239 static void decode_version (char *buf, int *version, int *mod, int *patch);
240 static int set_kdebugflag(int level);
241 static int ppp_registered(void);
242 static int make_ppp_unit(void);
243 static int setifstate (int u, int state);
245 extern u_char inpacket_buf[]; /* borrowed from main.c */
247 extern int dfl_route_metric;
250 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
254 #define SET_SA_FAMILY(addr, family) \
255 memset ((char *) &(addr), '\0', sizeof(addr)); \
256 addr.sa_family = (family);
259 * Determine if the PPP connection should still be present.
264 /* new_fd is the fd of a tty */
265 static void set_ppp_fd (int new_fd)
268 if (!new_style_driver)
272 static int still_ppp(void)
274 if (new_style_driver)
275 return !hungup && ppp_fd >= 0;
276 if (!hungup || ppp_fd == slave_fd)
279 set_ppp_fd(slave_fd);
286 * modify_flags - set and clear flag bits controlling the kernel
289 static int modify_flags(int fd, int clear_bits, int set_bits)
293 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
295 flags = (flags & ~clear_bits) | set_bits;
296 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
303 error("Failed to set PPP kernel option flags: %m");
307 /********************************************************************
309 * sys_init - System-dependent initialization.
314 /* Get an internet socket for doing socket ioctls. */
315 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
317 fatal("Couldn't create IP socket: %m(%d)", errno);
320 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
322 sock6_fd = -errno; /* save errno for later */
329 /********************************************************************
331 * sys_cleanup - restore any system state we modified before exiting:
332 * mark the interface down, delete default route and/or proxy arp entry.
333 * This shouldn't call die() because it's called from die().
336 void sys_cleanup(void)
339 * Take down the device
349 * Delete any routes through the device.
351 if (have_default_route)
352 cifdefaultroute(0, 0, 0);
355 cifproxyarp(0, proxy_arp_addr);
358 /********************************************************************
360 * sys_close - Clean up in a child process before execing.
365 if (new_style_driver && ppp_dev_fd >= 0)
379 /********************************************************************
381 * set_kdebugflag - Define the debugging level for the kernel
384 static int set_kdebugflag (int requested_level)
388 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
389 if ( ! ok_error (errno) )
390 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
396 /********************************************************************
398 * tty_establish_ppp - Turn the serial port into a ppp interface.
401 int tty_establish_ppp (int tty_fd)
406 * Ensure that the tty device is in exclusive mode.
408 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
409 if ( ! ok_error ( errno ))
410 warn("Couldn't make tty exclusive: %m");
413 * Demand mode - prime the old ppp device to relinquish the unit.
415 if (!new_style_driver && looped
416 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
417 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
421 * Set the current tty to the PPP discpline
425 #define N_SYNC_PPP 14
427 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
428 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
429 if ( ! ok_error (errno) ) {
430 error("Couldn't set tty to PPP discipline: %m");
435 ret_fd = generic_establish_ppp(tty_fd);
437 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
438 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
442 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
443 (kdebugflag * SC_DEBUG) & SC_LOGB);
445 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
446 warn("Couldn't reset tty to normal line discipline: %m");
452 /********************************************************************
454 * generic_establish_ppp - Turn the fd into a ppp interface.
456 int generic_establish_ppp (int fd)
460 if (new_style_driver) {
463 /* Open an instance of /dev/ppp and connect the channel to it */
464 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
465 error("Couldn't get channel number: %m");
468 dbglog("using channel %d", chindex);
469 fd = open("/dev/ppp", O_RDWR);
471 error("Couldn't reopen /dev/ppp: %m");
474 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
475 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
476 error("Couldn't attach to channel %d: %m", chindex);
479 flags = fcntl(fd, F_GETFL);
480 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
481 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
486 if (!looped && !multilink) {
488 * Create a new PPP unit.
490 if (make_ppp_unit() < 0)
495 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
499 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
500 error("Couldn't attach to PPP unit %d: %m", ifunit);
507 * Old-style driver: find out which interface we were given.
510 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
511 if (ok_error (errno))
513 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
515 /* Check that we got the same unit again. */
516 if (looped && x != ifunit)
517 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
521 * Fetch the initial file flags and reset blocking mode on the file.
523 initfdflags = fcntl(fd, F_GETFL);
524 if (initfdflags == -1 ||
525 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
526 if ( ! ok_error (errno))
527 warn("Couldn't set device to non-blocking mode: %m");
532 * Enable debug in the driver if requested.
535 set_kdebugflag (kdebugflag);
547 /********************************************************************
549 * tty_disestablish_ppp - Restore the serial port to normal operation.
550 * This shouldn't call die() because it's called from die().
553 void tty_disestablish_ppp(int tty_fd)
557 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
559 if (tcflush(tty_fd, TCIOFLUSH) < 0)
561 warn("tcflush failed: %m");
565 * Restore the previous line discipline
567 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
568 if ( ! ok_error (errno))
569 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
572 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
573 if ( ! ok_error (errno))
574 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
577 /* Reset non-blocking mode on fd. */
578 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
579 if ( ! ok_error (errno))
580 warn("Couldn't restore device fd flags: %m");
586 generic_disestablish_ppp(tty_fd);
589 /********************************************************************
591 * generic_disestablish_ppp - Restore device components to normal
592 * operation, and reconnect the ppp unit to the loopback if in demand
593 * mode. This shouldn't call die() because it's called from die().
595 void generic_disestablish_ppp(int dev_fd)
597 if (new_style_driver) {
601 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
603 } else if (!doing_multilink && ppp_dev_fd >= 0) {
605 remove_fd(ppp_dev_fd);
609 /* old-style driver */
611 set_ppp_fd(slave_fd);
618 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
619 * Assumes new_style_driver.
621 static int make_ppp_unit()
625 if (ppp_dev_fd >= 0) {
626 dbglog("in make_ppp_unit, already had /dev/ppp open?");
629 ppp_dev_fd = open("/dev/ppp", O_RDWR);
631 fatal("Couldn't open /dev/ppp: %m");
632 flags = fcntl(ppp_dev_fd, F_GETFL);
634 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
635 warn("Couldn't set /dev/ppp to nonblock: %m");
638 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
639 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
640 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
642 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
645 error("Couldn't create new ppp unit: %m");
650 * cfg_bundle - configure the existing bundle.
651 * Used in demand mode.
653 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
655 if (!new_style_driver)
658 /* set the mrru, mtu and flags */
659 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
660 error("Couldn't set MRRU: %m");
662 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
663 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
664 | (mrru? SC_MULTILINK: 0)));
666 /* connect up the channel */
667 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
668 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
673 * make_new_bundle - create a new PPP unit (i.e. a bundle)
674 * and connect our channel to it. This should only get called
675 * if `multilink' was set at the time establish_ppp was called.
676 * In demand mode this uses our existing bundle instead of making
679 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
681 if (!new_style_driver)
684 /* make us a ppp unit */
685 if (make_ppp_unit() < 0)
688 /* set the mrru and flags */
689 cfg_bundle(mrru, mtru, rssn, tssn);
693 * bundle_attach - attach our link to a given PPP unit.
694 * We assume the unit is controlled by another pppd.
696 int bundle_attach(int ifnum)
700 if (!new_style_driver)
703 master_fd = open("/dev/ppp", O_RDWR);
705 fatal("Couldn't open /dev/ppp: %m");
706 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
707 if (errno == ENXIO) {
709 return 0; /* doesn't still exist */
711 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
713 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
714 fatal("Couldn't connect to interface unit %d: %m", ifnum);
715 modify_flags(master_fd, 0, SC_MULTILINK);
723 * destroy_bundle - tell the driver to destroy our bundle.
725 void destroy_bundle(void)
727 if (ppp_dev_fd >= 0) {
729 remove_fd(ppp_dev_fd);
734 /********************************************************************
736 * clean_check - Fetch the flags for the device and generate
737 * appropriate error messages.
739 void clean_check(void)
745 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
747 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
749 s = "all had bit 7 set to 1";
753 s = "all had bit 7 set to 0";
757 s = "all had odd parity";
761 s = "all had even parity";
766 warn("Receive serial link is not 8-bit clean:");
767 warn("Problem: %s", s);
775 * List of valid speeds.
779 int speed_int, speed_val;
860 { 1000000, B1000000 },
863 { 1152000, B1152000 },
866 { 1500000, B1500000 },
869 { 2000000, B2000000 },
872 { 2500000, B2500000 },
875 { 3000000, B3000000 },
878 { 3500000, B3500000 },
881 { 4000000, B4000000 },
886 /********************************************************************
888 * Translate from bits/second to a speed_t.
891 static int translate_speed (int bps)
893 struct speed *speedp;
896 for (speedp = speeds; speedp->speed_int; speedp++) {
897 if (bps == speedp->speed_int)
898 return speedp->speed_val;
900 warn("speed %d not supported", bps);
905 /********************************************************************
907 * Translate from a speed_t to bits/second.
910 static int baud_rate_of (int speed)
912 struct speed *speedp;
915 for (speedp = speeds; speedp->speed_int; speedp++) {
916 if (speed == speedp->speed_val)
917 return speedp->speed_int;
923 /********************************************************************
925 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
926 * at the requested speed, etc. If `local' is true, set CLOCAL
927 * regardless of whether the modem option was specified.
930 void set_up_tty(int tty_fd, int local)
936 if (tcgetattr(tty_fd, &tios) < 0) {
937 if (!ok_error(errno))
938 fatal("tcgetattr: %m (line %d)", __LINE__);
945 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
946 tios.c_cflag |= CS8 | CREAD | HUPCL;
948 tios.c_iflag = IGNBRK | IGNPAR;
952 tios.c_cc[VTIME] = 0;
955 tios.c_cflag ^= (CLOCAL | HUPCL);
959 tios.c_cflag |= CRTSCTS;
963 tios.c_iflag |= IXON | IXOFF;
964 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
965 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
969 tios.c_cflag &= ~CRTSCTS;
977 tios.c_cflag |= CSTOPB;
979 speed = translate_speed(inspeed);
981 cfsetospeed (&tios, speed);
982 cfsetispeed (&tios, speed);
985 * We can't proceed if the serial port speed is B0,
986 * since that implies that the serial port is disabled.
989 speed = cfgetospeed(&tios);
991 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
994 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
996 fatal("tcsetattr: %m (line %d)", __LINE__);
998 baud_rate = baud_rate_of(speed);
1002 /********************************************************************
1004 * setdtr - control the DTR line on the serial port.
1005 * This is called from die(), so it shouldn't call die().
1008 void setdtr (int tty_fd, int on)
1010 int modembits = TIOCM_DTR;
1012 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1015 /********************************************************************
1017 * restore_tty - restore the terminal to the saved settings.
1020 void restore_tty (int tty_fd)
1025 * Turn off echoing, because otherwise we can get into
1026 * a loop with the tty and the modem echoing to each other.
1027 * We presume we are the sole user of this tty device, so
1028 * when we close it, it will revert to its defaults anyway.
1030 if (!default_device)
1031 inittermios.c_lflag &= ~(ECHO | ECHONL);
1033 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1034 if (! ok_error (errno))
1035 warn("tcsetattr: %m (line %d)", __LINE__);
1040 /********************************************************************
1042 * output - Output PPP packet.
1045 void output (int unit, unsigned char *p, int len)
1050 dump_packet("sent", p, len);
1051 if (snoop_send_hook) snoop_send_hook(p, len);
1053 if (len < PPP_HDRLEN)
1055 if (new_style_driver) {
1058 proto = (p[0] << 8) + p[1];
1059 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1062 if (write(fd, p, len) < 0) {
1063 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1064 || errno == ENXIO || errno == EIO || errno == EINTR)
1065 warn("write: warning: %m (%d)", errno);
1067 error("write: %m (%d)", errno);
1071 /********************************************************************
1073 * wait_input - wait until there is data available,
1074 * for the length of time specified by *timo (indefinite
1078 void wait_input(struct timeval *timo)
1085 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1086 if (n < 0 && errno != EINTR)
1087 fatal("select: %m");
1091 * add_fd - add an fd to the set that wait_input waits for.
1095 if (fd >= FD_SETSIZE)
1096 fatal("internal error: file descriptor too large (%d)", fd);
1097 FD_SET(fd, &in_fds);
1103 * remove_fd - remove an fd from the set that wait_input waits for.
1105 void remove_fd(int fd)
1107 FD_CLR(fd, &in_fds);
1111 /********************************************************************
1113 * read_packet - get a PPP packet from the serial device.
1116 int read_packet (unsigned char *buf)
1120 len = PPP_MRU + PPP_HDRLEN;
1121 if (new_style_driver) {
1122 *buf++ = PPP_ALLSTATIONS;
1128 nr = read(ppp_fd, buf, len);
1129 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1130 && errno != EIO && errno != EINTR)
1132 if (nr < 0 && errno == ENXIO)
1135 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1136 /* N.B. we read ppp_fd first since LCP packets come in there. */
1137 nr = read(ppp_dev_fd, buf, len);
1138 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1139 && errno != EIO && errno != EINTR)
1140 error("read /dev/ppp: %m");
1141 if (nr < 0 && errno == ENXIO)
1143 if (nr == 0 && doing_multilink) {
1144 remove_fd(ppp_dev_fd);
1148 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1150 return (new_style_driver && nr > 0)? nr+2: nr;
1153 /********************************************************************
1155 * get_loop_output - get outgoing packets from the ppp device,
1156 * and detect when we want to bring the real link up.
1157 * Return value is 1 if we need to bring up the link, 0 otherwise.
1160 get_loop_output(void)
1165 if (new_style_driver) {
1166 while ((n = read_packet(inpacket_buf)) > 0)
1167 if (loop_frame(inpacket_buf, n))
1172 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1173 if (loop_chars(inbuf, n))
1177 fatal("eof on loopback");
1179 if (errno != EWOULDBLOCK && errno != EAGAIN)
1180 fatal("read from loopback: %m(%d)", errno);
1186 * netif_set_mtu - set the MTU on the PPP network interface.
1189 netif_set_mtu(int unit, int mtu)
1193 memset (&ifr, '\0', sizeof (ifr));
1194 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1197 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1198 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1202 * netif_get_mtu - get the MTU on the PPP network interface.
1205 netif_get_mtu(int unit)
1209 memset (&ifr, '\0', sizeof (ifr));
1210 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1212 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1213 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1219 /********************************************************************
1221 * tty_send_config - configure the transmit characteristics of
1222 * the ppp interface.
1225 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1232 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1233 if (errno != EIO && errno != ENOTTY)
1234 error("Couldn't set transmit async character map: %m");
1239 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1240 | (sync_serial? SC_SYNC: 0);
1241 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1244 /********************************************************************
1246 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1249 void tty_set_xaccm (ext_accm accm)
1253 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1254 if ( ! ok_error (errno))
1255 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1259 /********************************************************************
1261 * tty_recv_config - configure the receive-side characteristics of
1262 * the ppp interface.
1265 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1268 * If we were called because the link has gone down then there is nothing
1269 * which may be done. Just return without incident.
1274 * Set the receiver parameters
1276 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1277 if (errno != EIO && errno != ENOTTY)
1278 error("Couldn't set channel receive MRU: %m");
1280 if (new_style_driver && ppp_dev_fd >= 0
1281 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1282 error("Couldn't set MRU in generic PPP layer: %m");
1284 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1285 if (errno != EIO && errno != ENOTTY)
1286 error("Couldn't set channel receive asyncmap: %m");
1290 /********************************************************************
1292 * ccp_test - ask kernel whether a given compression method
1293 * is acceptable for use.
1297 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1299 struct ppp_option_data data;
1301 memset (&data, '\0', sizeof (data));
1303 data.length = opt_len;
1304 data.transmit = for_transmit;
1306 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1309 return (errno == ENOBUFS)? 0: -1;
1312 /********************************************************************
1314 * ccp_flags_set - inform kernel about the current state of CCP.
1317 void ccp_flags_set (int unit, int isopen, int isup)
1321 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1322 if (still_ppp() && ppp_dev_fd >= 0)
1323 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1328 * set_filters - set the active and pass filters in the kernel driver.
1330 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1332 struct sock_fprog fp;
1334 fp.len = pass->bf_len;
1335 fp.filter = (struct sock_filter *) pass->bf_insns;
1336 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1337 if (errno == ENOTTY)
1338 warn("kernel does not support PPP filtering");
1340 error("Couldn't set pass-filter in kernel: %m");
1343 fp.len = active->bf_len;
1344 fp.filter = (struct sock_filter *) active->bf_insns;
1345 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1346 error("Couldn't set active-filter in kernel: %m");
1351 #endif /* PPP_FILTER */
1353 /********************************************************************
1355 * get_idle_time - return how long the link has been idle.
1358 get_idle_time(u, ip)
1360 struct ppp_idle *ip;
1362 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1365 /********************************************************************
1367 * get_ppp_stats - return statistics for the link.
1370 get_ppp_stats(u, stats)
1372 struct pppd_stats *stats;
1374 struct ifpppstatsreq req;
1376 memset (&req, 0, sizeof (req));
1378 req.stats_ptr = (caddr_t) &req.stats;
1379 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1380 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1381 error("Couldn't get PPP statistics: %m");
1384 stats->bytes_in = req.stats.p.ppp_ibytes;
1385 stats->bytes_out = req.stats.p.ppp_obytes;
1386 stats->pkts_in = req.stats.p.ppp_ipackets;
1387 stats->pkts_out = req.stats.p.ppp_opackets;
1391 /********************************************************************
1393 * ccp_fatal_error - returns 1 if decompression was disabled as a
1394 * result of an error detected after decompression of a packet,
1395 * 0 otherwise. This is necessary because of patent nonsense.
1398 int ccp_fatal_error (int unit)
1402 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1403 error("Couldn't read compression error flags: %m");
1406 return flags & SC_DC_FERROR;
1409 /********************************************************************
1411 * path_to_procfs - find the path to the proc file system mount point
1413 static char proc_path[MAXPATHLEN];
1414 static int proc_path_len;
1416 static char *path_to_procfs(const char *tail)
1418 struct mntent *mntent;
1421 if (proc_path_len == 0) {
1422 /* Default the mount location of /proc */
1423 strlcpy (proc_path, "/proc", sizeof(proc_path));
1425 fp = fopen(MOUNTED, "r");
1427 while ((mntent = getmntent(fp)) != NULL) {
1428 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1430 if (strcmp(mntent->mnt_type, "proc") == 0) {
1431 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1432 proc_path_len = strlen(proc_path);
1440 strlcpy(proc_path + proc_path_len, tail,
1441 sizeof(proc_path) - proc_path_len);
1446 * /proc/net/route parsing stuff.
1448 #define ROUTE_MAX_COLS 12
1449 FILE *route_fd = (FILE *) 0;
1450 static char route_buffer[512];
1451 static int route_dev_col, route_dest_col, route_gw_col;
1452 static int route_flags_col, route_metric_col, route_mask_col;
1453 static int route_num_cols;
1455 static int open_route_table (void);
1456 static void close_route_table (void);
1457 static int read_route_table (struct rtentry *rt);
1459 /********************************************************************
1461 * close_route_table - close the interface to the route table
1464 static void close_route_table (void)
1466 if (route_fd != (FILE *) 0) {
1468 route_fd = (FILE *) 0;
1472 /********************************************************************
1474 * open_route_table - open the interface to the route table
1476 static char route_delims[] = " \t\n";
1478 static int open_route_table (void)
1482 close_route_table();
1484 path = path_to_procfs("/net/route");
1485 route_fd = fopen (path, "r");
1486 if (route_fd == NULL) {
1487 error("can't open routing table %s: %m", path);
1491 route_dev_col = 0; /* default to usual columns */
1494 route_flags_col = 3;
1495 route_metric_col = 6;
1499 /* parse header line */
1500 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1501 char *p = route_buffer, *q;
1503 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1505 if ((q = strtok(p, route_delims)) == 0)
1507 if (strcasecmp(q, "iface") == 0)
1508 route_dev_col = col;
1509 else if (strcasecmp(q, "destination") == 0)
1510 route_dest_col = col;
1511 else if (strcasecmp(q, "gateway") == 0)
1513 else if (strcasecmp(q, "flags") == 0)
1514 route_flags_col = col;
1515 else if (strcasecmp(q, "mask") == 0)
1516 route_mask_col = col;
1519 if (used && col >= route_num_cols)
1520 route_num_cols = col + 1;
1528 /********************************************************************
1530 * read_route_table - read the next entry from the route table
1533 static int read_route_table(struct rtentry *rt)
1535 char *cols[ROUTE_MAX_COLS], *p;
1538 memset (rt, '\0', sizeof (struct rtentry));
1540 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1544 for (col = 0; col < route_num_cols; ++col) {
1545 cols[col] = strtok(p, route_delims);
1546 if (cols[col] == NULL)
1547 return 0; /* didn't get enough columns */
1551 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1552 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1553 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1555 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1556 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
1557 rt->rt_dev = cols[route_dev_col];
1562 /********************************************************************
1564 * defaultroute_exists - determine if there is a default route
1565 * with the given metric (or negative for any)
1568 static int defaultroute_exists (struct rtentry *rt, int metric)
1572 if (!open_route_table())
1575 while (read_route_table(rt) != 0) {
1576 if ((rt->rt_flags & RTF_UP) == 0)
1579 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1581 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1582 || rt->rt_metric == metric)) {
1588 close_route_table();
1593 * have_route_to - determine if the system has any route to
1594 * a given IP address. `addr' is in network byte order.
1595 * Return value is 1 if yes, 0 if no, -1 if don't know.
1596 * For demand mode to work properly, we have to ignore routes
1597 * through our own interface.
1599 int have_route_to(u_int32_t addr)
1604 if (!open_route_table())
1605 return -1; /* don't know */
1607 while (read_route_table(&rt)) {
1608 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1610 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1616 close_route_table();
1620 /********************************************************************
1622 * sifdefaultroute - assign a default route through the address given.
1625 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1629 if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) {
1630 if (rt.rt_flags & RTF_GATEWAY)
1631 error("not replacing existing default route via %I with metric %d",
1632 SIN_ADDR(rt.rt_gateway), dfl_route_metric);
1634 error("not replacing existing default route through %s with metric %d",
1635 rt.rt_dev, dfl_route_metric);
1639 memset (&rt, 0, sizeof (rt));
1640 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1643 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1645 if (kernel_version > KVERSION(2,1,0)) {
1646 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1647 SIN_ADDR(rt.rt_genmask) = 0L;
1650 rt.rt_flags = RTF_UP;
1651 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1652 if ( ! ok_error ( errno ))
1653 error("default route ioctl(SIOCADDRT): %m");
1657 have_default_route = 1;
1661 /********************************************************************
1663 * cifdefaultroute - delete a default route through the address given.
1666 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1670 have_default_route = 0;
1672 memset (&rt, '\0', sizeof (rt));
1673 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1674 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1679 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1681 if (kernel_version > KVERSION(2,1,0)) {
1682 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1683 SIN_ADDR(rt.rt_genmask) = 0L;
1686 rt.rt_flags = RTF_UP;
1687 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1689 if ( ! ok_error ( errno ))
1690 error("default route ioctl(SIOCDELRT): %m");
1698 /********************************************************************
1700 * sifproxyarp - Make a proxy ARP entry for the peer.
1703 int sifproxyarp (int unit, u_int32_t his_adr)
1705 struct arpreq arpreq;
1708 if (has_proxy_arp == 0) {
1709 memset (&arpreq, '\0', sizeof(arpreq));
1711 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1712 SIN_ADDR(arpreq.arp_pa) = his_adr;
1713 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1715 * Get the hardware address of an interface on the same subnet
1716 * as our local address.
1718 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1719 sizeof(proxy_arp_dev))) {
1720 error("Cannot determine ethernet address for proxy ARP");
1723 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1725 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1726 if ( ! ok_error ( errno ))
1727 error("ioctl(SIOCSARP): %m");
1730 proxy_arp_addr = his_adr;
1734 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1735 if (forw_path != 0) {
1736 int fd = open(forw_path, O_WRONLY);
1738 if (write(fd, "1", 1) != 1)
1739 error("Couldn't enable IP forwarding: %m");
1749 /********************************************************************
1751 * cifproxyarp - Delete the proxy ARP entry for the peer.
1754 int cifproxyarp (int unit, u_int32_t his_adr)
1756 struct arpreq arpreq;
1758 if (has_proxy_arp) {
1760 memset (&arpreq, '\0', sizeof(arpreq));
1761 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1762 SIN_ADDR(arpreq.arp_pa) = his_adr;
1763 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1764 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1766 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1767 if ( ! ok_error ( errno ))
1768 warn("ioctl(SIOCDARP): %m");
1775 /********************************************************************
1777 * get_ether_addr - get the hardware address of an interface on the
1778 * the same subnet as ipaddr.
1781 static int get_ether_addr (u_int32_t ipaddr,
1782 struct sockaddr *hwaddr,
1783 char *name, int namelen)
1785 struct ifreq *ifr, *ifend;
1786 u_int32_t ina, mask;
1788 struct ifreq ifreq, bestifreq;
1790 struct ifreq ifs[MAX_IFS];
1792 u_int32_t bestmask=0;
1793 int found_interface = 0;
1795 ifc.ifc_len = sizeof(ifs);
1797 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1798 if ( ! ok_error ( errno ))
1799 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1804 * Scan through looking for an interface with an Internet
1805 * address on the same subnet as `ipaddr'.
1807 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1808 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1809 if (ifr->ifr_addr.sa_family == AF_INET) {
1810 ina = SIN_ADDR(ifr->ifr_addr);
1811 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1813 * Check that the interface is up, and not point-to-point
1816 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1819 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1822 * Get its netmask and check that it's on the right subnet.
1824 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1827 mask = SIN_ADDR(ifreq.ifr_addr);
1829 if (((ipaddr ^ ina) & mask) != 0)
1830 continue; /* no match */
1832 if (mask >= bestmask) {
1833 /* Compare using >= instead of > -- it is possible for
1834 an interface to have a netmask of 0.0.0.0 */
1835 found_interface = 1;
1842 if (!found_interface) return 0;
1844 strlcpy(name, bestifreq.ifr_name, namelen);
1846 /* trim off the :1 in eth0:1 */
1847 aliasp = strchr(name, ':');
1851 info("found interface %s for proxy arp", name);
1853 * Now get the hardware address.
1855 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1856 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1857 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1862 &bestifreq.ifr_hwaddr,
1863 sizeof (struct sockaddr));
1869 * get_if_hwaddr - get the hardware address for the specified
1870 * network interface device.
1873 get_if_hwaddr(u_char *addr, char *name)
1878 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1881 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1882 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1883 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1886 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1891 * get_first_ethernet - return the name of the first ethernet-style
1892 * interface on this system.
1895 get_first_ethernet()
1900 /********************************************************************
1902 * Return user specified netmask, modified by any mask we might determine
1903 * for address `addr' (in network byte order).
1904 * Here we scan through the system's list of interfaces, looking for
1905 * any non-point-to-point interfaces which might appear to be on the same
1906 * network as `addr'. If we find any, we OR in their netmask to the
1907 * user-specified netmask.
1910 u_int32_t GetMask (u_int32_t addr)
1912 u_int32_t mask, nmask, ina;
1913 struct ifreq *ifr, *ifend, ifreq;
1915 struct ifreq ifs[MAX_IFS];
1919 if (IN_CLASSA(addr)) /* determine network mask for address class */
1920 nmask = IN_CLASSA_NET;
1921 else if (IN_CLASSB(addr))
1922 nmask = IN_CLASSB_NET;
1924 nmask = IN_CLASSC_NET;
1926 /* class D nets are disallowed by bad_ip_adrs */
1927 mask = netmask | htonl(nmask);
1929 * Scan through the system's network interfaces.
1931 ifc.ifc_len = sizeof(ifs);
1933 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1934 if ( ! ok_error ( errno ))
1935 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1939 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1940 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1942 * Check the interface's internet address.
1944 if (ifr->ifr_addr.sa_family != AF_INET)
1946 ina = SIN_ADDR(ifr->ifr_addr);
1947 if (((ntohl(ina) ^ addr) & nmask) != 0)
1950 * Check that the interface is up, and not point-to-point nor loopback.
1952 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1953 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1956 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1959 * Get its netmask and OR it into our mask.
1961 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1963 mask |= SIN_ADDR(ifreq.ifr_addr);
1969 /********************************************************************
1971 * Internal routine to decode the version.modification.patch level
1974 static void decode_version (char *buf, int *version,
1975 int *modification, int *patch)
1979 *version = (int) strtoul (buf, &endp, 10);
1983 if (endp != buf && *endp == '.') {
1985 *modification = (int) strtoul (buf, &endp, 10);
1986 if (endp != buf && *endp == '.') {
1988 *patch = (int) strtoul (buf, &buf, 10);
1993 /********************************************************************
1995 * Procedure to determine if the PPP line discipline is registered.
1999 ppp_registered(void)
2007 * We used to open the serial device and set it to the ppp line
2008 * discipline here, in order to create a ppp unit. But that is
2009 * not a good idea - the user might have specified a device that
2010 * they can't open (permission, or maybe it doesn't really exist).
2011 * So we grab a pty master/slave pair and use that.
2013 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2014 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2019 * Try to put the device into the PPP discipline.
2021 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2022 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2031 /********************************************************************
2033 * ppp_available - check whether the system has any ppp interfaces
2034 * (in fact we check whether we can do an ioctl on ppp0).
2037 int ppp_available(void)
2042 int my_version, my_modification, my_patch;
2043 int osmaj, osmin, ospatch;
2045 /* get the kernel version now, since we are called before sys_init */
2047 osmaj = osmin = ospatch = 0;
2048 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2049 kernel_version = KVERSION(osmaj, osmin, ospatch);
2051 fd = open("/dev/ppp", O_RDWR);
2053 new_style_driver = 1;
2055 /* XXX should get from driver */
2057 driver_modification = 4;
2063 if (kernel_version >= KVERSION(2,3,13)) {
2064 error("Couldn't open the /dev/ppp device: %m");
2065 if (errno == ENOENT)
2067 "You need to create the /dev/ppp device node by\n"
2068 "executing the following command as root:\n"
2069 " mknod /dev/ppp c 108 0\n";
2070 else if (errno == ENODEV || errno == ENXIO)
2072 "Please load the ppp_generic kernel module.\n";
2076 /* we are running on a really really old kernel */
2078 "This system lacks kernel support for PPP. This could be because\n"
2079 "the PPP kernel module could not be loaded, or because PPP was not\n"
2080 "included in the kernel configuration. If PPP was included as a\n"
2081 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2082 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2083 "See README.linux file in the ppp distribution for more details.\n";
2086 * Open a socket for doing the ioctl operations.
2088 s = socket(AF_INET, SOCK_DGRAM, 0);
2092 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2093 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2095 * If the device did not exist then attempt to create one by putting the
2096 * current tty into the PPP discipline. If this works then obtain the
2097 * flags for the device again.
2100 if (ppp_registered()) {
2101 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2102 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2106 * Ensure that the hardware address is for PPP and not something else
2109 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2111 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2115 * This is the PPP device. Validate the version of the driver at this
2116 * point to ensure that this program will work with the driver.
2119 char abBuffer [1024];
2121 ifr.ifr_data = abBuffer;
2122 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2124 error("Couldn't read driver version: %m");
2126 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2129 decode_version(abBuffer,
2131 &driver_modification,
2134 * Validate the version of the driver against the version that we used.
2136 decode_version(VERSION,
2141 /* The version numbers must match */
2142 if (driver_version != my_version)
2145 /* The modification levels must be legal */
2146 if (driver_modification < 3) {
2147 if (driver_modification >= 2) {
2148 /* we can cope with 2.2.0 and above */
2157 slprintf(route_buffer, sizeof(route_buffer),
2158 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2159 driver_version, driver_modification, driver_patch);
2161 no_ppp_msg = route_buffer;
2168 #ifndef HAVE_LOGWTMP
2169 /********************************************************************
2171 * Update the wtmp file with the appropriate user name and tty device.
2174 void logwtmp (const char *line, const char *name, const char *host)
2176 struct utmp ut, *utp;
2177 pid_t mypid = getpid();
2183 * Update the signon database for users.
2184 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2186 utmpname(_PATH_UTMP);
2188 while ((utp = getutent()) && (utp->ut_pid != mypid))
2192 memcpy(&ut, utp, sizeof(ut));
2194 /* some gettys/telnetds don't initialize utmp... */
2195 memset(&ut, 0, sizeof(ut));
2197 if (ut.ut_id[0] == 0)
2198 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2200 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2201 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2205 ut.ut_type = USER_PROCESS;
2208 /* Insert the host name if one is supplied */
2210 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2212 /* Insert the IP address of the remote system if IP is enabled */
2213 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2214 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2215 sizeof(ut.ut_addr));
2217 /* CL: Makes sure that the logout works */
2218 if (*host == 0 && *name==0)
2224 * Update the wtmp file.
2227 updwtmp(_PATH_WTMP, &ut);
2229 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2231 flock(wtmp, LOCK_EX);
2233 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2234 warn("error writing %s: %m", _PATH_WTMP);
2236 flock(wtmp, LOCK_UN);
2242 #endif /* HAVE_LOGWTMP */
2244 /********************************************************************
2246 * sifvjcomp - config tcp header compression
2249 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2254 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2255 error("Couldn't set up TCP header compression: %m");
2260 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2261 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2266 /********************************************************************
2268 * sifup - Config the interface up and enable IP packets to pass.
2275 if ((ret = setifstate(u, 1)))
2281 /********************************************************************
2283 * sifdown - Disable the indicated protocol and config the interface
2284 * down if there are no remaining protocols.
2289 if (if_is_up && --if_is_up > 0)
2297 return setifstate(u, 0);
2301 /********************************************************************
2303 * sif6up - Config the interface up for IPv6
2310 if ((ret = setifstate(u, 1)))
2316 /********************************************************************
2318 * sif6down - Disable the IPv6CP protocol and config the interface
2319 * down if there are no remaining protocols.
2322 int sif6down (int u)
2329 return setifstate(u, 0);
2333 /********************************************************************
2335 * setifstate - Config the interface up or down
2338 static int setifstate (int u, int state)
2342 memset (&ifr, '\0', sizeof (ifr));
2343 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2344 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2345 if (! ok_error (errno))
2346 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2351 ifr.ifr_flags |= IFF_UP;
2353 ifr.ifr_flags &= ~IFF_UP;
2354 ifr.ifr_flags |= IFF_POINTOPOINT;
2355 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2356 if (! ok_error (errno))
2357 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2363 /********************************************************************
2365 * sifaddr - Config the interface IP addresses and netmask.
2368 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2374 memset (&ifr, '\0', sizeof (ifr));
2375 memset (&rt, '\0', sizeof (rt));
2377 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2378 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2379 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2381 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2383 * Set our IP address
2385 SIN_ADDR(ifr.ifr_addr) = our_adr;
2386 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2387 if (errno != EEXIST) {
2388 if (! ok_error (errno))
2389 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2392 warn("ioctl(SIOCSIFADDR): Address already exists");
2397 * Set the gateway address
2400 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2401 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2402 if (! ok_error (errno))
2403 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2409 * For recent kernels, force the netmask to 255.255.255.255.
2411 if (kernel_version >= KVERSION(2,1,16))
2413 if (net_mask != 0) {
2414 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2415 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2416 if (! ok_error (errno))
2417 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2422 * Add the device route
2424 if (kernel_version < KVERSION(2,1,16)) {
2425 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2426 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2429 SIN_ADDR(rt.rt_gateway) = 0L;
2430 SIN_ADDR(rt.rt_dst) = his_adr;
2431 rt.rt_flags = RTF_UP | RTF_HOST;
2433 if (kernel_version > KVERSION(2,1,0)) {
2434 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2435 SIN_ADDR(rt.rt_genmask) = -1L;
2438 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2439 if (! ok_error (errno))
2440 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2445 /* set ip_dynaddr in demand mode if address changes */
2446 if (demand && tune_kernel && !dynaddr_set
2447 && our_old_addr && our_old_addr != our_adr) {
2448 /* set ip_dynaddr if possible */
2452 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2453 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2454 if (write(fd, "1", 1) != 1)
2455 error("Couldn't enable dynamic IP addressing: %m");
2458 dynaddr_set = 1; /* only 1 attempt */
2465 /********************************************************************
2467 * cifaddr - Clear the interface IP addresses, and delete routes
2468 * through the interface if possible.
2471 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2475 if (kernel_version < KVERSION(2,1,16)) {
2477 * Delete the route through the device
2480 memset (&rt, '\0', sizeof (rt));
2482 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2483 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2486 SIN_ADDR(rt.rt_gateway) = 0;
2487 SIN_ADDR(rt.rt_dst) = his_adr;
2488 rt.rt_flags = RTF_UP | RTF_HOST;
2490 if (kernel_version > KVERSION(2,1,0)) {
2491 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2492 SIN_ADDR(rt.rt_genmask) = -1L;
2495 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2496 if (still_ppp() && ! ok_error (errno))
2497 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2502 /* This way it is possible to have an IPX-only or IPv6-only interface */
2503 memset(&ifr, 0, sizeof(ifr));
2504 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2505 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2507 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2508 if (! ok_error (errno)) {
2509 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2514 our_old_addr = our_adr;
2520 /********************************************************************
2522 * sif6addr - Config the interface with an IPv6 link-local address
2524 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2526 struct in6_ifreq ifr6;
2528 struct in6_rtmsg rt6;
2532 error("IPv6 socket creation failed: %m");
2535 memset(&ifr, 0, sizeof (ifr));
2536 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2537 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2538 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2542 /* Local interface */
2543 memset(&ifr6, 0, sizeof(ifr6));
2544 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2545 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2546 ifr6.ifr6_prefixlen = 10;
2548 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2549 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2553 /* Route to remote host */
2554 memset(&rt6, 0, sizeof(rt6));
2555 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2556 rt6.rtmsg_flags = RTF_UP;
2557 rt6.rtmsg_dst_len = 10;
2558 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2559 rt6.rtmsg_metric = 1;
2561 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2562 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2570 /********************************************************************
2572 * cif6addr - Remove IPv6 address from interface
2574 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2577 struct in6_ifreq ifr6;
2581 error("IPv6 socket creation failed: %m");
2584 memset(&ifr, 0, sizeof(ifr));
2585 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2586 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2587 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2591 memset(&ifr6, 0, sizeof(ifr6));
2592 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2593 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2594 ifr6.ifr6_prefixlen = 10;
2596 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2597 if (errno != EADDRNOTAVAIL) {
2598 if (! ok_error (errno))
2599 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2602 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2611 * get_pty - get a pty master/slave pair and chown the slave side
2612 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2615 get_pty(master_fdp, slave_fdp, slave_name, uid)
2621 int i, mfd, sfd = -1;
2623 struct termios tios;
2627 * Try the unix98 way first.
2629 mfd = open("/dev/ptmx", O_RDWR);
2632 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2633 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2634 chmod(pty_name, S_IRUSR | S_IWUSR);
2637 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2638 warn("Couldn't unlock pty slave %s: %m", pty_name);
2640 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2641 warn("Couldn't open pty slave %s: %m", pty_name);
2644 #endif /* TIOCGPTN */
2647 /* the old way - scan through the pty name space */
2648 for (i = 0; i < 64; ++i) {
2649 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2650 'p' + i / 16, i % 16);
2651 mfd = open(pty_name, O_RDWR, 0);
2654 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2656 fchown(sfd, uid, -1);
2657 fchmod(sfd, S_IRUSR | S_IWUSR);
2668 strlcpy(slave_name, pty_name, 16);
2671 if (tcgetattr(sfd, &tios) == 0) {
2672 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2673 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2674 tios.c_iflag = IGNPAR;
2677 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2678 warn("couldn't set attributes on pty: %m");
2680 warn("couldn't get attributes on pty: %m");
2685 /********************************************************************
2687 * open_loopback - open the device we use for getting packets
2688 * in demand mode. Under Linux, we use a pty master/slave pair.
2691 open_ppp_loopback(void)
2696 if (new_style_driver) {
2697 /* allocate ourselves a ppp unit */
2698 if (make_ppp_unit() < 0)
2700 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2701 set_kdebugflag(kdebugflag);
2706 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2707 fatal("No free pty for loopback");
2709 set_ppp_fd(slave_fd);
2711 flags = fcntl(master_fd, F_GETFL);
2713 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2714 warn("couldn't set master loopback to nonblock: %m");
2716 flags = fcntl(ppp_fd, F_GETFL);
2718 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2719 warn("couldn't set slave loopback to nonblock: %m");
2721 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2722 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2724 * Find out which interface we were given.
2726 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2727 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2729 * Enable debug in the driver if requested.
2731 set_kdebugflag (kdebugflag);
2736 /********************************************************************
2738 * sifnpmode - Set the mode for handling packets for a given NP.
2742 sifnpmode(u, proto, mode)
2749 npi.protocol = proto;
2751 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2752 if (! ok_error (errno))
2753 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2760 /********************************************************************
2762 * sipxfaddr - Config the interface IPX networknumber
2765 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2772 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2774 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2776 if (! ok_error (errno))
2777 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2781 memset (&ifr, '\0', sizeof (ifr));
2782 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2784 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2785 sipx->sipx_family = AF_IPX;
2786 sipx->sipx_port = 0;
2787 sipx->sipx_network = htonl (network);
2788 sipx->sipx_type = IPX_FRAME_ETHERII;
2789 sipx->sipx_action = IPX_CRTITF;
2791 * Set the IPX device
2793 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2795 if (errno != EEXIST) {
2796 if (! ok_error (errno))
2797 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2800 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2809 /********************************************************************
2811 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2812 * are removed and the device is no longer able to pass IPX
2816 int cipxfaddr (int unit)
2823 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2825 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2827 if (! ok_error (errno))
2828 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2832 memset (&ifr, '\0', sizeof (ifr));
2833 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2835 sipx->sipx_type = IPX_FRAME_ETHERII;
2836 sipx->sipx_action = IPX_DLTITF;
2837 sipx->sipx_family = AF_IPX;
2839 * Set the IPX device
2841 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2842 if (! ok_error (errno))
2843 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2853 * Use the hostname as part of the random number seed.
2862 for (p = hostname; *p != 0; ++p)
2867 /********************************************************************
2869 * sys_check_options - check the options that the user specified
2873 sys_check_options(void)
2877 * Disable the IPX protocol if the support is not present in the kernel.
2881 if (ipxcp_protent.enabled_flag) {
2882 struct stat stat_buf;
2883 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
2884 && (path = path_to_procfs("/net/ipx_interface")) == NULL)
2885 || lstat(path, &stat_buf) < 0) {
2886 error("IPX support is not present in the kernel\n");
2887 ipxcp_protent.enabled_flag = 0;
2891 if (demand && driver_is_old) {
2892 option_error("demand dialling is not supported by kernel driver "
2893 "version %d.%d.%d", driver_version, driver_modification,
2897 if (multilink && !new_style_driver) {
2898 warn("Warning: multilink is not supported by the kernel driver");
2906 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2908 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2909 * that the system has a properly configured Ethernet interface for this
2910 * function to return non-zero.
2913 ether_to_eui64(eui64_t *p_eui64)
2917 const unsigned char *ptr;
2919 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2922 warn("could not open IPv6 socket");
2926 strcpy(ifr.ifr_name, "eth0");
2927 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2930 warn("could not obtain hardware address for eth0");
2936 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2938 ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data;
2939 p_eui64->e8[0] = ptr[0] | 0x02;
2940 p_eui64->e8[1] = ptr[1];
2941 p_eui64->e8[2] = ptr[2];
2942 p_eui64->e8[3] = 0xFF;
2943 p_eui64->e8[4] = 0xFE;
2944 p_eui64->e8[5] = ptr[3];
2945 p_eui64->e8[6] = ptr[4];
2946 p_eui64->e8[7] = ptr[5];