2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
5 * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. The name(s) of the authors of this software must not be used to
15 * endorse or promote products derived from this software without
16 * prior written permission.
18 * 3. Redistributions of any form whatsoever must retain the following
20 * "This product includes software developed by Paul Mackerras
21 * <paulus@samba.org>".
23 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
24 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
25 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
26 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
29 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 * Derived from main.c and pppd.h, which are:
33 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
47 * 3. The name "Carnegie Mellon University" must not be used to
48 * endorse or promote products derived from this software without
49 * prior written permission. For permission or any legal
50 * details, please contact
51 * Office of Technology Transfer
52 * Carnegie Mellon University
54 * Pittsburgh, PA 15213-3890
55 * (412) 268-4387, fax: (412) 268-7395
56 * tech-transfer@andrew.cmu.edu
58 * 4. Redistributions of any form whatsoever must retain the following
60 * "This product includes software developed by Computing Services
61 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
63 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
64 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
65 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
66 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
67 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
68 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
69 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
76 #include <sys/ioctl.h>
77 #include <sys/types.h>
78 #include <sys/socket.h>
82 #include <sys/utsname.h>
83 #include <sys/sysmacros.h>
103 /* This is in netdevice.h. However, this compile will fail miserably if
104 you attempt to include netdevice.h because it has so many references
105 to __memcpy functions which it should not attempt to do. So, since I
106 really don't use it, but it must be defined, define it now. */
109 #define MAX_ADDR_LEN 7
112 #if !defined(__GLIBC__) || __GLIBC__ >= 2
113 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
115 #include <net/if_arp.h>
116 #include <net/route.h>
117 #include <netinet/if_ether.h>
119 #include <linux/types.h>
120 #include <linux/if.h>
121 #include <linux/if_arp.h>
122 #include <linux/route.h>
123 #include <linux/if_ether.h>
125 #include <netinet/in.h>
126 #include <arpa/inet.h>
128 #include <linux/ppp_defs.h>
129 #include <linux/if_ppp.h>
131 #include <linux/netlink.h>
132 #include <linux/rtnetlink.h>
133 #include <linux/if_link.h>
134 /* Attempt at retaining compile-support with older than 4.7 kernels, or kernels
135 * where RTM_NEWSTATS isn't defined for whatever reason.
138 #define RTM_NEWSTATS 92
139 #define RTM_GETSTATS 94
140 #define IFLA_STATS_LINK_64 1
144 #include <linux/if_addr.h>
145 /* glibc versions prior to 2.24 do not define SOL_NETLINK */
147 #define SOL_NETLINK 270
149 /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
150 #ifndef NETLINK_CAP_ACK
151 #define NETLINK_CAP_ACK 10
161 #if __GLIBC__ >= 2 && \
162 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
163 #include <netipx/ipx.h>
165 #include <linux/ipx.h>
167 #endif /* IPX_CHANGE */
170 #include <pcap-bpf.h>
171 #include <linux/filter.h>
172 #endif /* PPP_FILTER */
175 #include <sys/locks.h>
179 * Instead of system header file <termios.h> use local "termios_linux.h" header
180 * file as it provides additional support for arbitrary baud rates via BOTHER.
182 #include "termios_linux.h"
187 * This is in linux/include/net/ipv6.h.
191 struct in6_addr ifr6_addr;
192 __u32 ifr6_prefixlen;
193 unsigned int ifr6_ifindex;
197 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
198 memset(&(sin6).s6_addr, 0, sizeof(struct in6_addr)); \
199 (sin6).s6_addr16[0] = htons(0xfe80); \
200 eui64_copy(eui64, (sin6).s6_addr32[2]); \
203 static const eui64_t nulleui64;
206 /* We can get an EIO error on an ioctl if the modem has hung up */
207 #define ok_error(num) ((num)==EIO)
209 static int tty_disc = N_TTY; /* The TTY discipline */
210 static int ppp_disc = N_PPP; /* The PPP discpline */
211 static int initfdflags = -1; /* Initial file descriptor flags for fd */
212 static int ppp_fd = -1; /* fd which is set to PPP discipline */
213 static int sock_fd = -1; /* socket for doing interface ioctls */
214 static int slave_fd = -1; /* pty for old-style demand mode, slave */
215 static int master_fd = -1; /* pty for old-style demand mode, master */
217 static int sock6_fd = -1;
221 * For the old-style kernel driver, this is the same as ppp_fd.
222 * For the new-style driver, it is the fd of an instance of /dev/ppp
223 * which is attached to the ppp unit and is used for controlling it.
225 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
227 static int chindex; /* channel index (new style driver) */
229 static fd_set in_fds; /* set of fds that wait_input waits for */
230 static int max_in_fd; /* highest fd set in in_fds */
232 static int has_proxy_arp = 0;
233 static int driver_version = 0;
234 static int driver_modification = 0;
235 static int driver_patch = 0;
236 static int driver_is_old = 0;
237 static int restore_term = 0; /* 1 => we've munged the terminal */
238 static struct termios inittermios; /* Initial TTY termios */
240 int new_style_driver = 0;
242 static char loop_name[20];
243 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
245 static int if_is_up; /* Interface has been marked up */
246 static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
247 static int have_default_route; /* Gateway for default route added */
248 static int have_default_route6; /* Gateway for default IPv6 route added */
249 static struct rtentry old_def_rt; /* Old default route */
250 static int default_rt_repl_rest; /* replace and restore old default rt */
251 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
252 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
253 static u_int32_t our_old_addr; /* for detecting address changes */
254 static int dynaddr_set; /* 1 if ip_dynaddr set */
255 static int looped; /* 1 if using loop */
256 static int link_mtu; /* mtu for the link (not bundle) */
258 static struct utsname utsname; /* for the kernel version */
259 static int kernel_version;
260 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
264 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
265 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
266 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
268 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
270 /* Prototypes for procedures local to this file. */
271 static int modify_flags(int fd, int clear_bits, int set_bits);
272 static int translate_speed (int bps);
273 static int baud_rate_of (int speed);
274 static void close_route_table (void);
275 static int open_route_table (void);
276 static int read_route_table (struct rtentry *rt);
277 static int defaultroute_exists (struct rtentry *rt, int metric);
278 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
279 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
280 char *name, int namelen);
281 static void decode_version (char *buf, int *version, int *mod, int *patch);
282 static int set_kdebugflag(int level);
283 static int ppp_registered(void);
284 static int make_ppp_unit(void);
285 static int setifstate (int u, int state);
287 extern u_char inpacket_buf[]; /* borrowed from main.c */
289 extern int dfl_route_metric;
292 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
296 #define SET_SA_FAMILY(addr, family) \
297 memset ((char *) &(addr), '\0', sizeof(addr)); \
298 addr.sa_family = (family);
301 * Determine if the PPP connection should still be present.
306 /* new_fd is the fd of a tty */
307 static void set_ppp_fd (int new_fd)
310 if (!new_style_driver)
314 static int still_ppp(void)
316 if (new_style_driver)
317 return !hungup && ppp_fd >= 0;
318 if (!hungup || ppp_fd == slave_fd)
321 set_ppp_fd(slave_fd);
328 * modify_flags - set and clear flag bits controlling the kernel
331 static int modify_flags(int fd, int clear_bits, int set_bits)
335 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
337 flags = (flags & ~clear_bits) | set_bits;
338 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
345 error("Failed to set PPP kernel option flags: %m");
349 /********************************************************************
351 * sys_init - System-dependent initialization.
356 /* Get an internet socket for doing socket ioctls. */
357 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
359 fatal("Couldn't create IP socket: %m(%d)", errno);
362 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
364 sock6_fd = -errno; /* save errno for later */
371 /********************************************************************
373 * sys_cleanup - restore any system state we modified before exiting:
374 * mark the interface down, delete default route and/or proxy arp entry.
375 * This shouldn't call die() because it's called from die().
378 void sys_cleanup(void)
381 * Take down the device
391 * Delete any routes through the device.
393 if (have_default_route)
394 cifdefaultroute(0, 0, 0);
396 if (have_default_route6)
397 cif6defaultroute(0, nulleui64, nulleui64);
401 cifproxyarp(0, proxy_arp_addr);
404 /********************************************************************
406 * sys_close - Clean up in a child process before execing.
411 if (new_style_driver && ppp_dev_fd >= 0)
425 /********************************************************************
427 * set_kdebugflag - Define the debugging level for the kernel
430 static int set_kdebugflag (int requested_level)
434 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
435 if ( ! ok_error (errno) )
436 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
442 /********************************************************************
444 * tty_establish_ppp - Turn the serial port into a ppp interface.
447 int tty_establish_ppp (int tty_fd)
452 * Ensure that the tty device is in exclusive mode.
454 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
455 if ( ! ok_error ( errno ))
456 warn("Couldn't make tty exclusive: %m");
459 * Demand mode - prime the old ppp device to relinquish the unit.
461 if (!new_style_driver && looped
462 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
463 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
467 * Set the current tty to the PPP discpline
471 #define N_SYNC_PPP 14
473 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
474 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
475 if ( ! ok_error (errno) ) {
476 error("Couldn't set tty to PPP discipline: %m");
481 ret_fd = generic_establish_ppp(tty_fd);
483 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
484 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
488 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
489 (kdebugflag * SC_DEBUG) & SC_LOGB);
491 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
492 warn("Couldn't reset tty to normal line discipline: %m");
498 /********************************************************************
500 * generic_establish_ppp - Turn the fd into a ppp interface.
502 int generic_establish_ppp (int fd)
506 if (new_style_driver) {
509 /* If a ppp_fd is already open, close it first */
516 /* Open an instance of /dev/ppp and connect the channel to it */
517 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
518 error("Couldn't get channel number: %m");
521 dbglog("using channel %d", chindex);
522 fd = open("/dev/ppp", O_RDWR);
524 error("Couldn't reopen /dev/ppp: %m");
527 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
528 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
529 error("Couldn't attach to channel %d: %m", chindex);
532 flags = fcntl(fd, F_GETFL);
533 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
534 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
539 if (!looped && !multilink) {
541 * Create a new PPP unit.
543 if (make_ppp_unit() < 0)
548 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
552 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
553 error("Couldn't attach to PPP unit %d: %m", ifunit);
560 * Old-style driver: find out which interface we were given.
563 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
564 if (ok_error (errno))
566 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
568 /* Check that we got the same unit again. */
569 if (looped && x != ifunit)
570 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
574 * Fetch the initial file flags and reset blocking mode on the file.
576 initfdflags = fcntl(fd, F_GETFL);
577 if (initfdflags == -1 ||
578 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
579 if ( ! ok_error (errno))
580 warn("Couldn't set device to non-blocking mode: %m");
585 * Enable debug in the driver if requested.
588 set_kdebugflag (kdebugflag);
600 /********************************************************************
602 * tty_disestablish_ppp - Restore the serial port to normal operation.
603 * This shouldn't call die() because it's called from die().
606 void tty_disestablish_ppp(int tty_fd)
610 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
612 if (tcflush(tty_fd, TCIOFLUSH) < 0)
614 warn("tcflush failed: %m");
618 * Restore the previous line discipline
620 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
621 if ( ! ok_error (errno))
622 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
625 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
626 if ( ! ok_error (errno))
627 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
630 /* Reset non-blocking mode on fd. */
631 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
632 if ( ! ok_error (errno))
633 warn("Couldn't restore device fd flags: %m");
639 generic_disestablish_ppp(tty_fd);
642 /********************************************************************
644 * generic_disestablish_ppp - Restore device components to normal
645 * operation, and reconnect the ppp unit to the loopback if in demand
646 * mode. This shouldn't call die() because it's called from die().
648 void generic_disestablish_ppp(int dev_fd)
650 if (new_style_driver) {
654 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
656 } else if (!doing_multilink && ppp_dev_fd >= 0) {
658 remove_fd(ppp_dev_fd);
662 /* old-style driver */
664 set_ppp_fd(slave_fd);
671 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
672 * Assumes new_style_driver.
674 static int make_ppp_unit(void)
678 if (ppp_dev_fd >= 0) {
679 dbglog("in make_ppp_unit, already had /dev/ppp open?");
682 ppp_dev_fd = open("/dev/ppp", O_RDWR);
684 fatal("Couldn't open /dev/ppp: %m");
685 flags = fcntl(ppp_dev_fd, F_GETFL);
687 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
688 warn("Couldn't set /dev/ppp to nonblock: %m");
691 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
692 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
693 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
695 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
698 error("Couldn't create new ppp unit: %m");
700 if (x == 0 && req_ifname[0] != '\0') {
703 memset(&ifr, 0, sizeof(struct ifreq));
704 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
705 strlcpy(ifr.ifr_name, t, IFNAMSIZ);
706 strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
707 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
709 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
711 info("Renamed interface %s to %s", t, req_ifname);
718 * cfg_bundle - configure the existing bundle.
719 * Used in demand mode.
721 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
723 if (!new_style_driver)
726 /* set the mrru, mtu and flags */
727 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
728 error("Couldn't set MRRU: %m");
730 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
731 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
732 | (mrru? SC_MULTILINK: 0)));
734 /* connect up the channel */
735 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
736 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
741 * make_new_bundle - create a new PPP unit (i.e. a bundle)
742 * and connect our channel to it. This should only get called
743 * if `multilink' was set at the time establish_ppp was called.
744 * In demand mode this uses our existing bundle instead of making
747 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
749 if (!new_style_driver)
752 /* make us a ppp unit */
753 if (make_ppp_unit() < 0)
756 /* set the mrru and flags */
757 cfg_bundle(mrru, mtru, rssn, tssn);
761 * bundle_attach - attach our link to a given PPP unit.
762 * We assume the unit is controlled by another pppd.
764 int bundle_attach(int ifnum)
768 if (!new_style_driver)
771 master_fd = open("/dev/ppp", O_RDWR);
773 fatal("Couldn't open /dev/ppp: %m");
774 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
775 if (errno == ENXIO) {
777 return 0; /* doesn't still exist */
779 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
781 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
782 fatal("Couldn't connect to interface unit %d: %m", ifnum);
783 modify_flags(master_fd, 0, SC_MULTILINK);
791 * destroy_bundle - tell the driver to destroy our bundle.
793 void destroy_bundle(void)
795 if (ppp_dev_fd >= 0) {
797 remove_fd(ppp_dev_fd);
802 /********************************************************************
804 * clean_check - Fetch the flags for the device and generate
805 * appropriate error messages.
807 void clean_check(void)
813 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
815 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
817 s = "all had bit 7 set to 1";
821 s = "all had bit 7 set to 0";
825 s = "all had odd parity";
829 s = "all had even parity";
834 warn("Receive serial link is not 8-bit clean:");
835 warn("Problem: %s", s);
843 * List of valid speeds.
847 int speed_int, speed_val;
943 { 1000000, B1000000 },
946 { 1152000, B1152000 },
949 { 1500000, B1500000 },
952 { 2000000, B2000000 },
955 { 2500000, B2500000 },
958 { 3000000, B3000000 },
961 { 3500000, B3500000 },
964 { 4000000, B4000000 },
969 /********************************************************************
971 * Translate from bits/second to a speed_t.
974 static int translate_speed (int bps)
976 struct speed *speedp;
979 for (speedp = speeds; speedp->speed_int; speedp++) {
980 if (bps == speedp->speed_int)
981 return speedp->speed_val;
987 /********************************************************************
989 * Translate from a speed_t to bits/second.
992 static int baud_rate_of (int speed)
994 struct speed *speedp;
997 for (speedp = speeds; speedp->speed_int; speedp++) {
998 if (speed == speedp->speed_val)
999 return speedp->speed_int;
1005 /********************************************************************
1007 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
1008 * at the requested speed, etc. If `local' is true, set CLOCAL
1009 * regardless of whether the modem option was specified.
1012 void set_up_tty(int tty_fd, int local)
1015 struct termios tios;
1018 if (tcgetattr(tty_fd, &tios) < 0) {
1019 if (!ok_error(errno))
1020 fatal("tcgetattr: %m (line %d)", __LINE__);
1027 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1028 tios.c_cflag |= CS8 | CREAD | HUPCL;
1030 tios.c_iflag = IGNBRK | IGNPAR;
1033 tios.c_cc[VMIN] = 1;
1034 tios.c_cc[VTIME] = 0;
1036 if (local || !modem)
1037 tios.c_cflag ^= (CLOCAL | HUPCL);
1041 tios.c_cflag |= CRTSCTS;
1045 tios.c_iflag |= IXON | IXOFF;
1046 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
1047 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1051 tios.c_cflag &= ~CRTSCTS;
1059 tios.c_cflag |= CSTOPB;
1062 speed = translate_speed(inspeed);
1064 cfsetospeed (&tios, speed);
1065 cfsetispeed (&tios, speed);
1066 speed = cfgetospeed(&tios);
1067 baud_rate = baud_rate_of(speed);
1070 tios.c_cflag &= ~CBAUD;
1071 tios.c_cflag |= BOTHER;
1072 tios.c_ospeed = inspeed;
1074 /* B0 sets input baudrate to the output baudrate */
1075 tios.c_cflag &= ~(CBAUD << IBSHIFT);
1076 tios.c_cflag |= B0 << IBSHIFT;
1077 tios.c_ispeed = inspeed;
1079 baud_rate = inspeed;
1086 speed = cfgetospeed(&tios);
1087 baud_rate = baud_rate_of(speed);
1090 baud_rate = tios.c_ospeed;
1095 * We can't proceed if the serial port baud rate is unknown,
1096 * since that implies that the serial port is disabled.
1100 fatal("speed %d not supported", inspeed);
1102 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1105 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1107 fatal("tcsetattr: %m (line %d)", __LINE__);
1111 /********************************************************************
1113 * setdtr - control the DTR line on the serial port.
1114 * This is called from die(), so it shouldn't call die().
1117 void setdtr (int tty_fd, int on)
1119 int modembits = TIOCM_DTR;
1121 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1124 /********************************************************************
1126 * restore_tty - restore the terminal to the saved settings.
1129 void restore_tty (int tty_fd)
1134 * Turn off echoing, because otherwise we can get into
1135 * a loop with the tty and the modem echoing to each other.
1136 * We presume we are the sole user of this tty device, so
1137 * when we close it, it will revert to its defaults anyway.
1139 if (!default_device)
1140 inittermios.c_lflag &= ~(ECHO | ECHONL);
1142 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1143 if (! ok_error (errno))
1144 warn("tcsetattr: %m (line %d)", __LINE__);
1149 /********************************************************************
1151 * output - Output PPP packet.
1154 void output (int unit, unsigned char *p, int len)
1159 dump_packet("sent", p, len);
1160 if (snoop_send_hook) snoop_send_hook(p, len);
1162 if (len < PPP_HDRLEN)
1164 if (new_style_driver) {
1167 proto = (p[0] << 8) + p[1];
1168 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1171 if (write(fd, p, len) < 0) {
1172 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1173 || errno == ENXIO || errno == EIO || errno == EINTR)
1174 warn("write: warning: %m (%d)", errno);
1176 error("write: %m (%d)", errno);
1180 /********************************************************************
1182 * wait_input - wait until there is data available,
1183 * for the length of time specified by *timo (indefinite
1187 void wait_input(struct timeval *timo)
1194 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1195 if (n < 0 && errno != EINTR)
1196 fatal("select: %m");
1200 * add_fd - add an fd to the set that wait_input waits for.
1204 if (fd >= FD_SETSIZE)
1205 fatal("internal error: file descriptor too large (%d)", fd);
1206 FD_SET(fd, &in_fds);
1212 * remove_fd - remove an fd from the set that wait_input waits for.
1214 void remove_fd(int fd)
1216 FD_CLR(fd, &in_fds);
1220 /********************************************************************
1222 * read_packet - get a PPP packet from the serial device.
1225 int read_packet (unsigned char *buf)
1229 len = PPP_MRU + PPP_HDRLEN;
1230 if (new_style_driver) {
1231 *buf++ = PPP_ALLSTATIONS;
1237 nr = read(ppp_fd, buf, len);
1238 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1239 && errno != EIO && errno != EINTR)
1241 if (nr < 0 && errno == ENXIO)
1244 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1245 /* N.B. we read ppp_fd first since LCP packets come in there. */
1246 nr = read(ppp_dev_fd, buf, len);
1247 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1248 && errno != EIO && errno != EINTR)
1249 error("read /dev/ppp: %m");
1250 if (nr < 0 && errno == ENXIO)
1252 if (nr == 0 && doing_multilink) {
1253 remove_fd(ppp_dev_fd);
1257 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1259 return (new_style_driver && nr > 0)? nr+2: nr;
1262 /********************************************************************
1264 * get_loop_output - get outgoing packets from the ppp device,
1265 * and detect when we want to bring the real link up.
1266 * Return value is 1 if we need to bring up the link, 0 otherwise.
1269 get_loop_output(void)
1274 if (new_style_driver) {
1275 while ((n = read_packet(inpacket_buf)) > 0)
1276 if (loop_frame(inpacket_buf, n))
1281 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1282 if (loop_chars(inbuf, n))
1286 fatal("eof on loopback");
1288 if (errno != EWOULDBLOCK && errno != EAGAIN)
1289 fatal("read from loopback: %m(%d)", errno);
1295 * netif_set_mtu - set the MTU on the PPP network interface.
1298 netif_set_mtu(int unit, int mtu)
1302 memset (&ifr, '\0', sizeof (ifr));
1303 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1306 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1307 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1311 * netif_get_mtu - get the MTU on the PPP network interface.
1314 netif_get_mtu(int unit)
1318 memset (&ifr, '\0', sizeof (ifr));
1319 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1321 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1322 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1328 /********************************************************************
1330 * tty_send_config - configure the transmit characteristics of
1331 * the ppp interface.
1334 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1341 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1342 if (errno != EIO && errno != ENOTTY)
1343 error("Couldn't set transmit async character map: %m");
1348 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1349 | (sync_serial? SC_SYNC: 0);
1350 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1353 /********************************************************************
1355 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1358 void tty_set_xaccm (ext_accm accm)
1362 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1363 if ( ! ok_error (errno))
1364 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1368 /********************************************************************
1370 * tty_recv_config - configure the receive-side characteristics of
1371 * the ppp interface.
1374 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1377 * If we were called because the link has gone down then there is nothing
1378 * which may be done. Just return without incident.
1383 * Set the receiver parameters
1385 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1386 if (errno != EIO && errno != ENOTTY)
1387 error("Couldn't set channel receive MRU: %m");
1389 if (new_style_driver && ppp_dev_fd >= 0
1390 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1391 error("Couldn't set MRU in generic PPP layer: %m");
1393 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1394 if (errno != EIO && errno != ENOTTY)
1395 error("Couldn't set channel receive asyncmap: %m");
1399 /********************************************************************
1401 * ccp_test - ask kernel whether a given compression method
1402 * is acceptable for use.
1406 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1408 struct ppp_option_data data;
1410 memset (&data, '\0', sizeof (data));
1412 data.length = opt_len;
1413 data.transmit = for_transmit;
1415 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1418 return (errno == ENOBUFS)? 0: -1;
1421 /********************************************************************
1423 * ccp_flags_set - inform kernel about the current state of CCP.
1426 void ccp_flags_set (int unit, int isopen, int isup)
1430 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1431 if (still_ppp() && ppp_dev_fd >= 0)
1432 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1437 * set_filters - set the active and pass filters in the kernel driver.
1439 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1441 struct sock_fprog fp;
1443 fp.len = pass->bf_len;
1444 fp.filter = (struct sock_filter *) pass->bf_insns;
1445 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1446 if (errno == ENOTTY)
1447 warn("kernel does not support PPP filtering");
1449 error("Couldn't set pass-filter in kernel: %m");
1452 fp.len = active->bf_len;
1453 fp.filter = (struct sock_filter *) active->bf_insns;
1454 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1455 error("Couldn't set active-filter in kernel: %m");
1460 #endif /* PPP_FILTER */
1462 /********************************************************************
1464 * get_idle_time - return how long the link has been idle.
1467 get_idle_time(int u, struct ppp_idle *ip)
1469 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1472 /********************************************************************
1474 * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1475 * this only supports 32-bit counters, so need to count the wraps.
1478 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1480 static u_int32_t previbytes = 0;
1481 static u_int32_t prevobytes = 0;
1482 static u_int32_t iwraps = 0;
1483 static u_int32_t owraps = 0;
1485 struct ifpppstatsreq req;
1487 memset (&req, 0, sizeof (req));
1489 req.stats_ptr = (caddr_t) &req.stats;
1490 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1491 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1492 error("Couldn't get PPP statistics: %m");
1495 stats->bytes_in = req.stats.p.ppp_ibytes;
1496 stats->bytes_out = req.stats.p.ppp_obytes;
1497 stats->pkts_in = req.stats.p.ppp_ipackets;
1498 stats->pkts_out = req.stats.p.ppp_opackets;
1500 if (stats->bytes_in < previbytes)
1502 if (stats->bytes_out < prevobytes)
1505 previbytes = stats->bytes_in;
1506 prevobytes = stats->bytes_out;
1508 stats->bytes_in += (uint64_t)iwraps << 32;
1509 stats->bytes_out += (uint64_t)owraps << 32;
1514 /********************************************************************
1515 * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1516 * This provides native 64-bit counters.
1519 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1521 static int rtnl_fd = -1;
1523 struct sockaddr_nl nladdr;
1525 struct nlmsghdr nlh;
1526 struct if_stats_msg ifsm;
1529 struct nlmsghdr nlh;
1532 struct nlmsgerr nlerr;
1538 /* We only case about these first fields from rtnl_link_stats64 */
1539 uint64_t rx_packets;
1540 uint64_t tx_packets;
1544 char __end_stats[0];
1552 memset(&nladdr, 0, sizeof(nladdr));
1553 nladdr.nl_family = AF_NETLINK;
1556 rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1558 error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__);
1562 if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
1563 error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
1568 memset(&nlreq, 0, sizeof(nlreq));
1569 nlreq.nlh.nlmsg_len = sizeof(nlreq);
1570 nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1571 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1573 nlreq.ifsm.ifindex = if_nametoindex(ifname);
1574 nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1576 memset(&iov, 0, sizeof(iov));
1577 iov.iov_base = &nlreq;
1578 iov.iov_len = sizeof(nlreq);
1580 memset(&msg, 0, sizeof(msg));
1581 msg.msg_name = &nladdr;
1582 msg.msg_namelen = sizeof(nladdr);
1586 if (sendmsg(rtnl_fd, &msg, 0) < 0) {
1587 error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1591 /* We just need to repoint to IOV ... everything else stays the same */
1592 iov.iov_base = &nlresp;
1593 iov.iov_len = sizeof(nlresp);
1595 nlresplen = recvmsg(rtnl_fd, &msg, 0);
1597 if (nlresplen < 0) {
1598 error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1602 if (nlresplen < sizeof(nlresp.nlh)) {
1603 error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__);
1607 if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) {
1608 if (nlresplen < offsetof(struct nlresp, __end_err)) {
1609 if (kernel_version >= KVERSION(4,7,0))
1610 error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
1612 error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).",
1618 if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) {
1619 error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)",
1620 nlresp.nlh.nlmsg_type, __LINE__);
1624 if (nlresplen < offsetof(struct nlresp, __end_stats)) {
1625 error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1629 stats->bytes_in = nlresp.stats.rx_bytes;
1630 stats->bytes_out = nlresp.stats.tx_bytes;
1631 stats->pkts_in = nlresp.stats.rx_packets;
1632 stats->pkts_out = nlresp.stats.tx_packets;
1641 /********************************************************************
1642 * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1643 * this provides native 64-bit counters.
1646 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1648 char fname[PATH_MAX+1];
1649 char buf[21], *err; /* 2^64 < 10^20 */
1651 unsigned long long val;
1658 #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1659 statfield(rx_bytes, bytes_in),
1660 statfield(tx_bytes, bytes_out),
1661 statfield(rx_packets, pkts_in),
1662 statfield(tx_packets, pkts_out),
1666 blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1667 if (blen >= sizeof(fname))
1668 return 0; /* ifname max 15, so this should be impossible */
1670 for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1671 if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1673 error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1677 fd = open(fname, O_RDONLY);
1679 error("%s: %m", fname);
1683 rlen = read(fd, buf, sizeof(buf) - 1);
1686 error("%s: %m", fname);
1689 /* trim trailing \n if present */
1690 while (rlen > 0 && buf[rlen-1] == '\n')
1695 val = strtoull(buf, &err, 10);
1696 if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1697 error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1698 buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1701 switch (slist[i].size) {
1702 #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1709 error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1717 /********************************************************************
1718 * Periodic timer function to be used to keep stats up to date in case of ioctl
1721 * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1722 * If you do change the timer, remember to also bring the get_ppp_stats (which
1723 * sets up the initial trigger) as well.
1726 ppp_stats_poller(void* u)
1728 struct pppd_stats dummy;
1729 get_ppp_stats_ioctl((long)u, &dummy);
1730 TIMEOUT(ppp_stats_poller, u, 25);
1733 /********************************************************************
1734 * get_ppp_stats - return statistics for the link.
1736 int get_ppp_stats(int u, struct pppd_stats *stats)
1738 static int (*func)(int, struct pppd_stats*) = NULL;
1741 if (get_ppp_stats_rtnetlink(u, stats)) {
1742 func = get_ppp_stats_rtnetlink;
1745 if (get_ppp_stats_sysfs(u, stats)) {
1746 func = get_ppp_stats_sysfs;
1749 warn("statistics falling back to ioctl which only supports 32-bit counters");
1750 func = get_ppp_stats_ioctl;
1751 TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1754 return func(u, stats);
1757 /********************************************************************
1759 * ccp_fatal_error - returns 1 if decompression was disabled as a
1760 * result of an error detected after decompression of a packet,
1761 * 0 otherwise. This is necessary because of patent nonsense.
1764 int ccp_fatal_error (int unit)
1768 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1769 error("Couldn't read compression error flags: %m");
1772 return flags & SC_DC_FERROR;
1775 /********************************************************************
1777 * path_to_procfs - find the path to the proc file system mount point
1779 static char proc_path[MAXPATHLEN];
1780 static int proc_path_len;
1782 static char *path_to_procfs(const char *tail)
1784 struct mntent *mntent;
1787 if (proc_path_len == 0) {
1788 /* Default the mount location of /proc */
1789 strlcpy (proc_path, "/proc", sizeof(proc_path));
1791 fp = fopen(MOUNTED, "r");
1793 while ((mntent = getmntent(fp)) != NULL) {
1794 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1796 if (strcmp(mntent->mnt_type, "proc") == 0) {
1797 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1798 proc_path_len = strlen(proc_path);
1806 strlcpy(proc_path + proc_path_len, tail,
1807 sizeof(proc_path) - proc_path_len);
1812 * /proc/net/route parsing stuff.
1814 #define ROUTE_MAX_COLS 12
1815 FILE *route_fd = (FILE *) 0;
1816 static char route_buffer[512];
1817 static int route_dev_col, route_dest_col, route_gw_col;
1818 static int route_flags_col, route_metric_col, route_mask_col;
1819 static int route_num_cols;
1821 static int open_route_table (void);
1822 static void close_route_table (void);
1823 static int read_route_table (struct rtentry *rt);
1825 /********************************************************************
1827 * close_route_table - close the interface to the route table
1830 static void close_route_table (void)
1832 if (route_fd != (FILE *) 0) {
1834 route_fd = (FILE *) 0;
1838 /********************************************************************
1840 * open_route_table - open the interface to the route table
1842 static char route_delims[] = " \t\n";
1844 static int open_route_table (void)
1848 close_route_table();
1850 path = path_to_procfs("/net/route");
1851 route_fd = fopen (path, "r");
1852 if (route_fd == NULL) {
1853 error("can't open routing table %s: %m", path);
1857 route_dev_col = 0; /* default to usual columns */
1860 route_flags_col = 3;
1861 route_metric_col = 6;
1865 /* parse header line */
1866 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1867 char *p = route_buffer, *q;
1869 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1871 if ((q = strtok(p, route_delims)) == 0)
1873 if (strcasecmp(q, "iface") == 0)
1874 route_dev_col = col;
1875 else if (strcasecmp(q, "destination") == 0)
1876 route_dest_col = col;
1877 else if (strcasecmp(q, "gateway") == 0)
1879 else if (strcasecmp(q, "flags") == 0)
1880 route_flags_col = col;
1881 else if (strcasecmp(q, "mask") == 0)
1882 route_mask_col = col;
1885 if (used && col >= route_num_cols)
1886 route_num_cols = col + 1;
1894 /********************************************************************
1896 * read_route_table - read the next entry from the route table
1899 static int read_route_table(struct rtentry *rt)
1901 char *cols[ROUTE_MAX_COLS], *p;
1904 memset (rt, '\0', sizeof (struct rtentry));
1906 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1910 for (col = 0; col < route_num_cols; ++col) {
1911 cols[col] = strtok(p, route_delims);
1912 if (cols[col] == NULL)
1913 return 0; /* didn't get enough columns */
1917 SET_SA_FAMILY (rt->rt_dst, AF_INET);
1918 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
1920 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1921 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1922 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1924 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1925 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
1926 rt->rt_dev = cols[route_dev_col];
1931 /********************************************************************
1933 * defaultroute_exists - determine if there is a default route
1934 * with the given metric (or negative for any)
1937 static int defaultroute_exists (struct rtentry *rt, int metric)
1941 if (!open_route_table())
1944 while (read_route_table(rt) != 0) {
1945 if ((rt->rt_flags & RTF_UP) == 0)
1948 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1950 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1951 || rt->rt_metric == metric)) {
1957 close_route_table();
1962 * have_route_to - determine if the system has any route to
1963 * a given IP address. `addr' is in network byte order.
1964 * Return value is 1 if yes, 0 if no, -1 if don't know.
1965 * For demand mode to work properly, we have to ignore routes
1966 * through our own interface.
1968 int have_route_to(u_int32_t addr)
1973 if (!open_route_table())
1974 return -1; /* don't know */
1976 while (read_route_table(&rt)) {
1977 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1979 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1985 close_route_table();
1989 /********************************************************************
1991 * sifdefaultroute - assign a default route through the address given.
1993 * If the global default_rt_repl_rest flag is set, then this function
1994 * already replaced the original system defaultroute with some other
1995 * route and it should just replace the current defaultroute with
1996 * another one, without saving the current route. Use: demand mode,
1997 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
1998 * and then changes the temporary addresses to the addresses for the real
1999 * ppp connection when it has come up.
2002 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
2004 struct rtentry rt, tmp_rt;
2005 struct rtentry *del_rt = NULL;
2007 if (default_rt_repl_rest) {
2008 /* We have already replaced the original defaultroute, if we
2009 * are called again, we will delete the current default route
2010 * and set the new default route in this function.
2011 * - this is normally only the case the doing demand: */
2012 if (defaultroute_exists(&tmp_rt, -1))
2014 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
2015 strcmp( old_def_rt.rt_dev, ifname) != 0) {
2017 * We did not yet replace an existing default route, let's
2018 * check if we should save and replace a default route:
2020 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2022 if (old_gateway != gateway) {
2024 error("not replacing default route to %s [%I]",
2025 old_def_rt.rt_dev, old_gateway);
2028 /* we need to copy rt_dev because we need it permanent too: */
2029 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2030 strcpy(tmp_dev, old_def_rt.rt_dev);
2031 old_def_rt.rt_dev = tmp_dev;
2033 notice("replacing old default route to %s [%I]",
2034 old_def_rt.rt_dev, old_gateway);
2035 default_rt_repl_rest = 1;
2036 del_rt = &old_def_rt;
2041 memset (&rt, 0, sizeof (rt));
2042 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2045 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2047 if (kernel_version > KVERSION(2,1,0)) {
2048 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2049 SIN_ADDR(rt.rt_genmask) = 0L;
2052 rt.rt_flags = RTF_UP;
2053 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2054 if ( ! ok_error ( errno ))
2055 error("default route ioctl(SIOCADDRT): %m");
2058 if (default_rt_repl_rest && del_rt)
2059 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2060 if ( ! ok_error ( errno ))
2061 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2065 have_default_route = 1;
2069 /********************************************************************
2071 * cifdefaultroute - delete a default route through the address given.
2074 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2078 have_default_route = 0;
2080 memset (&rt, '\0', sizeof (rt));
2081 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2082 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2087 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2089 if (kernel_version > KVERSION(2,1,0)) {
2090 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2091 SIN_ADDR(rt.rt_genmask) = 0L;
2094 rt.rt_flags = RTF_UP;
2095 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2097 if ( ! ok_error ( errno ))
2098 error("default route ioctl(SIOCDELRT): %m");
2102 if (default_rt_repl_rest) {
2103 notice("restoring old default route to %s [%I]",
2104 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2105 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2106 if ( ! ok_error ( errno ))
2107 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2110 default_rt_repl_rest = 0;
2118 * /proc/net/ipv6_route parsing stuff.
2120 static int route_dest_plen_col;
2121 static int open_route6_table (void);
2122 static int read_route6_table (struct in6_rtmsg *rt);
2124 /********************************************************************
2126 * open_route6_table - open the interface to the route table
2128 static int open_route6_table (void)
2132 close_route_table();
2134 path = path_to_procfs("/net/ipv6_route");
2135 route_fd = fopen (path, "r");
2136 if (route_fd == NULL) {
2137 error("can't open routing table %s: %m", path);
2141 /* default to usual columns */
2143 route_dest_plen_col = 1;
2145 route_metric_col = 5;
2146 route_flags_col = 8;
2148 route_num_cols = 10;
2153 /********************************************************************
2155 * read_route6_table - read the next entry from the route table
2158 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2165 for (i = 0; i < 4; i++) {
2166 memcpy(hex8, s + 8*i, 8);
2167 v = strtoul(hex8, NULL, 16);
2168 addr->s6_addr32[i] = v;
2172 static int read_route6_table(struct in6_rtmsg *rt)
2174 char *cols[ROUTE_MAX_COLS], *p;
2177 memset (rt, '\0', sizeof (struct in6_rtmsg));
2179 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2183 for (col = 0; col < route_num_cols; ++col) {
2184 cols[col] = strtok(p, route_delims);
2185 if (cols[col] == NULL)
2186 return 0; /* didn't get enough columns */
2190 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2191 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2192 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2194 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2195 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2196 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2201 /********************************************************************
2203 * defaultroute6_exists - determine if there is a default route
2206 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2210 if (!open_route6_table())
2213 while (read_route6_table(rt) != 0) {
2214 if ((rt->rtmsg_flags & RTF_UP) == 0)
2217 if (rt->rtmsg_dst_len != 0)
2219 if (rt->rtmsg_dst.s6_addr32[0] == 0L
2220 && rt->rtmsg_dst.s6_addr32[1] == 0L
2221 && rt->rtmsg_dst.s6_addr32[2] == 0L
2222 && rt->rtmsg_dst.s6_addr32[3] == 0L
2223 && (metric < 0 || rt->rtmsg_metric == metric)) {
2229 close_route_table();
2233 /********************************************************************
2235 * sif6defaultroute - assign a default route through the address given.
2237 * If the global default_rt_repl_rest flag is set, then this function
2238 * already replaced the original system defaultroute with some other
2239 * route and it should just replace the current defaultroute with
2240 * another one, without saving the current route. Use: demand mode,
2241 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2242 * and then changes the temporary addresses to the addresses for the real
2243 * ppp connection when it has come up.
2246 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2248 struct in6_rtmsg rt;
2249 char buf[IF_NAMESIZE];
2251 if (defaultroute6_exists(&rt, dfl_route_metric) &&
2252 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2253 if (rt.rtmsg_flags & RTF_GATEWAY)
2254 error("not replacing existing default route via gateway");
2256 error("not replacing existing default route through %s",
2257 if_indextoname(rt.rtmsg_ifindex, buf));
2261 memset (&rt, 0, sizeof (rt));
2263 rt.rtmsg_ifindex = if_nametoindex(ifname);
2264 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2265 rt.rtmsg_dst_len = 0;
2267 rt.rtmsg_flags = RTF_UP;
2268 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2269 if ( ! ok_error ( errno ))
2270 error("default route ioctl(SIOCADDRT): %m");
2274 have_default_route6 = 1;
2278 /********************************************************************
2280 * cif6defaultroute - delete a default route through the address given.
2283 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2285 struct in6_rtmsg rt;
2287 have_default_route6 = 0;
2289 memset (&rt, '\0', sizeof (rt));
2291 rt.rtmsg_ifindex = if_nametoindex(ifname);
2292 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2293 rt.rtmsg_dst_len = 0;
2295 rt.rtmsg_flags = RTF_UP;
2296 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2298 if ( ! ok_error ( errno ))
2299 error("default route ioctl(SIOCDELRT): %m");
2308 /********************************************************************
2310 * sifproxyarp - Make a proxy ARP entry for the peer.
2313 int sifproxyarp (int unit, u_int32_t his_adr)
2315 struct arpreq arpreq;
2318 if (has_proxy_arp == 0) {
2319 memset (&arpreq, '\0', sizeof(arpreq));
2321 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2322 SIN_ADDR(arpreq.arp_pa) = his_adr;
2323 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2325 * Get the hardware address of an interface on the same subnet
2326 * as our local address.
2328 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2329 sizeof(proxy_arp_dev))) {
2330 error("Cannot determine ethernet address for proxy ARP");
2333 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2335 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2336 if ( ! ok_error ( errno ))
2337 error("ioctl(SIOCSARP): %m");
2340 proxy_arp_addr = his_adr;
2344 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2345 if (forw_path != 0) {
2346 int fd = open(forw_path, O_WRONLY);
2348 if (write(fd, "1", 1) != 1)
2349 error("Couldn't enable IP forwarding: %m");
2359 /********************************************************************
2361 * cifproxyarp - Delete the proxy ARP entry for the peer.
2364 int cifproxyarp (int unit, u_int32_t his_adr)
2366 struct arpreq arpreq;
2368 if (has_proxy_arp) {
2370 memset (&arpreq, '\0', sizeof(arpreq));
2371 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2372 SIN_ADDR(arpreq.arp_pa) = his_adr;
2373 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2374 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2376 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2377 if ( ! ok_error ( errno ))
2378 warn("ioctl(SIOCDARP): %m");
2385 /********************************************************************
2387 * get_ether_addr - get the hardware address of an interface on the
2388 * the same subnet as ipaddr.
2391 static int get_ether_addr (u_int32_t ipaddr,
2392 struct sockaddr *hwaddr,
2393 char *name, int namelen)
2395 struct ifreq *ifr, *ifend;
2396 u_int32_t ina, mask;
2398 struct ifreq ifreq, bestifreq;
2400 struct ifreq ifs[MAX_IFS];
2402 u_int32_t bestmask=0;
2403 int found_interface = 0;
2405 ifc.ifc_len = sizeof(ifs);
2407 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2408 if ( ! ok_error ( errno ))
2409 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2414 * Scan through looking for an interface with an Internet
2415 * address on the same subnet as `ipaddr'.
2417 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2418 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2419 if (ifr->ifr_addr.sa_family == AF_INET) {
2420 ina = SIN_ADDR(ifr->ifr_addr);
2421 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2423 * Check that the interface is up, and not point-to-point
2426 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2429 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2432 * Get its netmask and check that it's on the right subnet.
2434 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2437 mask = SIN_ADDR(ifreq.ifr_addr);
2439 if (((ipaddr ^ ina) & mask) != 0)
2440 continue; /* no match */
2442 if (mask >= bestmask) {
2443 /* Compare using >= instead of > -- it is possible for
2444 an interface to have a netmask of 0.0.0.0 */
2445 found_interface = 1;
2452 if (!found_interface) return 0;
2454 strlcpy(name, bestifreq.ifr_name, namelen);
2456 /* trim off the :1 in eth0:1 */
2457 aliasp = strchr(name, ':');
2461 info("found interface %s for proxy arp", name);
2463 * Now get the hardware address.
2465 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2466 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2467 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2472 &bestifreq.ifr_hwaddr,
2473 sizeof (struct sockaddr));
2479 * get_if_hwaddr - get the hardware address for the specified
2480 * network interface device.
2483 get_if_hwaddr(u_char *addr, char *name)
2488 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2491 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2492 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2493 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2496 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2501 * get_first_ether_hwaddr - get the hardware address for the first
2502 * ethernet-style interface on this system.
2505 get_first_ether_hwaddr(u_char *addr)
2507 struct if_nameindex *if_ni, *i;
2511 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2515 if_ni = if_nameindex();
2523 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2524 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2525 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2526 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2527 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2528 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2534 if_freenameindex(if_ni);
2540 /********************************************************************
2542 * Return user specified netmask, modified by any mask we might determine
2543 * for address `addr' (in network byte order).
2544 * Here we scan through the system's list of interfaces, looking for
2545 * any non-point-to-point interfaces which might appear to be on the same
2546 * network as `addr'. If we find any, we OR in their netmask to the
2547 * user-specified netmask.
2550 u_int32_t GetMask (u_int32_t addr)
2552 u_int32_t mask, nmask, ina;
2553 struct ifreq *ifr, *ifend, ifreq;
2555 struct ifreq ifs[MAX_IFS];
2559 if (IN_CLASSA(addr)) /* determine network mask for address class */
2560 nmask = IN_CLASSA_NET;
2561 else if (IN_CLASSB(addr))
2562 nmask = IN_CLASSB_NET;
2564 nmask = IN_CLASSC_NET;
2566 /* class D nets are disallowed by bad_ip_adrs */
2567 mask = netmask | htonl(nmask);
2569 * Scan through the system's network interfaces.
2571 ifc.ifc_len = sizeof(ifs);
2573 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2574 if ( ! ok_error ( errno ))
2575 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2579 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2580 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2582 * Check the interface's internet address.
2584 if (ifr->ifr_addr.sa_family != AF_INET)
2586 ina = SIN_ADDR(ifr->ifr_addr);
2587 if (((ntohl(ina) ^ addr) & nmask) != 0)
2590 * Check that the interface is up, and not point-to-point nor loopback.
2592 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2593 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2596 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2599 * Get its netmask and OR it into our mask.
2601 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2603 mask |= SIN_ADDR(ifreq.ifr_addr);
2609 /********************************************************************
2611 * Internal routine to decode the version.modification.patch level
2614 static void decode_version (char *buf, int *version,
2615 int *modification, int *patch)
2619 *version = (int) strtoul (buf, &endp, 10);
2623 if (endp != buf && *endp == '.') {
2625 *modification = (int) strtoul (buf, &endp, 10);
2626 if (endp != buf && *endp == '.') {
2628 *patch = (int) strtoul (buf, &buf, 10);
2633 /********************************************************************
2635 * Procedure to determine if the PPP line discipline is registered.
2639 ppp_registered(void)
2647 * We used to open the serial device and set it to the ppp line
2648 * discipline here, in order to create a ppp unit. But that is
2649 * not a good idea - the user might have specified a device that
2650 * they can't open (permission, or maybe it doesn't really exist).
2651 * So we grab a pty master/slave pair and use that.
2653 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2654 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2659 * Try to put the device into the PPP discipline.
2661 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2662 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2671 /********************************************************************
2673 * ppp_available - check whether the system has any ppp interfaces
2674 * (in fact we check whether we can do an ioctl on ppp0).
2677 int ppp_available(void)
2682 int my_version, my_modification, my_patch;
2683 int osmaj, osmin, ospatch;
2685 /* get the kernel version now, since we are called before sys_init */
2687 osmaj = osmin = ospatch = 0;
2688 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2689 kernel_version = KVERSION(osmaj, osmin, ospatch);
2691 fd = open("/dev/ppp", O_RDWR);
2693 new_style_driver = 1;
2695 /* XXX should get from driver */
2697 driver_modification = 4;
2703 if (kernel_version >= KVERSION(2,3,13)) {
2704 error("Couldn't open the /dev/ppp device: %m");
2705 if (errno == ENOENT)
2707 "You need to create the /dev/ppp device node by\n"
2708 "executing the following command as root:\n"
2709 " mknod /dev/ppp c 108 0\n";
2710 else if (errno == ENODEV || errno == ENXIO)
2712 "Please load the ppp_generic kernel module.\n";
2716 /* we are running on a really really old kernel */
2718 "This system lacks kernel support for PPP. This could be because\n"
2719 "the PPP kernel module could not be loaded, or because PPP was not\n"
2720 "included in the kernel configuration. If PPP was included as a\n"
2721 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2722 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2723 "See README.linux file in the ppp distribution for more details.\n";
2726 * Open a socket for doing the ioctl operations.
2728 s = socket(AF_INET, SOCK_DGRAM, 0);
2732 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2733 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2735 * If the device did not exist then attempt to create one by putting the
2736 * current tty into the PPP discipline. If this works then obtain the
2737 * flags for the device again.
2740 if (ppp_registered()) {
2741 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2742 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2746 * Ensure that the hardware address is for PPP and not something else
2749 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2751 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2755 * This is the PPP device. Validate the version of the driver at this
2756 * point to ensure that this program will work with the driver.
2759 char abBuffer [1024];
2761 ifr.ifr_data = abBuffer;
2762 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2764 error("Couldn't read driver version: %m");
2766 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2769 decode_version(abBuffer,
2771 &driver_modification,
2774 * Validate the version of the driver against the version that we used.
2776 decode_version(VERSION,
2781 /* The version numbers must match */
2782 if (driver_version != my_version)
2785 /* The modification levels must be legal */
2786 if (driver_modification < 3) {
2787 if (driver_modification >= 2) {
2788 /* we can cope with 2.2.0 and above */
2796 slprintf(route_buffer, sizeof(route_buffer),
2797 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2798 driver_version, driver_modification, driver_patch);
2800 no_ppp_msg = route_buffer;
2808 #ifndef HAVE_LOGWTMP
2809 /********************************************************************
2811 * Update the wtmp file with the appropriate user name and tty device.
2814 void logwtmp (const char *line, const char *name, const char *host)
2816 struct utmp ut, *utp;
2817 pid_t mypid = getpid();
2823 * Update the signon database for users.
2824 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2826 utmpname(_PATH_UTMP);
2828 while ((utp = getutent()) && (utp->ut_pid != mypid))
2832 memcpy(&ut, utp, sizeof(ut));
2834 /* some gettys/telnetds don't initialize utmp... */
2835 memset(&ut, 0, sizeof(ut));
2837 if (ut.ut_id[0] == 0)
2838 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2840 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2841 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2845 ut.ut_type = USER_PROCESS;
2848 /* Insert the host name if one is supplied */
2850 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2852 /* Insert the IP address of the remote system if IP is enabled */
2853 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2854 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2855 sizeof(ut.ut_addr));
2857 /* CL: Makes sure that the logout works */
2858 if (*host == 0 && *name==0)
2864 * Update the wtmp file.
2867 updwtmp(_PATH_WTMP, &ut);
2869 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2871 flock(wtmp, LOCK_EX);
2873 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2874 warn("error writing %s: %m", _PATH_WTMP);
2876 flock(wtmp, LOCK_UN);
2882 #endif /* HAVE_LOGWTMP */
2884 /********************************************************************
2886 * sifvjcomp - config tcp header compression
2889 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2894 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2895 error("Couldn't set up TCP header compression: %m");
2900 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2901 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2906 /********************************************************************
2908 * sifup - Config the interface up and enable IP packets to pass.
2915 if ((ret = setifstate(u, 1)))
2921 /********************************************************************
2923 * sifdown - Disable the indicated protocol and config the interface
2924 * down if there are no remaining protocols.
2929 if (if_is_up && --if_is_up > 0)
2937 return setifstate(u, 0);
2941 /********************************************************************
2943 * sif6up - Config the interface up for IPv6
2950 if ((ret = setifstate(u, 1)))
2956 /********************************************************************
2958 * sif6down - Disable the IPv6CP protocol and config the interface
2959 * down if there are no remaining protocols.
2962 int sif6down (int u)
2969 return setifstate(u, 0);
2973 /********************************************************************
2975 * setifstate - Config the interface up or down
2978 static int setifstate (int u, int state)
2982 memset (&ifr, '\0', sizeof (ifr));
2983 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2984 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2985 if (! ok_error (errno))
2986 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2991 ifr.ifr_flags |= IFF_UP;
2993 ifr.ifr_flags &= ~IFF_UP;
2994 ifr.ifr_flags |= IFF_POINTOPOINT;
2995 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2996 if (! ok_error (errno))
2997 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
3003 /********************************************************************
3005 * sifaddr - Config the interface IP addresses and netmask.
3008 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3014 memset (&ifr, '\0', sizeof (ifr));
3015 memset (&rt, '\0', sizeof (rt));
3017 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
3018 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3019 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3021 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3023 * Set our IP address
3025 SIN_ADDR(ifr.ifr_addr) = our_adr;
3026 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3027 if (errno != EEXIST) {
3028 if (! ok_error (errno))
3029 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3032 warn("ioctl(SIOCSIFADDR): Address already exists");
3037 * Set the gateway address
3040 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3041 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3042 if (! ok_error (errno))
3043 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3049 * For recent kernels, force the netmask to 255.255.255.255.
3051 if (kernel_version >= KVERSION(2,1,16))
3053 if (net_mask != 0) {
3054 SIN_ADDR(ifr.ifr_netmask) = net_mask;
3055 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3056 if (! ok_error (errno))
3057 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3062 * Add the device route
3064 if (kernel_version < KVERSION(2,1,16)) {
3065 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3066 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3069 SIN_ADDR(rt.rt_gateway) = 0L;
3070 SIN_ADDR(rt.rt_dst) = his_adr;
3071 rt.rt_flags = RTF_UP | RTF_HOST;
3073 if (kernel_version > KVERSION(2,1,0)) {
3074 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3075 SIN_ADDR(rt.rt_genmask) = -1L;
3078 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3079 if (! ok_error (errno))
3080 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3085 /* set ip_dynaddr in demand mode if address changes */
3086 if (demand && tune_kernel && !dynaddr_set
3087 && our_old_addr && our_old_addr != our_adr) {
3088 /* set ip_dynaddr if possible */
3092 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3093 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3094 if (write(fd, "1", 1) != 1)
3095 error("Couldn't enable dynamic IP addressing: %m");
3098 dynaddr_set = 1; /* only 1 attempt */
3105 /********************************************************************
3107 * cifaddr - Clear the interface IP addresses, and delete routes
3108 * through the interface if possible.
3111 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3115 if (kernel_version < KVERSION(2,1,16)) {
3117 * Delete the route through the device
3120 memset (&rt, '\0', sizeof (rt));
3122 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3123 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3126 SIN_ADDR(rt.rt_gateway) = 0;
3127 SIN_ADDR(rt.rt_dst) = his_adr;
3128 rt.rt_flags = RTF_UP | RTF_HOST;
3130 if (kernel_version > KVERSION(2,1,0)) {
3131 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3132 SIN_ADDR(rt.rt_genmask) = -1L;
3135 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3136 if (still_ppp() && ! ok_error (errno))
3137 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3142 /* This way it is possible to have an IPX-only or IPv6-only interface */
3143 memset(&ifr, 0, sizeof(ifr));
3144 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3145 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3147 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3148 if (! ok_error (errno)) {
3149 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3154 our_old_addr = our_adr;
3160 /********************************************************************
3162 * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3164 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3167 struct nlmsghdr nlh;
3168 struct ifaddrmsg ifa;
3171 struct in6_addr addr;
3175 struct nlmsghdr nlh;
3176 struct nlmsgerr nlerr;
3178 struct sockaddr_nl nladdr;
3185 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
3187 error("sif6addr_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
3192 * Tell kernel to not send to us payload of acknowledgment error message.
3193 * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
3194 * older kernel versions always send full payload in acknowledgment netlink
3195 * message. We ignore payload of this message as we need only error code,
3196 * to check if our set remote peer address request succeeded or failed.
3197 * So ignore return value from the following setsockopt() call as setting
3198 * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
3201 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
3203 memset(&nladdr, 0, sizeof(nladdr));
3204 nladdr.nl_family = AF_NETLINK;
3206 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
3207 error("sif6addr_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
3212 memset(&nlreq, 0, sizeof(nlreq));
3213 nlreq.nlh.nlmsg_len = sizeof(nlreq);
3214 nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3215 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3216 nlreq.ifa.ifa_family = AF_INET6;
3217 nlreq.ifa.ifa_prefixlen = 128;
3218 nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3219 nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3220 nlreq.ifa.ifa_index = iface;
3221 nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3222 nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3223 IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3224 nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3225 nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3228 * To set only local address, older kernel expects that local address is
3229 * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3230 * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3231 * compatibility when setting only local address, set it via both IFA_LOCAL
3232 * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3233 * from iproute2 project.
3235 if (!eui64_iszero(his_eui64))
3236 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3238 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3240 memset(&nladdr, 0, sizeof(nladdr));
3241 nladdr.nl_family = AF_NETLINK;
3243 memset(&iov, 0, sizeof(iov));
3244 iov.iov_base = &nlreq;
3245 iov.iov_len = sizeof(nlreq);
3247 memset(&msg, 0, sizeof(msg));
3248 msg.msg_name = &nladdr;
3249 msg.msg_namelen = sizeof(nladdr);
3253 if (sendmsg(fd, &msg, 0) < 0) {
3254 error("sif6addr_rtnetlink: sendmsg(RTM_NEWADDR/NLM_F_CREATE): %m (line %d)", __LINE__);
3259 memset(&iov, 0, sizeof(iov));
3260 iov.iov_base = &nlresp;
3261 iov.iov_len = sizeof(nlresp);
3263 memset(&msg, 0, sizeof(msg));
3264 msg.msg_name = &nladdr;
3265 msg.msg_namelen = sizeof(nladdr);
3269 nlresplen = recvmsg(fd, &msg, 0);
3271 if (nlresplen < 0) {
3272 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
3279 if (nladdr.nl_family != AF_NETLINK) {
3280 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
3284 if ((size_t)nlresplen != sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
3285 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
3289 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
3290 if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
3291 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
3295 /* error == 0 indicates success, negative value is errno code */
3296 if (nlresp.nlerr.error != 0) {
3298 * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3299 * addresses and error response is expected. On older kernel versions
3300 * do not show this error message. On error pppd tries to fallback to
3301 * the old IOCTL method.
3303 if (kernel_version >= KVERSION(3,11,0))
3304 error("sif6addr_rtnetlink: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
3311 /********************************************************************
3313 * sif6addr - Config the interface with an IPv6 link-local address
3315 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3317 struct in6_ifreq ifr6;
3319 struct in6_rtmsg rt6;
3324 error("IPv6 socket creation failed: %m");
3327 memset(&ifr, 0, sizeof (ifr));
3328 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3329 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3330 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3334 if (kernel_version >= KVERSION(2,1,16)) {
3335 /* Set both local address and remote peer address (with route for it) via rtnetlink */
3336 ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3342 * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3343 * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3346 /* Local interface */
3347 memset(&ifr6, 0, sizeof(ifr6));
3348 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3349 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3350 ifr6.ifr6_prefixlen = 128;
3352 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3353 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3358 if (!ret && !eui64_iszero(his_eui64)) {
3360 * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3361 * setting remote peer host address, so set only route to remote host.
3364 /* Route to remote host */
3365 memset(&rt6, 0, sizeof(rt6));
3366 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3367 rt6.rtmsg_flags = RTF_UP;
3368 rt6.rtmsg_dst_len = 128;
3369 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3370 rt6.rtmsg_metric = 1;
3372 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3373 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3382 /********************************************************************
3384 * cif6addr - Remove IPv6 address from interface
3386 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3389 struct in6_ifreq ifr6;
3393 error("IPv6 socket creation failed: %m");
3396 memset(&ifr, 0, sizeof(ifr));
3397 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3398 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3399 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3403 memset(&ifr6, 0, sizeof(ifr6));
3404 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3405 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3406 ifr6.ifr6_prefixlen = 128;
3408 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3409 if (errno != EADDRNOTAVAIL) {
3410 if (! ok_error (errno))
3411 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3414 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3423 * get_pty - get a pty master/slave pair and chown the slave side
3424 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
3427 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3429 int i, mfd, ret, sfd = -1;
3431 struct termios tios;
3435 * Try the unix98 way first.
3437 mfd = open("/dev/ptmx", O_RDWR);
3440 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3441 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3442 chmod(pty_name, S_IRUSR | S_IWUSR);
3445 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3446 warn("Couldn't unlock pty slave %s: %m", pty_name);
3448 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3450 warn("Couldn't open pty slave %s: %m", pty_name);
3455 #endif /* TIOCGPTN */
3458 /* the old way - scan through the pty name space */
3459 for (i = 0; i < 64; ++i) {
3460 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3461 'p' + i / 16, i % 16);
3462 mfd = open(pty_name, O_RDWR, 0);
3465 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3467 ret = fchown(sfd, uid, -1);
3469 warn("Couldn't change ownership of %s, %m", pty_name);
3471 ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3473 warn("Couldn't change permissions of %s, %m", pty_name);
3485 strlcpy(slave_name, pty_name, 16);
3488 if (tcgetattr(sfd, &tios) == 0) {
3489 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3490 tios.c_cflag |= CS8 | CREAD | CLOCAL;
3491 tios.c_iflag = IGNPAR;
3494 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3495 warn("couldn't set attributes on pty: %m");
3497 warn("couldn't get attributes on pty: %m");
3502 /********************************************************************
3504 * open_loopback - open the device we use for getting packets
3505 * in demand mode. Under Linux, we use a pty master/slave pair.
3508 open_ppp_loopback(void)
3513 if (new_style_driver) {
3514 /* allocate ourselves a ppp unit */
3515 if (make_ppp_unit() < 0)
3517 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3518 set_kdebugflag(kdebugflag);
3523 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3524 fatal("No free pty for loopback");
3526 set_ppp_fd(slave_fd);
3528 flags = fcntl(master_fd, F_GETFL);
3530 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3531 warn("couldn't set master loopback to nonblock: %m");
3533 flags = fcntl(ppp_fd, F_GETFL);
3535 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3536 warn("couldn't set slave loopback to nonblock: %m");
3538 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3539 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3541 * Find out which interface we were given.
3543 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3544 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3546 * Enable debug in the driver if requested.
3548 set_kdebugflag (kdebugflag);
3553 /********************************************************************
3555 * sifnpmode - Set the mode for handling packets for a given NP.
3559 sifnpmode(int u, int proto, enum NPmode mode)
3563 npi.protocol = proto;
3565 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3566 if (! ok_error (errno))
3567 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3574 /********************************************************************
3576 * sipxfaddr - Config the interface IPX networknumber
3579 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
3586 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3588 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3590 if (! ok_error (errno))
3591 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3595 memset (&ifr, '\0', sizeof (ifr));
3596 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3598 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
3599 sipx->sipx_family = AF_IPX;
3600 sipx->sipx_port = 0;
3601 sipx->sipx_network = htonl (network);
3602 sipx->sipx_type = IPX_FRAME_ETHERII;
3603 sipx->sipx_action = IPX_CRTITF;
3605 * Set the IPX device
3607 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3609 if (errno != EEXIST) {
3610 if (! ok_error (errno))
3611 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
3614 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
3623 /********************************************************************
3625 * cipxfaddr - Clear the information for the IPX network. The IPX routes
3626 * are removed and the device is no longer able to pass IPX
3630 int cipxfaddr (int unit)
3637 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3639 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3641 if (! ok_error (errno))
3642 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3646 memset (&ifr, '\0', sizeof (ifr));
3647 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3649 sipx->sipx_type = IPX_FRAME_ETHERII;
3650 sipx->sipx_action = IPX_DLTITF;
3651 sipx->sipx_family = AF_IPX;
3653 * Set the IPX device
3655 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3656 if (! ok_error (errno))
3657 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
3667 * Use the hostname as part of the random number seed.
3676 for (p = hostname; *p != 0; ++p)
3681 /********************************************************************
3683 * sys_check_options - check the options that the user specified
3687 sys_check_options(void)
3691 * Disable the IPX protocol if the support is not present in the kernel.
3695 if (ipxcp_protent.enabled_flag) {
3696 struct stat stat_buf;
3697 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
3698 && (path = path_to_procfs("/net/ipx_interface")) == NULL)
3699 || lstat(path, &stat_buf) < 0) {
3700 error("IPX support is not present in the kernel\n");
3701 ipxcp_protent.enabled_flag = 0;
3705 if (demand && driver_is_old) {
3706 option_error("demand dialling is not supported by kernel driver "
3707 "version %d.%d.%d", driver_version, driver_modification,
3711 if (multilink && !new_style_driver) {
3712 warn("Warning: multilink is not supported by the kernel driver");
3718 /********************************************************************
3720 * get_time - Get current time, monotonic if possible.
3723 get_time(struct timeval *tv)
3725 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3726 * Runtime checking makes it safe. */
3727 #ifndef CLOCK_MONOTONIC
3728 #define CLOCK_MONOTONIC 1
3730 static int monotonic = -1;
3735 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3739 tv->tv_sec = ts.tv_sec;
3740 tv->tv_usec = ts.tv_nsec / 1000;
3743 } else if (monotonic > 0)
3747 warn("Couldn't use monotonic clock source: %m");
3750 return gettimeofday(tv, NULL);