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>
76 #include <sys/errno.h>
79 #include <sys/utsname.h>
80 #include <sys/sysmacros.h>
97 /* This is in netdevice.h. However, this compile will fail miserably if
98 you attempt to include netdevice.h because it has so many references
99 to __memcpy functions which it should not attempt to do. So, since I
100 really don't use it, but it must be defined, define it now. */
103 #define xxMAX_ADDR_LEN 7
107 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
109 #include <net/if_arp.h>
110 #include <net/route.h>
111 #include <netinet/if_ether.h>
113 #include <linux/types.h>
114 #include <linux/tty.h>
115 #include <linux/if.h>
116 #include <linux/if_arp.h>
117 #include <linux/route.h>
118 #include <linux/if_ether.h>
120 #include <linux/sockios.h>
121 #include <netinet/in.h>
122 #include <arpa/inet.h>
124 #include <linux/ppp_defs.h>
125 #include <linux/if_ppp.h>
133 #if __GLIBC__ >= 2 && \
134 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
135 #include <netipx/ipx.h>
137 #include <linux/ipx.h>
139 #endif /* IPX_CHANGE */
142 #include <pcap-bpf.h>
143 #include <linux/filter.h>
144 #endif /* PPP_FILTER */
147 #include <sys/locks.h>
153 * This is in linux/include/net/ipv6.h.
157 struct in6_addr ifr6_addr;
158 __u32 ifr6_prefixlen;
159 unsigned int ifr6_ifindex;
163 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
164 memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \
165 sin6.s6_addr16[0] = htons(0xfe80); \
166 eui64_copy(eui64, sin6.s6_addr32[2]); \
171 /* We can get an EIO error on an ioctl if the modem has hung up */
172 #define ok_error(num) ((num)==EIO)
174 static int tty_disc = N_TTY; /* The TTY discipline */
175 static int ppp_disc = N_PPP; /* The PPP discpline */
176 static int initfdflags = -1; /* Initial file descriptor flags for fd */
177 static int ppp_fd = -1; /* fd which is set to PPP discipline */
178 static int sock_fd = -1; /* socket for doing interface ioctls */
179 static int slave_fd = -1; /* pty for old-style demand mode, slave */
180 static int master_fd = -1; /* pty for old-style demand mode, master */
182 static int sock6_fd = -1;
186 * For the old-style kernel driver, this is the same as ppp_fd.
187 * For the new-style driver, it is the fd of an instance of /dev/ppp
188 * which is attached to the ppp unit and is used for controlling it.
190 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
192 static int chindex; /* channel index (new style driver) */
194 static fd_set in_fds; /* set of fds that wait_input waits for */
195 static int max_in_fd; /* highest fd set in in_fds */
197 static int has_proxy_arp = 0;
198 static int driver_version = 0;
199 static int driver_modification = 0;
200 static int driver_patch = 0;
201 static int driver_is_old = 0;
202 static int restore_term = 0; /* 1 => we've munged the terminal */
203 static struct termios inittermios; /* Initial TTY termios */
205 int new_style_driver = 0;
207 static char loop_name[20];
208 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
210 static int if_is_up; /* Interface has been marked up */
211 static u_int32_t default_route_gateway; /* Gateway for default 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);
239 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
240 char *name, int namelen);
241 static void decode_version (char *buf, int *version, int *mod, int *patch);
242 static int set_kdebugflag(int level);
243 static int ppp_registered(void);
244 static int make_ppp_unit(void);
246 extern u_char inpacket_buf[]; /* borrowed from main.c */
249 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
253 #define SET_SA_FAMILY(addr, family) \
254 memset ((char *) &(addr), '\0', sizeof(addr)); \
255 addr.sa_family = (family);
258 * Determine if the PPP connection should still be present.
263 /* new_fd is the fd of a tty */
264 static void set_ppp_fd (int new_fd)
267 if (!new_style_driver)
271 static int still_ppp(void)
273 if (new_style_driver)
274 return !hungup && ppp_fd >= 0;
275 if (!hungup || ppp_fd == slave_fd)
278 set_ppp_fd(slave_fd);
285 * modify_flags - set and clear flag bits controlling the kernel
288 static int modify_flags(int fd, int clear_bits, int set_bits)
292 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
294 flags = (flags & ~clear_bits) | set_bits;
295 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
302 error("Failed to set PPP kernel option flags: %m");
306 /********************************************************************
308 * sys_init - System-dependent initialization.
313 /* Get an internet socket for doing socket ioctls. */
314 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
316 fatal("Couldn't create IP socket: %m(%d)", errno);
319 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
321 sock6_fd = -errno; /* save errno for later */
328 /********************************************************************
330 * sys_cleanup - restore any system state we modified before exiting:
331 * mark the interface down, delete default route and/or proxy arp entry.
332 * This shouldn't call die() because it's called from die().
335 void sys_cleanup(void)
338 * Take down the device
345 * Delete any routes through the device.
347 if (default_route_gateway != 0)
348 cifdefaultroute(0, 0, default_route_gateway);
351 cifproxyarp(0, proxy_arp_addr);
354 /********************************************************************
356 * sys_close - Clean up in a child process before execing.
361 if (new_style_driver && ppp_dev_fd >= 0)
375 /********************************************************************
377 * set_kdebugflag - Define the debugging level for the kernel
380 static int set_kdebugflag (int requested_level)
384 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
385 if ( ! ok_error (errno) )
386 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
392 /********************************************************************
394 * tty_establish_ppp - Turn the serial port into a ppp interface.
397 int tty_establish_ppp (int tty_fd)
402 * Ensure that the tty device is in exclusive mode.
404 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
405 if ( ! ok_error ( errno ))
406 warn("Couldn't make tty exclusive: %m");
409 * Demand mode - prime the old ppp device to relinquish the unit.
411 if (!new_style_driver && looped
412 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
413 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
417 * Set the current tty to the PPP discpline
421 #define N_SYNC_PPP 14
423 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
424 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
425 if ( ! ok_error (errno) ) {
426 error("Couldn't set tty to PPP discipline: %m");
431 ret_fd = generic_establish_ppp(tty_fd);
433 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
434 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
438 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
439 (kdebugflag * SC_DEBUG) & SC_LOGB);
441 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
442 warn("Couldn't reset tty to normal line discipline: %m");
448 /********************************************************************
450 * generic_establish_ppp - Turn the fd into a ppp interface.
452 int generic_establish_ppp (int fd)
456 if (new_style_driver) {
459 /* Open an instance of /dev/ppp and connect the channel to it */
460 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
461 error("Couldn't get channel number: %m");
464 dbglog("using channel %d", chindex);
465 fd = open("/dev/ppp", O_RDWR);
467 error("Couldn't reopen /dev/ppp: %m");
470 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
471 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
472 error("Couldn't attach to channel %d: %m", chindex);
475 flags = fcntl(fd, F_GETFL);
476 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
477 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
482 if (!looped && !multilink) {
484 * Create a new PPP unit.
486 if (make_ppp_unit() < 0)
491 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
495 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
496 error("Couldn't attach to PPP unit %d: %m", ifunit);
503 * Old-style driver: find out which interface we were given.
506 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
507 if (ok_error (errno))
509 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
511 /* Check that we got the same unit again. */
512 if (looped && x != ifunit)
513 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
517 * Fetch the initial file flags and reset blocking mode on the file.
519 initfdflags = fcntl(fd, F_GETFL);
520 if (initfdflags == -1 ||
521 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
522 if ( ! ok_error (errno))
523 warn("Couldn't set device to non-blocking mode: %m");
528 * Enable debug in the driver if requested.
531 set_kdebugflag (kdebugflag);
543 /********************************************************************
545 * tty_disestablish_ppp - Restore the serial port to normal operation.
546 * This shouldn't call die() because it's called from die().
549 void tty_disestablish_ppp(int tty_fd)
553 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
555 if (tcflush(tty_fd, TCIOFLUSH) < 0)
557 warn("tcflush failed: %m");
561 * Restore the previous line discipline
563 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
564 if ( ! ok_error (errno))
565 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
568 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
569 if ( ! ok_error (errno))
570 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
573 /* Reset non-blocking mode on fd. */
574 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
575 if ( ! ok_error (errno))
576 warn("Couldn't restore device fd flags: %m");
582 generic_disestablish_ppp(tty_fd);
585 /********************************************************************
587 * generic_disestablish_ppp - Restore device components to normal
588 * operation, and reconnect the ppp unit to the loopback if in demand
589 * mode. This shouldn't call die() because it's called from die().
591 void generic_disestablish_ppp(int dev_fd)
593 if (new_style_driver) {
597 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
599 } else if (!doing_multilink && ppp_dev_fd >= 0) {
601 remove_fd(ppp_dev_fd);
605 /* old-style driver */
607 set_ppp_fd(slave_fd);
614 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
615 * Assumes new_style_driver.
617 static int make_ppp_unit()
621 if (ppp_dev_fd >= 0) {
622 dbglog("in make_ppp_unit, already had /dev/ppp open?");
625 ppp_dev_fd = open("/dev/ppp", O_RDWR);
627 fatal("Couldn't open /dev/ppp: %m");
628 flags = fcntl(ppp_dev_fd, F_GETFL);
630 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
631 warn("Couldn't set /dev/ppp to nonblock: %m");
634 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
635 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
636 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
638 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
641 error("Couldn't create new ppp unit: %m");
646 * cfg_bundle - configure the existing bundle.
647 * Used in demand mode.
649 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
651 if (!new_style_driver)
654 /* set the mrru, mtu and flags */
655 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
656 error("Couldn't set MRRU: %m");
658 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
659 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
660 | (mrru? SC_MULTILINK: 0)));
662 /* connect up the channel */
663 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
664 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
669 * make_new_bundle - create a new PPP unit (i.e. a bundle)
670 * and connect our channel to it. This should only get called
671 * if `multilink' was set at the time establish_ppp was called.
672 * In demand mode this uses our existing bundle instead of making
675 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
677 if (!new_style_driver)
680 /* make us a ppp unit */
681 if (make_ppp_unit() < 0)
684 /* set the mrru and flags */
685 cfg_bundle(mrru, mtru, rssn, tssn);
689 * bundle_attach - attach our link to a given PPP unit.
690 * We assume the unit is controlled by another pppd.
692 int bundle_attach(int ifnum)
696 if (!new_style_driver)
699 master_fd = open("/dev/ppp", O_RDWR);
701 fatal("Couldn't open /dev/ppp: %m");
702 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
703 if (errno == ENXIO) {
705 return 0; /* doesn't still exist */
707 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
709 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
710 fatal("Couldn't connect to interface unit %d: %m", ifnum);
711 modify_flags(master_fd, 0, SC_MULTILINK);
719 * destroy_bundle - tell the driver to destroy our bundle.
721 void destroy_bundle(void)
723 if (ppp_dev_fd >= 0) {
725 remove_fd(ppp_dev_fd);
730 /********************************************************************
732 * clean_check - Fetch the flags for the device and generate
733 * appropriate error messages.
735 void clean_check(void)
741 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
743 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
745 s = "all had bit 7 set to 1";
749 s = "all had bit 7 set to 0";
753 s = "all had odd parity";
757 s = "all had even parity";
762 warn("Receive serial link is not 8-bit clean:");
763 warn("Problem: %s", s);
771 * List of valid speeds.
775 int speed_int, speed_val;
858 /********************************************************************
860 * Translate from bits/second to a speed_t.
863 static int translate_speed (int bps)
865 struct speed *speedp;
868 for (speedp = speeds; speedp->speed_int; speedp++) {
869 if (bps == speedp->speed_int)
870 return speedp->speed_val;
872 warn("speed %d not supported", bps);
877 /********************************************************************
879 * Translate from a speed_t to bits/second.
882 static int baud_rate_of (int speed)
884 struct speed *speedp;
887 for (speedp = speeds; speedp->speed_int; speedp++) {
888 if (speed == speedp->speed_val)
889 return speedp->speed_int;
895 /********************************************************************
897 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
898 * at the requested speed, etc. If `local' is true, set CLOCAL
899 * regardless of whether the modem option was specified.
902 void set_up_tty(int tty_fd, int local)
908 if (tcgetattr(tty_fd, &tios) < 0) {
909 if (!ok_error(errno))
910 fatal("tcgetattr: %m (line %d)", __LINE__);
917 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
918 tios.c_cflag |= CS8 | CREAD | HUPCL;
920 tios.c_iflag = IGNBRK | IGNPAR;
924 tios.c_cc[VTIME] = 0;
927 tios.c_cflag ^= (CLOCAL | HUPCL);
931 tios.c_cflag |= CRTSCTS;
935 tios.c_iflag |= IXON | IXOFF;
936 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
937 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
941 tios.c_cflag &= ~CRTSCTS;
948 speed = translate_speed(inspeed);
950 cfsetospeed (&tios, speed);
951 cfsetispeed (&tios, speed);
954 * We can't proceed if the serial port speed is B0,
955 * since that implies that the serial port is disabled.
958 speed = cfgetospeed(&tios);
960 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
963 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
965 fatal("tcsetattr: %m (line %d)", __LINE__);
967 baud_rate = baud_rate_of(speed);
971 /********************************************************************
973 * setdtr - control the DTR line on the serial port.
974 * This is called from die(), so it shouldn't call die().
977 void setdtr (int tty_fd, int on)
979 int modembits = TIOCM_DTR;
981 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
984 /********************************************************************
986 * restore_tty - restore the terminal to the saved settings.
989 void restore_tty (int tty_fd)
994 * Turn off echoing, because otherwise we can get into
995 * a loop with the tty and the modem echoing to each other.
996 * We presume we are the sole user of this tty device, so
997 * when we close it, it will revert to its defaults anyway.
1000 inittermios.c_lflag &= ~(ECHO | ECHONL);
1002 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1003 if (! ok_error (errno))
1004 warn("tcsetattr: %m (line %d)", __LINE__);
1009 /********************************************************************
1011 * output - Output PPP packet.
1014 void output (int unit, unsigned char *p, int len)
1019 dump_packet("sent", p, len);
1020 if (snoop_send_hook) snoop_send_hook(p, len);
1022 if (len < PPP_HDRLEN)
1024 if (new_style_driver) {
1027 proto = (p[0] << 8) + p[1];
1028 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1031 if (write(fd, p, len) < 0) {
1032 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1033 || errno == ENXIO || errno == EIO || errno == EINTR)
1034 warn("write: warning: %m (%d)", errno);
1036 error("write: %m (%d)", errno);
1040 /********************************************************************
1042 * wait_input - wait until there is data available,
1043 * for the length of time specified by *timo (indefinite
1047 void wait_input(struct timeval *timo)
1054 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1055 if (n < 0 && errno != EINTR)
1056 fatal("select: %m");
1060 * add_fd - add an fd to the set that wait_input waits for.
1064 if (fd >= FD_SETSIZE)
1065 fatal("internal error: file descriptor too large (%d)", fd);
1066 FD_SET(fd, &in_fds);
1072 * remove_fd - remove an fd from the set that wait_input waits for.
1074 void remove_fd(int fd)
1076 FD_CLR(fd, &in_fds);
1080 /********************************************************************
1082 * read_packet - get a PPP packet from the serial device.
1085 int read_packet (unsigned char *buf)
1089 len = PPP_MRU + PPP_HDRLEN;
1090 if (new_style_driver) {
1091 *buf++ = PPP_ALLSTATIONS;
1098 nr = read(ppp_fd, buf, len);
1099 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1100 && errno != EIO && errno != EINTR)
1102 if (nr < 0 && errno == ENXIO)
1105 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1106 /* N.B. we read ppp_fd first since LCP packets come in there. */
1107 nr = read(ppp_dev_fd, buf, len);
1108 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1109 && errno != EIO && errno != EINTR)
1110 error("read /dev/ppp: %m");
1111 if (nr < 0 && errno == ENXIO)
1113 if (nr == 0 && doing_multilink) {
1114 remove_fd(ppp_dev_fd);
1118 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1120 return (new_style_driver && nr > 0)? nr+2: nr;
1123 /********************************************************************
1125 * get_loop_output - get outgoing packets from the ppp device,
1126 * and detect when we want to bring the real link up.
1127 * Return value is 1 if we need to bring up the link, 0 otherwise.
1130 get_loop_output(void)
1135 if (new_style_driver) {
1136 while ((n = read_packet(inpacket_buf)) > 0)
1137 if (loop_frame(inpacket_buf, n))
1142 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1143 if (loop_chars(inbuf, n))
1147 fatal("eof on loopback");
1149 if (errno != EWOULDBLOCK && errno != EAGAIN)
1150 fatal("read from loopback: %m(%d)", errno);
1156 * netif_set_mtu - set the MTU on the PPP network interface.
1159 netif_set_mtu(int unit, int mtu)
1163 memset (&ifr, '\0', sizeof (ifr));
1164 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1167 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1168 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1172 * netif_get_mtu - get the MTU on the PPP network interface.
1175 netif_get_mtu(int unit)
1179 memset (&ifr, '\0', sizeof (ifr));
1180 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1182 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1183 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1189 /********************************************************************
1191 * tty_send_config - configure the transmit characteristics of
1192 * the ppp interface.
1195 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1202 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1203 if (errno != EIO && errno != ENOTTY)
1204 error("Couldn't set transmit async character map: %m");
1209 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1210 | (sync_serial? SC_SYNC: 0);
1211 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1214 /********************************************************************
1216 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1219 void tty_set_xaccm (ext_accm accm)
1223 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1224 if ( ! ok_error (errno))
1225 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1229 /********************************************************************
1231 * tty_recv_config - configure the receive-side characteristics of
1232 * the ppp interface.
1235 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1238 * If we were called because the link has gone down then there is nothing
1239 * which may be done. Just return without incident.
1244 * Set the receiver parameters
1246 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1247 if (errno != EIO && errno != ENOTTY)
1248 error("Couldn't set channel receive MRU: %m");
1250 if (new_style_driver && ppp_dev_fd >= 0
1251 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1252 error("Couldn't set MRU in generic PPP layer: %m");
1254 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1255 if (errno != EIO && errno != ENOTTY)
1256 error("Couldn't set channel receive asyncmap: %m");
1260 /********************************************************************
1262 * ccp_test - ask kernel whether a given compression method
1263 * is acceptable for use.
1267 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1269 struct ppp_option_data data;
1271 memset (&data, '\0', sizeof (data));
1273 data.length = opt_len;
1274 data.transmit = for_transmit;
1276 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1279 return (errno == ENOBUFS)? 0: -1;
1282 /********************************************************************
1284 * ccp_flags_set - inform kernel about the current state of CCP.
1287 void ccp_flags_set (int unit, int isopen, int isup)
1291 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1292 if (still_ppp() && ppp_dev_fd >= 0)
1293 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1298 * set_filters - set the active and pass filters in the kernel driver.
1300 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1302 struct sock_fprog fp;
1304 fp.len = pass->bf_len;
1305 fp.filter = (struct sock_filter *) pass->bf_insns;
1306 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1307 if (errno == ENOTTY)
1308 warn("kernel does not support PPP filtering");
1310 error("Couldn't set pass-filter in kernel: %m");
1313 fp.len = active->bf_len;
1314 fp.filter = (struct sock_filter *) active->bf_insns;
1315 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1316 error("Couldn't set active-filter in kernel: %m");
1321 #endif /* PPP_FILTER */
1323 /********************************************************************
1325 * get_idle_time - return how long the link has been idle.
1328 get_idle_time(u, ip)
1330 struct ppp_idle *ip;
1332 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1335 /********************************************************************
1337 * get_ppp_stats - return statistics for the link.
1340 get_ppp_stats(u, stats)
1342 struct pppd_stats *stats;
1344 struct ifpppstatsreq req;
1346 memset (&req, 0, sizeof (req));
1348 req.stats_ptr = (caddr_t) &req.stats;
1349 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1350 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1351 error("Couldn't get PPP statistics: %m");
1354 stats->bytes_in = req.stats.p.ppp_ibytes;
1355 stats->bytes_out = req.stats.p.ppp_obytes;
1356 stats->pkts_in = req.stats.p.ppp_ipackets;
1357 stats->pkts_out = req.stats.p.ppp_opackets;
1361 /********************************************************************
1363 * ccp_fatal_error - returns 1 if decompression was disabled as a
1364 * result of an error detected after decompression of a packet,
1365 * 0 otherwise. This is necessary because of patent nonsense.
1368 int ccp_fatal_error (int unit)
1372 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1373 error("Couldn't read compression error flags: %m");
1376 return flags & SC_DC_FERROR;
1379 /********************************************************************
1381 * path_to_procfs - find the path to the proc file system mount point
1383 static char proc_path[MAXPATHLEN];
1384 static int proc_path_len;
1386 static char *path_to_procfs(const char *tail)
1388 struct mntent *mntent;
1391 if (proc_path_len == 0) {
1392 /* Default the mount location of /proc */
1393 strlcpy (proc_path, "/proc", sizeof(proc_path));
1395 fp = fopen(_PATH_MOUNTED, "r");
1397 while ((mntent = getmntent(fp)) != NULL) {
1398 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1400 if (strcmp(mntent->mnt_type, "proc") == 0) {
1401 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1402 proc_path_len = strlen(proc_path);
1410 strlcpy(proc_path + proc_path_len, tail,
1411 sizeof(proc_path) - proc_path_len);
1416 * /proc/net/route parsing stuff.
1418 #define ROUTE_MAX_COLS 12
1419 FILE *route_fd = (FILE *) 0;
1420 static char route_buffer[512];
1421 static int route_dev_col, route_dest_col, route_gw_col;
1422 static int route_flags_col, route_mask_col;
1423 static int route_num_cols;
1425 static int open_route_table (void);
1426 static void close_route_table (void);
1427 static int read_route_table (struct rtentry *rt);
1429 /********************************************************************
1431 * close_route_table - close the interface to the route table
1434 static void close_route_table (void)
1436 if (route_fd != (FILE *) 0) {
1438 route_fd = (FILE *) 0;
1442 /********************************************************************
1444 * open_route_table - open the interface to the route table
1446 static char route_delims[] = " \t\n";
1448 static int open_route_table (void)
1452 close_route_table();
1454 path = path_to_procfs("/net/route");
1455 route_fd = fopen (path, "r");
1456 if (route_fd == NULL) {
1457 error("can't open routing table %s: %m", path);
1461 route_dev_col = 0; /* default to usual columns */
1464 route_flags_col = 3;
1468 /* parse header line */
1469 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1470 char *p = route_buffer, *q;
1472 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1474 if ((q = strtok(p, route_delims)) == 0)
1476 if (strcasecmp(q, "iface") == 0)
1477 route_dev_col = col;
1478 else if (strcasecmp(q, "destination") == 0)
1479 route_dest_col = col;
1480 else if (strcasecmp(q, "gateway") == 0)
1482 else if (strcasecmp(q, "flags") == 0)
1483 route_flags_col = col;
1484 else if (strcasecmp(q, "mask") == 0)
1485 route_mask_col = col;
1488 if (used && col >= route_num_cols)
1489 route_num_cols = col + 1;
1497 /********************************************************************
1499 * read_route_table - read the next entry from the route table
1502 static int read_route_table(struct rtentry *rt)
1504 char *cols[ROUTE_MAX_COLS], *p;
1507 memset (rt, '\0', sizeof (struct rtentry));
1509 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1513 for (col = 0; col < route_num_cols; ++col) {
1514 cols[col] = strtok(p, route_delims);
1515 if (cols[col] == NULL)
1516 return 0; /* didn't get enough columns */
1520 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1521 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1522 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1524 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1525 rt->rt_dev = cols[route_dev_col];
1530 /********************************************************************
1532 * defaultroute_exists - determine if there is a default route
1535 static int defaultroute_exists (struct rtentry *rt)
1539 if (!open_route_table())
1542 while (read_route_table(rt) != 0) {
1543 if ((rt->rt_flags & RTF_UP) == 0)
1546 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1548 if (SIN_ADDR(rt->rt_dst) == 0L) {
1554 close_route_table();
1559 * have_route_to - determine if the system has any route to
1560 * a given IP address. `addr' is in network byte order.
1561 * Return value is 1 if yes, 0 if no, -1 if don't know.
1562 * For demand mode to work properly, we have to ignore routes
1563 * through our own interface.
1565 int have_route_to(u_int32_t addr)
1570 if (!open_route_table())
1571 return -1; /* don't know */
1573 while (read_route_table(&rt)) {
1574 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1576 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1582 close_route_table();
1586 /********************************************************************
1588 * sifdefaultroute - assign a default route through the address given.
1591 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1595 if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1596 u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1598 if (old_gateway != gateway)
1599 error("not replacing existing default route to %s [%I]",
1600 rt.rt_dev, old_gateway);
1604 memset (&rt, '\0', sizeof (rt));
1605 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1606 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1610 if (kernel_version > KVERSION(2,1,0)) {
1611 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1612 SIN_ADDR(rt.rt_genmask) = 0L;
1615 SIN_ADDR(rt.rt_gateway) = gateway;
1617 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1618 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1619 if ( ! ok_error ( errno ))
1620 error("default route ioctl(SIOCADDRT): %m");
1624 default_route_gateway = gateway;
1628 /********************************************************************
1630 * cifdefaultroute - delete a default route through the address given.
1633 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1637 default_route_gateway = 0;
1639 memset (&rt, '\0', sizeof (rt));
1640 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1641 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1643 if (kernel_version > KVERSION(2,1,0)) {
1644 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1645 SIN_ADDR(rt.rt_genmask) = 0L;
1648 SIN_ADDR(rt.rt_gateway) = gateway;
1650 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1651 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1653 if ( ! ok_error ( errno ))
1654 error("default route ioctl(SIOCDELRT): %m");
1662 /********************************************************************
1664 * sifproxyarp - Make a proxy ARP entry for the peer.
1667 int sifproxyarp (int unit, u_int32_t his_adr)
1669 struct arpreq arpreq;
1672 if (has_proxy_arp == 0) {
1673 memset (&arpreq, '\0', sizeof(arpreq));
1675 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1676 SIN_ADDR(arpreq.arp_pa) = his_adr;
1677 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1679 * Get the hardware address of an interface on the same subnet
1680 * as our local address.
1682 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1683 sizeof(proxy_arp_dev))) {
1684 error("Cannot determine ethernet address for proxy ARP");
1687 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1689 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1690 if ( ! ok_error ( errno ))
1691 error("ioctl(SIOCSARP): %m");
1694 proxy_arp_addr = his_adr;
1698 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1699 if (forw_path != 0) {
1700 int fd = open(forw_path, O_WRONLY);
1702 if (write(fd, "1", 1) != 1)
1703 error("Couldn't enable IP forwarding: %m");
1713 /********************************************************************
1715 * cifproxyarp - Delete the proxy ARP entry for the peer.
1718 int cifproxyarp (int unit, u_int32_t his_adr)
1720 struct arpreq arpreq;
1722 if (has_proxy_arp) {
1724 memset (&arpreq, '\0', sizeof(arpreq));
1725 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1726 SIN_ADDR(arpreq.arp_pa) = his_adr;
1727 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1728 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1730 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1731 if ( ! ok_error ( errno ))
1732 warn("ioctl(SIOCDARP): %m");
1739 /********************************************************************
1741 * get_ether_addr - get the hardware address of an interface on the
1742 * the same subnet as ipaddr.
1745 static int get_ether_addr (u_int32_t ipaddr,
1746 struct sockaddr *hwaddr,
1747 char *name, int namelen)
1749 struct ifreq *ifr, *ifend;
1750 u_int32_t ina, mask;
1752 struct ifreq ifreq, bestifreq;
1754 struct ifreq ifs[MAX_IFS];
1756 u_int32_t bestmask=0;
1757 int found_interface = 0;
1759 ifc.ifc_len = sizeof(ifs);
1761 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1762 if ( ! ok_error ( errno ))
1763 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1768 * Scan through looking for an interface with an Internet
1769 * address on the same subnet as `ipaddr'.
1771 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1772 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1773 if (ifr->ifr_addr.sa_family == AF_INET) {
1774 ina = SIN_ADDR(ifr->ifr_addr);
1775 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1777 * Check that the interface is up, and not point-to-point
1780 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1783 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1786 * Get its netmask and check that it's on the right subnet.
1788 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1791 mask = SIN_ADDR(ifreq.ifr_addr);
1793 if (((ipaddr ^ ina) & mask) != 0)
1794 continue; /* no match */
1796 if (mask >= bestmask) {
1797 /* Compare using >= instead of > -- it is possible for
1798 an interface to have a netmask of 0.0.0.0 */
1799 found_interface = 1;
1806 if (!found_interface) return 0;
1808 strlcpy(name, bestifreq.ifr_name, namelen);
1810 /* trim off the :1 in eth0:1 */
1811 aliasp = strchr(name, ':');
1815 info("found interface %s for proxy arp", name);
1817 * Now get the hardware address.
1819 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1820 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1821 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1826 &bestifreq.ifr_hwaddr,
1827 sizeof (struct sockaddr));
1833 * get_if_hwaddr - get the hardware address for the specified
1834 * network interface device.
1837 get_if_hwaddr(u_char *addr, char *name)
1842 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1845 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1846 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1847 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1850 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1855 * get_first_ethernet - return the name of the first ethernet-style
1856 * interface on this system.
1859 get_first_ethernet()
1864 /********************************************************************
1866 * Return user specified netmask, modified by any mask we might determine
1867 * for address `addr' (in network byte order).
1868 * Here we scan through the system's list of interfaces, looking for
1869 * any non-point-to-point interfaces which might appear to be on the same
1870 * network as `addr'. If we find any, we OR in their netmask to the
1871 * user-specified netmask.
1874 u_int32_t GetMask (u_int32_t addr)
1876 u_int32_t mask, nmask, ina;
1877 struct ifreq *ifr, *ifend, ifreq;
1879 struct ifreq ifs[MAX_IFS];
1883 if (IN_CLASSA(addr)) /* determine network mask for address class */
1884 nmask = IN_CLASSA_NET;
1885 else if (IN_CLASSB(addr))
1886 nmask = IN_CLASSB_NET;
1888 nmask = IN_CLASSC_NET;
1890 /* class D nets are disallowed by bad_ip_adrs */
1891 mask = netmask | htonl(nmask);
1893 * Scan through the system's network interfaces.
1895 ifc.ifc_len = sizeof(ifs);
1897 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1898 if ( ! ok_error ( errno ))
1899 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1903 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1904 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1906 * Check the interface's internet address.
1908 if (ifr->ifr_addr.sa_family != AF_INET)
1910 ina = SIN_ADDR(ifr->ifr_addr);
1911 if (((ntohl(ina) ^ addr) & nmask) != 0)
1914 * Check that the interface is up, and not point-to-point nor loopback.
1916 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1917 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1920 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1923 * Get its netmask and OR it into our mask.
1925 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1927 mask |= SIN_ADDR(ifreq.ifr_addr);
1933 /********************************************************************
1935 * Internal routine to decode the version.modification.patch level
1938 static void decode_version (char *buf, int *version,
1939 int *modification, int *patch)
1943 *version = (int) strtoul (buf, &endp, 10);
1947 if (endp != buf && *endp == '.') {
1949 *modification = (int) strtoul (buf, &endp, 10);
1950 if (endp != buf && *endp == '.') {
1952 *patch = (int) strtoul (buf, &buf, 10);
1957 /********************************************************************
1959 * Procedure to determine if the PPP line discipline is registered.
1963 ppp_registered(void)
1971 * We used to open the serial device and set it to the ppp line
1972 * discipline here, in order to create a ppp unit. But that is
1973 * not a good idea - the user might have specified a device that
1974 * they can't open (permission, or maybe it doesn't really exist).
1975 * So we grab a pty master/slave pair and use that.
1977 if (!get_pty(&mfd, &local_fd, slave, 0)) {
1978 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1983 * Try to put the device into the PPP discipline.
1985 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1986 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
1995 /********************************************************************
1997 * ppp_available - check whether the system has any ppp interfaces
1998 * (in fact we check whether we can do an ioctl on ppp0).
2001 int ppp_available(void)
2006 int my_version, my_modification, my_patch;
2007 int osmaj, osmin, ospatch;
2010 "This system lacks kernel support for PPP. This could be because\n"
2011 "the PPP kernel module could not be loaded, or because PPP was not\n"
2012 "included in the kernel configuration. If PPP was included as a\n"
2013 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2014 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2015 "See README.linux file in the ppp distribution for more details.\n";
2017 /* get the kernel version now, since we are called before sys_init */
2019 osmaj = osmin = ospatch = 0;
2020 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2021 kernel_version = KVERSION(osmaj, osmin, ospatch);
2023 fd = open("/dev/ppp", O_RDWR);
2025 if (fd < 0 && errno == ENOENT) {
2026 /* try making it and see if that helps. */
2027 if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR,
2028 makedev(108, 0)) >= 0) {
2029 fd = open("/dev/ppp", O_RDWR);
2031 info("Created /dev/ppp device node");
2033 unlink("/dev/ppp"); /* didn't work, undo the mknod */
2034 } else if (errno == EEXIST) {
2035 fd = open("/dev/ppp", O_RDWR);
2040 new_style_driver = 1;
2042 /* XXX should get from driver */
2044 driver_modification = 4;
2049 if (kernel_version >= KVERSION(2,3,13)) {
2050 if (errno == ENOENT)
2052 "pppd is unable to open the /dev/ppp device.\n"
2053 "You need to create the /dev/ppp device node by\n"
2054 "executing the following command as root:\n"
2055 " mknod /dev/ppp c 108 0\n";
2060 * Open a socket for doing the ioctl operations.
2062 s = socket(AF_INET, SOCK_DGRAM, 0);
2066 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2067 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2069 * If the device did not exist then attempt to create one by putting the
2070 * current tty into the PPP discipline. If this works then obtain the
2071 * flags for the device again.
2074 if (ppp_registered()) {
2075 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2076 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2080 * Ensure that the hardware address is for PPP and not something else
2083 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2085 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2089 * This is the PPP device. Validate the version of the driver at this
2090 * point to ensure that this program will work with the driver.
2093 char abBuffer [1024];
2095 ifr.ifr_data = abBuffer;
2096 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2098 error("Couldn't read driver version: %m");
2100 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2103 decode_version(abBuffer,
2105 &driver_modification,
2108 * Validate the version of the driver against the version that we used.
2110 decode_version(VERSION,
2115 /* The version numbers must match */
2116 if (driver_version != my_version)
2119 /* The modification levels must be legal */
2120 if (driver_modification < 3) {
2121 if (driver_modification >= 2) {
2122 /* we can cope with 2.2.0 and above */
2131 slprintf(route_buffer, sizeof(route_buffer),
2132 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2133 driver_version, driver_modification, driver_patch);
2135 no_ppp_msg = route_buffer;
2142 /********************************************************************
2144 * Update the wtmp file with the appropriate user name and tty device.
2147 void logwtmp (const char *line, const char *name, const char *host)
2149 struct utmp ut, *utp;
2150 pid_t mypid = getpid();
2156 * Update the signon database for users.
2157 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2159 utmpname(_PATH_UTMP);
2161 while ((utp = getutent()) && (utp->ut_pid != mypid))
2165 memcpy(&ut, utp, sizeof(ut));
2167 /* some gettys/telnetds don't initialize utmp... */
2168 memset(&ut, 0, sizeof(ut));
2170 if (ut.ut_id[0] == 0)
2171 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2173 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2174 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2178 ut.ut_type = USER_PROCESS;
2181 /* Insert the host name if one is supplied */
2183 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2185 /* Insert the IP address of the remote system if IP is enabled */
2186 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2187 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2188 sizeof(ut.ut_addr));
2190 /* CL: Makes sure that the logout works */
2191 if (*host == 0 && *name==0)
2197 * Update the wtmp file.
2200 updwtmp(_PATH_WTMP, &ut);
2202 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2204 flock(wtmp, LOCK_EX);
2206 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2207 warn("error writing %s: %m", _PATH_WTMP);
2209 flock(wtmp, LOCK_UN);
2217 /********************************************************************
2219 * sifvjcomp - config tcp header compression
2222 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2227 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)
2228 error("Couldn't set up TCP header compression: %m");
2232 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2233 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2238 /********************************************************************
2240 * sifup - Config the interface up and enable IP packets to pass.
2247 memset (&ifr, '\0', sizeof (ifr));
2248 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2249 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2250 if (! ok_error (errno))
2251 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2255 ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2256 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2257 if (! ok_error (errno))
2258 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2266 /********************************************************************
2268 * sifdown - Disable the indicated protocol and config the interface
2269 * down if there are no remaining protocols.
2276 if (if_is_up && --if_is_up > 0)
2279 memset (&ifr, '\0', sizeof (ifr));
2280 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2281 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2282 if (! ok_error (errno))
2283 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2287 ifr.ifr_flags &= ~IFF_UP;
2288 ifr.ifr_flags |= IFF_POINTOPOINT;
2289 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2290 if (! ok_error (errno))
2291 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2297 /********************************************************************
2299 * sifaddr - Config the interface IP addresses and netmask.
2302 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2308 memset (&ifr, '\0', sizeof (ifr));
2309 memset (&rt, '\0', sizeof (rt));
2311 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2312 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2313 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2315 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2317 * Set our IP address
2319 SIN_ADDR(ifr.ifr_addr) = our_adr;
2320 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2321 if (errno != EEXIST) {
2322 if (! ok_error (errno))
2323 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2326 warn("ioctl(SIOCSIFADDR): Address already exists");
2331 * Set the gateway address
2333 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2334 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2335 if (! ok_error (errno))
2336 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2341 * For recent kernels, force the netmask to 255.255.255.255.
2343 if (kernel_version >= KVERSION(2,1,16))
2345 if (net_mask != 0) {
2346 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2347 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2348 if (! ok_error (errno))
2349 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2354 * Add the device route
2356 if (kernel_version < KVERSION(2,1,16)) {
2357 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2358 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2361 SIN_ADDR(rt.rt_gateway) = 0L;
2362 SIN_ADDR(rt.rt_dst) = his_adr;
2363 rt.rt_flags = RTF_UP | RTF_HOST;
2365 if (kernel_version > KVERSION(2,1,0)) {
2366 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2367 SIN_ADDR(rt.rt_genmask) = -1L;
2370 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2371 if (! ok_error (errno))
2372 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2377 /* set ip_dynaddr in demand mode if address changes */
2378 if (demand && tune_kernel && !dynaddr_set
2379 && our_old_addr && our_old_addr != our_adr) {
2380 /* set ip_dynaddr if possible */
2384 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2385 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2386 if (write(fd, "1", 1) != 1)
2387 error("Couldn't enable dynamic IP addressing: %m");
2390 dynaddr_set = 1; /* only 1 attempt */
2397 /********************************************************************
2399 * cifaddr - Clear the interface IP addresses, and delete routes
2400 * through the interface if possible.
2403 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2407 if (kernel_version < KVERSION(2,1,16)) {
2409 * Delete the route through the device
2412 memset (&rt, '\0', sizeof (rt));
2414 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2415 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2418 SIN_ADDR(rt.rt_gateway) = 0;
2419 SIN_ADDR(rt.rt_dst) = his_adr;
2420 rt.rt_flags = RTF_UP | RTF_HOST;
2422 if (kernel_version > KVERSION(2,1,0)) {
2423 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2424 SIN_ADDR(rt.rt_genmask) = -1L;
2427 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2428 if (still_ppp() && ! ok_error (errno))
2429 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2434 /* This way it is possible to have an IPX-only or IPv6-only interface */
2435 memset(&ifr, 0, sizeof(ifr));
2436 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2437 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2439 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2440 if (! ok_error (errno)) {
2441 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2446 our_old_addr = our_adr;
2452 /********************************************************************
2454 * sif6addr - Config the interface with an IPv6 link-local address
2456 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2458 struct in6_ifreq ifr6;
2460 struct in6_rtmsg rt6;
2464 error("IPv6 socket creation failed: %m");
2467 memset(&ifr, 0, sizeof (ifr));
2468 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2469 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2470 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2474 /* Local interface */
2475 memset(&ifr6, 0, sizeof(ifr6));
2476 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2477 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2478 ifr6.ifr6_prefixlen = 10;
2480 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2481 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2485 /* Route to remote host */
2486 memset(&rt6, 0, sizeof(rt6));
2487 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2488 rt6.rtmsg_flags = RTF_UP;
2489 rt6.rtmsg_dst_len = 10;
2490 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2491 rt6.rtmsg_metric = 1;
2493 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2494 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2502 /********************************************************************
2504 * cif6addr - Remove IPv6 address from interface
2506 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2509 struct in6_ifreq ifr6;
2513 error("IPv6 socket creation failed: %m");
2516 memset(&ifr, 0, sizeof(ifr));
2517 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2518 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2519 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2523 memset(&ifr6, 0, sizeof(ifr6));
2524 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2525 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2526 ifr6.ifr6_prefixlen = 10;
2528 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2529 if (errno != EADDRNOTAVAIL) {
2530 if (! ok_error (errno))
2531 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2534 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2543 * get_pty - get a pty master/slave pair and chown the slave side
2544 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2547 get_pty(master_fdp, slave_fdp, slave_name, uid)
2553 int i, mfd, sfd = -1;
2555 struct termios tios;
2559 * Try the unix98 way first.
2561 mfd = open("/dev/ptmx", O_RDWR);
2564 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2565 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2566 chmod(pty_name, S_IRUSR | S_IWUSR);
2569 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2570 warn("Couldn't unlock pty slave %s: %m", pty_name);
2572 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2573 warn("Couldn't open pty slave %s: %m", pty_name);
2576 #endif /* TIOCGPTN */
2579 /* the old way - scan through the pty name space */
2580 for (i = 0; i < 64; ++i) {
2581 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2582 'p' + i / 16, i % 16);
2583 mfd = open(pty_name, O_RDWR, 0);
2586 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2588 fchown(sfd, uid, -1);
2589 fchmod(sfd, S_IRUSR | S_IWUSR);
2600 strlcpy(slave_name, pty_name, 16);
2603 if (tcgetattr(sfd, &tios) == 0) {
2604 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2605 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2606 tios.c_iflag = IGNPAR;
2609 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2610 warn("couldn't set attributes on pty: %m");
2612 warn("couldn't get attributes on pty: %m");
2617 /********************************************************************
2619 * open_loopback - open the device we use for getting packets
2620 * in demand mode. Under Linux, we use a pty master/slave pair.
2623 open_ppp_loopback(void)
2628 if (new_style_driver) {
2629 /* allocate ourselves a ppp unit */
2630 if (make_ppp_unit() < 0)
2632 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2633 set_kdebugflag(kdebugflag);
2638 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2639 fatal("No free pty for loopback");
2641 set_ppp_fd(slave_fd);
2643 flags = fcntl(master_fd, F_GETFL);
2645 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2646 warn("couldn't set master loopback to nonblock: %m");
2648 flags = fcntl(ppp_fd, F_GETFL);
2650 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2651 warn("couldn't set slave loopback to nonblock: %m");
2653 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2654 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2656 * Find out which interface we were given.
2658 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2659 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2661 * Enable debug in the driver if requested.
2663 set_kdebugflag (kdebugflag);
2668 /********************************************************************
2670 * sifnpmode - Set the mode for handling packets for a given NP.
2674 sifnpmode(u, proto, mode)
2681 npi.protocol = proto;
2683 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2684 if (! ok_error (errno))
2685 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2692 /********************************************************************
2694 * sipxfaddr - Config the interface IPX networknumber
2697 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2704 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2706 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2708 if (! ok_error (errno))
2709 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2713 memset (&ifr, '\0', sizeof (ifr));
2714 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2716 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2717 sipx->sipx_family = AF_IPX;
2718 sipx->sipx_port = 0;
2719 sipx->sipx_network = htonl (network);
2720 sipx->sipx_type = IPX_FRAME_ETHERII;
2721 sipx->sipx_action = IPX_CRTITF;
2723 * Set the IPX device
2725 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2727 if (errno != EEXIST) {
2728 if (! ok_error (errno))
2729 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2732 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2741 /********************************************************************
2743 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2744 * are removed and the device is no longer able to pass IPX
2748 int cipxfaddr (int unit)
2755 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2757 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2759 if (! ok_error (errno))
2760 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2764 memset (&ifr, '\0', sizeof (ifr));
2765 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2767 sipx->sipx_type = IPX_FRAME_ETHERII;
2768 sipx->sipx_action = IPX_DLTITF;
2769 sipx->sipx_family = AF_IPX;
2771 * Set the IPX device
2773 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2774 if (! ok_error (errno))
2775 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2785 * Use the hostname as part of the random number seed.
2794 for (p = hostname; *p != 0; ++p)
2799 /********************************************************************
2801 * sys_check_options - check the options that the user specified
2805 sys_check_options(void)
2809 * Disable the IPX protocol if the support is not present in the kernel.
2813 if (ipxcp_protent.enabled_flag) {
2814 struct stat stat_buf;
2815 if ((path = path_to_procfs("/net/ipx/interface")) == 0
2816 || (path = path_to_procfs("/net/ipx_interface")) == 0
2817 || lstat(path, &stat_buf) < 0) {
2818 error("IPX support is not present in the kernel\n");
2819 ipxcp_protent.enabled_flag = 0;
2823 if (demand && driver_is_old) {
2824 option_error("demand dialling is not supported by kernel driver "
2825 "version %d.%d.%d", driver_version, driver_modification,
2829 if (multilink && !new_style_driver) {
2830 warn("Warning: multilink is not supported by the kernel driver");
2838 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2840 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2841 * that the system has a properly configured Ethernet interface for this
2842 * function to return non-zero.
2845 ether_to_eui64(eui64_t *p_eui64)
2849 const unsigned char *ptr;
2851 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2854 warn("could not open IPv6 socket");
2858 strcpy(ifr.ifr_name, "eth0");
2859 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2862 warn("could not obtain hardware address for eth0");
2868 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2870 ptr = ifr.ifr_hwaddr.sa_data;
2871 p_eui64->e8[0] = ptr[0] | 0x02;
2872 p_eui64->e8[1] = ptr[1];
2873 p_eui64->e8[2] = ptr[2];
2874 p_eui64->e8[3] = 0xFF;
2875 p_eui64->e8[4] = 0xFE;
2876 p_eui64->e8[5] = ptr[3];
2877 p_eui64->e8[6] = ptr[4];
2878 p_eui64->e8[7] = ptr[5];