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");
647 if (x == 0 && req_ifname[0] != '\0') {
649 char t[MAXIFNAMELEN];
650 memset(&ifr, 0, sizeof(struct ifreq));
651 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
652 strncpy(ifr.ifr_name, t, IF_NAMESIZE);
653 strncpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE);
654 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
656 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
658 info("Renamed interface %s to %s", t, req_ifname);
665 * cfg_bundle - configure the existing bundle.
666 * Used in demand mode.
668 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
670 if (!new_style_driver)
673 /* set the mrru, mtu and flags */
674 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
675 error("Couldn't set MRRU: %m");
677 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
678 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
679 | (mrru? SC_MULTILINK: 0)));
681 /* connect up the channel */
682 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
683 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
688 * make_new_bundle - create a new PPP unit (i.e. a bundle)
689 * and connect our channel to it. This should only get called
690 * if `multilink' was set at the time establish_ppp was called.
691 * In demand mode this uses our existing bundle instead of making
694 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
696 if (!new_style_driver)
699 /* make us a ppp unit */
700 if (make_ppp_unit() < 0)
703 /* set the mrru and flags */
704 cfg_bundle(mrru, mtru, rssn, tssn);
708 * bundle_attach - attach our link to a given PPP unit.
709 * We assume the unit is controlled by another pppd.
711 int bundle_attach(int ifnum)
715 if (!new_style_driver)
718 master_fd = open("/dev/ppp", O_RDWR);
720 fatal("Couldn't open /dev/ppp: %m");
721 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
722 if (errno == ENXIO) {
724 return 0; /* doesn't still exist */
726 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
728 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
729 fatal("Couldn't connect to interface unit %d: %m", ifnum);
730 modify_flags(master_fd, 0, SC_MULTILINK);
738 * destroy_bundle - tell the driver to destroy our bundle.
740 void destroy_bundle(void)
742 if (ppp_dev_fd >= 0) {
744 remove_fd(ppp_dev_fd);
749 /********************************************************************
751 * clean_check - Fetch the flags for the device and generate
752 * appropriate error messages.
754 void clean_check(void)
760 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
762 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
764 s = "all had bit 7 set to 1";
768 s = "all had bit 7 set to 0";
772 s = "all had odd parity";
776 s = "all had even parity";
781 warn("Receive serial link is not 8-bit clean:");
782 warn("Problem: %s", s);
790 * List of valid speeds.
794 int speed_int, speed_val;
875 { 1000000, B1000000 },
878 { 1152000, B1152000 },
881 { 1500000, B1500000 },
884 { 2000000, B2000000 },
887 { 2500000, B2500000 },
890 { 3000000, B3000000 },
893 { 3500000, B3500000 },
896 { 4000000, B4000000 },
901 /********************************************************************
903 * Translate from bits/second to a speed_t.
906 static int translate_speed (int bps)
908 struct speed *speedp;
911 for (speedp = speeds; speedp->speed_int; speedp++) {
912 if (bps == speedp->speed_int)
913 return speedp->speed_val;
915 warn("speed %d not supported", bps);
920 /********************************************************************
922 * Translate from a speed_t to bits/second.
925 static int baud_rate_of (int speed)
927 struct speed *speedp;
930 for (speedp = speeds; speedp->speed_int; speedp++) {
931 if (speed == speedp->speed_val)
932 return speedp->speed_int;
938 /********************************************************************
940 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
941 * at the requested speed, etc. If `local' is true, set CLOCAL
942 * regardless of whether the modem option was specified.
945 void set_up_tty(int tty_fd, int local)
951 if (tcgetattr(tty_fd, &tios) < 0) {
952 if (!ok_error(errno))
953 fatal("tcgetattr: %m (line %d)", __LINE__);
960 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
961 tios.c_cflag |= CS8 | CREAD | HUPCL;
963 tios.c_iflag = IGNBRK | IGNPAR;
967 tios.c_cc[VTIME] = 0;
970 tios.c_cflag ^= (CLOCAL | HUPCL);
974 tios.c_cflag |= CRTSCTS;
978 tios.c_iflag |= IXON | IXOFF;
979 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
980 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
984 tios.c_cflag &= ~CRTSCTS;
992 tios.c_cflag |= CSTOPB;
994 speed = translate_speed(inspeed);
996 cfsetospeed (&tios, speed);
997 cfsetispeed (&tios, speed);
1000 * We can't proceed if the serial port speed is B0,
1001 * since that implies that the serial port is disabled.
1004 speed = cfgetospeed(&tios);
1006 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1009 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1011 fatal("tcsetattr: %m (line %d)", __LINE__);
1013 baud_rate = baud_rate_of(speed);
1017 /********************************************************************
1019 * setdtr - control the DTR line on the serial port.
1020 * This is called from die(), so it shouldn't call die().
1023 void setdtr (int tty_fd, int on)
1025 int modembits = TIOCM_DTR;
1027 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1030 /********************************************************************
1032 * restore_tty - restore the terminal to the saved settings.
1035 void restore_tty (int tty_fd)
1040 * Turn off echoing, because otherwise we can get into
1041 * a loop with the tty and the modem echoing to each other.
1042 * We presume we are the sole user of this tty device, so
1043 * when we close it, it will revert to its defaults anyway.
1045 if (!default_device)
1046 inittermios.c_lflag &= ~(ECHO | ECHONL);
1048 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1049 if (! ok_error (errno))
1050 warn("tcsetattr: %m (line %d)", __LINE__);
1055 /********************************************************************
1057 * output - Output PPP packet.
1060 void output (int unit, unsigned char *p, int len)
1065 dump_packet("sent", p, len);
1066 if (snoop_send_hook) snoop_send_hook(p, len);
1068 if (len < PPP_HDRLEN)
1070 if (new_style_driver) {
1073 proto = (p[0] << 8) + p[1];
1074 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1077 if (write(fd, p, len) < 0) {
1078 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1079 || errno == ENXIO || errno == EIO || errno == EINTR)
1080 warn("write: warning: %m (%d)", errno);
1082 error("write: %m (%d)", errno);
1086 /********************************************************************
1088 * wait_input - wait until there is data available,
1089 * for the length of time specified by *timo (indefinite
1093 void wait_input(struct timeval *timo)
1100 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1101 if (n < 0 && errno != EINTR)
1102 fatal("select: %m");
1106 * add_fd - add an fd to the set that wait_input waits for.
1110 if (fd >= FD_SETSIZE)
1111 fatal("internal error: file descriptor too large (%d)", fd);
1112 FD_SET(fd, &in_fds);
1118 * remove_fd - remove an fd from the set that wait_input waits for.
1120 void remove_fd(int fd)
1122 FD_CLR(fd, &in_fds);
1126 /********************************************************************
1128 * read_packet - get a PPP packet from the serial device.
1131 int read_packet (unsigned char *buf)
1135 len = PPP_MRU + PPP_HDRLEN;
1136 if (new_style_driver) {
1137 *buf++ = PPP_ALLSTATIONS;
1143 nr = read(ppp_fd, buf, len);
1144 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1145 && errno != EIO && errno != EINTR)
1147 if (nr < 0 && errno == ENXIO)
1150 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1151 /* N.B. we read ppp_fd first since LCP packets come in there. */
1152 nr = read(ppp_dev_fd, buf, len);
1153 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1154 && errno != EIO && errno != EINTR)
1155 error("read /dev/ppp: %m");
1156 if (nr < 0 && errno == ENXIO)
1158 if (nr == 0 && doing_multilink) {
1159 remove_fd(ppp_dev_fd);
1163 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1165 return (new_style_driver && nr > 0)? nr+2: nr;
1168 /********************************************************************
1170 * get_loop_output - get outgoing packets from the ppp device,
1171 * and detect when we want to bring the real link up.
1172 * Return value is 1 if we need to bring up the link, 0 otherwise.
1175 get_loop_output(void)
1180 if (new_style_driver) {
1181 while ((n = read_packet(inpacket_buf)) > 0)
1182 if (loop_frame(inpacket_buf, n))
1187 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1188 if (loop_chars(inbuf, n))
1192 fatal("eof on loopback");
1194 if (errno != EWOULDBLOCK && errno != EAGAIN)
1195 fatal("read from loopback: %m(%d)", errno);
1201 * netif_set_mtu - set the MTU on the PPP network interface.
1204 netif_set_mtu(int unit, int mtu)
1208 memset (&ifr, '\0', sizeof (ifr));
1209 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1212 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1213 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1217 * netif_get_mtu - get the MTU on the PPP network interface.
1220 netif_get_mtu(int unit)
1224 memset (&ifr, '\0', sizeof (ifr));
1225 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1227 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1228 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1234 /********************************************************************
1236 * tty_send_config - configure the transmit characteristics of
1237 * the ppp interface.
1240 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1247 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1248 if (errno != EIO && errno != ENOTTY)
1249 error("Couldn't set transmit async character map: %m");
1254 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1255 | (sync_serial? SC_SYNC: 0);
1256 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1259 /********************************************************************
1261 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1264 void tty_set_xaccm (ext_accm accm)
1268 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1269 if ( ! ok_error (errno))
1270 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1274 /********************************************************************
1276 * tty_recv_config - configure the receive-side characteristics of
1277 * the ppp interface.
1280 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1283 * If we were called because the link has gone down then there is nothing
1284 * which may be done. Just return without incident.
1289 * Set the receiver parameters
1291 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1292 if (errno != EIO && errno != ENOTTY)
1293 error("Couldn't set channel receive MRU: %m");
1295 if (new_style_driver && ppp_dev_fd >= 0
1296 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1297 error("Couldn't set MRU in generic PPP layer: %m");
1299 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1300 if (errno != EIO && errno != ENOTTY)
1301 error("Couldn't set channel receive asyncmap: %m");
1305 /********************************************************************
1307 * ccp_test - ask kernel whether a given compression method
1308 * is acceptable for use.
1312 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1314 struct ppp_option_data data;
1316 memset (&data, '\0', sizeof (data));
1318 data.length = opt_len;
1319 data.transmit = for_transmit;
1321 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1324 return (errno == ENOBUFS)? 0: -1;
1327 /********************************************************************
1329 * ccp_flags_set - inform kernel about the current state of CCP.
1332 void ccp_flags_set (int unit, int isopen, int isup)
1336 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1337 if (still_ppp() && ppp_dev_fd >= 0)
1338 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1343 * set_filters - set the active and pass filters in the kernel driver.
1345 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1347 struct sock_fprog fp;
1349 fp.len = pass->bf_len;
1350 fp.filter = (struct sock_filter *) pass->bf_insns;
1351 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1352 if (errno == ENOTTY)
1353 warn("kernel does not support PPP filtering");
1355 error("Couldn't set pass-filter in kernel: %m");
1358 fp.len = active->bf_len;
1359 fp.filter = (struct sock_filter *) active->bf_insns;
1360 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1361 error("Couldn't set active-filter in kernel: %m");
1366 #endif /* PPP_FILTER */
1368 /********************************************************************
1370 * get_idle_time - return how long the link has been idle.
1373 get_idle_time(u, ip)
1375 struct ppp_idle *ip;
1377 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1380 /********************************************************************
1382 * get_ppp_stats - return statistics for the link.
1385 get_ppp_stats(u, stats)
1387 struct pppd_stats *stats;
1389 struct ifpppstatsreq req;
1391 memset (&req, 0, sizeof (req));
1393 req.stats_ptr = (caddr_t) &req.stats;
1394 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1395 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1396 error("Couldn't get PPP statistics: %m");
1399 stats->bytes_in = req.stats.p.ppp_ibytes;
1400 stats->bytes_out = req.stats.p.ppp_obytes;
1401 stats->pkts_in = req.stats.p.ppp_ipackets;
1402 stats->pkts_out = req.stats.p.ppp_opackets;
1406 /********************************************************************
1408 * ccp_fatal_error - returns 1 if decompression was disabled as a
1409 * result of an error detected after decompression of a packet,
1410 * 0 otherwise. This is necessary because of patent nonsense.
1413 int ccp_fatal_error (int unit)
1417 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1418 error("Couldn't read compression error flags: %m");
1421 return flags & SC_DC_FERROR;
1424 /********************************************************************
1426 * path_to_procfs - find the path to the proc file system mount point
1428 static char proc_path[MAXPATHLEN];
1429 static int proc_path_len;
1431 static char *path_to_procfs(const char *tail)
1433 struct mntent *mntent;
1436 if (proc_path_len == 0) {
1437 /* Default the mount location of /proc */
1438 strlcpy (proc_path, "/proc", sizeof(proc_path));
1440 fp = fopen(MOUNTED, "r");
1442 while ((mntent = getmntent(fp)) != NULL) {
1443 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1445 if (strcmp(mntent->mnt_type, "proc") == 0) {
1446 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1447 proc_path_len = strlen(proc_path);
1455 strlcpy(proc_path + proc_path_len, tail,
1456 sizeof(proc_path) - proc_path_len);
1461 * /proc/net/route parsing stuff.
1463 #define ROUTE_MAX_COLS 12
1464 FILE *route_fd = (FILE *) 0;
1465 static char route_buffer[512];
1466 static int route_dev_col, route_dest_col, route_gw_col;
1467 static int route_flags_col, route_metric_col, route_mask_col;
1468 static int route_num_cols;
1470 static int open_route_table (void);
1471 static void close_route_table (void);
1472 static int read_route_table (struct rtentry *rt);
1474 /********************************************************************
1476 * close_route_table - close the interface to the route table
1479 static void close_route_table (void)
1481 if (route_fd != (FILE *) 0) {
1483 route_fd = (FILE *) 0;
1487 /********************************************************************
1489 * open_route_table - open the interface to the route table
1491 static char route_delims[] = " \t\n";
1493 static int open_route_table (void)
1497 close_route_table();
1499 path = path_to_procfs("/net/route");
1500 route_fd = fopen (path, "r");
1501 if (route_fd == NULL) {
1502 error("can't open routing table %s: %m", path);
1506 route_dev_col = 0; /* default to usual columns */
1509 route_flags_col = 3;
1510 route_metric_col = 6;
1514 /* parse header line */
1515 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1516 char *p = route_buffer, *q;
1518 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1520 if ((q = strtok(p, route_delims)) == 0)
1522 if (strcasecmp(q, "iface") == 0)
1523 route_dev_col = col;
1524 else if (strcasecmp(q, "destination") == 0)
1525 route_dest_col = col;
1526 else if (strcasecmp(q, "gateway") == 0)
1528 else if (strcasecmp(q, "flags") == 0)
1529 route_flags_col = col;
1530 else if (strcasecmp(q, "mask") == 0)
1531 route_mask_col = col;
1534 if (used && col >= route_num_cols)
1535 route_num_cols = col + 1;
1543 /********************************************************************
1545 * read_route_table - read the next entry from the route table
1548 static int read_route_table(struct rtentry *rt)
1550 char *cols[ROUTE_MAX_COLS], *p;
1553 memset (rt, '\0', sizeof (struct rtentry));
1555 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1559 for (col = 0; col < route_num_cols; ++col) {
1560 cols[col] = strtok(p, route_delims);
1561 if (cols[col] == NULL)
1562 return 0; /* didn't get enough columns */
1566 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1567 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1568 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1570 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1571 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
1572 rt->rt_dev = cols[route_dev_col];
1577 /********************************************************************
1579 * defaultroute_exists - determine if there is a default route
1580 * with the given metric (or negative for any)
1583 static int defaultroute_exists (struct rtentry *rt, int metric)
1587 if (!open_route_table())
1590 while (read_route_table(rt) != 0) {
1591 if ((rt->rt_flags & RTF_UP) == 0)
1594 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1596 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1597 || rt->rt_metric == metric)) {
1603 close_route_table();
1608 * have_route_to - determine if the system has any route to
1609 * a given IP address. `addr' is in network byte order.
1610 * Return value is 1 if yes, 0 if no, -1 if don't know.
1611 * For demand mode to work properly, we have to ignore routes
1612 * through our own interface.
1614 int have_route_to(u_int32_t addr)
1619 if (!open_route_table())
1620 return -1; /* don't know */
1622 while (read_route_table(&rt)) {
1623 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1625 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1631 close_route_table();
1635 /********************************************************************
1637 * sifdefaultroute - assign a default route through the address given.
1640 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1644 if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) {
1645 if (rt.rt_flags & RTF_GATEWAY)
1646 error("not replacing existing default route via %I with metric %d",
1647 SIN_ADDR(rt.rt_gateway), dfl_route_metric);
1649 error("not replacing existing default route through %s with metric %d",
1650 rt.rt_dev, dfl_route_metric);
1654 memset (&rt, 0, sizeof (rt));
1655 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1658 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1660 if (kernel_version > KVERSION(2,1,0)) {
1661 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1662 SIN_ADDR(rt.rt_genmask) = 0L;
1665 rt.rt_flags = RTF_UP;
1666 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1667 if ( ! ok_error ( errno ))
1668 error("default route ioctl(SIOCADDRT): %m");
1672 have_default_route = 1;
1676 /********************************************************************
1678 * cifdefaultroute - delete a default route through the address given.
1681 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1685 have_default_route = 0;
1687 memset (&rt, '\0', sizeof (rt));
1688 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1689 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1694 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1696 if (kernel_version > KVERSION(2,1,0)) {
1697 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1698 SIN_ADDR(rt.rt_genmask) = 0L;
1701 rt.rt_flags = RTF_UP;
1702 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1704 if ( ! ok_error ( errno ))
1705 error("default route ioctl(SIOCDELRT): %m");
1713 /********************************************************************
1715 * sifproxyarp - Make a proxy ARP entry for the peer.
1718 int sifproxyarp (int unit, u_int32_t his_adr)
1720 struct arpreq arpreq;
1723 if (has_proxy_arp == 0) {
1724 memset (&arpreq, '\0', sizeof(arpreq));
1726 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1727 SIN_ADDR(arpreq.arp_pa) = his_adr;
1728 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1730 * Get the hardware address of an interface on the same subnet
1731 * as our local address.
1733 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1734 sizeof(proxy_arp_dev))) {
1735 error("Cannot determine ethernet address for proxy ARP");
1738 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1740 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1741 if ( ! ok_error ( errno ))
1742 error("ioctl(SIOCSARP): %m");
1745 proxy_arp_addr = his_adr;
1749 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1750 if (forw_path != 0) {
1751 int fd = open(forw_path, O_WRONLY);
1753 if (write(fd, "1", 1) != 1)
1754 error("Couldn't enable IP forwarding: %m");
1764 /********************************************************************
1766 * cifproxyarp - Delete the proxy ARP entry for the peer.
1769 int cifproxyarp (int unit, u_int32_t his_adr)
1771 struct arpreq arpreq;
1773 if (has_proxy_arp) {
1775 memset (&arpreq, '\0', sizeof(arpreq));
1776 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1777 SIN_ADDR(arpreq.arp_pa) = his_adr;
1778 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1779 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1781 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1782 if ( ! ok_error ( errno ))
1783 warn("ioctl(SIOCDARP): %m");
1790 /********************************************************************
1792 * get_ether_addr - get the hardware address of an interface on the
1793 * the same subnet as ipaddr.
1796 static int get_ether_addr (u_int32_t ipaddr,
1797 struct sockaddr *hwaddr,
1798 char *name, int namelen)
1800 struct ifreq *ifr, *ifend;
1801 u_int32_t ina, mask;
1803 struct ifreq ifreq, bestifreq;
1805 struct ifreq ifs[MAX_IFS];
1807 u_int32_t bestmask=0;
1808 int found_interface = 0;
1810 ifc.ifc_len = sizeof(ifs);
1812 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1813 if ( ! ok_error ( errno ))
1814 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1819 * Scan through looking for an interface with an Internet
1820 * address on the same subnet as `ipaddr'.
1822 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1823 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1824 if (ifr->ifr_addr.sa_family == AF_INET) {
1825 ina = SIN_ADDR(ifr->ifr_addr);
1826 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1828 * Check that the interface is up, and not point-to-point
1831 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1834 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1837 * Get its netmask and check that it's on the right subnet.
1839 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1842 mask = SIN_ADDR(ifreq.ifr_addr);
1844 if (((ipaddr ^ ina) & mask) != 0)
1845 continue; /* no match */
1847 if (mask >= bestmask) {
1848 /* Compare using >= instead of > -- it is possible for
1849 an interface to have a netmask of 0.0.0.0 */
1850 found_interface = 1;
1857 if (!found_interface) return 0;
1859 strlcpy(name, bestifreq.ifr_name, namelen);
1861 /* trim off the :1 in eth0:1 */
1862 aliasp = strchr(name, ':');
1866 info("found interface %s for proxy arp", name);
1868 * Now get the hardware address.
1870 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1871 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1872 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1877 &bestifreq.ifr_hwaddr,
1878 sizeof (struct sockaddr));
1884 * get_if_hwaddr - get the hardware address for the specified
1885 * network interface device.
1888 get_if_hwaddr(u_char *addr, char *name)
1893 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1896 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1897 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1898 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1901 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1906 * get_first_ethernet - return the name of the first ethernet-style
1907 * interface on this system.
1910 get_first_ethernet()
1915 /********************************************************************
1917 * Return user specified netmask, modified by any mask we might determine
1918 * for address `addr' (in network byte order).
1919 * Here we scan through the system's list of interfaces, looking for
1920 * any non-point-to-point interfaces which might appear to be on the same
1921 * network as `addr'. If we find any, we OR in their netmask to the
1922 * user-specified netmask.
1925 u_int32_t GetMask (u_int32_t addr)
1927 u_int32_t mask, nmask, ina;
1928 struct ifreq *ifr, *ifend, ifreq;
1930 struct ifreq ifs[MAX_IFS];
1934 if (IN_CLASSA(addr)) /* determine network mask for address class */
1935 nmask = IN_CLASSA_NET;
1936 else if (IN_CLASSB(addr))
1937 nmask = IN_CLASSB_NET;
1939 nmask = IN_CLASSC_NET;
1941 /* class D nets are disallowed by bad_ip_adrs */
1942 mask = netmask | htonl(nmask);
1944 * Scan through the system's network interfaces.
1946 ifc.ifc_len = sizeof(ifs);
1948 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1949 if ( ! ok_error ( errno ))
1950 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1954 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1955 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1957 * Check the interface's internet address.
1959 if (ifr->ifr_addr.sa_family != AF_INET)
1961 ina = SIN_ADDR(ifr->ifr_addr);
1962 if (((ntohl(ina) ^ addr) & nmask) != 0)
1965 * Check that the interface is up, and not point-to-point nor loopback.
1967 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1968 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1971 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1974 * Get its netmask and OR it into our mask.
1976 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1978 mask |= SIN_ADDR(ifreq.ifr_addr);
1984 /********************************************************************
1986 * Internal routine to decode the version.modification.patch level
1989 static void decode_version (char *buf, int *version,
1990 int *modification, int *patch)
1994 *version = (int) strtoul (buf, &endp, 10);
1998 if (endp != buf && *endp == '.') {
2000 *modification = (int) strtoul (buf, &endp, 10);
2001 if (endp != buf && *endp == '.') {
2003 *patch = (int) strtoul (buf, &buf, 10);
2008 /********************************************************************
2010 * Procedure to determine if the PPP line discipline is registered.
2014 ppp_registered(void)
2022 * We used to open the serial device and set it to the ppp line
2023 * discipline here, in order to create a ppp unit. But that is
2024 * not a good idea - the user might have specified a device that
2025 * they can't open (permission, or maybe it doesn't really exist).
2026 * So we grab a pty master/slave pair and use that.
2028 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2029 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2034 * Try to put the device into the PPP discipline.
2036 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2037 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2046 /********************************************************************
2048 * ppp_available - check whether the system has any ppp interfaces
2049 * (in fact we check whether we can do an ioctl on ppp0).
2052 int ppp_available(void)
2057 int my_version, my_modification, my_patch;
2058 int osmaj, osmin, ospatch;
2060 /* get the kernel version now, since we are called before sys_init */
2062 osmaj = osmin = ospatch = 0;
2063 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2064 kernel_version = KVERSION(osmaj, osmin, ospatch);
2066 fd = open("/dev/ppp", O_RDWR);
2068 new_style_driver = 1;
2070 /* XXX should get from driver */
2072 driver_modification = 4;
2078 if (kernel_version >= KVERSION(2,3,13)) {
2079 error("Couldn't open the /dev/ppp device: %m");
2080 if (errno == ENOENT)
2082 "You need to create the /dev/ppp device node by\n"
2083 "executing the following command as root:\n"
2084 " mknod /dev/ppp c 108 0\n";
2085 else if (errno == ENODEV || errno == ENXIO)
2087 "Please load the ppp_generic kernel module.\n";
2091 /* we are running on a really really old kernel */
2093 "This system lacks kernel support for PPP. This could be because\n"
2094 "the PPP kernel module could not be loaded, or because PPP was not\n"
2095 "included in the kernel configuration. If PPP was included as a\n"
2096 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2097 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2098 "See README.linux file in the ppp distribution for more details.\n";
2101 * Open a socket for doing the ioctl operations.
2103 s = socket(AF_INET, SOCK_DGRAM, 0);
2107 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2108 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2110 * If the device did not exist then attempt to create one by putting the
2111 * current tty into the PPP discipline. If this works then obtain the
2112 * flags for the device again.
2115 if (ppp_registered()) {
2116 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2117 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2121 * Ensure that the hardware address is for PPP and not something else
2124 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2126 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2130 * This is the PPP device. Validate the version of the driver at this
2131 * point to ensure that this program will work with the driver.
2134 char abBuffer [1024];
2136 ifr.ifr_data = abBuffer;
2137 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2139 error("Couldn't read driver version: %m");
2141 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2144 decode_version(abBuffer,
2146 &driver_modification,
2149 * Validate the version of the driver against the version that we used.
2151 decode_version(VERSION,
2156 /* The version numbers must match */
2157 if (driver_version != my_version)
2160 /* The modification levels must be legal */
2161 if (driver_modification < 3) {
2162 if (driver_modification >= 2) {
2163 /* we can cope with 2.2.0 and above */
2171 slprintf(route_buffer, sizeof(route_buffer),
2172 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2173 driver_version, driver_modification, driver_patch);
2175 no_ppp_msg = route_buffer;
2183 #ifndef HAVE_LOGWTMP
2184 /********************************************************************
2186 * Update the wtmp file with the appropriate user name and tty device.
2189 void logwtmp (const char *line, const char *name, const char *host)
2191 struct utmp ut, *utp;
2192 pid_t mypid = getpid();
2198 * Update the signon database for users.
2199 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2201 utmpname(_PATH_UTMP);
2203 while ((utp = getutent()) && (utp->ut_pid != mypid))
2207 memcpy(&ut, utp, sizeof(ut));
2209 /* some gettys/telnetds don't initialize utmp... */
2210 memset(&ut, 0, sizeof(ut));
2212 if (ut.ut_id[0] == 0)
2213 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2215 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2216 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2220 ut.ut_type = USER_PROCESS;
2223 /* Insert the host name if one is supplied */
2225 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2227 /* Insert the IP address of the remote system if IP is enabled */
2228 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2229 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2230 sizeof(ut.ut_addr));
2232 /* CL: Makes sure that the logout works */
2233 if (*host == 0 && *name==0)
2239 * Update the wtmp file.
2242 updwtmp(_PATH_WTMP, &ut);
2244 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2246 flock(wtmp, LOCK_EX);
2248 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2249 warn("error writing %s: %m", _PATH_WTMP);
2251 flock(wtmp, LOCK_UN);
2257 #endif /* HAVE_LOGWTMP */
2259 /********************************************************************
2261 * sifvjcomp - config tcp header compression
2264 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2269 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2270 error("Couldn't set up TCP header compression: %m");
2275 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2276 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2281 /********************************************************************
2283 * sifup - Config the interface up and enable IP packets to pass.
2290 if ((ret = setifstate(u, 1)))
2296 /********************************************************************
2298 * sifdown - Disable the indicated protocol and config the interface
2299 * down if there are no remaining protocols.
2304 if (if_is_up && --if_is_up > 0)
2312 return setifstate(u, 0);
2316 /********************************************************************
2318 * sif6up - Config the interface up for IPv6
2325 if ((ret = setifstate(u, 1)))
2331 /********************************************************************
2333 * sif6down - Disable the IPv6CP protocol and config the interface
2334 * down if there are no remaining protocols.
2337 int sif6down (int u)
2344 return setifstate(u, 0);
2348 /********************************************************************
2350 * setifstate - Config the interface up or down
2353 static int setifstate (int u, int state)
2357 memset (&ifr, '\0', sizeof (ifr));
2358 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2359 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2360 if (! ok_error (errno))
2361 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2366 ifr.ifr_flags |= IFF_UP;
2368 ifr.ifr_flags &= ~IFF_UP;
2369 ifr.ifr_flags |= IFF_POINTOPOINT;
2370 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2371 if (! ok_error (errno))
2372 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2378 /********************************************************************
2380 * sifaddr - Config the interface IP addresses and netmask.
2383 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2389 memset (&ifr, '\0', sizeof (ifr));
2390 memset (&rt, '\0', sizeof (rt));
2392 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2393 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2394 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2396 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2398 * Set our IP address
2400 SIN_ADDR(ifr.ifr_addr) = our_adr;
2401 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2402 if (errno != EEXIST) {
2403 if (! ok_error (errno))
2404 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2407 warn("ioctl(SIOCSIFADDR): Address already exists");
2412 * Set the gateway address
2415 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2416 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2417 if (! ok_error (errno))
2418 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2424 * For recent kernels, force the netmask to 255.255.255.255.
2426 if (kernel_version >= KVERSION(2,1,16))
2428 if (net_mask != 0) {
2429 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2430 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2431 if (! ok_error (errno))
2432 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2437 * Add the device route
2439 if (kernel_version < KVERSION(2,1,16)) {
2440 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2441 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2444 SIN_ADDR(rt.rt_gateway) = 0L;
2445 SIN_ADDR(rt.rt_dst) = his_adr;
2446 rt.rt_flags = RTF_UP | RTF_HOST;
2448 if (kernel_version > KVERSION(2,1,0)) {
2449 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2450 SIN_ADDR(rt.rt_genmask) = -1L;
2453 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2454 if (! ok_error (errno))
2455 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2460 /* set ip_dynaddr in demand mode if address changes */
2461 if (demand && tune_kernel && !dynaddr_set
2462 && our_old_addr && our_old_addr != our_adr) {
2463 /* set ip_dynaddr if possible */
2467 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2468 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2469 if (write(fd, "1", 1) != 1)
2470 error("Couldn't enable dynamic IP addressing: %m");
2473 dynaddr_set = 1; /* only 1 attempt */
2480 /********************************************************************
2482 * cifaddr - Clear the interface IP addresses, and delete routes
2483 * through the interface if possible.
2486 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2490 if (kernel_version < KVERSION(2,1,16)) {
2492 * Delete the route through the device
2495 memset (&rt, '\0', sizeof (rt));
2497 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2498 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2501 SIN_ADDR(rt.rt_gateway) = 0;
2502 SIN_ADDR(rt.rt_dst) = his_adr;
2503 rt.rt_flags = RTF_UP | RTF_HOST;
2505 if (kernel_version > KVERSION(2,1,0)) {
2506 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2507 SIN_ADDR(rt.rt_genmask) = -1L;
2510 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2511 if (still_ppp() && ! ok_error (errno))
2512 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2517 /* This way it is possible to have an IPX-only or IPv6-only interface */
2518 memset(&ifr, 0, sizeof(ifr));
2519 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2520 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2522 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2523 if (! ok_error (errno)) {
2524 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2529 our_old_addr = our_adr;
2535 /********************************************************************
2537 * sif6addr - Config the interface with an IPv6 link-local address
2539 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2541 struct in6_ifreq ifr6;
2543 struct in6_rtmsg rt6;
2547 error("IPv6 socket creation failed: %m");
2550 memset(&ifr, 0, sizeof (ifr));
2551 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2552 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2553 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2557 /* Local interface */
2558 memset(&ifr6, 0, sizeof(ifr6));
2559 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2560 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2561 ifr6.ifr6_prefixlen = 10;
2563 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2564 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2568 /* Route to remote host */
2569 memset(&rt6, 0, sizeof(rt6));
2570 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2571 rt6.rtmsg_flags = RTF_UP;
2572 rt6.rtmsg_dst_len = 10;
2573 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2574 rt6.rtmsg_metric = 1;
2576 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2577 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2585 /********************************************************************
2587 * cif6addr - Remove IPv6 address from interface
2589 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2592 struct in6_ifreq ifr6;
2596 error("IPv6 socket creation failed: %m");
2599 memset(&ifr, 0, sizeof(ifr));
2600 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2601 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2602 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2606 memset(&ifr6, 0, sizeof(ifr6));
2607 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2608 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2609 ifr6.ifr6_prefixlen = 10;
2611 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2612 if (errno != EADDRNOTAVAIL) {
2613 if (! ok_error (errno))
2614 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2617 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2626 * get_pty - get a pty master/slave pair and chown the slave side
2627 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2630 get_pty(master_fdp, slave_fdp, slave_name, uid)
2636 int i, mfd, sfd = -1;
2638 struct termios tios;
2642 * Try the unix98 way first.
2644 mfd = open("/dev/ptmx", O_RDWR);
2647 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2648 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2649 chmod(pty_name, S_IRUSR | S_IWUSR);
2652 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2653 warn("Couldn't unlock pty slave %s: %m", pty_name);
2655 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2657 warn("Couldn't open pty slave %s: %m", pty_name);
2662 #endif /* TIOCGPTN */
2665 /* the old way - scan through the pty name space */
2666 for (i = 0; i < 64; ++i) {
2667 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2668 'p' + i / 16, i % 16);
2669 mfd = open(pty_name, O_RDWR, 0);
2672 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2674 fchown(sfd, uid, -1);
2675 fchmod(sfd, S_IRUSR | S_IWUSR);
2686 strlcpy(slave_name, pty_name, 16);
2689 if (tcgetattr(sfd, &tios) == 0) {
2690 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2691 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2692 tios.c_iflag = IGNPAR;
2695 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2696 warn("couldn't set attributes on pty: %m");
2698 warn("couldn't get attributes on pty: %m");
2703 /********************************************************************
2705 * open_loopback - open the device we use for getting packets
2706 * in demand mode. Under Linux, we use a pty master/slave pair.
2709 open_ppp_loopback(void)
2714 if (new_style_driver) {
2715 /* allocate ourselves a ppp unit */
2716 if (make_ppp_unit() < 0)
2718 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2719 set_kdebugflag(kdebugflag);
2724 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2725 fatal("No free pty for loopback");
2727 set_ppp_fd(slave_fd);
2729 flags = fcntl(master_fd, F_GETFL);
2731 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2732 warn("couldn't set master loopback to nonblock: %m");
2734 flags = fcntl(ppp_fd, F_GETFL);
2736 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2737 warn("couldn't set slave loopback to nonblock: %m");
2739 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2740 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2742 * Find out which interface we were given.
2744 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2745 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2747 * Enable debug in the driver if requested.
2749 set_kdebugflag (kdebugflag);
2754 /********************************************************************
2756 * sifnpmode - Set the mode for handling packets for a given NP.
2760 sifnpmode(u, proto, mode)
2767 npi.protocol = proto;
2769 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2770 if (! ok_error (errno))
2771 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2778 /********************************************************************
2780 * sipxfaddr - Config the interface IPX networknumber
2783 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2790 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2792 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2794 if (! ok_error (errno))
2795 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2799 memset (&ifr, '\0', sizeof (ifr));
2800 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2802 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2803 sipx->sipx_family = AF_IPX;
2804 sipx->sipx_port = 0;
2805 sipx->sipx_network = htonl (network);
2806 sipx->sipx_type = IPX_FRAME_ETHERII;
2807 sipx->sipx_action = IPX_CRTITF;
2809 * Set the IPX device
2811 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2813 if (errno != EEXIST) {
2814 if (! ok_error (errno))
2815 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2818 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2827 /********************************************************************
2829 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2830 * are removed and the device is no longer able to pass IPX
2834 int cipxfaddr (int unit)
2841 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2843 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2845 if (! ok_error (errno))
2846 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2850 memset (&ifr, '\0', sizeof (ifr));
2851 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2853 sipx->sipx_type = IPX_FRAME_ETHERII;
2854 sipx->sipx_action = IPX_DLTITF;
2855 sipx->sipx_family = AF_IPX;
2857 * Set the IPX device
2859 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2860 if (! ok_error (errno))
2861 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2871 * Use the hostname as part of the random number seed.
2880 for (p = hostname; *p != 0; ++p)
2885 /********************************************************************
2887 * sys_check_options - check the options that the user specified
2891 sys_check_options(void)
2895 * Disable the IPX protocol if the support is not present in the kernel.
2899 if (ipxcp_protent.enabled_flag) {
2900 struct stat stat_buf;
2901 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
2902 && (path = path_to_procfs("/net/ipx_interface")) == NULL)
2903 || lstat(path, &stat_buf) < 0) {
2904 error("IPX support is not present in the kernel\n");
2905 ipxcp_protent.enabled_flag = 0;
2909 if (demand && driver_is_old) {
2910 option_error("demand dialling is not supported by kernel driver "
2911 "version %d.%d.%d", driver_version, driver_modification,
2915 if (multilink && !new_style_driver) {
2916 warn("Warning: multilink is not supported by the kernel driver");
2924 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2926 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2927 * that the system has a properly configured Ethernet interface for this
2928 * function to return non-zero.
2931 ether_to_eui64(eui64_t *p_eui64)
2935 const unsigned char *ptr;
2937 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2940 warn("could not open IPv6 socket");
2944 strcpy(ifr.ifr_name, "eth0");
2945 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2948 warn("could not obtain hardware address for eth0");
2954 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2956 ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data;
2957 p_eui64->e8[0] = ptr[0] | 0x02;
2958 p_eui64->e8[1] = ptr[1];
2959 p_eui64->e8[2] = ptr[2];
2960 p_eui64->e8[3] = 0xFF;
2961 p_eui64->e8[4] = 0xFE;
2962 p_eui64->e8[5] = ptr[3];
2963 p_eui64->e8[6] = ptr[4];
2964 p_eui64->e8[7] = ptr[5];