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 */
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;
186 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
187 static int chindex; /* channel index (new style driver) */
189 static fd_set in_fds; /* set of fds that wait_input waits for */
190 static int max_in_fd; /* highest fd set in in_fds */
192 static int has_proxy_arp = 0;
193 static int driver_version = 0;
194 static int driver_modification = 0;
195 static int driver_patch = 0;
196 static int driver_is_old = 0;
197 static int restore_term = 0; /* 1 => we've munged the terminal */
198 static struct termios inittermios; /* Initial TTY termios */
200 int new_style_driver = 0;
202 static char loop_name[20];
203 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
205 static int if_is_up; /* Interface has been marked up */
206 static u_int32_t default_route_gateway; /* Gateway for default route added */
207 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
208 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
209 static u_int32_t our_old_addr; /* for detecting address changes */
210 static int dynaddr_set; /* 1 if ip_dynaddr set */
211 static int looped; /* 1 if using loop */
212 static int link_mtu; /* mtu for the link (not bundle) */
214 static struct utsname utsname; /* for the kernel version */
215 static int kernel_version;
216 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
220 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
221 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
222 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
224 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
226 /* Prototypes for procedures local to this file. */
227 static int get_flags (int fd);
228 static int set_flags (int fd, int flags);
229 static int translate_speed (int bps);
230 static int baud_rate_of (int speed);
231 static void close_route_table (void);
232 static int open_route_table (void);
233 static int read_route_table (struct rtentry *rt);
234 static int defaultroute_exists (struct rtentry *rt);
235 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
236 char *name, int namelen);
237 static void decode_version (char *buf, int *version, int *mod, int *patch);
238 static int set_kdebugflag(int level);
239 static int ppp_registered(void);
240 static int make_ppp_unit(void);
242 extern u_char inpacket_buf[]; /* borrowed from main.c */
245 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
249 #define SET_SA_FAMILY(addr, family) \
250 memset ((char *) &(addr), '\0', sizeof(addr)); \
251 addr.sa_family = (family);
254 * Determine if the PPP connection should still be present.
259 /* new_fd is the fd of a tty */
260 static void set_ppp_fd (int new_fd)
262 SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
264 if (!new_style_driver)
268 static int still_ppp(void)
270 if (new_style_driver)
271 return !hungup && ppp_fd >= 0;
272 if (!hungup || ppp_fd == slave_fd)
275 set_ppp_fd(slave_fd);
281 /********************************************************************
283 * Functions to read and set the flags value in the device driver
286 static int get_flags (int fd)
290 if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) {
291 if ( ok_error (errno) )
294 fatal("ioctl(PPPIOCGFLAGS): %m (line %d)", __LINE__);
297 SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags));
301 /********************************************************************/
303 static int set_flags (int fd, int flags)
305 SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
307 if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
308 if (! ok_error (errno) )
309 error("Failed to set PPP kernel option flags: %m", flags);
315 /********************************************************************
317 * sys_init - System-dependent initialization.
322 /* Get an internet socket for doing socket ioctls. */
323 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
325 fatal("Couldn't create IP socket: %m(%d)", errno);
328 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
330 sock6_fd = -errno; /* save errno for later */
337 /********************************************************************
339 * sys_cleanup - restore any system state we modified before exiting:
340 * mark the interface down, delete default route and/or proxy arp entry.
341 * This shouldn't call die() because it's called from die().
344 void sys_cleanup(void)
347 * Take down the device
354 * Delete any routes through the device.
356 if (default_route_gateway != 0)
357 cifdefaultroute(0, 0, default_route_gateway);
360 cifproxyarp(0, proxy_arp_addr);
363 /********************************************************************
365 * sys_close - Clean up in a child process before execing.
370 if (new_style_driver)
384 /********************************************************************
386 * set_kdebugflag - Define the debugging level for the kernel
389 static int set_kdebugflag (int requested_level)
391 if (new_style_driver && ifunit < 0)
393 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
394 if ( ! ok_error (errno) )
395 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
398 SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
403 /********************************************************************
405 * tty_establish_ppp - Turn the serial port into a ppp interface.
408 int tty_establish_ppp (int tty_fd)
413 * Ensure that the tty device is in exclusive mode.
415 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
416 if ( ! ok_error ( errno ))
417 warn("Couldn't make tty exclusive: %m");
420 * Demand mode - prime the old ppp device to relinquish the unit.
422 if (!new_style_driver && looped
423 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
424 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
428 * Set the current tty to the PPP discpline
432 #define N_SYNC_PPP 14
434 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
435 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
436 if ( ! ok_error (errno) ) {
437 error("Couldn't set tty to PPP discipline: %m");
442 ret_fd = generic_establish_ppp(tty_fd);
444 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
445 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
449 set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB))
450 | ((kdebugflag * SC_DEBUG) & SC_LOGB)));
452 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
453 warn("Couldn't reset tty to normal line discipline: %m");
459 /********************************************************************
461 * generic_establish_ppp - Turn the fd into a ppp interface.
463 int generic_establish_ppp (int fd)
467 if (new_style_driver) {
470 /* Open an instance of /dev/ppp and connect the channel to it */
471 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
472 error("Couldn't get channel number: %m");
475 dbglog("using channel %d", chindex);
476 fd = open("/dev/ppp", O_RDWR);
478 error("Couldn't reopen /dev/ppp: %m");
481 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
482 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
483 error("Couldn't attach to channel %d: %m", chindex);
486 flags = fcntl(fd, F_GETFL);
487 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
488 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
493 if (!looped && !multilink) {
495 * Create a new PPP unit.
497 if (make_ppp_unit() < 0)
502 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC);
506 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
507 error("Couldn't attach to PPP unit %d: %m", ifunit);
514 * Old-style driver: find out which interface we were given.
517 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
518 if (ok_error (errno))
520 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
522 /* Check that we got the same unit again. */
523 if (looped && x != ifunit)
524 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
528 * Fetch the initial file flags and reset blocking mode on the file.
530 initfdflags = fcntl(fd, F_GETFL);
531 if (initfdflags == -1 ||
532 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
533 if ( ! ok_error (errno))
534 warn("Couldn't set device to non-blocking mode: %m");
541 * Enable debug in the driver if requested.
544 set_kdebugflag (kdebugflag);
546 SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
547 driver_version, driver_modification, driver_patch));
557 /********************************************************************
559 * tty_disestablish_ppp - Restore the serial port to normal operation.
560 * This shouldn't call die() because it's called from die().
563 void tty_disestablish_ppp(int tty_fd)
567 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
569 if (tcflush(tty_fd, TCIOFLUSH) < 0)
571 warn("tcflush failed: %m");
575 * Restore the previous line discipline
577 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
578 if ( ! ok_error (errno))
579 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
582 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
583 if ( ! ok_error (errno))
584 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
587 /* Reset non-blocking mode on fd. */
588 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
589 if ( ! ok_error (errno))
590 warn("Couldn't restore device fd flags: %m");
596 generic_disestablish_ppp(tty_fd);
599 /********************************************************************
601 * generic_disestablish_ppp - Restore device components to normal
602 * operation, and reconnect the ppp unit to the loopback if in demand
603 * mode. This shouldn't call die() because it's called from die().
605 void generic_disestablish_ppp(int dev_fd)
607 if (new_style_driver) {
611 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC);
613 } else if (ifunit >= 0) {
615 remove_fd(ppp_dev_fd);
619 /* old-style driver */
621 set_ppp_fd(slave_fd);
626 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
627 * Assumes new_style_driver.
629 static int make_ppp_unit()
633 if (ppp_dev_fd >= 0) {
634 dbglog("in make_ppp_unit, already had /dev/ppp open?");
637 ppp_dev_fd = open("/dev/ppp", O_RDWR);
639 fatal("Couldn't open /dev/ppp: %m");
640 flags = fcntl(ppp_dev_fd, F_GETFL);
642 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
643 warn("Couldn't set /dev/ppp to nonblock: %m");
646 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
647 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
648 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
650 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
653 error("Couldn't create new ppp unit: %m");
658 * cfg_bundle - configure the existing bundle.
659 * Used in demand mode.
661 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
665 if (!new_style_driver)
668 /* set the mrru, mtu and flags */
669 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
670 error("Couldn't set MRRU: %m");
671 flags = get_flags(ppp_dev_fd);
672 flags &= ~(SC_MP_SHORTSEQ | SC_MP_XSHORTSEQ);
673 flags |= (rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
674 | (mrru? SC_MULTILINK: 0);
676 set_flags(ppp_dev_fd, flags);
678 /* connect up the channel */
679 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
680 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
685 * make_new_bundle - create a new PPP unit (i.e. a bundle)
686 * and connect our channel to it. This should only get called
687 * if `multilink' was set at the time establish_ppp was called.
688 * In demand mode this uses our existing bundle instead of making
691 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
693 if (!new_style_driver)
696 /* make us a ppp unit */
697 if (make_ppp_unit() < 0)
700 /* set the mrru and flags */
701 cfg_bundle(mrru, mtru, rssn, tssn);
705 * bundle_attach - attach our link to a given PPP unit.
706 * We assume the unit is controlled by another pppd.
708 int bundle_attach(int ifnum)
712 if (!new_style_driver)
715 master_fd = open("/dev/ppp", O_RDWR);
717 fatal("Couldn't open /dev/ppp: %m");
718 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
719 if (errno == ENXIO) {
721 return 0; /* doesn't still exist */
723 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
725 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
726 fatal("Couldn't connect to interface unit %d: %m", ifnum);
727 set_flags(master_fd, get_flags(master_fd) | SC_MULTILINK);
734 /********************************************************************
736 * clean_check - Fetch the flags for the device and generate
737 * appropriate error messages.
739 void clean_check(void)
745 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
747 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
749 s = "all had bit 7 set to 1";
753 s = "all had bit 7 set to 0";
757 s = "all had odd parity";
761 s = "all had even parity";
766 warn("Receive serial link is not 8-bit clean:");
767 warn("Problem: %s", s);
775 * List of valid speeds.
779 int speed_int, speed_val;
862 /********************************************************************
864 * Translate from bits/second to a speed_t.
867 static int translate_speed (int bps)
869 struct speed *speedp;
872 for (speedp = speeds; speedp->speed_int; speedp++) {
873 if (bps == speedp->speed_int)
874 return speedp->speed_val;
876 warn("speed %d not supported", bps);
881 /********************************************************************
883 * Translate from a speed_t to bits/second.
886 static int baud_rate_of (int speed)
888 struct speed *speedp;
891 for (speedp = speeds; speedp->speed_int; speedp++) {
892 if (speed == speedp->speed_val)
893 return speedp->speed_int;
899 /********************************************************************
901 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
902 * at the requested speed, etc. If `local' is true, set CLOCAL
903 * regardless of whether the modem option was specified.
906 void set_up_tty(int tty_fd, int local)
912 if (tcgetattr(tty_fd, &tios) < 0) {
913 if (!ok_error(errno))
914 fatal("tcgetattr: %m (line %d)", __LINE__);
921 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
922 tios.c_cflag |= CS8 | CREAD | HUPCL;
924 tios.c_iflag = IGNBRK | IGNPAR;
928 tios.c_cc[VTIME] = 0;
931 tios.c_cflag ^= (CLOCAL | HUPCL);
935 tios.c_cflag |= CRTSCTS;
939 tios.c_iflag |= IXON | IXOFF;
940 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
941 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
945 tios.c_cflag &= ~CRTSCTS;
952 speed = translate_speed(inspeed);
954 cfsetospeed (&tios, speed);
955 cfsetispeed (&tios, speed);
958 * We can't proceed if the serial port speed is B0,
959 * since that implies that the serial port is disabled.
962 speed = cfgetospeed(&tios);
964 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
967 if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0)
968 if (!ok_error(errno))
969 fatal("tcsetattr: %m (line %d)", __LINE__);
971 baud_rate = baud_rate_of(speed);
975 /********************************************************************
977 * setdtr - control the DTR line on the serial port.
978 * This is called from die(), so it shouldn't call die().
981 void setdtr (int tty_fd, int on)
983 int modembits = TIOCM_DTR;
985 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
988 /********************************************************************
990 * restore_tty - restore the terminal to the saved settings.
993 void restore_tty (int tty_fd)
998 * Turn off echoing, because otherwise we can get into
999 * a loop with the tty and the modem echoing to each other.
1000 * We presume we are the sole user of this tty device, so
1001 * when we close it, it will revert to its defaults anyway.
1003 if (!default_device)
1004 inittermios.c_lflag &= ~(ECHO | ECHONL);
1006 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1007 if (! ok_error (errno))
1008 warn("tcsetattr: %m (line %d)", __LINE__);
1013 /********************************************************************
1015 * output - Output PPP packet.
1018 void output (int unit, unsigned char *p, int len)
1023 dump_packet("sent", p, len);
1024 if (snoop_send_hook) snoop_send_hook(p, len);
1026 if (len < PPP_HDRLEN)
1028 if (new_style_driver) {
1031 proto = (p[0] << 8) + p[1];
1032 if (ifunit >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1035 if (write(fd, p, len) < 0) {
1036 if (errno == EWOULDBLOCK || errno == ENOBUFS
1037 || errno == ENXIO || errno == EIO || errno == EINTR)
1038 warn("write: warning: %m (%d)", errno);
1040 error("write: %m (%d)", errno);
1044 /********************************************************************
1046 * wait_input - wait until there is data available,
1047 * for the length of time specified by *timo (indefinite
1051 void wait_input(struct timeval *timo)
1058 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1059 if (n < 0 && errno != EINTR)
1060 fatal("select: %m");
1064 * add_fd - add an fd to the set that wait_input waits for.
1068 if (fd >= FD_SETSIZE)
1069 fatal("internal error: file descriptor too large (%d)", fd);
1070 FD_SET(fd, &in_fds);
1076 * remove_fd - remove an fd from the set that wait_input waits for.
1078 void remove_fd(int fd)
1080 FD_CLR(fd, &in_fds);
1084 /********************************************************************
1086 * read_packet - get a PPP packet from the serial device.
1089 int read_packet (unsigned char *buf)
1093 len = PPP_MRU + PPP_HDRLEN;
1094 if (new_style_driver) {
1095 *buf++ = PPP_ALLSTATIONS;
1101 nr = read(ppp_fd, buf, len);
1102 if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
1104 if (nr < 0 && errno == ENXIO)
1107 if (nr < 0 && new_style_driver && ifunit >= 0) {
1108 /* N.B. we read ppp_fd first since LCP packets come in there. */
1109 nr = read(ppp_dev_fd, buf, len);
1110 if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
1111 error("read /dev/ppp: %m");
1112 if (nr < 0 && errno == ENXIO)
1115 return (new_style_driver && nr > 0)? nr+2: nr;
1118 /********************************************************************
1120 * get_loop_output - get outgoing packets from the ppp device,
1121 * and detect when we want to bring the real link up.
1122 * Return value is 1 if we need to bring up the link, 0 otherwise.
1125 get_loop_output(void)
1130 if (new_style_driver) {
1131 while ((n = read_packet(inpacket_buf)) > 0)
1132 if (loop_frame(inpacket_buf, n))
1137 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1138 if (loop_chars(inbuf, n))
1142 fatal("eof on loopback");
1144 if (errno != EWOULDBLOCK)
1145 fatal("read from loopback: %m(%d)", errno);
1151 * netif_set_mtu - set the MTU on the PPP network interface.
1154 netif_set_mtu(int unit, int mtu)
1158 SYSDEBUG ((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu));
1160 memset (&ifr, '\0', sizeof (ifr));
1161 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1164 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1165 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1169 * netif_get_mtu - get the MTU on the PPP network interface.
1172 netif_get_mtu(int unit)
1176 memset (&ifr, '\0', sizeof (ifr));
1177 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1179 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1180 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1186 /********************************************************************
1188 * tty_send_config - configure the transmit characteristics of
1189 * the ppp interface.
1192 int tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
1197 * Set the asyncmap and other parameters for the ppp device
1202 SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
1203 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1204 if (errno != EIO && errno != ENOTTY)
1205 error("Couldn't set transmit async character map: %m");
1207 dbglog("PPPIOCSASYNCMAP: %m");
1211 x = get_flags(ppp_fd);
1212 x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
1213 x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
1214 x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
1215 return set_flags(ppp_fd, x);
1218 /********************************************************************
1220 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1223 void tty_set_xaccm (ext_accm accm)
1225 SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
1226 accm[0], accm[1], accm[2], accm[3]));
1230 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1231 if ( ! ok_error (errno))
1232 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1236 /********************************************************************
1238 * tty_recv_config - configure the receive-side characteristics of
1239 * the ppp interface.
1242 int tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp)
1246 SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
1248 * If we were called because the link has gone down then there is nothing
1249 * which may be done. Just return without incident.
1254 * Set the receiver parameters
1256 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1257 if (errno != EIO && errno != ENOTTY)
1258 error("Couldn't set channel receive MRU: %m");
1260 dbglog("PPPIOCSMRU: %m");
1263 if (new_style_driver && ifunit >= 0
1264 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1265 error("Couldn't set MRU in generic PPP layer: %m");
1269 SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
1270 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1271 if (errno != EIO && errno != ENOTTY)
1272 error("Couldn't set channel receive asyncmap: %m");
1274 dbglog("PPPIOCSRASYNCMAP: %m");
1280 /********************************************************************
1282 * ccp_test - ask kernel whether a given compression method
1283 * is acceptable for use.
1287 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1289 struct ppp_option_data data;
1291 memset (&data, '\0', sizeof (data));
1293 data.length = opt_len;
1294 data.transmit = for_transmit;
1296 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1299 return (errno == ENOBUFS)? 0: -1;
1302 /********************************************************************
1304 * ccp_flags_set - inform kernel about the current state of CCP.
1307 void ccp_flags_set (int unit, int isopen, int isup)
1309 if (still_ppp() && ifunit >= 0) {
1310 int x = get_flags(ppp_dev_fd);
1311 x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;
1312 x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP;
1313 set_flags (ppp_dev_fd, x);
1319 * set_filters - set the active and pass filters in the kernel driver.
1321 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1323 struct sock_fprog fp;
1325 fp.len = pass->bf_len;
1326 fp.filter = (struct sock_filter *) pass->bf_insns;
1327 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1328 if (errno == ENOTTY)
1329 warn("kernel does not support PPP filtering");
1331 error("Couldn't set pass-filter in kernel: %m");
1334 fp.len = active->bf_len;
1335 fp.filter = (struct sock_filter *) active->bf_insns;
1336 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1337 error("Couldn't set active-filter in kernel: %m");
1342 #endif /* PPP_FILTER */
1344 /********************************************************************
1346 * get_idle_time - return how long the link has been idle.
1349 get_idle_time(u, ip)
1351 struct ppp_idle *ip;
1353 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1356 /********************************************************************
1358 * get_ppp_stats - return statistics for the link.
1361 get_ppp_stats(u, stats)
1363 struct pppd_stats *stats;
1365 struct ifpppstatsreq req;
1367 memset (&req, 0, sizeof (req));
1369 req.stats_ptr = (caddr_t) &req.stats;
1370 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1371 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1372 error("Couldn't get PPP statistics: %m");
1375 stats->bytes_in = req.stats.p.ppp_ibytes;
1376 stats->bytes_out = req.stats.p.ppp_obytes;
1377 stats->pkts_in = req.stats.p.ppp_ipackets;
1378 stats->pkts_out = req.stats.p.ppp_opackets;
1382 /********************************************************************
1384 * ccp_fatal_error - returns 1 if decompression was disabled as a
1385 * result of an error detected after decompression of a packet,
1386 * 0 otherwise. This is necessary because of patent nonsense.
1389 int ccp_fatal_error (int unit)
1391 int x = get_flags(ppp_dev_fd);
1393 return x & SC_DC_FERROR;
1396 /********************************************************************
1398 * path_to_procfs - find the path to the proc file system mount point
1400 static char proc_path[MAXPATHLEN];
1401 static int proc_path_len;
1403 static char *path_to_procfs(const char *tail)
1405 struct mntent *mntent;
1408 if (proc_path_len == 0) {
1409 /* Default the mount location of /proc */
1410 strlcpy (proc_path, "/proc", sizeof(proc_path));
1412 fp = fopen(MOUNTED, "r");
1414 while ((mntent = getmntent(fp)) != NULL) {
1415 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1417 if (strcmp(mntent->mnt_type, "proc") == 0) {
1418 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1419 proc_path_len = strlen(proc_path);
1427 strlcpy(proc_path + proc_path_len, tail,
1428 sizeof(proc_path) - proc_path_len);
1433 * /proc/net/route parsing stuff.
1435 #define ROUTE_MAX_COLS 12
1436 FILE *route_fd = (FILE *) 0;
1437 static char route_buffer[512];
1438 static int route_dev_col, route_dest_col, route_gw_col;
1439 static int route_flags_col, route_mask_col;
1440 static int route_num_cols;
1442 static int open_route_table (void);
1443 static void close_route_table (void);
1444 static int read_route_table (struct rtentry *rt);
1446 /********************************************************************
1448 * close_route_table - close the interface to the route table
1451 static void close_route_table (void)
1453 if (route_fd != (FILE *) 0) {
1455 route_fd = (FILE *) 0;
1459 /********************************************************************
1461 * open_route_table - open the interface to the route table
1463 static char route_delims[] = " \t\n";
1465 static int open_route_table (void)
1469 close_route_table();
1471 path = path_to_procfs("/net/route");
1472 route_fd = fopen (path, "r");
1473 if (route_fd == NULL) {
1474 error("can't open routing table %s: %m", path);
1478 route_dev_col = 0; /* default to usual columns */
1481 route_flags_col = 3;
1485 /* parse header line */
1486 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1487 char *p = route_buffer, *q;
1489 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1491 if ((q = strtok(p, route_delims)) == 0)
1493 if (strcasecmp(q, "iface") == 0)
1494 route_dev_col = col;
1495 else if (strcasecmp(q, "destination") == 0)
1496 route_dest_col = col;
1497 else if (strcasecmp(q, "gateway") == 0)
1499 else if (strcasecmp(q, "flags") == 0)
1500 route_flags_col = col;
1501 else if (strcasecmp(q, "mask") == 0)
1502 route_mask_col = col;
1505 if (used && col >= route_num_cols)
1506 route_num_cols = col + 1;
1514 /********************************************************************
1516 * read_route_table - read the next entry from the route table
1519 static int read_route_table(struct rtentry *rt)
1521 char *cols[ROUTE_MAX_COLS], *p;
1524 memset (rt, '\0', sizeof (struct rtentry));
1526 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1530 for (col = 0; col < route_num_cols; ++col) {
1531 cols[col] = strtok(p, route_delims);
1532 if (cols[col] == NULL)
1533 return 0; /* didn't get enough columns */
1537 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1538 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1539 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1541 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1542 rt->rt_dev = cols[route_dev_col];
1547 /********************************************************************
1549 * defaultroute_exists - determine if there is a default route
1552 static int defaultroute_exists (struct rtentry *rt)
1556 if (!open_route_table())
1559 while (read_route_table(rt) != 0) {
1560 if ((rt->rt_flags & RTF_UP) == 0)
1563 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1565 if (SIN_ADDR(rt->rt_dst) == 0L) {
1571 close_route_table();
1576 * have_route_to - determine if the system has any route to
1577 * a given IP address. `addr' is in network byte order.
1578 * Return value is 1 if yes, 0 if no, -1 if don't know.
1579 * For demand mode to work properly, we have to ignore routes
1580 * through our own interface.
1582 int have_route_to(u_int32_t addr)
1587 if (!open_route_table())
1588 return -1; /* don't know */
1590 while (read_route_table(&rt)) {
1591 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1593 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1599 close_route_table();
1603 /********************************************************************
1605 * sifdefaultroute - assign a default route through the address given.
1608 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1612 if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1613 u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1615 if (old_gateway != gateway)
1616 error("not replacing existing default route to %s [%I]",
1617 rt.rt_dev, old_gateway);
1621 memset (&rt, '\0', sizeof (rt));
1622 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1623 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1627 if (kernel_version > KVERSION(2,1,0)) {
1628 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1629 SIN_ADDR(rt.rt_genmask) = 0L;
1632 SIN_ADDR(rt.rt_gateway) = gateway;
1634 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1635 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1636 if ( ! ok_error ( errno ))
1637 error("default route ioctl(SIOCADDRT): %m");
1641 default_route_gateway = gateway;
1645 /********************************************************************
1647 * cifdefaultroute - delete a default route through the address given.
1650 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1654 default_route_gateway = 0;
1656 memset (&rt, '\0', sizeof (rt));
1657 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1658 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
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 SIN_ADDR(rt.rt_gateway) = gateway;
1667 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1668 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1670 if ( ! ok_error ( errno ))
1671 error("default route ioctl(SIOCDELRT): %m");
1679 /********************************************************************
1681 * sifproxyarp - Make a proxy ARP entry for the peer.
1684 int sifproxyarp (int unit, u_int32_t his_adr)
1686 struct arpreq arpreq;
1689 if (has_proxy_arp == 0) {
1690 memset (&arpreq, '\0', sizeof(arpreq));
1692 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1693 SIN_ADDR(arpreq.arp_pa) = his_adr;
1694 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1696 * Get the hardware address of an interface on the same subnet
1697 * as our local address.
1699 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1700 sizeof(proxy_arp_dev))) {
1701 error("Cannot determine ethernet address for proxy ARP");
1704 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1706 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1707 if ( ! ok_error ( errno ))
1708 error("ioctl(SIOCSARP): %m");
1711 proxy_arp_addr = his_adr;
1715 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1716 if (forw_path != 0) {
1717 int fd = open(forw_path, O_WRONLY);
1719 if (write(fd, "1", 1) != 1)
1720 error("Couldn't enable IP forwarding: %m");
1730 /********************************************************************
1732 * cifproxyarp - Delete the proxy ARP entry for the peer.
1735 int cifproxyarp (int unit, u_int32_t his_adr)
1737 struct arpreq arpreq;
1739 if (has_proxy_arp) {
1741 memset (&arpreq, '\0', sizeof(arpreq));
1742 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1743 SIN_ADDR(arpreq.arp_pa) = his_adr;
1744 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1745 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1747 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1748 if ( ! ok_error ( errno ))
1749 warn("ioctl(SIOCDARP): %m");
1756 /********************************************************************
1758 * get_ether_addr - get the hardware address of an interface on the
1759 * the same subnet as ipaddr.
1762 static int get_ether_addr (u_int32_t ipaddr,
1763 struct sockaddr *hwaddr,
1764 char *name, int namelen)
1766 struct ifreq *ifr, *ifend;
1767 u_int32_t ina, mask;
1769 struct ifreq ifreq, bestifreq;
1771 struct ifreq ifs[MAX_IFS];
1773 u_int32_t bestmask=0;
1774 int found_interface = 0;
1776 ifc.ifc_len = sizeof(ifs);
1778 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1779 if ( ! ok_error ( errno ))
1780 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1784 SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1785 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1787 * Scan through looking for an interface with an Internet
1788 * address on the same subnet as `ipaddr'.
1790 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1791 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1792 if (ifr->ifr_addr.sa_family == AF_INET) {
1793 ina = SIN_ADDR(ifr->ifr_addr);
1794 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1795 SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1798 * Check that the interface is up, and not point-to-point
1801 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1804 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1807 * Get its netmask and check that it's on the right subnet.
1809 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1812 mask = SIN_ADDR(ifreq.ifr_addr);
1813 SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1814 ip_ntoa(ina), ntohl(mask)));
1816 if (((ipaddr ^ ina) & mask) != 0)
1817 continue; /* no match */
1819 if (mask >= bestmask) {
1820 /* Compare using >= instead of > -- it is possible for
1821 an interface to have a netmask of 0.0.0.0 */
1822 found_interface = 1;
1829 if (!found_interface) return 0;
1831 strlcpy(name, bestifreq.ifr_name, namelen);
1833 /* trim off the :1 in eth0:1 */
1834 aliasp = strchr(name, ':');
1838 info("found interface %s for proxy arp", name);
1840 * Now get the hardware address.
1842 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1843 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1844 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1849 &bestifreq.ifr_hwaddr,
1850 sizeof (struct sockaddr));
1852 SYSDEBUG ((LOG_DEBUG,
1853 "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1854 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1855 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1856 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1857 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1858 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1859 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1860 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1861 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1866 * get_if_hwaddr - get the hardware address for the specified
1867 * network interface device.
1870 get_if_hwaddr(u_char *addr, char *name)
1875 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1878 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1879 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1880 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1883 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1888 * get_first_ethernet - return the name of the first ethernet-style
1889 * interface on this system.
1892 get_first_ethernet()
1897 /********************************************************************
1899 * Return user specified netmask, modified by any mask we might determine
1900 * for address `addr' (in network byte order).
1901 * Here we scan through the system's list of interfaces, looking for
1902 * any non-point-to-point interfaces which might appear to be on the same
1903 * network as `addr'. If we find any, we OR in their netmask to the
1904 * user-specified netmask.
1907 u_int32_t GetMask (u_int32_t addr)
1909 u_int32_t mask, nmask, ina;
1910 struct ifreq *ifr, *ifend, ifreq;
1912 struct ifreq ifs[MAX_IFS];
1916 if (IN_CLASSA(addr)) /* determine network mask for address class */
1917 nmask = IN_CLASSA_NET;
1918 else if (IN_CLASSB(addr))
1919 nmask = IN_CLASSB_NET;
1921 nmask = IN_CLASSC_NET;
1923 /* class D nets are disallowed by bad_ip_adrs */
1924 mask = netmask | htonl(nmask);
1926 * Scan through the system's network interfaces.
1928 ifc.ifc_len = sizeof(ifs);
1930 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1931 if ( ! ok_error ( errno ))
1932 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1936 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1937 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1939 * Check the interface's internet address.
1941 if (ifr->ifr_addr.sa_family != AF_INET)
1943 ina = SIN_ADDR(ifr->ifr_addr);
1944 if (((ntohl(ina) ^ addr) & nmask) != 0)
1947 * Check that the interface is up, and not point-to-point nor loopback.
1949 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1950 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1953 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1956 * Get its netmask and OR it into our mask.
1958 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1960 mask |= SIN_ADDR(ifreq.ifr_addr);
1966 /********************************************************************
1968 * Internal routine to decode the version.modification.patch level
1971 static void decode_version (char *buf, int *version,
1972 int *modification, int *patch)
1976 *version = (int) strtoul (buf, &endp, 10);
1980 if (endp != buf && *endp == '.') {
1982 *modification = (int) strtoul (buf, &endp, 10);
1983 if (endp != buf && *endp == '.') {
1985 *patch = (int) strtoul (buf, &buf, 10);
1990 /********************************************************************
1992 * Procedure to determine if the PPP line discipline is registered.
1996 ppp_registered(void)
2004 * We used to open the serial device and set it to the ppp line
2005 * discipline here, in order to create a ppp unit. But that is
2006 * not a good idea - the user might have specified a device that
2007 * they can't open (permission, or maybe it doesn't really exist).
2008 * So we grab a pty master/slave pair and use that.
2010 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2011 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2016 * Try to put the device into the PPP discipline.
2018 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2019 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2028 /********************************************************************
2030 * ppp_available - check whether the system has any ppp interfaces
2031 * (in fact we check whether we can do an ioctl on ppp0).
2034 int ppp_available(void)
2039 int my_version, my_modification, my_patch;
2040 int osmaj, osmin, ospatch;
2043 "This system lacks kernel support for PPP. This could be because\n"
2044 "the PPP kernel module could not be loaded, or because PPP was not\n"
2045 "included in the kernel configuration. If PPP was included as a\n"
2046 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2047 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2048 "See README.linux file in the ppp distribution for more details.\n";
2050 /* get the kernel version now, since we are called before sys_init */
2052 osmaj = osmin = ospatch = 0;
2053 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2054 kernel_version = KVERSION(osmaj, osmin, ospatch);
2056 fd = open("/dev/ppp", O_RDWR);
2058 if (fd < 0 && errno == ENOENT) {
2059 /* try making it and see if that helps. */
2060 if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR,
2061 makedev(108, 0)) >= 0) {
2062 fd = open("/dev/ppp", O_RDWR);
2064 info("Created /dev/ppp device node");
2066 unlink("/dev/ppp"); /* didn't work, undo the mknod */
2067 } else if (errno == EEXIST) {
2068 fd = open("/dev/ppp", O_RDWR);
2073 new_style_driver = 1;
2075 /* XXX should get from driver */
2077 driver_modification = 4;
2082 if (kernel_version >= KVERSION(2,3,13)) {
2083 if (errno == ENOENT)
2085 "pppd is unable to open the /dev/ppp device.\n"
2086 "You need to create the /dev/ppp device node by\n"
2087 "executing the following command as root:\n"
2088 " mknod /dev/ppp c 108 0\n";
2093 * Open a socket for doing the ioctl operations.
2095 s = socket(AF_INET, SOCK_DGRAM, 0);
2099 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2100 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2102 * If the device did not exist then attempt to create one by putting the
2103 * current tty into the PPP discipline. If this works then obtain the
2104 * flags for the device again.
2107 if (ppp_registered()) {
2108 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2109 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2113 * Ensure that the hardware address is for PPP and not something else
2116 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2118 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2122 * This is the PPP device. Validate the version of the driver at this
2123 * point to ensure that this program will work with the driver.
2126 char abBuffer [1024];
2128 ifr.ifr_data = abBuffer;
2129 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2131 error("Couldn't read driver version: %m");
2133 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2136 decode_version(abBuffer,
2138 &driver_modification,
2141 * Validate the version of the driver against the version that we used.
2143 decode_version(VERSION,
2148 /* The version numbers must match */
2149 if (driver_version != my_version)
2152 /* The modification levels must be legal */
2153 if (driver_modification < 3) {
2154 if (driver_modification >= 2) {
2155 /* we can cope with 2.2.0 and above */
2164 slprintf(route_buffer, sizeof(route_buffer),
2165 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2166 driver_version, driver_modification, driver_patch);
2168 no_ppp_msg = route_buffer;
2175 /********************************************************************
2177 * Update the wtmp file with the appropriate user name and tty device.
2180 void logwtmp (const char *line, const char *name, const char *host)
2182 struct utmp ut, *utp;
2183 pid_t mypid = getpid();
2189 * Update the signon database for users.
2190 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2192 utmpname(_PATH_UTMP);
2194 while ((utp = getutent()) && (utp->ut_pid != mypid))
2198 memcpy(&ut, utp, sizeof(ut));
2200 /* some gettys/telnetds don't initialize utmp... */
2201 memset(&ut, 0, sizeof(ut));
2203 if (ut.ut_id[0] == 0)
2204 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2206 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2207 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2211 ut.ut_type = USER_PROCESS;
2214 /* Insert the host name if one is supplied */
2216 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2218 /* Insert the IP address of the remote system if IP is enabled */
2219 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2220 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2221 sizeof(ut.ut_addr));
2223 /* CL: Makes sure that the logout works */
2224 if (*host == 0 && *name==0)
2230 * Update the wtmp file.
2233 updwtmp(_PATH_WTMP, &ut);
2235 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2237 flock(wtmp, LOCK_EX);
2239 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2240 warn("error writing %s: %m", _PATH_WTMP);
2242 flock(wtmp, LOCK_UN);
2250 /********************************************************************
2252 * sifvjcomp - config tcp header compression
2255 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2257 u_int x = get_flags(ppp_dev_fd);
2260 if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2261 if (! ok_error (errno))
2262 error("ioctl(PPPIOCSMAXCID): %m (line %d)", __LINE__);
2267 x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP;
2268 x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
2269 set_flags (ppp_dev_fd, x);
2274 /********************************************************************
2276 * sifup - Config the interface up and enable IP packets to pass.
2283 memset (&ifr, '\0', sizeof (ifr));
2284 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2285 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2286 if (! ok_error (errno))
2287 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2291 ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2292 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2293 if (! ok_error (errno))
2294 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2302 /********************************************************************
2304 * sifdown - Disable the indicated protocol and config the interface
2305 * down if there are no remaining protocols.
2312 if (if_is_up && --if_is_up > 0)
2315 memset (&ifr, '\0', sizeof (ifr));
2316 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2317 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2318 if (! ok_error (errno))
2319 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2323 ifr.ifr_flags &= ~IFF_UP;
2324 ifr.ifr_flags |= IFF_POINTOPOINT;
2325 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2326 if (! ok_error (errno))
2327 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2333 /********************************************************************
2335 * sifaddr - Config the interface IP addresses and netmask.
2338 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2344 memset (&ifr, '\0', sizeof (ifr));
2345 memset (&rt, '\0', sizeof (rt));
2347 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2348 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2349 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2351 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2353 * Set our IP address
2355 SIN_ADDR(ifr.ifr_addr) = our_adr;
2356 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2357 if (errno != EEXIST) {
2358 if (! ok_error (errno))
2359 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2362 warn("ioctl(SIOCSIFADDR): Address already exists");
2367 * Set the gateway address
2369 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2370 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2371 if (! ok_error (errno))
2372 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2377 * For recent kernels, force the netmask to 255.255.255.255.
2379 if (kernel_version >= KVERSION(2,1,16))
2381 if (net_mask != 0) {
2382 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2383 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2384 if (! ok_error (errno))
2385 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2390 * Add the device route
2392 if (kernel_version < KVERSION(2,1,16)) {
2393 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2394 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2397 SIN_ADDR(rt.rt_gateway) = 0L;
2398 SIN_ADDR(rt.rt_dst) = his_adr;
2399 rt.rt_flags = RTF_UP | RTF_HOST;
2401 if (kernel_version > KVERSION(2,1,0)) {
2402 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2403 SIN_ADDR(rt.rt_genmask) = -1L;
2406 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2407 if (! ok_error (errno))
2408 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2413 /* set ip_dynaddr in demand mode if address changes */
2414 if (demand && tune_kernel && !dynaddr_set
2415 && our_old_addr && our_old_addr != our_adr) {
2416 /* set ip_dynaddr if possible */
2420 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2421 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2422 if (write(fd, "1", 1) != 1)
2423 error("Couldn't enable dynamic IP addressing: %m");
2426 dynaddr_set = 1; /* only 1 attempt */
2433 /********************************************************************
2435 * cifaddr - Clear the interface IP addresses, and delete routes
2436 * through the interface if possible.
2439 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2443 if (kernel_version < KVERSION(2,1,16)) {
2445 * Delete the route through the device
2448 memset (&rt, '\0', sizeof (rt));
2450 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2451 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2454 SIN_ADDR(rt.rt_gateway) = 0;
2455 SIN_ADDR(rt.rt_dst) = his_adr;
2456 rt.rt_flags = RTF_UP | RTF_HOST;
2458 if (kernel_version > KVERSION(2,1,0)) {
2459 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2460 SIN_ADDR(rt.rt_genmask) = -1L;
2463 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2464 if (still_ppp() && ! ok_error (errno))
2465 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2470 /* This way it is possible to have an IPX-only or IPv6-only interface */
2471 memset(&ifr, 0, sizeof(ifr));
2472 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2473 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2475 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2476 if (! ok_error (errno)) {
2477 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2482 our_old_addr = our_adr;
2488 /********************************************************************
2490 * sif6addr - Config the interface with an IPv6 link-local address
2492 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2494 struct in6_ifreq ifr6;
2496 struct in6_rtmsg rt6;
2500 error("IPv6 socket creation failed: %m");
2503 memset(&ifr, 0, sizeof (ifr));
2504 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2505 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2506 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2510 /* Local interface */
2511 memset(&ifr6, 0, sizeof(ifr6));
2512 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2513 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2514 ifr6.ifr6_prefixlen = 10;
2516 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2517 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2521 /* Route to remote host */
2522 memset(&rt6, 0, sizeof(rt6));
2523 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2524 rt6.rtmsg_flags = RTF_UP;
2525 rt6.rtmsg_dst_len = 10;
2526 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2527 rt6.rtmsg_metric = 1;
2529 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2530 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2538 /********************************************************************
2540 * cif6addr - Remove IPv6 address from interface
2542 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2545 struct in6_ifreq ifr6;
2549 error("IPv6 socket creation failed: %m");
2552 memset(&ifr, 0, sizeof(ifr));
2553 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2554 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2555 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2559 memset(&ifr6, 0, sizeof(ifr6));
2560 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2561 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2562 ifr6.ifr6_prefixlen = 10;
2564 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2565 if (errno != EADDRNOTAVAIL) {
2566 if (! ok_error (errno))
2567 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2570 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2579 * get_pty - get a pty master/slave pair and chown the slave side
2580 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2583 get_pty(master_fdp, slave_fdp, slave_name, uid)
2589 int i, mfd, sfd = -1;
2591 struct termios tios;
2595 * Try the unix98 way first.
2597 mfd = open("/dev/ptmx", O_RDWR);
2600 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2601 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2602 chmod(pty_name, S_IRUSR | S_IWUSR);
2605 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2606 warn("Couldn't unlock pty slave %s: %m", pty_name);
2608 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2609 warn("Couldn't open pty slave %s: %m", pty_name);
2612 #endif /* TIOCGPTN */
2615 /* the old way - scan through the pty name space */
2616 for (i = 0; i < 64; ++i) {
2617 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2618 'p' + i / 16, i % 16);
2619 mfd = open(pty_name, O_RDWR, 0);
2622 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2624 fchown(sfd, uid, -1);
2625 fchmod(sfd, S_IRUSR | S_IWUSR);
2636 strlcpy(slave_name, pty_name, 16);
2639 if (tcgetattr(sfd, &tios) == 0) {
2640 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2641 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2642 tios.c_iflag = IGNPAR;
2645 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2646 warn("couldn't set attributes on pty: %m");
2648 warn("couldn't get attributes on pty: %m");
2653 /********************************************************************
2655 * open_loopback - open the device we use for getting packets
2656 * in demand mode. Under Linux, we use a pty master/slave pair.
2659 open_ppp_loopback(void)
2664 if (new_style_driver) {
2665 /* allocate ourselves a ppp unit */
2666 if (make_ppp_unit() < 0)
2668 set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC);
2669 set_kdebugflag(kdebugflag);
2674 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2675 fatal("No free pty for loopback");
2676 SYSDEBUG(("using %s for loopback", loop_name));
2678 set_ppp_fd(slave_fd);
2680 flags = fcntl(master_fd, F_GETFL);
2682 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2683 warn("couldn't set master loopback to nonblock: %m");
2685 flags = fcntl(ppp_fd, F_GETFL);
2687 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2688 warn("couldn't set slave loopback to nonblock: %m");
2690 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2691 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2693 * Find out which interface we were given.
2695 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2696 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2698 * Enable debug in the driver if requested.
2700 set_kdebugflag (kdebugflag);
2705 /********************************************************************
2707 * sifnpmode - Set the mode for handling packets for a given NP.
2711 sifnpmode(u, proto, mode)
2718 npi.protocol = proto;
2720 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2721 if (! ok_error (errno))
2722 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2729 /********************************************************************
2731 * sipxfaddr - Config the interface IPX networknumber
2734 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2741 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2743 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2745 if (! ok_error (errno))
2746 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2750 memset (&ifr, '\0', sizeof (ifr));
2751 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2753 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2754 sipx->sipx_family = AF_IPX;
2755 sipx->sipx_port = 0;
2756 sipx->sipx_network = htonl (network);
2757 sipx->sipx_type = IPX_FRAME_ETHERII;
2758 sipx->sipx_action = IPX_CRTITF;
2760 * Set the IPX device
2762 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2764 if (errno != EEXIST) {
2765 if (! ok_error (errno))
2766 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2769 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2778 /********************************************************************
2780 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2781 * are removed and the device is no longer able to pass IPX
2785 int cipxfaddr (int unit)
2792 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2794 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2796 if (! ok_error (errno))
2797 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2801 memset (&ifr, '\0', sizeof (ifr));
2802 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2804 sipx->sipx_type = IPX_FRAME_ETHERII;
2805 sipx->sipx_action = IPX_DLTITF;
2806 sipx->sipx_family = AF_IPX;
2808 * Set the IPX device
2810 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2811 if (! ok_error (errno))
2812 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2822 * Use the hostname as part of the random number seed.
2831 for (p = hostname; *p != 0; ++p)
2836 /********************************************************************
2838 * sys_check_options - check the options that the user specified
2842 sys_check_options(void)
2846 * Disable the IPX protocol if the support is not present in the kernel.
2850 if (ipxcp_protent.enabled_flag) {
2851 struct stat stat_buf;
2852 if ((path = path_to_procfs("/net/ipx_interface")) == 0
2853 || lstat(path, &stat_buf) < 0) {
2854 error("IPX support is not present in the kernel\n");
2855 ipxcp_protent.enabled_flag = 0;
2859 if (demand && driver_is_old) {
2860 option_error("demand dialling is not supported by kernel driver "
2861 "version %d.%d.%d", driver_version, driver_modification,
2865 if (multilink && !new_style_driver) {
2866 warn("Warning: multilink is not supported by the kernel driver");
2874 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2876 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2877 * that the system has a properly configured Ethernet interface for this
2878 * function to return non-zero.
2881 ether_to_eui64(eui64_t *p_eui64)
2885 const unsigned char *ptr;
2887 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2890 warn("could not open IPv6 socket");
2894 strcpy(ifr.ifr_name, "eth0");
2895 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2898 warn("could not obtain hardware address for eth0");
2904 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2906 ptr = ifr.ifr_hwaddr.sa_data;
2907 p_eui64->e8[0] = ptr[0] | 0x02;
2908 p_eui64->e8[1] = ptr[1];
2909 p_eui64->e8[2] = ptr[2];
2910 p_eui64->e8[3] = 0xFF;
2911 p_eui64->e8[4] = 0xFE;
2912 p_eui64->e8[5] = ptr[3];
2913 p_eui64->e8[6] = ptr[4];
2914 p_eui64->e8[7] = ptr[5];