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;
934 { 1000000, B1000000 },
937 { 1152000, B1152000 },
940 { 1500000, B1500000 },
943 { 2000000, B2000000 },
946 { 2500000, B2500000 },
949 { 3000000, B3000000 },
952 { 3500000, B3500000 },
955 { 4000000, B4000000 },
960 /********************************************************************
962 * Translate from bits/second to a speed_t.
965 static int translate_speed (int bps)
967 struct speed *speedp;
970 for (speedp = speeds; speedp->speed_int; speedp++) {
971 if (bps == speedp->speed_int)
972 return speedp->speed_val;
978 /********************************************************************
980 * Translate from a speed_t to bits/second.
983 static int baud_rate_of (int speed)
985 struct speed *speedp;
988 for (speedp = speeds; speedp->speed_int; speedp++) {
989 if (speed == speedp->speed_val)
990 return speedp->speed_int;
996 /********************************************************************
998 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
999 * at the requested speed, etc. If `local' is true, set CLOCAL
1000 * regardless of whether the modem option was specified.
1003 void set_up_tty(int tty_fd, int local)
1006 struct termios tios;
1009 if (tcgetattr(tty_fd, &tios) < 0) {
1010 if (!ok_error(errno))
1011 fatal("tcgetattr: %m (line %d)", __LINE__);
1018 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1019 tios.c_cflag |= CS8 | CREAD | HUPCL;
1021 tios.c_iflag = IGNBRK | IGNPAR;
1024 tios.c_cc[VMIN] = 1;
1025 tios.c_cc[VTIME] = 0;
1027 if (local || !modem)
1028 tios.c_cflag ^= (CLOCAL | HUPCL);
1032 tios.c_cflag |= CRTSCTS;
1036 tios.c_iflag |= IXON | IXOFF;
1037 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
1038 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1042 tios.c_cflag &= ~CRTSCTS;
1050 tios.c_cflag |= CSTOPB;
1053 speed = translate_speed(inspeed);
1055 cfsetospeed (&tios, speed);
1056 cfsetispeed (&tios, speed);
1057 speed = cfgetospeed(&tios);
1058 baud_rate = baud_rate_of(speed);
1061 tios.c_cflag &= ~CBAUD;
1062 tios.c_cflag |= BOTHER;
1063 tios.c_ospeed = inspeed;
1065 /* B0 sets input baudrate to the output baudrate */
1066 tios.c_cflag &= ~(CBAUD << IBSHIFT);
1067 tios.c_cflag |= B0 << IBSHIFT;
1068 tios.c_ispeed = inspeed;
1070 baud_rate = inspeed;
1077 speed = cfgetospeed(&tios);
1078 baud_rate = baud_rate_of(speed);
1081 baud_rate = tios.c_ospeed;
1086 * We can't proceed if the serial port baud rate is unknown,
1087 * since that implies that the serial port is disabled.
1091 fatal("speed %d not supported", inspeed);
1093 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1096 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1098 fatal("tcsetattr: %m (line %d)", __LINE__);
1102 /********************************************************************
1104 * setdtr - control the DTR line on the serial port.
1105 * This is called from die(), so it shouldn't call die().
1108 void setdtr (int tty_fd, int on)
1110 int modembits = TIOCM_DTR;
1112 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1115 /********************************************************************
1117 * restore_tty - restore the terminal to the saved settings.
1120 void restore_tty (int tty_fd)
1125 * Turn off echoing, because otherwise we can get into
1126 * a loop with the tty and the modem echoing to each other.
1127 * We presume we are the sole user of this tty device, so
1128 * when we close it, it will revert to its defaults anyway.
1130 if (!default_device)
1131 inittermios.c_lflag &= ~(ECHO | ECHONL);
1133 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1134 if (! ok_error (errno))
1135 warn("tcsetattr: %m (line %d)", __LINE__);
1140 /********************************************************************
1142 * output - Output PPP packet.
1145 void output (int unit, unsigned char *p, int len)
1150 dump_packet("sent", p, len);
1151 if (snoop_send_hook) snoop_send_hook(p, len);
1153 if (len < PPP_HDRLEN)
1155 if (new_style_driver) {
1158 proto = (p[0] << 8) + p[1];
1159 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1162 if (write(fd, p, len) < 0) {
1163 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1164 || errno == ENXIO || errno == EIO || errno == EINTR)
1165 warn("write: warning: %m (%d)", errno);
1167 error("write: %m (%d)", errno);
1171 /********************************************************************
1173 * wait_input - wait until there is data available,
1174 * for the length of time specified by *timo (indefinite
1178 void wait_input(struct timeval *timo)
1185 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1186 if (n < 0 && errno != EINTR)
1187 fatal("select: %m");
1191 * add_fd - add an fd to the set that wait_input waits for.
1195 if (fd >= FD_SETSIZE)
1196 fatal("internal error: file descriptor too large (%d)", fd);
1197 FD_SET(fd, &in_fds);
1203 * remove_fd - remove an fd from the set that wait_input waits for.
1205 void remove_fd(int fd)
1207 FD_CLR(fd, &in_fds);
1211 /********************************************************************
1213 * read_packet - get a PPP packet from the serial device.
1216 int read_packet (unsigned char *buf)
1220 len = PPP_MRU + PPP_HDRLEN;
1221 if (new_style_driver) {
1222 *buf++ = PPP_ALLSTATIONS;
1228 nr = read(ppp_fd, buf, len);
1229 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1230 && errno != EIO && errno != EINTR)
1232 if (nr < 0 && errno == ENXIO)
1235 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1236 /* N.B. we read ppp_fd first since LCP packets come in there. */
1237 nr = read(ppp_dev_fd, buf, len);
1238 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1239 && errno != EIO && errno != EINTR)
1240 error("read /dev/ppp: %m");
1241 if (nr < 0 && errno == ENXIO)
1243 if (nr == 0 && doing_multilink) {
1244 remove_fd(ppp_dev_fd);
1248 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1250 return (new_style_driver && nr > 0)? nr+2: nr;
1253 /********************************************************************
1255 * get_loop_output - get outgoing packets from the ppp device,
1256 * and detect when we want to bring the real link up.
1257 * Return value is 1 if we need to bring up the link, 0 otherwise.
1260 get_loop_output(void)
1265 if (new_style_driver) {
1266 while ((n = read_packet(inpacket_buf)) > 0)
1267 if (loop_frame(inpacket_buf, n))
1272 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1273 if (loop_chars(inbuf, n))
1277 fatal("eof on loopback");
1279 if (errno != EWOULDBLOCK && errno != EAGAIN)
1280 fatal("read from loopback: %m(%d)", errno);
1286 * netif_set_mtu - set the MTU on the PPP network interface.
1289 netif_set_mtu(int unit, int mtu)
1293 memset (&ifr, '\0', sizeof (ifr));
1294 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1297 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1298 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1302 * netif_get_mtu - get the MTU on the PPP network interface.
1305 netif_get_mtu(int unit)
1309 memset (&ifr, '\0', sizeof (ifr));
1310 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1312 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1313 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1319 /********************************************************************
1321 * tty_send_config - configure the transmit characteristics of
1322 * the ppp interface.
1325 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1332 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1333 if (errno != EIO && errno != ENOTTY)
1334 error("Couldn't set transmit async character map: %m");
1339 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1340 | (sync_serial? SC_SYNC: 0);
1341 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1344 /********************************************************************
1346 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1349 void tty_set_xaccm (ext_accm accm)
1353 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1354 if ( ! ok_error (errno))
1355 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1359 /********************************************************************
1361 * tty_recv_config - configure the receive-side characteristics of
1362 * the ppp interface.
1365 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1368 * If we were called because the link has gone down then there is nothing
1369 * which may be done. Just return without incident.
1374 * Set the receiver parameters
1376 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1377 if (errno != EIO && errno != ENOTTY)
1378 error("Couldn't set channel receive MRU: %m");
1380 if (new_style_driver && ppp_dev_fd >= 0
1381 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1382 error("Couldn't set MRU in generic PPP layer: %m");
1384 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1385 if (errno != EIO && errno != ENOTTY)
1386 error("Couldn't set channel receive asyncmap: %m");
1390 /********************************************************************
1392 * ccp_test - ask kernel whether a given compression method
1393 * is acceptable for use.
1397 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1399 struct ppp_option_data data;
1401 memset (&data, '\0', sizeof (data));
1403 data.length = opt_len;
1404 data.transmit = for_transmit;
1406 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1409 return (errno == ENOBUFS)? 0: -1;
1412 /********************************************************************
1414 * ccp_flags_set - inform kernel about the current state of CCP.
1417 void ccp_flags_set (int unit, int isopen, int isup)
1421 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1422 if (still_ppp() && ppp_dev_fd >= 0)
1423 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1428 * set_filters - set the active and pass filters in the kernel driver.
1430 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1432 struct sock_fprog fp;
1434 fp.len = pass->bf_len;
1435 fp.filter = (struct sock_filter *) pass->bf_insns;
1436 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1437 if (errno == ENOTTY)
1438 warn("kernel does not support PPP filtering");
1440 error("Couldn't set pass-filter in kernel: %m");
1443 fp.len = active->bf_len;
1444 fp.filter = (struct sock_filter *) active->bf_insns;
1445 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1446 error("Couldn't set active-filter in kernel: %m");
1451 #endif /* PPP_FILTER */
1453 /********************************************************************
1455 * get_idle_time - return how long the link has been idle.
1458 get_idle_time(int u, struct ppp_idle *ip)
1460 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1463 /********************************************************************
1465 * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1466 * this only supports 32-bit counters, so need to count the wraps.
1469 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1471 static u_int32_t previbytes = 0;
1472 static u_int32_t prevobytes = 0;
1473 static u_int32_t iwraps = 0;
1474 static u_int32_t owraps = 0;
1476 struct ifpppstatsreq req;
1478 memset (&req, 0, sizeof (req));
1480 req.stats_ptr = (caddr_t) &req.stats;
1481 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1482 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1483 error("Couldn't get PPP statistics: %m");
1486 stats->bytes_in = req.stats.p.ppp_ibytes;
1487 stats->bytes_out = req.stats.p.ppp_obytes;
1488 stats->pkts_in = req.stats.p.ppp_ipackets;
1489 stats->pkts_out = req.stats.p.ppp_opackets;
1491 if (stats->bytes_in < previbytes)
1493 if (stats->bytes_out < prevobytes)
1496 previbytes = stats->bytes_in;
1497 prevobytes = stats->bytes_out;
1499 stats->bytes_in += (uint64_t)iwraps << 32;
1500 stats->bytes_out += (uint64_t)owraps << 32;
1505 /********************************************************************
1506 * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1507 * This provides native 64-bit counters.
1510 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1512 static int rtnl_fd = -1;
1514 struct sockaddr_nl nladdr;
1516 struct nlmsghdr nlh;
1517 struct if_stats_msg ifsm;
1520 struct nlmsghdr nlh;
1523 struct nlmsgerr nlerr;
1529 /* We only case about these first fields from rtnl_link_stats64 */
1530 uint64_t rx_packets;
1531 uint64_t tx_packets;
1535 char __end_stats[0];
1543 memset(&nladdr, 0, sizeof(nladdr));
1544 nladdr.nl_family = AF_NETLINK;
1547 rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1549 error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__);
1553 if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
1554 error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
1559 memset(&nlreq, 0, sizeof(nlreq));
1560 nlreq.nlh.nlmsg_len = sizeof(nlreq);
1561 nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1562 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1564 nlreq.ifsm.ifindex = if_nametoindex(ifname);
1565 nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1567 memset(&iov, 0, sizeof(iov));
1568 iov.iov_base = &nlreq;
1569 iov.iov_len = sizeof(nlreq);
1571 memset(&msg, 0, sizeof(msg));
1572 msg.msg_name = &nladdr;
1573 msg.msg_namelen = sizeof(nladdr);
1577 if (sendmsg(rtnl_fd, &msg, 0) < 0) {
1578 error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1582 /* We just need to repoint to IOV ... everything else stays the same */
1583 iov.iov_base = &nlresp;
1584 iov.iov_len = sizeof(nlresp);
1586 nlresplen = recvmsg(rtnl_fd, &msg, 0);
1588 if (nlresplen < 0) {
1589 error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1593 if (nlresplen < sizeof(nlresp.nlh)) {
1594 error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__);
1598 if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) {
1599 if (nlresplen < offsetof(struct nlresp, __end_err)) {
1600 if (kernel_version >= KVERSION(4,7,0))
1601 error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
1603 error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).",
1609 if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) {
1610 error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)",
1611 nlresp.nlh.nlmsg_type, __LINE__);
1615 if (nlresplen < offsetof(struct nlresp, __end_stats)) {
1616 error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1620 stats->bytes_in = nlresp.stats.rx_bytes;
1621 stats->bytes_out = nlresp.stats.tx_bytes;
1622 stats->pkts_in = nlresp.stats.rx_packets;
1623 stats->pkts_out = nlresp.stats.tx_packets;
1632 /********************************************************************
1633 * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1634 * this provides native 64-bit counters.
1637 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1639 char fname[PATH_MAX+1];
1640 char buf[21], *err; /* 2^64 < 10^20 */
1642 unsigned long long val;
1649 #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1650 statfield(rx_bytes, bytes_in),
1651 statfield(tx_bytes, bytes_out),
1652 statfield(rx_packets, pkts_in),
1653 statfield(tx_packets, pkts_out),
1657 blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1658 if (blen >= sizeof(fname))
1659 return 0; /* ifname max 15, so this should be impossible */
1661 for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1662 if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1664 error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1668 fd = open(fname, O_RDONLY);
1670 error("%s: %m", fname);
1674 rlen = read(fd, buf, sizeof(buf) - 1);
1677 error("%s: %m", fname);
1680 /* trim trailing \n if present */
1681 while (rlen > 0 && buf[rlen-1] == '\n')
1686 val = strtoull(buf, &err, 10);
1687 if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1688 error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1689 buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1692 switch (slist[i].size) {
1693 #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1700 error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1708 /********************************************************************
1709 * Periodic timer function to be used to keep stats up to date in case of ioctl
1712 * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1713 * If you do change the timer, remember to also bring the get_ppp_stats (which
1714 * sets up the initial trigger) as well.
1717 ppp_stats_poller(void* u)
1719 struct pppd_stats dummy;
1720 get_ppp_stats_ioctl((long)u, &dummy);
1721 TIMEOUT(ppp_stats_poller, u, 25);
1724 /********************************************************************
1725 * get_ppp_stats - return statistics for the link.
1727 int get_ppp_stats(int u, struct pppd_stats *stats)
1729 static int (*func)(int, struct pppd_stats*) = NULL;
1732 if (get_ppp_stats_rtnetlink(u, stats)) {
1733 func = get_ppp_stats_rtnetlink;
1736 if (get_ppp_stats_sysfs(u, stats)) {
1737 func = get_ppp_stats_sysfs;
1740 warn("statistics falling back to ioctl which only supports 32-bit counters");
1741 func = get_ppp_stats_ioctl;
1742 TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1745 return func(u, stats);
1748 /********************************************************************
1750 * ccp_fatal_error - returns 1 if decompression was disabled as a
1751 * result of an error detected after decompression of a packet,
1752 * 0 otherwise. This is necessary because of patent nonsense.
1755 int ccp_fatal_error (int unit)
1759 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1760 error("Couldn't read compression error flags: %m");
1763 return flags & SC_DC_FERROR;
1766 /********************************************************************
1768 * path_to_procfs - find the path to the proc file system mount point
1770 static char proc_path[MAXPATHLEN];
1771 static int proc_path_len;
1773 static char *path_to_procfs(const char *tail)
1775 struct mntent *mntent;
1778 if (proc_path_len == 0) {
1779 /* Default the mount location of /proc */
1780 strlcpy (proc_path, "/proc", sizeof(proc_path));
1782 fp = fopen(MOUNTED, "r");
1784 while ((mntent = getmntent(fp)) != NULL) {
1785 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1787 if (strcmp(mntent->mnt_type, "proc") == 0) {
1788 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1789 proc_path_len = strlen(proc_path);
1797 strlcpy(proc_path + proc_path_len, tail,
1798 sizeof(proc_path) - proc_path_len);
1803 * /proc/net/route parsing stuff.
1805 #define ROUTE_MAX_COLS 12
1806 FILE *route_fd = (FILE *) 0;
1807 static char route_buffer[512];
1808 static int route_dev_col, route_dest_col, route_gw_col;
1809 static int route_flags_col, route_metric_col, route_mask_col;
1810 static int route_num_cols;
1812 static int open_route_table (void);
1813 static void close_route_table (void);
1814 static int read_route_table (struct rtentry *rt);
1816 /********************************************************************
1818 * close_route_table - close the interface to the route table
1821 static void close_route_table (void)
1823 if (route_fd != (FILE *) 0) {
1825 route_fd = (FILE *) 0;
1829 /********************************************************************
1831 * open_route_table - open the interface to the route table
1833 static char route_delims[] = " \t\n";
1835 static int open_route_table (void)
1839 close_route_table();
1841 path = path_to_procfs("/net/route");
1842 route_fd = fopen (path, "r");
1843 if (route_fd == NULL) {
1844 error("can't open routing table %s: %m", path);
1848 route_dev_col = 0; /* default to usual columns */
1851 route_flags_col = 3;
1852 route_metric_col = 6;
1856 /* parse header line */
1857 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1858 char *p = route_buffer, *q;
1860 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1862 if ((q = strtok(p, route_delims)) == 0)
1864 if (strcasecmp(q, "iface") == 0)
1865 route_dev_col = col;
1866 else if (strcasecmp(q, "destination") == 0)
1867 route_dest_col = col;
1868 else if (strcasecmp(q, "gateway") == 0)
1870 else if (strcasecmp(q, "flags") == 0)
1871 route_flags_col = col;
1872 else if (strcasecmp(q, "mask") == 0)
1873 route_mask_col = col;
1876 if (used && col >= route_num_cols)
1877 route_num_cols = col + 1;
1885 /********************************************************************
1887 * read_route_table - read the next entry from the route table
1890 static int read_route_table(struct rtentry *rt)
1892 char *cols[ROUTE_MAX_COLS], *p;
1895 memset (rt, '\0', sizeof (struct rtentry));
1897 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1901 for (col = 0; col < route_num_cols; ++col) {
1902 cols[col] = strtok(p, route_delims);
1903 if (cols[col] == NULL)
1904 return 0; /* didn't get enough columns */
1908 SET_SA_FAMILY (rt->rt_dst, AF_INET);
1909 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
1911 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1912 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1913 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1915 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1916 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
1917 rt->rt_dev = cols[route_dev_col];
1922 /********************************************************************
1924 * defaultroute_exists - determine if there is a default route
1925 * with the given metric (or negative for any)
1928 static int defaultroute_exists (struct rtentry *rt, int metric)
1932 if (!open_route_table())
1935 while (read_route_table(rt) != 0) {
1936 if ((rt->rt_flags & RTF_UP) == 0)
1939 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1941 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1942 || rt->rt_metric == metric)) {
1948 close_route_table();
1953 * have_route_to - determine if the system has any route to
1954 * a given IP address. `addr' is in network byte order.
1955 * Return value is 1 if yes, 0 if no, -1 if don't know.
1956 * For demand mode to work properly, we have to ignore routes
1957 * through our own interface.
1959 int have_route_to(u_int32_t addr)
1964 if (!open_route_table())
1965 return -1; /* don't know */
1967 while (read_route_table(&rt)) {
1968 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1970 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1976 close_route_table();
1980 /********************************************************************
1982 * sifdefaultroute - assign a default route through the address given.
1984 * If the global default_rt_repl_rest flag is set, then this function
1985 * already replaced the original system defaultroute with some other
1986 * route and it should just replace the current defaultroute with
1987 * another one, without saving the current route. Use: demand mode,
1988 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
1989 * and then changes the temporary addresses to the addresses for the real
1990 * ppp connection when it has come up.
1993 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
1995 struct rtentry rt, tmp_rt;
1996 struct rtentry *del_rt = NULL;
1998 if (default_rt_repl_rest) {
1999 /* We have already replaced the original defaultroute, if we
2000 * are called again, we will delete the current default route
2001 * and set the new default route in this function.
2002 * - this is normally only the case the doing demand: */
2003 if (defaultroute_exists(&tmp_rt, -1))
2005 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
2006 strcmp( old_def_rt.rt_dev, ifname) != 0) {
2008 * We did not yet replace an existing default route, let's
2009 * check if we should save and replace a default route:
2011 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2013 if (old_gateway != gateway) {
2015 error("not replacing default route to %s [%I]",
2016 old_def_rt.rt_dev, old_gateway);
2019 /* we need to copy rt_dev because we need it permanent too: */
2020 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2021 strcpy(tmp_dev, old_def_rt.rt_dev);
2022 old_def_rt.rt_dev = tmp_dev;
2024 notice("replacing old default route to %s [%I]",
2025 old_def_rt.rt_dev, old_gateway);
2026 default_rt_repl_rest = 1;
2027 del_rt = &old_def_rt;
2032 memset (&rt, 0, sizeof (rt));
2033 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2036 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2038 if (kernel_version > KVERSION(2,1,0)) {
2039 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2040 SIN_ADDR(rt.rt_genmask) = 0L;
2043 rt.rt_flags = RTF_UP;
2044 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2045 if ( ! ok_error ( errno ))
2046 error("default route ioctl(SIOCADDRT): %m");
2049 if (default_rt_repl_rest && del_rt)
2050 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2051 if ( ! ok_error ( errno ))
2052 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2056 have_default_route = 1;
2060 /********************************************************************
2062 * cifdefaultroute - delete a default route through the address given.
2065 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2069 have_default_route = 0;
2071 memset (&rt, '\0', sizeof (rt));
2072 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2073 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2078 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2080 if (kernel_version > KVERSION(2,1,0)) {
2081 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2082 SIN_ADDR(rt.rt_genmask) = 0L;
2085 rt.rt_flags = RTF_UP;
2086 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2088 if ( ! ok_error ( errno ))
2089 error("default route ioctl(SIOCDELRT): %m");
2093 if (default_rt_repl_rest) {
2094 notice("restoring old default route to %s [%I]",
2095 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2096 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2097 if ( ! ok_error ( errno ))
2098 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2101 default_rt_repl_rest = 0;
2109 * /proc/net/ipv6_route parsing stuff.
2111 static int route_dest_plen_col;
2112 static int open_route6_table (void);
2113 static int read_route6_table (struct in6_rtmsg *rt);
2115 /********************************************************************
2117 * open_route6_table - open the interface to the route table
2119 static int open_route6_table (void)
2123 close_route_table();
2125 path = path_to_procfs("/net/ipv6_route");
2126 route_fd = fopen (path, "r");
2127 if (route_fd == NULL) {
2128 error("can't open routing table %s: %m", path);
2132 /* default to usual columns */
2134 route_dest_plen_col = 1;
2136 route_metric_col = 5;
2137 route_flags_col = 8;
2139 route_num_cols = 10;
2144 /********************************************************************
2146 * read_route6_table - read the next entry from the route table
2149 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2156 for (i = 0; i < 4; i++) {
2157 memcpy(hex8, s + 8*i, 8);
2158 v = strtoul(hex8, NULL, 16);
2159 addr->s6_addr32[i] = v;
2163 static int read_route6_table(struct in6_rtmsg *rt)
2165 char *cols[ROUTE_MAX_COLS], *p;
2168 memset (rt, '\0', sizeof (struct in6_rtmsg));
2170 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2174 for (col = 0; col < route_num_cols; ++col) {
2175 cols[col] = strtok(p, route_delims);
2176 if (cols[col] == NULL)
2177 return 0; /* didn't get enough columns */
2181 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2182 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2183 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2185 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2186 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2187 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2192 /********************************************************************
2194 * defaultroute6_exists - determine if there is a default route
2197 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2201 if (!open_route6_table())
2204 while (read_route6_table(rt) != 0) {
2205 if ((rt->rtmsg_flags & RTF_UP) == 0)
2208 if (rt->rtmsg_dst_len != 0)
2210 if (rt->rtmsg_dst.s6_addr32[0] == 0L
2211 && rt->rtmsg_dst.s6_addr32[1] == 0L
2212 && rt->rtmsg_dst.s6_addr32[2] == 0L
2213 && rt->rtmsg_dst.s6_addr32[3] == 0L
2214 && (metric < 0 || rt->rtmsg_metric == metric)) {
2220 close_route_table();
2224 /********************************************************************
2226 * sif6defaultroute - assign a default route through the address given.
2228 * If the global default_rt_repl_rest flag is set, then this function
2229 * already replaced the original system defaultroute with some other
2230 * route and it should just replace the current defaultroute with
2231 * another one, without saving the current route. Use: demand mode,
2232 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2233 * and then changes the temporary addresses to the addresses for the real
2234 * ppp connection when it has come up.
2237 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2239 struct in6_rtmsg rt;
2240 char buf[IF_NAMESIZE];
2242 if (defaultroute6_exists(&rt, dfl_route_metric) &&
2243 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2244 if (rt.rtmsg_flags & RTF_GATEWAY)
2245 error("not replacing existing default route via gateway");
2247 error("not replacing existing default route through %s",
2248 if_indextoname(rt.rtmsg_ifindex, buf));
2252 memset (&rt, 0, sizeof (rt));
2254 rt.rtmsg_ifindex = if_nametoindex(ifname);
2255 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2256 rt.rtmsg_dst_len = 0;
2258 rt.rtmsg_flags = RTF_UP;
2259 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2260 if ( ! ok_error ( errno ))
2261 error("default route ioctl(SIOCADDRT): %m");
2265 have_default_route6 = 1;
2269 /********************************************************************
2271 * cif6defaultroute - delete a default route through the address given.
2274 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2276 struct in6_rtmsg rt;
2278 have_default_route6 = 0;
2280 memset (&rt, '\0', sizeof (rt));
2282 rt.rtmsg_ifindex = if_nametoindex(ifname);
2283 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2284 rt.rtmsg_dst_len = 0;
2286 rt.rtmsg_flags = RTF_UP;
2287 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2289 if ( ! ok_error ( errno ))
2290 error("default route ioctl(SIOCDELRT): %m");
2299 /********************************************************************
2301 * sifproxyarp - Make a proxy ARP entry for the peer.
2304 int sifproxyarp (int unit, u_int32_t his_adr)
2306 struct arpreq arpreq;
2309 if (has_proxy_arp == 0) {
2310 memset (&arpreq, '\0', sizeof(arpreq));
2312 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2313 SIN_ADDR(arpreq.arp_pa) = his_adr;
2314 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2316 * Get the hardware address of an interface on the same subnet
2317 * as our local address.
2319 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2320 sizeof(proxy_arp_dev))) {
2321 error("Cannot determine ethernet address for proxy ARP");
2324 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2326 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2327 if ( ! ok_error ( errno ))
2328 error("ioctl(SIOCSARP): %m");
2331 proxy_arp_addr = his_adr;
2335 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2336 if (forw_path != 0) {
2337 int fd = open(forw_path, O_WRONLY);
2339 if (write(fd, "1", 1) != 1)
2340 error("Couldn't enable IP forwarding: %m");
2350 /********************************************************************
2352 * cifproxyarp - Delete the proxy ARP entry for the peer.
2355 int cifproxyarp (int unit, u_int32_t his_adr)
2357 struct arpreq arpreq;
2359 if (has_proxy_arp) {
2361 memset (&arpreq, '\0', sizeof(arpreq));
2362 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2363 SIN_ADDR(arpreq.arp_pa) = his_adr;
2364 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2365 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2367 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2368 if ( ! ok_error ( errno ))
2369 warn("ioctl(SIOCDARP): %m");
2376 /********************************************************************
2378 * get_ether_addr - get the hardware address of an interface on the
2379 * the same subnet as ipaddr.
2382 static int get_ether_addr (u_int32_t ipaddr,
2383 struct sockaddr *hwaddr,
2384 char *name, int namelen)
2386 struct ifreq *ifr, *ifend;
2387 u_int32_t ina, mask;
2389 struct ifreq ifreq, bestifreq;
2391 struct ifreq ifs[MAX_IFS];
2393 u_int32_t bestmask=0;
2394 int found_interface = 0;
2396 ifc.ifc_len = sizeof(ifs);
2398 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2399 if ( ! ok_error ( errno ))
2400 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2405 * Scan through looking for an interface with an Internet
2406 * address on the same subnet as `ipaddr'.
2408 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2409 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2410 if (ifr->ifr_addr.sa_family == AF_INET) {
2411 ina = SIN_ADDR(ifr->ifr_addr);
2412 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2414 * Check that the interface is up, and not point-to-point
2417 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2420 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2423 * Get its netmask and check that it's on the right subnet.
2425 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2428 mask = SIN_ADDR(ifreq.ifr_addr);
2430 if (((ipaddr ^ ina) & mask) != 0)
2431 continue; /* no match */
2433 if (mask >= bestmask) {
2434 /* Compare using >= instead of > -- it is possible for
2435 an interface to have a netmask of 0.0.0.0 */
2436 found_interface = 1;
2443 if (!found_interface) return 0;
2445 strlcpy(name, bestifreq.ifr_name, namelen);
2447 /* trim off the :1 in eth0:1 */
2448 aliasp = strchr(name, ':');
2452 info("found interface %s for proxy arp", name);
2454 * Now get the hardware address.
2456 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2457 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2458 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2463 &bestifreq.ifr_hwaddr,
2464 sizeof (struct sockaddr));
2470 * get_if_hwaddr - get the hardware address for the specified
2471 * network interface device.
2474 get_if_hwaddr(u_char *addr, char *name)
2479 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2482 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2483 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2484 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2487 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2492 * get_first_ether_hwaddr - get the hardware address for the first
2493 * ethernet-style interface on this system.
2496 get_first_ether_hwaddr(u_char *addr)
2498 struct if_nameindex *if_ni, *i;
2502 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2506 if_ni = if_nameindex();
2514 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2515 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2516 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2517 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2518 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2519 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2525 if_freenameindex(if_ni);
2531 /********************************************************************
2533 * Return user specified netmask, modified by any mask we might determine
2534 * for address `addr' (in network byte order).
2535 * Here we scan through the system's list of interfaces, looking for
2536 * any non-point-to-point interfaces which might appear to be on the same
2537 * network as `addr'. If we find any, we OR in their netmask to the
2538 * user-specified netmask.
2541 u_int32_t GetMask (u_int32_t addr)
2543 u_int32_t mask, nmask, ina;
2544 struct ifreq *ifr, *ifend, ifreq;
2546 struct ifreq ifs[MAX_IFS];
2550 if (IN_CLASSA(addr)) /* determine network mask for address class */
2551 nmask = IN_CLASSA_NET;
2552 else if (IN_CLASSB(addr))
2553 nmask = IN_CLASSB_NET;
2555 nmask = IN_CLASSC_NET;
2557 /* class D nets are disallowed by bad_ip_adrs */
2558 mask = netmask | htonl(nmask);
2560 * Scan through the system's network interfaces.
2562 ifc.ifc_len = sizeof(ifs);
2564 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2565 if ( ! ok_error ( errno ))
2566 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2570 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2571 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2573 * Check the interface's internet address.
2575 if (ifr->ifr_addr.sa_family != AF_INET)
2577 ina = SIN_ADDR(ifr->ifr_addr);
2578 if (((ntohl(ina) ^ addr) & nmask) != 0)
2581 * Check that the interface is up, and not point-to-point nor loopback.
2583 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2584 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2587 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2590 * Get its netmask and OR it into our mask.
2592 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2594 mask |= SIN_ADDR(ifreq.ifr_addr);
2600 /********************************************************************
2602 * Internal routine to decode the version.modification.patch level
2605 static void decode_version (char *buf, int *version,
2606 int *modification, int *patch)
2610 *version = (int) strtoul (buf, &endp, 10);
2614 if (endp != buf && *endp == '.') {
2616 *modification = (int) strtoul (buf, &endp, 10);
2617 if (endp != buf && *endp == '.') {
2619 *patch = (int) strtoul (buf, &buf, 10);
2624 /********************************************************************
2626 * Procedure to determine if the PPP line discipline is registered.
2630 ppp_registered(void)
2638 * We used to open the serial device and set it to the ppp line
2639 * discipline here, in order to create a ppp unit. But that is
2640 * not a good idea - the user might have specified a device that
2641 * they can't open (permission, or maybe it doesn't really exist).
2642 * So we grab a pty master/slave pair and use that.
2644 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2645 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2650 * Try to put the device into the PPP discipline.
2652 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2653 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2662 /********************************************************************
2664 * ppp_available - check whether the system has any ppp interfaces
2665 * (in fact we check whether we can do an ioctl on ppp0).
2668 int ppp_available(void)
2673 int my_version, my_modification, my_patch;
2674 int osmaj, osmin, ospatch;
2676 /* get the kernel version now, since we are called before sys_init */
2678 osmaj = osmin = ospatch = 0;
2679 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2680 kernel_version = KVERSION(osmaj, osmin, ospatch);
2682 fd = open("/dev/ppp", O_RDWR);
2684 new_style_driver = 1;
2686 /* XXX should get from driver */
2688 driver_modification = 4;
2694 if (kernel_version >= KVERSION(2,3,13)) {
2695 error("Couldn't open the /dev/ppp device: %m");
2696 if (errno == ENOENT)
2698 "You need to create the /dev/ppp device node by\n"
2699 "executing the following command as root:\n"
2700 " mknod /dev/ppp c 108 0\n";
2701 else if (errno == ENODEV || errno == ENXIO)
2703 "Please load the ppp_generic kernel module.\n";
2707 /* we are running on a really really old kernel */
2709 "This system lacks kernel support for PPP. This could be because\n"
2710 "the PPP kernel module could not be loaded, or because PPP was not\n"
2711 "included in the kernel configuration. If PPP was included as a\n"
2712 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2713 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2714 "See README.linux file in the ppp distribution for more details.\n";
2717 * Open a socket for doing the ioctl operations.
2719 s = socket(AF_INET, SOCK_DGRAM, 0);
2723 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2724 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2726 * If the device did not exist then attempt to create one by putting the
2727 * current tty into the PPP discipline. If this works then obtain the
2728 * flags for the device again.
2731 if (ppp_registered()) {
2732 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2733 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2737 * Ensure that the hardware address is for PPP and not something else
2740 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2742 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2746 * This is the PPP device. Validate the version of the driver at this
2747 * point to ensure that this program will work with the driver.
2750 char abBuffer [1024];
2752 ifr.ifr_data = abBuffer;
2753 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2755 error("Couldn't read driver version: %m");
2757 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2760 decode_version(abBuffer,
2762 &driver_modification,
2765 * Validate the version of the driver against the version that we used.
2767 decode_version(VERSION,
2772 /* The version numbers must match */
2773 if (driver_version != my_version)
2776 /* The modification levels must be legal */
2777 if (driver_modification < 3) {
2778 if (driver_modification >= 2) {
2779 /* we can cope with 2.2.0 and above */
2787 slprintf(route_buffer, sizeof(route_buffer),
2788 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2789 driver_version, driver_modification, driver_patch);
2791 no_ppp_msg = route_buffer;
2799 #ifndef HAVE_LOGWTMP
2800 /********************************************************************
2802 * Update the wtmp file with the appropriate user name and tty device.
2805 void logwtmp (const char *line, const char *name, const char *host)
2807 struct utmp ut, *utp;
2808 pid_t mypid = getpid();
2814 * Update the signon database for users.
2815 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2817 utmpname(_PATH_UTMP);
2819 while ((utp = getutent()) && (utp->ut_pid != mypid))
2823 memcpy(&ut, utp, sizeof(ut));
2825 /* some gettys/telnetds don't initialize utmp... */
2826 memset(&ut, 0, sizeof(ut));
2828 if (ut.ut_id[0] == 0)
2829 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2831 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2832 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2836 ut.ut_type = USER_PROCESS;
2839 /* Insert the host name if one is supplied */
2841 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2843 /* Insert the IP address of the remote system if IP is enabled */
2844 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2845 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2846 sizeof(ut.ut_addr));
2848 /* CL: Makes sure that the logout works */
2849 if (*host == 0 && *name==0)
2855 * Update the wtmp file.
2858 updwtmp(_PATH_WTMP, &ut);
2860 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2862 flock(wtmp, LOCK_EX);
2864 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2865 warn("error writing %s: %m", _PATH_WTMP);
2867 flock(wtmp, LOCK_UN);
2873 #endif /* HAVE_LOGWTMP */
2875 /********************************************************************
2877 * sifvjcomp - config tcp header compression
2880 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2885 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2886 error("Couldn't set up TCP header compression: %m");
2891 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2892 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2897 /********************************************************************
2899 * sifup - Config the interface up and enable IP packets to pass.
2906 if ((ret = setifstate(u, 1)))
2912 /********************************************************************
2914 * sifdown - Disable the indicated protocol and config the interface
2915 * down if there are no remaining protocols.
2920 if (if_is_up && --if_is_up > 0)
2928 return setifstate(u, 0);
2932 /********************************************************************
2934 * sif6up - Config the interface up for IPv6
2941 if ((ret = setifstate(u, 1)))
2947 /********************************************************************
2949 * sif6down - Disable the IPv6CP protocol and config the interface
2950 * down if there are no remaining protocols.
2953 int sif6down (int u)
2960 return setifstate(u, 0);
2964 /********************************************************************
2966 * setifstate - Config the interface up or down
2969 static int setifstate (int u, int state)
2973 memset (&ifr, '\0', sizeof (ifr));
2974 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2975 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2976 if (! ok_error (errno))
2977 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2982 ifr.ifr_flags |= IFF_UP;
2984 ifr.ifr_flags &= ~IFF_UP;
2985 ifr.ifr_flags |= IFF_POINTOPOINT;
2986 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2987 if (! ok_error (errno))
2988 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2994 /********************************************************************
2996 * sifaddr - Config the interface IP addresses and netmask.
2999 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3005 memset (&ifr, '\0', sizeof (ifr));
3006 memset (&rt, '\0', sizeof (rt));
3008 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
3009 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3010 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3012 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3014 * Set our IP address
3016 SIN_ADDR(ifr.ifr_addr) = our_adr;
3017 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3018 if (errno != EEXIST) {
3019 if (! ok_error (errno))
3020 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3023 warn("ioctl(SIOCSIFADDR): Address already exists");
3028 * Set the gateway address
3031 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3032 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3033 if (! ok_error (errno))
3034 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3040 * For recent kernels, force the netmask to 255.255.255.255.
3042 if (kernel_version >= KVERSION(2,1,16))
3044 if (net_mask != 0) {
3045 SIN_ADDR(ifr.ifr_netmask) = net_mask;
3046 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3047 if (! ok_error (errno))
3048 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3053 * Add the device route
3055 if (kernel_version < KVERSION(2,1,16)) {
3056 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3057 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3060 SIN_ADDR(rt.rt_gateway) = 0L;
3061 SIN_ADDR(rt.rt_dst) = his_adr;
3062 rt.rt_flags = RTF_UP | RTF_HOST;
3064 if (kernel_version > KVERSION(2,1,0)) {
3065 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3066 SIN_ADDR(rt.rt_genmask) = -1L;
3069 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3070 if (! ok_error (errno))
3071 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3076 /* set ip_dynaddr in demand mode if address changes */
3077 if (demand && tune_kernel && !dynaddr_set
3078 && our_old_addr && our_old_addr != our_adr) {
3079 /* set ip_dynaddr if possible */
3083 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3084 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3085 if (write(fd, "1", 1) != 1)
3086 error("Couldn't enable dynamic IP addressing: %m");
3089 dynaddr_set = 1; /* only 1 attempt */
3096 /********************************************************************
3098 * cifaddr - Clear the interface IP addresses, and delete routes
3099 * through the interface if possible.
3102 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3106 if (kernel_version < KVERSION(2,1,16)) {
3108 * Delete the route through the device
3111 memset (&rt, '\0', sizeof (rt));
3113 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3114 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3117 SIN_ADDR(rt.rt_gateway) = 0;
3118 SIN_ADDR(rt.rt_dst) = his_adr;
3119 rt.rt_flags = RTF_UP | RTF_HOST;
3121 if (kernel_version > KVERSION(2,1,0)) {
3122 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3123 SIN_ADDR(rt.rt_genmask) = -1L;
3126 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3127 if (still_ppp() && ! ok_error (errno))
3128 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3133 /* This way it is possible to have an IPX-only or IPv6-only interface */
3134 memset(&ifr, 0, sizeof(ifr));
3135 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3136 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3138 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3139 if (! ok_error (errno)) {
3140 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3145 our_old_addr = our_adr;
3151 /********************************************************************
3153 * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3155 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3158 struct nlmsghdr nlh;
3159 struct ifaddrmsg ifa;
3162 struct in6_addr addr;
3166 struct nlmsghdr nlh;
3167 struct nlmsgerr nlerr;
3169 struct sockaddr_nl nladdr;
3176 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
3178 error("sif6addr_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
3183 * Tell kernel to not send to us payload of acknowledgment error message.
3184 * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
3185 * older kernel versions always send full payload in acknowledgment netlink
3186 * message. We ignore payload of this message as we need only error code,
3187 * to check if our set remote peer address request succeeded or failed.
3188 * So ignore return value from the following setsockopt() call as setting
3189 * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
3192 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
3194 memset(&nladdr, 0, sizeof(nladdr));
3195 nladdr.nl_family = AF_NETLINK;
3197 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
3198 error("sif6addr_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
3203 memset(&nlreq, 0, sizeof(nlreq));
3204 nlreq.nlh.nlmsg_len = sizeof(nlreq);
3205 nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3206 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3207 nlreq.ifa.ifa_family = AF_INET6;
3208 nlreq.ifa.ifa_prefixlen = 128;
3209 nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3210 nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3211 nlreq.ifa.ifa_index = iface;
3212 nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3213 nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3214 IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3215 nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3216 nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3219 * To set only local address, older kernel expects that local address is
3220 * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3221 * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3222 * compatibility when setting only local address, set it via both IFA_LOCAL
3223 * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3224 * from iproute2 project.
3226 if (!eui64_iszero(his_eui64))
3227 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3229 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3231 memset(&nladdr, 0, sizeof(nladdr));
3232 nladdr.nl_family = AF_NETLINK;
3234 memset(&iov, 0, sizeof(iov));
3235 iov.iov_base = &nlreq;
3236 iov.iov_len = sizeof(nlreq);
3238 memset(&msg, 0, sizeof(msg));
3239 msg.msg_name = &nladdr;
3240 msg.msg_namelen = sizeof(nladdr);
3244 if (sendmsg(fd, &msg, 0) < 0) {
3245 error("sif6addr_rtnetlink: sendmsg(RTM_NEWADDR/NLM_F_CREATE): %m (line %d)", __LINE__);
3250 memset(&iov, 0, sizeof(iov));
3251 iov.iov_base = &nlresp;
3252 iov.iov_len = sizeof(nlresp);
3254 memset(&msg, 0, sizeof(msg));
3255 msg.msg_name = &nladdr;
3256 msg.msg_namelen = sizeof(nladdr);
3260 nlresplen = recvmsg(fd, &msg, 0);
3262 if (nlresplen < 0) {
3263 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
3270 if (nladdr.nl_family != AF_NETLINK) {
3271 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
3275 if ((size_t)nlresplen != sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
3276 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
3280 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
3281 if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
3282 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
3286 /* error == 0 indicates success, negative value is errno code */
3287 if (nlresp.nlerr.error != 0) {
3289 * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3290 * addresses and error response is expected. On older kernel versions
3291 * do not show this error message. On error pppd tries to fallback to
3292 * the old IOCTL method.
3294 if (kernel_version >= KVERSION(3,11,0))
3295 error("sif6addr_rtnetlink: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
3302 /********************************************************************
3304 * sif6addr - Config the interface with an IPv6 link-local address
3306 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3308 struct in6_ifreq ifr6;
3310 struct in6_rtmsg rt6;
3315 error("IPv6 socket creation failed: %m");
3318 memset(&ifr, 0, sizeof (ifr));
3319 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3320 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3321 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3325 if (kernel_version >= KVERSION(2,1,16)) {
3326 /* Set both local address and remote peer address (with route for it) via rtnetlink */
3327 ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3333 * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3334 * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3337 /* Local interface */
3338 memset(&ifr6, 0, sizeof(ifr6));
3339 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3340 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3341 ifr6.ifr6_prefixlen = 128;
3343 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3344 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3349 if (!ret && !eui64_iszero(his_eui64)) {
3351 * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3352 * setting remote peer host address, so set only route to remote host.
3355 /* Route to remote host */
3356 memset(&rt6, 0, sizeof(rt6));
3357 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3358 rt6.rtmsg_flags = RTF_UP;
3359 rt6.rtmsg_dst_len = 128;
3360 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3361 rt6.rtmsg_metric = 1;
3363 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3364 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3373 /********************************************************************
3375 * cif6addr - Remove IPv6 address from interface
3377 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3380 struct in6_ifreq ifr6;
3384 error("IPv6 socket creation failed: %m");
3387 memset(&ifr, 0, sizeof(ifr));
3388 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3389 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3390 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3394 memset(&ifr6, 0, sizeof(ifr6));
3395 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3396 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3397 ifr6.ifr6_prefixlen = 128;
3399 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3400 if (errno != EADDRNOTAVAIL) {
3401 if (! ok_error (errno))
3402 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3405 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3414 * get_pty - get a pty master/slave pair and chown the slave side
3415 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
3418 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3420 int i, mfd, ret, sfd = -1;
3422 struct termios tios;
3426 * Try the unix98 way first.
3428 mfd = open("/dev/ptmx", O_RDWR);
3431 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3432 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3433 chmod(pty_name, S_IRUSR | S_IWUSR);
3436 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3437 warn("Couldn't unlock pty slave %s: %m", pty_name);
3439 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3441 warn("Couldn't open pty slave %s: %m", pty_name);
3446 #endif /* TIOCGPTN */
3449 /* the old way - scan through the pty name space */
3450 for (i = 0; i < 64; ++i) {
3451 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3452 'p' + i / 16, i % 16);
3453 mfd = open(pty_name, O_RDWR, 0);
3456 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3458 ret = fchown(sfd, uid, -1);
3460 warn("Couldn't change ownership of %s, %m", pty_name);
3462 ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3464 warn("Couldn't change permissions of %s, %m", pty_name);
3476 strlcpy(slave_name, pty_name, 16);
3479 if (tcgetattr(sfd, &tios) == 0) {
3480 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3481 tios.c_cflag |= CS8 | CREAD | CLOCAL;
3482 tios.c_iflag = IGNPAR;
3485 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3486 warn("couldn't set attributes on pty: %m");
3488 warn("couldn't get attributes on pty: %m");
3493 /********************************************************************
3495 * open_loopback - open the device we use for getting packets
3496 * in demand mode. Under Linux, we use a pty master/slave pair.
3499 open_ppp_loopback(void)
3504 if (new_style_driver) {
3505 /* allocate ourselves a ppp unit */
3506 if (make_ppp_unit() < 0)
3508 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3509 set_kdebugflag(kdebugflag);
3514 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3515 fatal("No free pty for loopback");
3517 set_ppp_fd(slave_fd);
3519 flags = fcntl(master_fd, F_GETFL);
3521 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3522 warn("couldn't set master loopback to nonblock: %m");
3524 flags = fcntl(ppp_fd, F_GETFL);
3526 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3527 warn("couldn't set slave loopback to nonblock: %m");
3529 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3530 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3532 * Find out which interface we were given.
3534 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3535 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3537 * Enable debug in the driver if requested.
3539 set_kdebugflag (kdebugflag);
3544 /********************************************************************
3546 * sifnpmode - Set the mode for handling packets for a given NP.
3550 sifnpmode(int u, int proto, enum NPmode mode)
3554 npi.protocol = proto;
3556 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3557 if (! ok_error (errno))
3558 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3565 /********************************************************************
3567 * sipxfaddr - Config the interface IPX networknumber
3570 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
3577 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3579 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3581 if (! ok_error (errno))
3582 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3586 memset (&ifr, '\0', sizeof (ifr));
3587 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3589 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
3590 sipx->sipx_family = AF_IPX;
3591 sipx->sipx_port = 0;
3592 sipx->sipx_network = htonl (network);
3593 sipx->sipx_type = IPX_FRAME_ETHERII;
3594 sipx->sipx_action = IPX_CRTITF;
3596 * Set the IPX device
3598 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3600 if (errno != EEXIST) {
3601 if (! ok_error (errno))
3602 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
3605 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
3614 /********************************************************************
3616 * cipxfaddr - Clear the information for the IPX network. The IPX routes
3617 * are removed and the device is no longer able to pass IPX
3621 int cipxfaddr (int unit)
3628 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3630 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3632 if (! ok_error (errno))
3633 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3637 memset (&ifr, '\0', sizeof (ifr));
3638 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3640 sipx->sipx_type = IPX_FRAME_ETHERII;
3641 sipx->sipx_action = IPX_DLTITF;
3642 sipx->sipx_family = AF_IPX;
3644 * Set the IPX device
3646 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3647 if (! ok_error (errno))
3648 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
3658 * Use the hostname as part of the random number seed.
3667 for (p = hostname; *p != 0; ++p)
3672 /********************************************************************
3674 * sys_check_options - check the options that the user specified
3678 sys_check_options(void)
3682 * Disable the IPX protocol if the support is not present in the kernel.
3686 if (ipxcp_protent.enabled_flag) {
3687 struct stat stat_buf;
3688 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
3689 && (path = path_to_procfs("/net/ipx_interface")) == NULL)
3690 || lstat(path, &stat_buf) < 0) {
3691 error("IPX support is not present in the kernel\n");
3692 ipxcp_protent.enabled_flag = 0;
3696 if (demand && driver_is_old) {
3697 option_error("demand dialling is not supported by kernel driver "
3698 "version %d.%d.%d", driver_version, driver_modification,
3702 if (multilink && !new_style_driver) {
3703 warn("Warning: multilink is not supported by the kernel driver");
3709 /********************************************************************
3711 * get_time - Get current time, monotonic if possible.
3714 get_time(struct timeval *tv)
3716 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3717 * Runtime checking makes it safe. */
3718 #ifndef CLOCK_MONOTONIC
3719 #define CLOCK_MONOTONIC 1
3721 static int monotonic = -1;
3726 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3730 tv->tv_sec = ts.tv_sec;
3731 tv->tv_usec = ts.tv_nsec / 1000;
3734 } else if (monotonic > 0)
3738 warn("Couldn't use monotonic clock source: %m");
3741 return gettimeofday(tv, NULL);