2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
5 * Copyright (c) 1994-2002 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. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * 3. The name(s) of the authors of this software must not be used to
20 * endorse or promote products derived from this software without
21 * prior written permission.
23 * 4. Redistributions of any form whatsoever must retain the following
25 * "This product includes software developed by Paul Mackerras
26 * <paulus@samba.org>".
28 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
29 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
30 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
31 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
32 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
33 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
34 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
36 * Derived from main.c and pppd.h, which are:
38 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in
49 * the documentation and/or other materials provided with the
52 * 3. The name "Carnegie Mellon University" must not be used to
53 * endorse or promote products derived from this software without
54 * prior written permission. For permission or any legal
55 * details, please contact
56 * Office of Technology Transfer
57 * Carnegie Mellon University
59 * Pittsburgh, PA 15213-3890
60 * (412) 268-4387, fax: (412) 268-7395
61 * tech-transfer@andrew.cmu.edu
63 * 4. Redistributions of any form whatsoever must retain the following
65 * "This product includes software developed by Computing Services
66 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
68 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
69 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
70 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
71 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
72 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
73 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
74 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
77 #include <sys/ioctl.h>
78 #include <sys/types.h>
79 #include <sys/socket.h>
81 #include <sys/errno.h>
84 #include <sys/utsname.h>
85 #include <sys/sysmacros.h>
101 /* This is in netdevice.h. However, this compile will fail miserably if
102 you attempt to include netdevice.h because it has so many references
103 to __memcpy functions which it should not attempt to do. So, since I
104 really don't use it, but it must be defined, define it now. */
107 #define MAX_ADDR_LEN 7
111 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
113 #include <net/if_arp.h>
114 #include <net/route.h>
115 #include <netinet/if_ether.h>
117 #include <linux/types.h>
118 #include <linux/if.h>
119 #include <linux/if_arp.h>
120 #include <linux/route.h>
121 #include <linux/if_ether.h>
123 #include <netinet/in.h>
124 #include <arpa/inet.h>
126 #include <linux/ppp_defs.h>
127 #include <linux/if_ppp.h>
135 #if __GLIBC__ >= 2 && \
136 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
137 #include <netipx/ipx.h>
139 #include <linux/ipx.h>
141 #endif /* IPX_CHANGE */
144 #include <pcap-bpf.h>
145 #include <linux/filter.h>
146 #endif /* PPP_FILTER */
149 #include <sys/locks.h>
155 * This is in linux/include/net/ipv6.h.
159 struct in6_addr ifr6_addr;
160 __u32 ifr6_prefixlen;
161 unsigned int ifr6_ifindex;
165 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
166 memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \
167 sin6.s6_addr16[0] = htons(0xfe80); \
168 eui64_copy(eui64, sin6.s6_addr32[2]); \
173 /* We can get an EIO error on an ioctl if the modem has hung up */
174 #define ok_error(num) ((num)==EIO)
176 static int tty_disc = N_TTY; /* The TTY discipline */
177 static int ppp_disc = N_PPP; /* The PPP discpline */
178 static int initfdflags = -1; /* Initial file descriptor flags for fd */
179 static int ppp_fd = -1; /* fd which is set to PPP discipline */
180 static int sock_fd = -1; /* socket for doing interface ioctls */
181 static int slave_fd = -1;
182 static int master_fd = -1;
184 static int sock6_fd = -1;
188 * For the old-style kernel driver, this is the same as ppp_fd.
189 * For the new-style driver, it is the fd of an instance of /dev/ppp
190 * which is attached to the ppp unit and is used for controlling it.
192 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
194 static int chindex; /* channel index (new style driver) */
196 static fd_set in_fds; /* set of fds that wait_input waits for */
197 static int max_in_fd; /* highest fd set in in_fds */
199 static int has_proxy_arp = 0;
200 static int driver_version = 0;
201 static int driver_modification = 0;
202 static int driver_patch = 0;
203 static int driver_is_old = 0;
204 static int restore_term = 0; /* 1 => we've munged the terminal */
205 static struct termios inittermios; /* Initial TTY termios */
207 int new_style_driver = 0;
209 static char loop_name[20];
210 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
212 static int if_is_up; /* Interface has been marked up */
213 static u_int32_t default_route_gateway; /* Gateway for default route added */
214 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
215 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
216 static u_int32_t our_old_addr; /* for detecting address changes */
217 static int dynaddr_set; /* 1 if ip_dynaddr set */
218 static int looped; /* 1 if using loop */
219 static int link_mtu; /* mtu for the link (not bundle) */
221 static struct utsname utsname; /* for the kernel version */
222 static int kernel_version;
223 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
227 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
228 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
229 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
231 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
233 /* Prototypes for procedures local to this file. */
234 static int modify_flags(int fd, int clear_bits, int set_bits);
235 static int translate_speed (int bps);
236 static int baud_rate_of (int speed);
237 static void close_route_table (void);
238 static int open_route_table (void);
239 static int read_route_table (struct rtentry *rt);
240 static int defaultroute_exists (struct rtentry *rt);
241 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
242 char *name, int namelen);
243 static void decode_version (char *buf, int *version, int *mod, int *patch);
244 static int set_kdebugflag(int level);
245 static int ppp_registered(void);
246 static int make_ppp_unit(void);
248 extern u_char inpacket_buf[]; /* borrowed from main.c */
251 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
255 #define SET_SA_FAMILY(addr, family) \
256 memset ((char *) &(addr), '\0', sizeof(addr)); \
257 addr.sa_family = (family);
260 * Determine if the PPP connection should still be present.
265 /* new_fd is the fd of a tty */
266 static void set_ppp_fd (int new_fd)
268 SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
270 if (!new_style_driver)
274 static int still_ppp(void)
276 if (new_style_driver)
277 return !hungup && ppp_fd >= 0;
278 if (!hungup || ppp_fd == slave_fd)
281 set_ppp_fd(slave_fd);
288 * modify_flags - set and clear flag bits controlling the kernel
291 static int modify_flags(int fd, int clear_bits, int set_bits)
295 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
297 flags = (flags & ~clear_bits) | set_bits;
298 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
305 error("Failed to set PPP kernel option flags: %m");
309 /********************************************************************
311 * sys_init - System-dependent initialization.
316 /* Get an internet socket for doing socket ioctls. */
317 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
319 fatal("Couldn't create IP socket: %m(%d)", errno);
322 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
324 sock6_fd = -errno; /* save errno for later */
331 /********************************************************************
333 * sys_cleanup - restore any system state we modified before exiting:
334 * mark the interface down, delete default route and/or proxy arp entry.
335 * This shouldn't call die() because it's called from die().
338 void sys_cleanup(void)
341 * Take down the device
348 * Delete any routes through the device.
350 if (default_route_gateway != 0)
351 cifdefaultroute(0, 0, default_route_gateway);
354 cifproxyarp(0, proxy_arp_addr);
357 /********************************************************************
359 * sys_close - Clean up in a child process before execing.
364 if (new_style_driver && ppp_dev_fd >= 0)
378 /********************************************************************
380 * set_kdebugflag - Define the debugging level for the kernel
383 static int set_kdebugflag (int requested_level)
387 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
388 if ( ! ok_error (errno) )
389 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
392 SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
397 /********************************************************************
399 * tty_establish_ppp - Turn the serial port into a ppp interface.
402 int tty_establish_ppp (int tty_fd)
407 * Ensure that the tty device is in exclusive mode.
409 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
410 if ( ! ok_error ( errno ))
411 warn("Couldn't make tty exclusive: %m");
414 * Demand mode - prime the old ppp device to relinquish the unit.
416 if (!new_style_driver && looped
417 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
418 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
422 * Set the current tty to the PPP discpline
426 #define N_SYNC_PPP 14
428 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
429 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
430 if ( ! ok_error (errno) ) {
431 error("Couldn't set tty to PPP discipline: %m");
436 ret_fd = generic_establish_ppp(tty_fd);
438 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
439 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
443 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
444 (kdebugflag * SC_DEBUG) & SC_LOGB);
446 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
447 warn("Couldn't reset tty to normal line discipline: %m");
453 /********************************************************************
455 * generic_establish_ppp - Turn the fd into a ppp interface.
457 int generic_establish_ppp (int fd)
461 if (new_style_driver) {
464 /* Open an instance of /dev/ppp and connect the channel to it */
465 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
466 error("Couldn't get channel number: %m");
469 dbglog("using channel %d", chindex);
470 fd = open("/dev/ppp", O_RDWR);
472 error("Couldn't reopen /dev/ppp: %m");
475 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
476 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
477 error("Couldn't attach to channel %d: %m", chindex);
480 flags = fcntl(fd, F_GETFL);
481 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
482 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
487 if (!looped && !multilink) {
489 * Create a new PPP unit.
491 if (make_ppp_unit() < 0)
496 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
500 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
501 error("Couldn't attach to PPP unit %d: %m", ifunit);
508 * Old-style driver: find out which interface we were given.
511 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
512 if (ok_error (errno))
514 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
516 /* Check that we got the same unit again. */
517 if (looped && x != ifunit)
518 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
522 * Fetch the initial file flags and reset blocking mode on the file.
524 initfdflags = fcntl(fd, F_GETFL);
525 if (initfdflags == -1 ||
526 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
527 if ( ! ok_error (errno))
528 warn("Couldn't set device to non-blocking mode: %m");
533 * Enable debug in the driver if requested.
536 set_kdebugflag (kdebugflag);
540 SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
541 driver_version, driver_modification, driver_patch));
551 /********************************************************************
553 * tty_disestablish_ppp - Restore the serial port to normal operation.
554 * This shouldn't call die() because it's called from die().
557 void tty_disestablish_ppp(int tty_fd)
561 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
563 if (tcflush(tty_fd, TCIOFLUSH) < 0)
565 warn("tcflush failed: %m");
569 * Restore the previous line discipline
571 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
572 if ( ! ok_error (errno))
573 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
576 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
577 if ( ! ok_error (errno))
578 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
581 /* Reset non-blocking mode on fd. */
582 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
583 if ( ! ok_error (errno))
584 warn("Couldn't restore device fd flags: %m");
590 generic_disestablish_ppp(tty_fd);
593 /********************************************************************
595 * generic_disestablish_ppp - Restore device components to normal
596 * operation, and reconnect the ppp unit to the loopback if in demand
597 * mode. This shouldn't call die() because it's called from die().
599 void generic_disestablish_ppp(int dev_fd)
601 if (new_style_driver) {
605 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
607 } else if (ppp_dev_fd >= 0) {
609 remove_fd(ppp_dev_fd);
613 /* old-style driver */
615 set_ppp_fd(slave_fd);
622 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
623 * Assumes new_style_driver.
625 static int make_ppp_unit()
629 if (ppp_dev_fd >= 0) {
630 dbglog("in make_ppp_unit, already had /dev/ppp open?");
633 ppp_dev_fd = open("/dev/ppp", O_RDWR);
635 fatal("Couldn't open /dev/ppp: %m");
636 flags = fcntl(ppp_dev_fd, F_GETFL);
638 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
639 warn("Couldn't set /dev/ppp to nonblock: %m");
642 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
643 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
644 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
646 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
649 error("Couldn't create new ppp unit: %m");
654 * cfg_bundle - configure the existing bundle.
655 * Used in demand mode.
657 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
659 if (!new_style_driver)
662 /* set the mrru, mtu and flags */
663 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
664 error("Couldn't set MRRU: %m");
666 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
667 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
668 | (mrru? SC_MULTILINK: 0)));
670 /* connect up the channel */
671 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
672 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
677 * make_new_bundle - create a new PPP unit (i.e. a bundle)
678 * and connect our channel to it. This should only get called
679 * if `multilink' was set at the time establish_ppp was called.
680 * In demand mode this uses our existing bundle instead of making
683 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
685 if (!new_style_driver)
688 /* make us a ppp unit */
689 if (make_ppp_unit() < 0)
692 /* set the mrru and flags */
693 cfg_bundle(mrru, mtru, rssn, tssn);
697 * bundle_attach - attach our link to a given PPP unit.
698 * We assume the unit is controlled by another pppd.
700 int bundle_attach(int ifnum)
704 if (!new_style_driver)
707 master_fd = open("/dev/ppp", O_RDWR);
709 fatal("Couldn't open /dev/ppp: %m");
710 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
711 if (errno == ENXIO) {
713 return 0; /* doesn't still exist */
715 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
717 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
718 fatal("Couldn't connect to interface unit %d: %m", ifnum);
719 modify_flags(master_fd, 0, SC_MULTILINK);
726 /********************************************************************
728 * clean_check - Fetch the flags for the device and generate
729 * appropriate error messages.
731 void clean_check(void)
737 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
739 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
741 s = "all had bit 7 set to 1";
745 s = "all had bit 7 set to 0";
749 s = "all had odd parity";
753 s = "all had even parity";
758 warn("Receive serial link is not 8-bit clean:");
759 warn("Problem: %s", s);
767 * List of valid speeds.
771 int speed_int, speed_val;
854 /********************************************************************
856 * Translate from bits/second to a speed_t.
859 static int translate_speed (int bps)
861 struct speed *speedp;
864 for (speedp = speeds; speedp->speed_int; speedp++) {
865 if (bps == speedp->speed_int)
866 return speedp->speed_val;
868 warn("speed %d not supported", bps);
873 /********************************************************************
875 * Translate from a speed_t to bits/second.
878 static int baud_rate_of (int speed)
880 struct speed *speedp;
883 for (speedp = speeds; speedp->speed_int; speedp++) {
884 if (speed == speedp->speed_val)
885 return speedp->speed_int;
891 /********************************************************************
893 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
894 * at the requested speed, etc. If `local' is true, set CLOCAL
895 * regardless of whether the modem option was specified.
898 void set_up_tty(int tty_fd, int local)
904 if (tcgetattr(tty_fd, &tios) < 0) {
905 if (!ok_error(errno))
906 fatal("tcgetattr: %m (line %d)", __LINE__);
913 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
914 tios.c_cflag |= CS8 | CREAD | HUPCL;
916 tios.c_iflag = IGNBRK | IGNPAR;
920 tios.c_cc[VTIME] = 0;
923 tios.c_cflag ^= (CLOCAL | HUPCL);
927 tios.c_cflag |= CRTSCTS;
931 tios.c_iflag |= IXON | IXOFF;
932 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
933 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
937 tios.c_cflag &= ~CRTSCTS;
944 speed = translate_speed(inspeed);
946 cfsetospeed (&tios, speed);
947 cfsetispeed (&tios, speed);
950 * We can't proceed if the serial port speed is B0,
951 * since that implies that the serial port is disabled.
954 speed = cfgetospeed(&tios);
956 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
959 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
961 fatal("tcsetattr: %m (line %d)", __LINE__);
963 baud_rate = baud_rate_of(speed);
967 /********************************************************************
969 * setdtr - control the DTR line on the serial port.
970 * This is called from die(), so it shouldn't call die().
973 void setdtr (int tty_fd, int on)
975 int modembits = TIOCM_DTR;
977 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
980 /********************************************************************
982 * restore_tty - restore the terminal to the saved settings.
985 void restore_tty (int tty_fd)
990 * Turn off echoing, because otherwise we can get into
991 * a loop with the tty and the modem echoing to each other.
992 * We presume we are the sole user of this tty device, so
993 * when we close it, it will revert to its defaults anyway.
996 inittermios.c_lflag &= ~(ECHO | ECHONL);
998 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
999 if (! ok_error (errno))
1000 warn("tcsetattr: %m (line %d)", __LINE__);
1005 /********************************************************************
1007 * output - Output PPP packet.
1010 void output (int unit, unsigned char *p, int len)
1015 dump_packet("sent", p, len);
1016 if (snoop_send_hook) snoop_send_hook(p, len);
1018 if (len < PPP_HDRLEN)
1020 if (new_style_driver) {
1023 proto = (p[0] << 8) + p[1];
1024 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1027 if (write(fd, p, len) < 0) {
1028 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1029 || errno == ENXIO || errno == EIO || errno == EINTR)
1030 warn("write: warning: %m (%d)", errno);
1032 error("write: %m (%d)", errno);
1036 /********************************************************************
1038 * wait_input - wait until there is data available,
1039 * for the length of time specified by *timo (indefinite
1043 void wait_input(struct timeval *timo)
1050 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1051 if (n < 0 && errno != EINTR)
1052 fatal("select: %m");
1056 * add_fd - add an fd to the set that wait_input waits for.
1060 if (fd >= FD_SETSIZE)
1061 fatal("internal error: file descriptor too large (%d)", fd);
1062 FD_SET(fd, &in_fds);
1068 * remove_fd - remove an fd from the set that wait_input waits for.
1070 void remove_fd(int fd)
1072 FD_CLR(fd, &in_fds);
1076 /********************************************************************
1078 * read_packet - get a PPP packet from the serial device.
1081 int read_packet (unsigned char *buf)
1085 len = PPP_MRU + PPP_HDRLEN;
1086 if (new_style_driver) {
1087 *buf++ = PPP_ALLSTATIONS;
1093 nr = read(ppp_fd, buf, len);
1094 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1095 && errno != EIO && errno != EINTR)
1097 if (nr < 0 && errno == ENXIO)
1100 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0) {
1101 /* N.B. we read ppp_fd first since LCP packets come in there. */
1102 nr = read(ppp_dev_fd, buf, len);
1103 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1104 && errno != EIO && errno != EINTR)
1105 error("read /dev/ppp: %m");
1106 if (nr < 0 && errno == ENXIO)
1109 return (new_style_driver && nr > 0)? nr+2: nr;
1112 /********************************************************************
1114 * get_loop_output - get outgoing packets from the ppp device,
1115 * and detect when we want to bring the real link up.
1116 * Return value is 1 if we need to bring up the link, 0 otherwise.
1119 get_loop_output(void)
1124 if (new_style_driver) {
1125 while ((n = read_packet(inpacket_buf)) > 0)
1126 if (loop_frame(inpacket_buf, n))
1131 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1132 if (loop_chars(inbuf, n))
1136 fatal("eof on loopback");
1138 if (errno != EWOULDBLOCK && errno != EAGAIN)
1139 fatal("read from loopback: %m(%d)", errno);
1145 * netif_set_mtu - set the MTU on the PPP network interface.
1148 netif_set_mtu(int unit, int mtu)
1152 SYSDEBUG ((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu));
1154 memset (&ifr, '\0', sizeof (ifr));
1155 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1158 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1159 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1163 * netif_get_mtu - get the MTU on the PPP network interface.
1166 netif_get_mtu(int unit)
1170 memset (&ifr, '\0', sizeof (ifr));
1171 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1173 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1174 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1180 /********************************************************************
1182 * tty_send_config - configure the transmit characteristics of
1183 * the ppp interface.
1186 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1193 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1194 if (errno != EIO && errno != ENOTTY)
1195 error("Couldn't set transmit async character map: %m");
1200 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1201 | (sync_serial? SC_SYNC: 0);
1202 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1205 /********************************************************************
1207 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1210 void tty_set_xaccm (ext_accm accm)
1212 SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
1213 accm[0], accm[1], accm[2], accm[3]));
1217 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1218 if ( ! ok_error (errno))
1219 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1223 /********************************************************************
1225 * tty_recv_config - configure the receive-side characteristics of
1226 * the ppp interface.
1229 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1232 * If we were called because the link has gone down then there is nothing
1233 * which may be done. Just return without incident.
1238 * Set the receiver parameters
1240 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1241 if (errno != EIO && errno != ENOTTY)
1242 error("Couldn't set channel receive MRU: %m");
1244 if (new_style_driver && ppp_dev_fd >= 0
1245 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1246 error("Couldn't set MRU in generic PPP layer: %m");
1248 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1249 if (errno != EIO && errno != ENOTTY)
1250 error("Couldn't set channel receive asyncmap: %m");
1254 /********************************************************************
1256 * ccp_test - ask kernel whether a given compression method
1257 * is acceptable for use.
1261 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1263 struct ppp_option_data data;
1265 memset (&data, '\0', sizeof (data));
1267 data.length = opt_len;
1268 data.transmit = for_transmit;
1270 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1273 return (errno == ENOBUFS)? 0: -1;
1276 /********************************************************************
1278 * ccp_flags_set - inform kernel about the current state of CCP.
1281 void ccp_flags_set (int unit, int isopen, int isup)
1285 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1286 if (still_ppp() && ppp_dev_fd >= 0)
1287 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1292 * set_filters - set the active and pass filters in the kernel driver.
1294 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1296 struct sock_fprog fp;
1298 fp.len = pass->bf_len;
1299 fp.filter = (struct sock_filter *) pass->bf_insns;
1300 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1301 if (errno == ENOTTY)
1302 warn("kernel does not support PPP filtering");
1304 error("Couldn't set pass-filter in kernel: %m");
1307 fp.len = active->bf_len;
1308 fp.filter = (struct sock_filter *) active->bf_insns;
1309 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1310 error("Couldn't set active-filter in kernel: %m");
1315 #endif /* PPP_FILTER */
1317 /********************************************************************
1319 * get_idle_time - return how long the link has been idle.
1322 get_idle_time(u, ip)
1324 struct ppp_idle *ip;
1326 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1329 /********************************************************************
1331 * get_ppp_stats - return statistics for the link.
1334 get_ppp_stats(u, stats)
1336 struct pppd_stats *stats;
1338 struct ifpppstatsreq req;
1340 memset (&req, 0, sizeof (req));
1342 req.stats_ptr = (caddr_t) &req.stats;
1343 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1344 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1345 error("Couldn't get PPP statistics: %m");
1348 stats->bytes_in = req.stats.p.ppp_ibytes;
1349 stats->bytes_out = req.stats.p.ppp_obytes;
1350 stats->pkts_in = req.stats.p.ppp_ipackets;
1351 stats->pkts_out = req.stats.p.ppp_opackets;
1355 /********************************************************************
1357 * ccp_fatal_error - returns 1 if decompression was disabled as a
1358 * result of an error detected after decompression of a packet,
1359 * 0 otherwise. This is necessary because of patent nonsense.
1362 int ccp_fatal_error (int unit)
1366 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1367 error("Couldn't read compression error flags: %m");
1370 return flags & SC_DC_FERROR;
1373 /********************************************************************
1375 * path_to_procfs - find the path to the proc file system mount point
1377 static char proc_path[MAXPATHLEN];
1378 static int proc_path_len;
1380 static char *path_to_procfs(const char *tail)
1382 struct mntent *mntent;
1385 if (proc_path_len == 0) {
1386 /* Default the mount location of /proc */
1387 strlcpy (proc_path, "/proc", sizeof(proc_path));
1389 fp = fopen(MOUNTED, "r");
1391 while ((mntent = getmntent(fp)) != NULL) {
1392 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1394 if (strcmp(mntent->mnt_type, "proc") == 0) {
1395 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1396 proc_path_len = strlen(proc_path);
1404 strlcpy(proc_path + proc_path_len, tail,
1405 sizeof(proc_path) - proc_path_len);
1410 * /proc/net/route parsing stuff.
1412 #define ROUTE_MAX_COLS 12
1413 FILE *route_fd = (FILE *) 0;
1414 static char route_buffer[512];
1415 static int route_dev_col, route_dest_col, route_gw_col;
1416 static int route_flags_col, route_mask_col;
1417 static int route_num_cols;
1419 static int open_route_table (void);
1420 static void close_route_table (void);
1421 static int read_route_table (struct rtentry *rt);
1423 /********************************************************************
1425 * close_route_table - close the interface to the route table
1428 static void close_route_table (void)
1430 if (route_fd != (FILE *) 0) {
1432 route_fd = (FILE *) 0;
1436 /********************************************************************
1438 * open_route_table - open the interface to the route table
1440 static char route_delims[] = " \t\n";
1442 static int open_route_table (void)
1446 close_route_table();
1448 path = path_to_procfs("/net/route");
1449 route_fd = fopen (path, "r");
1450 if (route_fd == NULL) {
1451 error("can't open routing table %s: %m", path);
1455 route_dev_col = 0; /* default to usual columns */
1458 route_flags_col = 3;
1462 /* parse header line */
1463 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1464 char *p = route_buffer, *q;
1466 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1468 if ((q = strtok(p, route_delims)) == 0)
1470 if (strcasecmp(q, "iface") == 0)
1471 route_dev_col = col;
1472 else if (strcasecmp(q, "destination") == 0)
1473 route_dest_col = col;
1474 else if (strcasecmp(q, "gateway") == 0)
1476 else if (strcasecmp(q, "flags") == 0)
1477 route_flags_col = col;
1478 else if (strcasecmp(q, "mask") == 0)
1479 route_mask_col = col;
1482 if (used && col >= route_num_cols)
1483 route_num_cols = col + 1;
1491 /********************************************************************
1493 * read_route_table - read the next entry from the route table
1496 static int read_route_table(struct rtentry *rt)
1498 char *cols[ROUTE_MAX_COLS], *p;
1501 memset (rt, '\0', sizeof (struct rtentry));
1503 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1507 for (col = 0; col < route_num_cols; ++col) {
1508 cols[col] = strtok(p, route_delims);
1509 if (cols[col] == NULL)
1510 return 0; /* didn't get enough columns */
1514 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1515 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1516 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1518 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1519 rt->rt_dev = cols[route_dev_col];
1524 /********************************************************************
1526 * defaultroute_exists - determine if there is a default route
1529 static int defaultroute_exists (struct rtentry *rt)
1533 if (!open_route_table())
1536 while (read_route_table(rt) != 0) {
1537 if ((rt->rt_flags & RTF_UP) == 0)
1540 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1542 if (SIN_ADDR(rt->rt_dst) == 0L) {
1548 close_route_table();
1553 * have_route_to - determine if the system has any route to
1554 * a given IP address. `addr' is in network byte order.
1555 * Return value is 1 if yes, 0 if no, -1 if don't know.
1556 * For demand mode to work properly, we have to ignore routes
1557 * through our own interface.
1559 int have_route_to(u_int32_t addr)
1564 if (!open_route_table())
1565 return -1; /* don't know */
1567 while (read_route_table(&rt)) {
1568 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1570 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1576 close_route_table();
1580 /********************************************************************
1582 * sifdefaultroute - assign a default route through the address given.
1585 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1589 if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1590 u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1592 if (old_gateway != gateway)
1593 error("not replacing existing default route to %s [%I]",
1594 rt.rt_dev, old_gateway);
1598 memset (&rt, '\0', sizeof (rt));
1599 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1600 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1604 if (kernel_version > KVERSION(2,1,0)) {
1605 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1606 SIN_ADDR(rt.rt_genmask) = 0L;
1609 SIN_ADDR(rt.rt_gateway) = gateway;
1611 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1612 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1613 if ( ! ok_error ( errno ))
1614 error("default route ioctl(SIOCADDRT): %m");
1618 default_route_gateway = gateway;
1622 /********************************************************************
1624 * cifdefaultroute - delete a default route through the address given.
1627 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1631 default_route_gateway = 0;
1633 memset (&rt, '\0', sizeof (rt));
1634 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1635 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1637 if (kernel_version > KVERSION(2,1,0)) {
1638 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1639 SIN_ADDR(rt.rt_genmask) = 0L;
1642 SIN_ADDR(rt.rt_gateway) = gateway;
1644 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1645 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1647 if ( ! ok_error ( errno ))
1648 error("default route ioctl(SIOCDELRT): %m");
1656 /********************************************************************
1658 * sifproxyarp - Make a proxy ARP entry for the peer.
1661 int sifproxyarp (int unit, u_int32_t his_adr)
1663 struct arpreq arpreq;
1666 if (has_proxy_arp == 0) {
1667 memset (&arpreq, '\0', sizeof(arpreq));
1669 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1670 SIN_ADDR(arpreq.arp_pa) = his_adr;
1671 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1673 * Get the hardware address of an interface on the same subnet
1674 * as our local address.
1676 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1677 sizeof(proxy_arp_dev))) {
1678 error("Cannot determine ethernet address for proxy ARP");
1681 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1683 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1684 if ( ! ok_error ( errno ))
1685 error("ioctl(SIOCSARP): %m");
1688 proxy_arp_addr = his_adr;
1692 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1693 if (forw_path != 0) {
1694 int fd = open(forw_path, O_WRONLY);
1696 if (write(fd, "1", 1) != 1)
1697 error("Couldn't enable IP forwarding: %m");
1707 /********************************************************************
1709 * cifproxyarp - Delete the proxy ARP entry for the peer.
1712 int cifproxyarp (int unit, u_int32_t his_adr)
1714 struct arpreq arpreq;
1716 if (has_proxy_arp) {
1718 memset (&arpreq, '\0', sizeof(arpreq));
1719 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1720 SIN_ADDR(arpreq.arp_pa) = his_adr;
1721 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1722 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1724 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1725 if ( ! ok_error ( errno ))
1726 warn("ioctl(SIOCDARP): %m");
1733 /********************************************************************
1735 * get_ether_addr - get the hardware address of an interface on the
1736 * the same subnet as ipaddr.
1739 static int get_ether_addr (u_int32_t ipaddr,
1740 struct sockaddr *hwaddr,
1741 char *name, int namelen)
1743 struct ifreq *ifr, *ifend;
1744 u_int32_t ina, mask;
1746 struct ifreq ifreq, bestifreq;
1748 struct ifreq ifs[MAX_IFS];
1750 u_int32_t bestmask=0;
1751 int found_interface = 0;
1753 ifc.ifc_len = sizeof(ifs);
1755 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1756 if ( ! ok_error ( errno ))
1757 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1761 SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1762 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1764 * Scan through looking for an interface with an Internet
1765 * address on the same subnet as `ipaddr'.
1767 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1768 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1769 if (ifr->ifr_addr.sa_family == AF_INET) {
1770 ina = SIN_ADDR(ifr->ifr_addr);
1771 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1772 SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1775 * Check that the interface is up, and not point-to-point
1778 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1781 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1784 * Get its netmask and check that it's on the right subnet.
1786 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1789 mask = SIN_ADDR(ifreq.ifr_addr);
1790 SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1791 ip_ntoa(ina), ntohl(mask)));
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));
1829 SYSDEBUG ((LOG_DEBUG,
1830 "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1831 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1832 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1833 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1834 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1835 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1836 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1837 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1838 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1843 * get_if_hwaddr - get the hardware address for the specified
1844 * network interface device.
1847 get_if_hwaddr(u_char *addr, char *name)
1852 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1855 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1856 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1857 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1860 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1865 * get_first_ethernet - return the name of the first ethernet-style
1866 * interface on this system.
1869 get_first_ethernet()
1874 /********************************************************************
1876 * Return user specified netmask, modified by any mask we might determine
1877 * for address `addr' (in network byte order).
1878 * Here we scan through the system's list of interfaces, looking for
1879 * any non-point-to-point interfaces which might appear to be on the same
1880 * network as `addr'. If we find any, we OR in their netmask to the
1881 * user-specified netmask.
1884 u_int32_t GetMask (u_int32_t addr)
1886 u_int32_t mask, nmask, ina;
1887 struct ifreq *ifr, *ifend, ifreq;
1889 struct ifreq ifs[MAX_IFS];
1893 if (IN_CLASSA(addr)) /* determine network mask for address class */
1894 nmask = IN_CLASSA_NET;
1895 else if (IN_CLASSB(addr))
1896 nmask = IN_CLASSB_NET;
1898 nmask = IN_CLASSC_NET;
1900 /* class D nets are disallowed by bad_ip_adrs */
1901 mask = netmask | htonl(nmask);
1903 * Scan through the system's network interfaces.
1905 ifc.ifc_len = sizeof(ifs);
1907 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1908 if ( ! ok_error ( errno ))
1909 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1913 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1914 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1916 * Check the interface's internet address.
1918 if (ifr->ifr_addr.sa_family != AF_INET)
1920 ina = SIN_ADDR(ifr->ifr_addr);
1921 if (((ntohl(ina) ^ addr) & nmask) != 0)
1924 * Check that the interface is up, and not point-to-point nor loopback.
1926 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1927 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1930 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1933 * Get its netmask and OR it into our mask.
1935 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1937 mask |= SIN_ADDR(ifreq.ifr_addr);
1943 /********************************************************************
1945 * Internal routine to decode the version.modification.patch level
1948 static void decode_version (char *buf, int *version,
1949 int *modification, int *patch)
1953 *version = (int) strtoul (buf, &endp, 10);
1957 if (endp != buf && *endp == '.') {
1959 *modification = (int) strtoul (buf, &endp, 10);
1960 if (endp != buf && *endp == '.') {
1962 *patch = (int) strtoul (buf, &buf, 10);
1967 /********************************************************************
1969 * Procedure to determine if the PPP line discipline is registered.
1973 ppp_registered(void)
1981 * We used to open the serial device and set it to the ppp line
1982 * discipline here, in order to create a ppp unit. But that is
1983 * not a good idea - the user might have specified a device that
1984 * they can't open (permission, or maybe it doesn't really exist).
1985 * So we grab a pty master/slave pair and use that.
1987 if (!get_pty(&mfd, &local_fd, slave, 0)) {
1988 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1993 * Try to put the device into the PPP discipline.
1995 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1996 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2005 /********************************************************************
2007 * ppp_available - check whether the system has any ppp interfaces
2008 * (in fact we check whether we can do an ioctl on ppp0).
2011 int ppp_available(void)
2016 int my_version, my_modification, my_patch;
2017 int osmaj, osmin, ospatch;
2020 "This system lacks kernel support for PPP. This could be because\n"
2021 "the PPP kernel module could not be loaded, or because PPP was not\n"
2022 "included in the kernel configuration. If PPP was included as a\n"
2023 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2024 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2025 "See README.linux file in the ppp distribution for more details.\n";
2027 /* get the kernel version now, since we are called before sys_init */
2029 osmaj = osmin = ospatch = 0;
2030 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2031 kernel_version = KVERSION(osmaj, osmin, ospatch);
2033 fd = open("/dev/ppp", O_RDWR);
2035 if (fd < 0 && errno == ENOENT) {
2036 /* try making it and see if that helps. */
2037 if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR,
2038 makedev(108, 0)) >= 0) {
2039 fd = open("/dev/ppp", O_RDWR);
2041 info("Created /dev/ppp device node");
2043 unlink("/dev/ppp"); /* didn't work, undo the mknod */
2044 } else if (errno == EEXIST) {
2045 fd = open("/dev/ppp", O_RDWR);
2050 new_style_driver = 1;
2052 /* XXX should get from driver */
2054 driver_modification = 4;
2059 if (kernel_version >= KVERSION(2,3,13)) {
2060 if (errno == ENOENT)
2062 "pppd is unable to open the /dev/ppp device.\n"
2063 "You need to create the /dev/ppp device node by\n"
2064 "executing the following command as root:\n"
2065 " mknod /dev/ppp c 108 0\n";
2070 * Open a socket for doing the ioctl operations.
2072 s = socket(AF_INET, SOCK_DGRAM, 0);
2076 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2077 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2079 * If the device did not exist then attempt to create one by putting the
2080 * current tty into the PPP discipline. If this works then obtain the
2081 * flags for the device again.
2084 if (ppp_registered()) {
2085 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2086 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2090 * Ensure that the hardware address is for PPP and not something else
2093 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2095 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2099 * This is the PPP device. Validate the version of the driver at this
2100 * point to ensure that this program will work with the driver.
2103 char abBuffer [1024];
2105 ifr.ifr_data = abBuffer;
2106 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2108 error("Couldn't read driver version: %m");
2110 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2113 decode_version(abBuffer,
2115 &driver_modification,
2118 * Validate the version of the driver against the version that we used.
2120 decode_version(VERSION,
2125 /* The version numbers must match */
2126 if (driver_version != my_version)
2129 /* The modification levels must be legal */
2130 if (driver_modification < 3) {
2131 if (driver_modification >= 2) {
2132 /* we can cope with 2.2.0 and above */
2141 slprintf(route_buffer, sizeof(route_buffer),
2142 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2143 driver_version, driver_modification, driver_patch);
2145 no_ppp_msg = route_buffer;
2152 /********************************************************************
2154 * Update the wtmp file with the appropriate user name and tty device.
2157 void logwtmp (const char *line, const char *name, const char *host)
2159 struct utmp ut, *utp;
2160 pid_t mypid = getpid();
2166 * Update the signon database for users.
2167 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2169 utmpname(_PATH_UTMP);
2171 while ((utp = getutent()) && (utp->ut_pid != mypid))
2175 memcpy(&ut, utp, sizeof(ut));
2177 /* some gettys/telnetds don't initialize utmp... */
2178 memset(&ut, 0, sizeof(ut));
2180 if (ut.ut_id[0] == 0)
2181 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2183 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2184 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2188 ut.ut_type = USER_PROCESS;
2191 /* Insert the host name if one is supplied */
2193 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2195 /* Insert the IP address of the remote system if IP is enabled */
2196 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2197 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2198 sizeof(ut.ut_addr));
2200 /* CL: Makes sure that the logout works */
2201 if (*host == 0 && *name==0)
2207 * Update the wtmp file.
2210 updwtmp(_PATH_WTMP, &ut);
2212 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2214 flock(wtmp, LOCK_EX);
2216 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2217 warn("error writing %s: %m", _PATH_WTMP);
2219 flock(wtmp, LOCK_UN);
2227 /********************************************************************
2229 * sifvjcomp - config tcp header compression
2232 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2237 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)
2238 error("Couldn't set up TCP header compression: %m");
2242 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2243 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2248 /********************************************************************
2250 * sifup - Config the interface up and enable IP packets to pass.
2257 memset (&ifr, '\0', sizeof (ifr));
2258 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2259 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2260 if (! ok_error (errno))
2261 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2265 ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2266 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2267 if (! ok_error (errno))
2268 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2276 /********************************************************************
2278 * sifdown - Disable the indicated protocol and config the interface
2279 * down if there are no remaining protocols.
2286 if (if_is_up && --if_is_up > 0)
2289 memset (&ifr, '\0', sizeof (ifr));
2290 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2291 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2292 if (! ok_error (errno))
2293 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2297 ifr.ifr_flags &= ~IFF_UP;
2298 ifr.ifr_flags |= IFF_POINTOPOINT;
2299 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2300 if (! ok_error (errno))
2301 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2307 /********************************************************************
2309 * sifaddr - Config the interface IP addresses and netmask.
2312 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2318 memset (&ifr, '\0', sizeof (ifr));
2319 memset (&rt, '\0', sizeof (rt));
2321 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2322 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2323 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2325 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2327 * Set our IP address
2329 SIN_ADDR(ifr.ifr_addr) = our_adr;
2330 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2331 if (errno != EEXIST) {
2332 if (! ok_error (errno))
2333 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2336 warn("ioctl(SIOCSIFADDR): Address already exists");
2341 * Set the gateway address
2343 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2344 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2345 if (! ok_error (errno))
2346 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2351 * For recent kernels, force the netmask to 255.255.255.255.
2353 if (kernel_version >= KVERSION(2,1,16))
2355 if (net_mask != 0) {
2356 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2357 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2358 if (! ok_error (errno))
2359 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2364 * Add the device route
2366 if (kernel_version < KVERSION(2,1,16)) {
2367 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2368 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2371 SIN_ADDR(rt.rt_gateway) = 0L;
2372 SIN_ADDR(rt.rt_dst) = his_adr;
2373 rt.rt_flags = RTF_UP | RTF_HOST;
2375 if (kernel_version > KVERSION(2,1,0)) {
2376 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2377 SIN_ADDR(rt.rt_genmask) = -1L;
2380 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2381 if (! ok_error (errno))
2382 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2387 /* set ip_dynaddr in demand mode if address changes */
2388 if (demand && tune_kernel && !dynaddr_set
2389 && our_old_addr && our_old_addr != our_adr) {
2390 /* set ip_dynaddr if possible */
2394 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2395 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2396 if (write(fd, "1", 1) != 1)
2397 error("Couldn't enable dynamic IP addressing: %m");
2400 dynaddr_set = 1; /* only 1 attempt */
2407 /********************************************************************
2409 * cifaddr - Clear the interface IP addresses, and delete routes
2410 * through the interface if possible.
2413 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2417 if (kernel_version < KVERSION(2,1,16)) {
2419 * Delete the route through the device
2422 memset (&rt, '\0', sizeof (rt));
2424 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2425 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2428 SIN_ADDR(rt.rt_gateway) = 0;
2429 SIN_ADDR(rt.rt_dst) = his_adr;
2430 rt.rt_flags = RTF_UP | RTF_HOST;
2432 if (kernel_version > KVERSION(2,1,0)) {
2433 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2434 SIN_ADDR(rt.rt_genmask) = -1L;
2437 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2438 if (still_ppp() && ! ok_error (errno))
2439 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2444 /* This way it is possible to have an IPX-only or IPv6-only interface */
2445 memset(&ifr, 0, sizeof(ifr));
2446 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2447 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2449 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2450 if (! ok_error (errno)) {
2451 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2456 our_old_addr = our_adr;
2462 /********************************************************************
2464 * sif6addr - Config the interface with an IPv6 link-local address
2466 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2468 struct in6_ifreq ifr6;
2470 struct in6_rtmsg rt6;
2474 error("IPv6 socket creation failed: %m");
2477 memset(&ifr, 0, sizeof (ifr));
2478 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2479 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2480 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2484 /* Local interface */
2485 memset(&ifr6, 0, sizeof(ifr6));
2486 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2487 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2488 ifr6.ifr6_prefixlen = 10;
2490 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2491 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2495 /* Route to remote host */
2496 memset(&rt6, 0, sizeof(rt6));
2497 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2498 rt6.rtmsg_flags = RTF_UP;
2499 rt6.rtmsg_dst_len = 10;
2500 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2501 rt6.rtmsg_metric = 1;
2503 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2504 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2512 /********************************************************************
2514 * cif6addr - Remove IPv6 address from interface
2516 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2519 struct in6_ifreq ifr6;
2523 error("IPv6 socket creation failed: %m");
2526 memset(&ifr, 0, sizeof(ifr));
2527 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2528 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2529 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2533 memset(&ifr6, 0, sizeof(ifr6));
2534 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2535 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2536 ifr6.ifr6_prefixlen = 10;
2538 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2539 if (errno != EADDRNOTAVAIL) {
2540 if (! ok_error (errno))
2541 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2544 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2553 * get_pty - get a pty master/slave pair and chown the slave side
2554 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2557 get_pty(master_fdp, slave_fdp, slave_name, uid)
2563 int i, mfd, sfd = -1;
2565 struct termios tios;
2569 * Try the unix98 way first.
2571 mfd = open("/dev/ptmx", O_RDWR);
2574 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2575 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2576 chmod(pty_name, S_IRUSR | S_IWUSR);
2579 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2580 warn("Couldn't unlock pty slave %s: %m", pty_name);
2582 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2583 warn("Couldn't open pty slave %s: %m", pty_name);
2586 #endif /* TIOCGPTN */
2589 /* the old way - scan through the pty name space */
2590 for (i = 0; i < 64; ++i) {
2591 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2592 'p' + i / 16, i % 16);
2593 mfd = open(pty_name, O_RDWR, 0);
2596 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2598 fchown(sfd, uid, -1);
2599 fchmod(sfd, S_IRUSR | S_IWUSR);
2610 strlcpy(slave_name, pty_name, 16);
2613 if (tcgetattr(sfd, &tios) == 0) {
2614 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2615 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2616 tios.c_iflag = IGNPAR;
2619 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2620 warn("couldn't set attributes on pty: %m");
2622 warn("couldn't get attributes on pty: %m");
2627 /********************************************************************
2629 * open_loopback - open the device we use for getting packets
2630 * in demand mode. Under Linux, we use a pty master/slave pair.
2633 open_ppp_loopback(void)
2638 if (new_style_driver) {
2639 /* allocate ourselves a ppp unit */
2640 if (make_ppp_unit() < 0)
2642 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2643 set_kdebugflag(kdebugflag);
2648 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2649 fatal("No free pty for loopback");
2650 SYSDEBUG(("using %s for loopback", loop_name));
2652 set_ppp_fd(slave_fd);
2654 flags = fcntl(master_fd, F_GETFL);
2656 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2657 warn("couldn't set master loopback to nonblock: %m");
2659 flags = fcntl(ppp_fd, F_GETFL);
2661 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2662 warn("couldn't set slave loopback to nonblock: %m");
2664 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2665 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2667 * Find out which interface we were given.
2669 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2670 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2672 * Enable debug in the driver if requested.
2674 set_kdebugflag (kdebugflag);
2679 /********************************************************************
2681 * sifnpmode - Set the mode for handling packets for a given NP.
2685 sifnpmode(u, proto, mode)
2692 npi.protocol = proto;
2694 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2695 if (! ok_error (errno))
2696 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2703 /********************************************************************
2705 * sipxfaddr - Config the interface IPX networknumber
2708 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2715 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2717 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2719 if (! ok_error (errno))
2720 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2724 memset (&ifr, '\0', sizeof (ifr));
2725 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2727 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2728 sipx->sipx_family = AF_IPX;
2729 sipx->sipx_port = 0;
2730 sipx->sipx_network = htonl (network);
2731 sipx->sipx_type = IPX_FRAME_ETHERII;
2732 sipx->sipx_action = IPX_CRTITF;
2734 * Set the IPX device
2736 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2738 if (errno != EEXIST) {
2739 if (! ok_error (errno))
2740 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2743 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2752 /********************************************************************
2754 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2755 * are removed and the device is no longer able to pass IPX
2759 int cipxfaddr (int unit)
2766 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2768 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2770 if (! ok_error (errno))
2771 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2775 memset (&ifr, '\0', sizeof (ifr));
2776 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2778 sipx->sipx_type = IPX_FRAME_ETHERII;
2779 sipx->sipx_action = IPX_DLTITF;
2780 sipx->sipx_family = AF_IPX;
2782 * Set the IPX device
2784 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2785 if (! ok_error (errno))
2786 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2796 * Use the hostname as part of the random number seed.
2805 for (p = hostname; *p != 0; ++p)
2810 /********************************************************************
2812 * sys_check_options - check the options that the user specified
2816 sys_check_options(void)
2820 * Disable the IPX protocol if the support is not present in the kernel.
2824 if (ipxcp_protent.enabled_flag) {
2825 struct stat stat_buf;
2826 if ((path = path_to_procfs("/net/ipx_interface")) == 0
2827 || lstat(path, &stat_buf) < 0) {
2828 error("IPX support is not present in the kernel\n");
2829 ipxcp_protent.enabled_flag = 0;
2833 if (demand && driver_is_old) {
2834 option_error("demand dialling is not supported by kernel driver "
2835 "version %d.%d.%d", driver_version, driver_modification,
2839 if (multilink && !new_style_driver) {
2840 warn("Warning: multilink is not supported by the kernel driver");
2848 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2850 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2851 * that the system has a properly configured Ethernet interface for this
2852 * function to return non-zero.
2855 ether_to_eui64(eui64_t *p_eui64)
2859 const unsigned char *ptr;
2861 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2864 warn("could not open IPv6 socket");
2868 strcpy(ifr.ifr_name, "eth0");
2869 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2872 warn("could not obtain hardware address for eth0");
2878 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2880 ptr = ifr.ifr_hwaddr.sa_data;
2881 p_eui64->e8[0] = ptr[0] | 0x02;
2882 p_eui64->e8[1] = ptr[1];
2883 p_eui64->e8[2] = ptr[2];
2884 p_eui64->e8[3] = 0xFF;
2885 p_eui64->e8[4] = 0xFE;
2886 p_eui64->e8[5] = ptr[3];
2887 p_eui64->e8[6] = ptr[4];
2888 p_eui64->e8[7] = ptr[5];