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>
84 #include <sys/param.h>
104 /* This is in netdevice.h. However, this compile will fail miserably if
105 you attempt to include netdevice.h because it has so many references
106 to __memcpy functions which it should not attempt to do. So, since I
107 really don't use it, but it must be defined, define it now. */
110 #define MAX_ADDR_LEN 7
113 #if !defined(__GLIBC__) || __GLIBC__ >= 2
114 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
116 #include <net/if_arp.h>
117 #include <net/route.h>
118 #include <netinet/if_ether.h>
120 #include <linux/types.h>
121 #include <linux/if.h>
122 #include <linux/if_arp.h>
123 #include <linux/route.h>
124 #include <linux/if_ether.h>
126 #include <netinet/in.h>
127 #include <arpa/inet.h>
129 #include <linux/ppp-ioctl.h>
131 #include <linux/netlink.h>
132 #include <linux/rtnetlink.h>
133 #include <linux/if_link.h>
135 /* Attempt at retaining compile-support with older than 4.7 kernels, or kernels
136 * where RTM_NEWSTATS isn't defined for whatever reason.
139 #define RTM_NEWSTATS 92
140 #define RTM_GETSTATS 94
141 #define IFLA_STATS_LINK_64 1
144 #include <linux/if_addr.h>
146 /* glibc versions prior to 2.24 do not define SOL_NETLINK */
148 #define SOL_NETLINK 270
151 /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
152 #ifndef NETLINK_CAP_ACK
153 #define NETLINK_CAP_ACK 10
156 /* linux kernel versions prior to 4.7 do not define/support IFLA_PPP_DEV_FD */
158 /* IFLA_PPP_DEV_FD is declared as enum when IFLA_PPP_MAX is defined */
159 #define IFLA_PPP_DEV_FD 1
166 #ifdef PPP_WITH_IPV6CP
168 #endif /* PPP_WITH_IPV6CP */
170 #ifdef PPP_WITH_FILTER
171 #include <pcap-bpf.h>
172 #include <linux/filter.h>
173 #endif /* PPP_WITH_FILTER */
176 #include <sys/locks.h>
180 * Instead of system header file <termios.h> use local "termios_linux.h" header
181 * file as it provides additional support for arbitrary baud rates via BOTHER.
183 #include "termios_linux.h"
185 #ifdef PPP_WITH_IPV6CP
188 * This is in linux/include/net/ipv6.h.
192 struct in6_addr ifr6_addr;
193 __u32 ifr6_prefixlen;
194 unsigned int ifr6_ifindex;
198 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
199 memset(&(sin6).s6_addr, 0, sizeof(struct in6_addr)); \
200 (sin6).s6_addr16[0] = htons(0xfe80); \
201 eui64_copy(eui64, (sin6).s6_addr32[2]); \
204 static const eui64_t nulleui64;
205 #endif /* PPP_WITH_IPV6CP */
207 /* We can get an EIO error on an ioctl if the modem has hung up */
208 #define ok_error(num) ((num)==EIO)
210 static int tty_disc = N_TTY; /* The TTY discipline */
211 static int ppp_disc = N_PPP; /* The PPP discpline */
212 static int initfdflags = -1; /* Initial file descriptor flags for fd */
213 static int ppp_fd = -1; /* fd which is set to PPP discipline */
214 static int sock_fd = -1; /* socket for doing interface ioctls */
215 static int slave_fd = -1; /* pty for old-style demand mode, slave */
216 static int master_fd = -1; /* pty for old-style demand mode, master */
217 #ifdef PPP_WITH_IPV6CP
218 static int sock6_fd = -1;
219 #endif /* PPP_WITH_IPV6CP */
222 * For the old-style kernel driver, this is the same as ppp_fd.
223 * For the new-style driver, it is the fd of an instance of /dev/ppp
224 * which is attached to the ppp unit and is used for controlling it.
226 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
228 static int chindex; /* channel index (new style driver) */
230 static fd_set in_fds; /* set of fds that wait_input waits for */
231 static int max_in_fd; /* highest fd set in in_fds */
233 static int has_proxy_arp = 0;
234 static int driver_version = 0;
235 static int driver_modification = 0;
236 static int driver_patch = 0;
237 static int driver_is_old = 0;
238 static int restore_term = 0; /* 1 => we've munged the terminal */
239 static struct termios inittermios; /* Initial TTY termios */
241 int new_style_driver = 0;
243 static char loop_name[20];
244 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
246 static int if_is_up; /* Interface has been marked up */
247 static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
248 static int have_default_route; /* Gateway for default route added */
249 static int have_default_route6; /* Gateway for default IPv6 route added */
250 static struct rtentry old_def_rt; /* Old default route */
251 static int default_rt_repl_rest; /* replace and restore old default rt */
252 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
253 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
254 static u_int32_t our_old_addr; /* for detecting address changes */
255 static int dynaddr_set; /* 1 if ip_dynaddr set */
256 static int looped; /* 1 if using loop */
257 static int link_mtu; /* mtu for the link (not bundle) */
259 static struct utsname utsname; /* for the kernel version */
260 static int kernel_version;
261 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
265 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
266 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
267 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
269 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
271 /* Prototypes for procedures local to this file. */
272 static int modify_flags(int fd, int clear_bits, int set_bits);
273 static int translate_speed (int bps);
274 static int baud_rate_of (int speed);
275 static void close_route_table (void);
276 static int open_route_table (void);
277 static int read_route_table (struct rtentry *rt);
278 static int defaultroute_exists (struct rtentry *rt, int metric);
279 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
280 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
281 char *name, int namelen);
282 static void decode_version (char *buf, int *version, int *mod, int *patch);
283 static int set_kdebugflag(int level);
284 static int ppp_registered(void);
285 static int make_ppp_unit(void);
286 static int setifstate (int u, int state);
288 extern u_char inpacket_buf[]; /* borrowed from main.c */
290 extern int dfl_route_metric;
293 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
297 #define SET_SA_FAMILY(addr, family) \
298 memset ((char *) &(addr), '\0', sizeof(addr)); \
299 addr.sa_family = (family);
302 * Determine if the PPP connection should still be present.
307 /* new_fd is the fd of a tty */
308 static void set_ppp_fd (int new_fd)
311 if (!new_style_driver)
315 static int still_ppp(void)
317 if (new_style_driver)
318 return !hungup && ppp_fd >= 0;
319 if (!hungup || ppp_fd == slave_fd)
322 set_ppp_fd(slave_fd);
329 * modify_flags - set and clear flag bits controlling the kernel
332 static int modify_flags(int fd, int clear_bits, int set_bits)
336 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
338 flags = (flags & ~clear_bits) | set_bits;
339 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
346 error("Failed to set PPP kernel option flags: %m");
350 /********************************************************************
352 * sys_init - System-dependent initialization.
357 /* Get an internet socket for doing socket ioctls. */
358 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
360 fatal("Couldn't create IP socket: %m(%d)", errno);
362 #ifdef PPP_WITH_IPV6CP
363 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
365 sock6_fd = -errno; /* save errno for later */
372 /********************************************************************
374 * sys_cleanup - restore any system state we modified before exiting:
375 * mark the interface down, delete default route and/or proxy arp entry.
376 * This shouldn't call die() because it's called from die().
379 void sys_cleanup(void)
382 * Take down the device
388 #ifdef PPP_WITH_IPV6CP
394 * Delete any routes through the device.
396 if (have_default_route)
397 cifdefaultroute(0, 0, 0);
398 #ifdef PPP_WITH_IPV6CP
399 if (have_default_route6)
400 cif6defaultroute(0, nulleui64, nulleui64);
404 cifproxyarp(0, proxy_arp_addr);
407 /********************************************************************
409 * sys_close - Clean up in a child process before execing.
414 if (new_style_driver && ppp_dev_fd >= 0)
418 #ifdef PPP_WITH_IPV6CP
428 /********************************************************************
430 * set_kdebugflag - Define the debugging level for the kernel
433 static int set_kdebugflag (int requested_level)
437 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
438 if ( ! ok_error (errno) )
439 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
445 /********************************************************************
447 * tty_establish_ppp - Turn the serial port into a ppp interface.
450 int tty_establish_ppp (int tty_fd)
455 * Ensure that the tty device is in exclusive mode.
457 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
458 if ( ! ok_error ( errno ))
459 warn("Couldn't make tty exclusive: %m");
462 * Demand mode - prime the old ppp device to relinquish the unit.
464 if (!new_style_driver && looped
465 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
466 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
470 * Set the current tty to the PPP discpline
474 #define N_SYNC_PPP 14
476 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
477 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
478 if ( ! ok_error (errno) ) {
479 error("Couldn't set tty to PPP discipline: %m");
484 ret_fd = generic_establish_ppp(tty_fd);
486 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
487 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
491 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
492 (kdebugflag * SC_DEBUG) & SC_LOGB);
494 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
495 warn("Couldn't reset tty to normal line discipline: %m");
501 /********************************************************************
503 * generic_establish_ppp - Turn the fd into a ppp interface.
505 int generic_establish_ppp (int fd)
509 if (new_style_driver) {
512 /* If a ppp_fd is already open, close it first */
519 /* Open an instance of /dev/ppp and connect the channel to it */
520 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
521 error("Couldn't get channel number: %m");
524 dbglog("using channel %d", chindex);
525 fd = open("/dev/ppp", O_RDWR);
527 error("Couldn't reopen /dev/ppp: %m");
530 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
531 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
532 error("Couldn't attach to channel %d: %m", chindex);
535 flags = fcntl(fd, F_GETFL);
536 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
537 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
542 if (!looped && !multilink) {
544 * Create a new PPP unit.
546 if (make_ppp_unit() < 0)
551 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
555 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
556 error("Couldn't attach to PPP unit %d: %m", ifunit);
563 * Old-style driver: find out which interface we were given.
566 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
567 if (ok_error (errno))
569 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
571 /* Check that we got the same unit again. */
572 if (looped && x != ifunit)
573 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
577 * Fetch the initial file flags and reset blocking mode on the file.
579 initfdflags = fcntl(fd, F_GETFL);
580 if (initfdflags == -1 ||
581 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
582 if ( ! ok_error (errno))
583 warn("Couldn't set device to non-blocking mode: %m");
588 * Enable debug in the driver if requested.
591 set_kdebugflag (kdebugflag);
603 /********************************************************************
605 * tty_disestablish_ppp - Restore the serial port to normal operation.
606 * This shouldn't call die() because it's called from die().
609 void tty_disestablish_ppp(int tty_fd)
613 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
615 if (tcflush(tty_fd, TCIOFLUSH) < 0)
617 warn("tcflush failed: %m");
621 * Restore the previous line discipline
623 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
624 if ( ! ok_error (errno))
625 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
628 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
629 if ( ! ok_error (errno))
630 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
633 /* Reset non-blocking mode on fd. */
634 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
635 if ( ! ok_error (errno))
636 warn("Couldn't restore device fd flags: %m");
642 generic_disestablish_ppp(tty_fd);
645 /********************************************************************
647 * generic_disestablish_ppp - Restore device components to normal
648 * operation, and reconnect the ppp unit to the loopback if in demand
649 * mode. This shouldn't call die() because it's called from die().
651 void generic_disestablish_ppp(int dev_fd)
653 if (new_style_driver) {
657 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
659 } else if (!doing_multilink && ppp_dev_fd >= 0) {
661 remove_fd(ppp_dev_fd);
665 /* old-style driver */
667 set_ppp_fd(slave_fd);
674 * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd
675 * with specified req_ifname via rtnetlink. Interface name req_ifname must not
676 * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free.
678 static int make_ppp_unit_rtnetlink(void)
682 struct ifinfomsg ifm;
685 char ifname[IFNAMSIZ];
691 char ifkind[sizeof("ppp")];
706 struct nlmsgerr nlerr;
708 struct sockaddr_nl nladdr;
715 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
717 error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
721 /* Tell kernel to not send to us payload of acknowledgment error message. */
723 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
725 memset(&nladdr, 0, sizeof(nladdr));
726 nladdr.nl_family = AF_NETLINK;
728 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
729 error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
734 memset(&nlreq, 0, sizeof(nlreq));
735 nlreq.nlh.nlmsg_len = sizeof(nlreq);
736 nlreq.nlh.nlmsg_type = RTM_NEWLINK;
737 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
738 nlreq.ifm.ifi_family = AF_UNSPEC;
739 nlreq.ifm.ifi_type = ARPHRD_NETROM;
740 nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
741 nlreq.ifn.rta.rta_type = IFLA_IFNAME;
742 strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
743 nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
744 nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
745 nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
746 nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
747 strcpy(nlreq.ifli.ifik.ifkind, "ppp");
748 nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
749 nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
750 nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
751 nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
752 nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
754 memset(&nladdr, 0, sizeof(nladdr));
755 nladdr.nl_family = AF_NETLINK;
757 memset(&iov, 0, sizeof(iov));
758 iov.iov_base = &nlreq;
759 iov.iov_len = sizeof(nlreq);
761 memset(&msg, 0, sizeof(msg));
762 msg.msg_name = &nladdr;
763 msg.msg_namelen = sizeof(nladdr);
767 if (sendmsg(fd, &msg, 0) < 0) {
768 error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__);
773 memset(&iov, 0, sizeof(iov));
774 iov.iov_base = &nlresp;
775 iov.iov_len = sizeof(nlresp);
777 memset(&msg, 0, sizeof(msg));
778 msg.msg_name = &nladdr;
779 msg.msg_namelen = sizeof(nladdr);
783 nlresplen = recvmsg(fd, &msg, 0);
786 error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
793 if (nladdr.nl_family != AF_NETLINK) {
794 error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
798 if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
799 error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
803 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
804 if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
805 error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
809 /* error == 0 indicates success, negative value is errno code */
810 if (nlresp.nlerr.error != 0) {
812 * Linux kernel versions prior to 4.7 do not support creating ppp
813 * interfaces via rtnetlink API and therefore error response is
814 * expected. On older kernel versions do not show this error message.
815 * When error is different than EEXIST then pppd tries to fallback to
816 * the old ioctl method.
818 errno = (nlresp.nlerr.error < 0) ? -nlresp.nlerr.error : EINVAL;
819 if (kernel_version >= KVERSION(4,7,0))
820 error("Couldn't create ppp interface %s: %m", req_ifname);
828 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
829 * Assumes new_style_driver.
831 static int make_ppp_unit(void)
835 if (ppp_dev_fd >= 0) {
836 dbglog("in make_ppp_unit, already had /dev/ppp open?");
839 ppp_dev_fd = open("/dev/ppp", O_RDWR);
841 fatal("Couldn't open /dev/ppp: %m");
842 flags = fcntl(ppp_dev_fd, F_GETFL);
844 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
845 warn("Couldn't set /dev/ppp to nonblock: %m");
848 * Via rtnetlink it is possible to create ppp network interface with
849 * custom ifname atomically. But it is not possible to specify custom
852 * Tools like systemd, udev or NetworkManager are trying to query
853 * interface attributes based on interface name immediately when new
854 * network interface is created. And therefore immediate interface
855 * renaming is causing issues.
857 * So use rtnetlink API only when user requested custom ifname. It will
858 * avoid system issues with interface renaming.
860 if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) {
861 if (make_ppp_unit_rtnetlink()) {
862 if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit))
863 fatal("Couldn't retrieve PPP unit id: %m");
867 * If interface with requested name already exist return error
868 * otherwise fallback to old ioctl method.
875 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
876 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
877 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
879 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
882 error("Couldn't create new ppp unit: %m");
884 if (x == 0 && req_ifname[0] != '\0') {
887 memset(&ifr, 0, sizeof(struct ifreq));
888 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
889 strlcpy(ifr.ifr_name, t, IFNAMSIZ);
890 strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
891 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
893 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
895 info("Renamed interface %s to %s", t, req_ifname);
902 * cfg_bundle - configure the existing bundle.
903 * Used in demand mode.
905 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
907 if (!new_style_driver)
910 /* set the mrru, mtu and flags */
911 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
912 error("Couldn't set MRRU: %m");
914 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
915 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
916 | (mrru? SC_MULTILINK: 0)));
918 /* connect up the channel */
919 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
920 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
925 * make_new_bundle - create a new PPP unit (i.e. a bundle)
926 * and connect our channel to it. This should only get called
927 * if `multilink' was set at the time establish_ppp was called.
928 * In demand mode this uses our existing bundle instead of making
931 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
933 if (!new_style_driver)
936 /* make us a ppp unit */
937 if (make_ppp_unit() < 0)
940 /* set the mrru and flags */
941 cfg_bundle(mrru, mtru, rssn, tssn);
945 * bundle_attach - attach our link to a given PPP unit.
946 * We assume the unit is controlled by another pppd.
948 int bundle_attach(int ifnum)
952 if (!new_style_driver)
955 master_fd = open("/dev/ppp", O_RDWR);
957 fatal("Couldn't open /dev/ppp: %m");
958 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
959 if (errno == ENXIO) {
961 return 0; /* doesn't still exist */
963 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
965 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
966 fatal("Couldn't connect to interface unit %d: %m", ifnum);
967 modify_flags(master_fd, 0, SC_MULTILINK);
975 * destroy_bundle - tell the driver to destroy our bundle.
977 void destroy_bundle(void)
979 if (ppp_dev_fd >= 0) {
981 remove_fd(ppp_dev_fd);
986 /********************************************************************
988 * clean_check - Fetch the flags for the device and generate
989 * appropriate error messages.
991 void clean_check(void)
997 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
999 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
1001 s = "all had bit 7 set to 1";
1005 s = "all had bit 7 set to 0";
1009 s = "all had odd parity";
1013 s = "all had even parity";
1018 warn("Receive serial link is not 8-bit clean:");
1019 warn("Problem: %s", s);
1027 * List of valid speeds.
1031 int speed_int, speed_val;
1094 { 115200, B115200 },
1097 { 153600, B153600 },
1106 { 230400, B230400 },
1109 { 307200, B307200 },
1112 { 460800, B460800 },
1115 { 500000, B500000 },
1118 { 576000, B576000 },
1121 { 614400, B614400 },
1124 { 921600, B921600 },
1127 { 1000000, B1000000 },
1130 { 1152000, B1152000 },
1133 { 1500000, B1500000 },
1136 { 2000000, B2000000 },
1139 { 2500000, B2500000 },
1142 { 3000000, B3000000 },
1145 { 3500000, B3500000 },
1148 { 4000000, B4000000 },
1153 /********************************************************************
1155 * Translate from bits/second to a speed_t.
1158 static int translate_speed (int bps)
1160 struct speed *speedp;
1163 for (speedp = speeds; speedp->speed_int; speedp++) {
1164 if (bps == speedp->speed_int)
1165 return speedp->speed_val;
1171 /********************************************************************
1173 * Translate from a speed_t to bits/second.
1176 static int baud_rate_of (int speed)
1178 struct speed *speedp;
1181 for (speedp = speeds; speedp->speed_int; speedp++) {
1182 if (speed == speedp->speed_val)
1183 return speedp->speed_int;
1189 /********************************************************************
1191 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
1192 * at the requested speed, etc. If `local' is true, set CLOCAL
1193 * regardless of whether the modem option was specified.
1196 void set_up_tty(int tty_fd, int local)
1199 struct termios tios;
1202 if (tcgetattr(tty_fd, &tios) < 0) {
1203 if (!ok_error(errno))
1204 fatal("tcgetattr: %m (line %d)", __LINE__);
1211 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1212 tios.c_cflag |= CS8 | CREAD | HUPCL;
1214 tios.c_iflag = IGNBRK | IGNPAR;
1217 tios.c_cc[VMIN] = 1;
1218 tios.c_cc[VTIME] = 0;
1220 if (local || !modem)
1221 tios.c_cflag ^= (CLOCAL | HUPCL);
1225 tios.c_cflag |= CRTSCTS;
1229 tios.c_iflag |= IXON | IXOFF;
1230 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
1231 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1235 tios.c_cflag &= ~CRTSCTS;
1243 tios.c_cflag |= CSTOPB;
1246 speed = translate_speed(inspeed);
1248 cfsetospeed (&tios, speed);
1249 cfsetispeed (&tios, speed);
1250 speed = cfgetospeed(&tios);
1251 baud_rate = baud_rate_of(speed);
1254 tios.c_cflag &= ~CBAUD;
1255 tios.c_cflag |= BOTHER;
1256 tios.c_ospeed = inspeed;
1258 /* B0 sets input baudrate to the output baudrate */
1259 tios.c_cflag &= ~(CBAUD << IBSHIFT);
1260 tios.c_cflag |= B0 << IBSHIFT;
1261 tios.c_ispeed = inspeed;
1263 baud_rate = inspeed;
1270 speed = cfgetospeed(&tios);
1271 baud_rate = baud_rate_of(speed);
1274 baud_rate = tios.c_ospeed;
1279 * We can't proceed if the serial port baud rate is unknown,
1280 * since that implies that the serial port is disabled.
1284 fatal("speed %d not supported", inspeed);
1286 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1289 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1291 fatal("tcsetattr: %m (line %d)", __LINE__);
1295 /********************************************************************
1297 * setdtr - control the DTR line on the serial port.
1298 * This is called from die(), so it shouldn't call die().
1301 void setdtr (int tty_fd, int on)
1303 int modembits = TIOCM_DTR;
1305 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1308 /********************************************************************
1310 * restore_tty - restore the terminal to the saved settings.
1313 void restore_tty (int tty_fd)
1318 * Turn off echoing, because otherwise we can get into
1319 * a loop with the tty and the modem echoing to each other.
1320 * We presume we are the sole user of this tty device, so
1321 * when we close it, it will revert to its defaults anyway.
1323 if (!default_device)
1324 inittermios.c_lflag &= ~(ECHO | ECHONL);
1326 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1327 if (! ok_error (errno))
1328 warn("tcsetattr: %m (line %d)", __LINE__);
1333 /********************************************************************
1335 * output - Output PPP packet.
1338 void output (int unit, unsigned char *p, int len)
1343 dump_packet("sent", p, len);
1344 if (snoop_send_hook) snoop_send_hook(p, len);
1346 if (len < PPP_HDRLEN)
1348 if (new_style_driver) {
1351 proto = (p[0] << 8) + p[1];
1352 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1355 if (write(fd, p, len) < 0) {
1356 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1357 || errno == ENXIO || errno == EIO || errno == EINTR)
1358 warn("write: warning: %m (%d)", errno);
1360 error("write: %m (%d)", errno);
1364 /********************************************************************
1366 * wait_input - wait until there is data available,
1367 * for the length of time specified by *timo (indefinite
1371 void wait_input(struct timeval *timo)
1378 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1379 if (n < 0 && errno != EINTR)
1380 fatal("select: %m");
1384 * add_fd - add an fd to the set that wait_input waits for.
1388 if (fd >= FD_SETSIZE)
1389 fatal("internal error: file descriptor too large (%d)", fd);
1390 FD_SET(fd, &in_fds);
1396 * remove_fd - remove an fd from the set that wait_input waits for.
1398 void remove_fd(int fd)
1400 FD_CLR(fd, &in_fds);
1404 /********************************************************************
1406 * read_packet - get a PPP packet from the serial device.
1409 int read_packet (unsigned char *buf)
1413 len = PPP_MRU + PPP_HDRLEN;
1414 if (new_style_driver) {
1415 *buf++ = PPP_ALLSTATIONS;
1421 nr = read(ppp_fd, buf, len);
1422 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1423 && errno != EIO && errno != EINTR)
1425 if (nr < 0 && errno == ENXIO)
1428 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1429 /* N.B. we read ppp_fd first since LCP packets come in there. */
1430 nr = read(ppp_dev_fd, buf, len);
1431 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1432 && errno != EIO && errno != EINTR)
1433 error("read /dev/ppp: %m");
1434 if (nr < 0 && errno == ENXIO)
1436 if (nr == 0 && doing_multilink) {
1437 remove_fd(ppp_dev_fd);
1441 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1443 return (new_style_driver && nr > 0)? nr+2: nr;
1446 /********************************************************************
1448 * get_loop_output - get outgoing packets from the ppp device,
1449 * and detect when we want to bring the real link up.
1450 * Return value is 1 if we need to bring up the link, 0 otherwise.
1453 get_loop_output(void)
1458 if (new_style_driver) {
1459 while ((n = read_packet(inpacket_buf)) > 0)
1460 if (loop_frame(inpacket_buf, n))
1465 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1466 if (loop_chars(inbuf, n))
1470 fatal("eof on loopback");
1472 if (errno != EWOULDBLOCK && errno != EAGAIN)
1473 fatal("read from loopback: %m(%d)", errno);
1479 * netif_set_mtu - set the MTU on the PPP network interface.
1482 netif_set_mtu(int unit, int mtu)
1486 memset (&ifr, '\0', sizeof (ifr));
1487 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1490 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1491 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1495 * netif_get_mtu - get the MTU on the PPP network interface.
1498 netif_get_mtu(int unit)
1502 memset (&ifr, '\0', sizeof (ifr));
1503 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1505 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1506 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1512 /********************************************************************
1514 * tty_send_config - configure the transmit characteristics of
1515 * the ppp interface.
1518 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1525 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1526 if (errno != EIO && errno != ENOTTY)
1527 error("Couldn't set transmit async character map: %m");
1532 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1533 | (sync_serial? SC_SYNC: 0);
1534 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1537 /********************************************************************
1539 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1542 void tty_set_xaccm (ext_accm accm)
1546 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1547 if ( ! ok_error (errno))
1548 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1552 /********************************************************************
1554 * tty_recv_config - configure the receive-side characteristics of
1555 * the ppp interface.
1558 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1561 * If we were called because the link has gone down then there is nothing
1562 * which may be done. Just return without incident.
1567 * Set the receiver parameters
1569 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1570 if (errno != EIO && errno != ENOTTY)
1571 error("Couldn't set channel receive MRU: %m");
1573 if (new_style_driver && ppp_dev_fd >= 0
1574 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1575 error("Couldn't set MRU in generic PPP layer: %m");
1577 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1578 if (errno != EIO && errno != ENOTTY)
1579 error("Couldn't set channel receive asyncmap: %m");
1583 /********************************************************************
1585 * ccp_test - ask kernel whether a given compression method
1586 * is acceptable for use.
1590 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1592 struct ppp_option_data data;
1594 memset (&data, '\0', sizeof (data));
1596 data.length = opt_len;
1597 data.transmit = for_transmit;
1599 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1602 return (errno == ENOBUFS)? 0: -1;
1605 /********************************************************************
1607 * ccp_flags_set - inform kernel about the current state of CCP.
1610 void ccp_flags_set (int unit, int isopen, int isup)
1614 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1615 if (still_ppp() && ppp_dev_fd >= 0)
1616 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1619 #ifdef PPP_WITH_FILTER
1621 * set_filters - set the active and pass filters in the kernel driver.
1623 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1625 struct sock_fprog fp;
1627 fp.len = pass->bf_len;
1628 fp.filter = (struct sock_filter *) pass->bf_insns;
1629 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1630 if (errno == ENOTTY)
1631 warn("kernel does not support PPP filtering");
1633 error("Couldn't set pass-filter in kernel: %m");
1636 fp.len = active->bf_len;
1637 fp.filter = (struct sock_filter *) active->bf_insns;
1638 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1639 error("Couldn't set active-filter in kernel: %m");
1644 #endif /* PPP_WITH_FILTER */
1646 /********************************************************************
1648 * get_idle_time - return how long the link has been idle.
1651 get_idle_time(int u, struct ppp_idle *ip)
1653 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1656 /********************************************************************
1658 * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1659 * this only supports 32-bit counters, so need to count the wraps.
1662 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1664 static u_int32_t previbytes = 0;
1665 static u_int32_t prevobytes = 0;
1666 static u_int32_t iwraps = 0;
1667 static u_int32_t owraps = 0;
1670 struct ppp_stats data;
1672 memset (&req, 0, sizeof (req));
1674 req.ifr_data = (caddr_t) &data;
1675 strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
1676 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1677 error("Couldn't get PPP statistics: %m");
1680 stats->bytes_in = data.p.ppp_ibytes;
1681 stats->bytes_out = data.p.ppp_obytes;
1682 stats->pkts_in = data.p.ppp_ipackets;
1683 stats->pkts_out = data.p.ppp_opackets;
1685 if (stats->bytes_in < previbytes)
1687 if (stats->bytes_out < prevobytes)
1690 previbytes = stats->bytes_in;
1691 prevobytes = stats->bytes_out;
1693 stats->bytes_in += (uint64_t)iwraps << 32;
1694 stats->bytes_out += (uint64_t)owraps << 32;
1699 /********************************************************************
1700 * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1701 * This provides native 64-bit counters.
1704 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1706 static int rtnl_fd = -1;
1708 struct sockaddr_nl nladdr;
1710 struct nlmsghdr nlh;
1711 struct if_stats_msg ifsm;
1714 struct nlmsghdr nlh;
1717 struct nlmsgerr nlerr;
1723 /* We only case about these first fields from rtnl_link_stats64 */
1724 uint64_t rx_packets;
1725 uint64_t tx_packets;
1729 char __end_stats[0];
1737 memset(&nladdr, 0, sizeof(nladdr));
1738 nladdr.nl_family = AF_NETLINK;
1741 rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1743 error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__);
1747 if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
1748 error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
1753 memset(&nlreq, 0, sizeof(nlreq));
1754 nlreq.nlh.nlmsg_len = sizeof(nlreq);
1755 nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1756 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1758 nlreq.ifsm.ifindex = if_nametoindex(ifname);
1759 nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1761 memset(&iov, 0, sizeof(iov));
1762 iov.iov_base = &nlreq;
1763 iov.iov_len = sizeof(nlreq);
1765 memset(&msg, 0, sizeof(msg));
1766 msg.msg_name = &nladdr;
1767 msg.msg_namelen = sizeof(nladdr);
1771 if (sendmsg(rtnl_fd, &msg, 0) < 0) {
1772 error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1776 /* We just need to repoint to IOV ... everything else stays the same */
1777 iov.iov_base = &nlresp;
1778 iov.iov_len = sizeof(nlresp);
1780 nlresplen = recvmsg(rtnl_fd, &msg, 0);
1782 if (nlresplen < 0) {
1783 error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1787 if (nlresplen < sizeof(nlresp.nlh)) {
1788 error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__);
1792 if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) {
1793 if (nlresplen < offsetof(struct nlresp, __end_err)) {
1794 if (kernel_version >= KVERSION(4,7,0))
1795 error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
1797 error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).",
1803 if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) {
1804 error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)",
1805 nlresp.nlh.nlmsg_type, __LINE__);
1809 if (nlresplen < offsetof(struct nlresp, __end_stats)) {
1810 error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1814 stats->bytes_in = nlresp.stats.rx_bytes;
1815 stats->bytes_out = nlresp.stats.tx_bytes;
1816 stats->pkts_in = nlresp.stats.rx_packets;
1817 stats->pkts_out = nlresp.stats.tx_packets;
1826 /********************************************************************
1827 * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1828 * this provides native 64-bit counters.
1831 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1833 char fname[PATH_MAX+1];
1834 char buf[21], *err; /* 2^64 < 10^20 */
1836 unsigned long long val;
1843 #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1844 statfield(rx_bytes, bytes_in),
1845 statfield(tx_bytes, bytes_out),
1846 statfield(rx_packets, pkts_in),
1847 statfield(tx_packets, pkts_out),
1851 blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1852 if (blen >= sizeof(fname))
1853 return 0; /* ifname max 15, so this should be impossible */
1855 for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1856 if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1858 error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1862 fd = open(fname, O_RDONLY);
1864 error("%s: %m", fname);
1868 rlen = read(fd, buf, sizeof(buf) - 1);
1871 error("%s: %m", fname);
1874 /* trim trailing \n if present */
1875 while (rlen > 0 && buf[rlen-1] == '\n')
1880 val = strtoull(buf, &err, 10);
1881 if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1882 error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1883 buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1886 switch (slist[i].size) {
1887 #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1894 error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1902 /********************************************************************
1903 * Periodic timer function to be used to keep stats up to date in case of ioctl
1906 * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1907 * If you do change the timer, remember to also bring the get_ppp_stats (which
1908 * sets up the initial trigger) as well.
1911 ppp_stats_poller(void* u)
1913 struct pppd_stats dummy;
1914 get_ppp_stats_ioctl((long)u, &dummy);
1915 TIMEOUT(ppp_stats_poller, u, 25);
1918 /********************************************************************
1919 * get_ppp_stats - return statistics for the link.
1921 int get_ppp_stats(int u, struct pppd_stats *stats)
1923 static int (*func)(int, struct pppd_stats*) = NULL;
1926 if (get_ppp_stats_rtnetlink(u, stats)) {
1927 func = get_ppp_stats_rtnetlink;
1930 if (get_ppp_stats_sysfs(u, stats)) {
1931 func = get_ppp_stats_sysfs;
1934 warn("statistics falling back to ioctl which only supports 32-bit counters");
1935 func = get_ppp_stats_ioctl;
1936 TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1939 return func(u, stats);
1942 /********************************************************************
1944 * ccp_fatal_error - returns 1 if decompression was disabled as a
1945 * result of an error detected after decompression of a packet,
1946 * 0 otherwise. This is necessary because of patent nonsense.
1949 int ccp_fatal_error (int unit)
1953 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1954 error("Couldn't read compression error flags: %m");
1957 return flags & SC_DC_FERROR;
1960 /********************************************************************
1962 * path_to_procfs - find the path to the proc file system mount point
1964 static char proc_path[MAXPATHLEN];
1965 static int proc_path_len;
1967 static char *path_to_procfs(const char *tail)
1969 struct mntent *mntent;
1972 if (proc_path_len == 0) {
1973 /* Default the mount location of /proc */
1974 strlcpy (proc_path, "/proc", sizeof(proc_path));
1976 fp = fopen(MOUNTED, "r");
1978 while ((mntent = getmntent(fp)) != NULL) {
1979 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1981 if (strcmp(mntent->mnt_type, "proc") == 0) {
1982 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1983 proc_path_len = strlen(proc_path);
1991 strlcpy(proc_path + proc_path_len, tail,
1992 sizeof(proc_path) - proc_path_len);
1997 * /proc/net/route parsing stuff.
1999 #define ROUTE_MAX_COLS 12
2000 FILE *route_fd = (FILE *) 0;
2001 static char route_buffer[512];
2002 static int route_dev_col, route_dest_col, route_gw_col;
2003 static int route_flags_col, route_metric_col, route_mask_col;
2004 static int route_num_cols;
2006 static int open_route_table (void);
2007 static void close_route_table (void);
2008 static int read_route_table (struct rtentry *rt);
2010 /********************************************************************
2012 * close_route_table - close the interface to the route table
2015 static void close_route_table (void)
2017 if (route_fd != (FILE *) 0) {
2019 route_fd = (FILE *) 0;
2023 /********************************************************************
2025 * open_route_table - open the interface to the route table
2027 static char route_delims[] = " \t\n";
2029 static int open_route_table (void)
2033 close_route_table();
2035 path = path_to_procfs("/net/route");
2036 route_fd = fopen (path, "r");
2037 if (route_fd == NULL) {
2038 error("can't open routing table %s: %m", path);
2042 route_dev_col = 0; /* default to usual columns */
2045 route_flags_col = 3;
2046 route_metric_col = 6;
2050 /* parse header line */
2051 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
2052 char *p = route_buffer, *q;
2054 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
2056 if ((q = strtok(p, route_delims)) == 0)
2058 if (strcasecmp(q, "iface") == 0)
2059 route_dev_col = col;
2060 else if (strcasecmp(q, "destination") == 0)
2061 route_dest_col = col;
2062 else if (strcasecmp(q, "gateway") == 0)
2064 else if (strcasecmp(q, "flags") == 0)
2065 route_flags_col = col;
2066 else if (strcasecmp(q, "mask") == 0)
2067 route_mask_col = col;
2070 if (used && col >= route_num_cols)
2071 route_num_cols = col + 1;
2079 /********************************************************************
2081 * read_route_table - read the next entry from the route table
2084 static int read_route_table(struct rtentry *rt)
2086 char *cols[ROUTE_MAX_COLS], *p;
2089 memset (rt, '\0', sizeof (struct rtentry));
2091 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2095 for (col = 0; col < route_num_cols; ++col) {
2096 cols[col] = strtok(p, route_delims);
2097 if (cols[col] == NULL)
2098 return 0; /* didn't get enough columns */
2102 SET_SA_FAMILY (rt->rt_dst, AF_INET);
2103 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
2105 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
2106 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
2107 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
2109 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
2110 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
2111 rt->rt_dev = cols[route_dev_col];
2116 /********************************************************************
2118 * defaultroute_exists - determine if there is a default route
2119 * with the given metric (or negative for any)
2122 static int defaultroute_exists (struct rtentry *rt, int metric)
2126 if (!open_route_table())
2129 while (read_route_table(rt) != 0) {
2130 if ((rt->rt_flags & RTF_UP) == 0)
2133 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
2135 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
2136 || rt->rt_metric == metric)) {
2142 close_route_table();
2147 * have_route_to - determine if the system has any route to
2148 * a given IP address. `addr' is in network byte order.
2149 * Return value is 1 if yes, 0 if no, -1 if don't know.
2150 * For demand mode to work properly, we have to ignore routes
2151 * through our own interface.
2153 int have_route_to(u_int32_t addr)
2158 if (!open_route_table())
2159 return -1; /* don't know */
2161 while (read_route_table(&rt)) {
2162 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
2164 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
2170 close_route_table();
2174 /********************************************************************
2176 * sifdefaultroute - assign a default route through the address given.
2178 * If the global default_rt_repl_rest flag is set, then this function
2179 * already replaced the original system defaultroute with some other
2180 * route and it should just replace the current defaultroute with
2181 * another one, without saving the current route. Use: demand mode,
2182 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2183 * and then changes the temporary addresses to the addresses for the real
2184 * ppp connection when it has come up.
2187 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
2189 struct rtentry rt, tmp_rt;
2190 struct rtentry *del_rt = NULL;
2192 if (default_rt_repl_rest) {
2193 /* We have already replaced the original defaultroute, if we
2194 * are called again, we will delete the current default route
2195 * and set the new default route in this function.
2196 * - this is normally only the case the doing demand: */
2197 if (defaultroute_exists(&tmp_rt, -1))
2199 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
2200 strcmp( old_def_rt.rt_dev, ifname) != 0) {
2202 * We did not yet replace an existing default route, let's
2203 * check if we should save and replace a default route:
2205 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2207 if (old_gateway != gateway) {
2209 error("not replacing default route to %s [%I]",
2210 old_def_rt.rt_dev, old_gateway);
2213 /* we need to copy rt_dev because we need it permanent too: */
2214 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2215 strcpy(tmp_dev, old_def_rt.rt_dev);
2216 old_def_rt.rt_dev = tmp_dev;
2218 notice("replacing old default route to %s [%I]",
2219 old_def_rt.rt_dev, old_gateway);
2220 default_rt_repl_rest = 1;
2221 del_rt = &old_def_rt;
2226 memset (&rt, 0, sizeof (rt));
2227 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2230 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2232 if (kernel_version > KVERSION(2,1,0)) {
2233 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2234 SIN_ADDR(rt.rt_genmask) = 0L;
2237 rt.rt_flags = RTF_UP;
2238 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2239 if ( ! ok_error ( errno ))
2240 error("default route ioctl(SIOCADDRT): %m");
2243 if (default_rt_repl_rest && del_rt)
2244 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2245 if ( ! ok_error ( errno ))
2246 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2250 have_default_route = 1;
2254 /********************************************************************
2256 * cifdefaultroute - delete a default route through the address given.
2259 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2263 have_default_route = 0;
2265 memset (&rt, '\0', sizeof (rt));
2266 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2267 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2272 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2274 if (kernel_version > KVERSION(2,1,0)) {
2275 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2276 SIN_ADDR(rt.rt_genmask) = 0L;
2279 rt.rt_flags = RTF_UP;
2280 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2282 if ( ! ok_error ( errno ))
2283 error("default route ioctl(SIOCDELRT): %m");
2287 if (default_rt_repl_rest) {
2288 notice("restoring old default route to %s [%I]",
2289 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2290 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2291 if ( ! ok_error ( errno ))
2292 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2295 default_rt_repl_rest = 0;
2301 #ifdef PPP_WITH_IPV6CP
2303 * /proc/net/ipv6_route parsing stuff.
2305 static int route_dest_plen_col;
2306 static int open_route6_table (void);
2307 static int read_route6_table (struct in6_rtmsg *rt);
2309 /********************************************************************
2311 * open_route6_table - open the interface to the route table
2313 static int open_route6_table (void)
2317 close_route_table();
2319 path = path_to_procfs("/net/ipv6_route");
2320 route_fd = fopen (path, "r");
2321 if (route_fd == NULL) {
2322 error("can't open routing table %s: %m", path);
2326 /* default to usual columns */
2328 route_dest_plen_col = 1;
2330 route_metric_col = 5;
2331 route_flags_col = 8;
2333 route_num_cols = 10;
2338 /********************************************************************
2340 * read_route6_table - read the next entry from the route table
2343 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2350 for (i = 0; i < 4; i++) {
2351 memcpy(hex8, s + 8*i, 8);
2352 v = strtoul(hex8, NULL, 16);
2353 addr->s6_addr32[i] = v;
2357 static int read_route6_table(struct in6_rtmsg *rt)
2359 char *cols[ROUTE_MAX_COLS], *p;
2362 memset (rt, '\0', sizeof (struct in6_rtmsg));
2364 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2368 for (col = 0; col < route_num_cols; ++col) {
2369 cols[col] = strtok(p, route_delims);
2370 if (cols[col] == NULL)
2371 return 0; /* didn't get enough columns */
2375 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2376 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2377 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2379 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2380 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2381 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2386 /********************************************************************
2388 * defaultroute6_exists - determine if there is a default route
2391 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2395 if (!open_route6_table())
2398 while (read_route6_table(rt) != 0) {
2399 if ((rt->rtmsg_flags & RTF_UP) == 0)
2402 if (rt->rtmsg_dst_len != 0)
2404 if (rt->rtmsg_dst.s6_addr32[0] == 0L
2405 && rt->rtmsg_dst.s6_addr32[1] == 0L
2406 && rt->rtmsg_dst.s6_addr32[2] == 0L
2407 && rt->rtmsg_dst.s6_addr32[3] == 0L
2408 && (metric < 0 || rt->rtmsg_metric == metric)) {
2414 close_route_table();
2418 /********************************************************************
2420 * sif6defaultroute - assign a default route through the address given.
2422 * If the global default_rt_repl_rest flag is set, then this function
2423 * already replaced the original system defaultroute with some other
2424 * route and it should just replace the current defaultroute with
2425 * another one, without saving the current route. Use: demand mode,
2426 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2427 * and then changes the temporary addresses to the addresses for the real
2428 * ppp connection when it has come up.
2431 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2433 struct in6_rtmsg rt;
2434 char buf[IF_NAMESIZE];
2436 if (defaultroute6_exists(&rt, dfl_route_metric) &&
2437 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2438 if (rt.rtmsg_flags & RTF_GATEWAY)
2439 error("not replacing existing default route via gateway");
2441 error("not replacing existing default route through %s",
2442 if_indextoname(rt.rtmsg_ifindex, buf));
2446 memset (&rt, 0, sizeof (rt));
2448 rt.rtmsg_ifindex = if_nametoindex(ifname);
2449 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2450 rt.rtmsg_dst_len = 0;
2452 rt.rtmsg_flags = RTF_UP;
2453 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2454 if ( ! ok_error ( errno ))
2455 error("default route ioctl(SIOCADDRT): %m");
2459 have_default_route6 = 1;
2463 /********************************************************************
2465 * cif6defaultroute - delete a default route through the address given.
2468 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2470 struct in6_rtmsg rt;
2472 have_default_route6 = 0;
2474 memset (&rt, '\0', sizeof (rt));
2476 rt.rtmsg_ifindex = if_nametoindex(ifname);
2477 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2478 rt.rtmsg_dst_len = 0;
2480 rt.rtmsg_flags = RTF_UP;
2481 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2483 if ( ! ok_error ( errno ))
2484 error("default route ioctl(SIOCDELRT): %m");
2491 #endif /* PPP_WITH_IPV6CP */
2493 /********************************************************************
2495 * sifproxyarp - Make a proxy ARP entry for the peer.
2498 int sifproxyarp (int unit, u_int32_t his_adr)
2500 struct arpreq arpreq;
2503 if (has_proxy_arp == 0) {
2504 memset (&arpreq, '\0', sizeof(arpreq));
2506 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2507 SIN_ADDR(arpreq.arp_pa) = his_adr;
2508 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2510 * Get the hardware address of an interface on the same subnet
2511 * as our local address.
2513 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2514 sizeof(proxy_arp_dev))) {
2515 error("Cannot determine ethernet address for proxy ARP");
2518 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2520 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2521 if ( ! ok_error ( errno ))
2522 error("ioctl(SIOCSARP): %m");
2525 proxy_arp_addr = his_adr;
2529 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2530 if (forw_path != 0) {
2531 int fd = open(forw_path, O_WRONLY);
2533 if (write(fd, "1", 1) != 1)
2534 error("Couldn't enable IP forwarding: %m");
2544 /********************************************************************
2546 * cifproxyarp - Delete the proxy ARP entry for the peer.
2549 int cifproxyarp (int unit, u_int32_t his_adr)
2551 struct arpreq arpreq;
2553 if (has_proxy_arp) {
2555 memset (&arpreq, '\0', sizeof(arpreq));
2556 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2557 SIN_ADDR(arpreq.arp_pa) = his_adr;
2558 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2559 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2561 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2562 if ( ! ok_error ( errno ))
2563 warn("ioctl(SIOCDARP): %m");
2570 /********************************************************************
2572 * get_ether_addr - get the hardware address of an interface on the
2573 * the same subnet as ipaddr.
2576 static int get_ether_addr (u_int32_t ipaddr,
2577 struct sockaddr *hwaddr,
2578 char *name, int namelen)
2580 struct ifreq *ifr, *ifend;
2581 u_int32_t ina, mask;
2583 struct ifreq ifreq, bestifreq;
2585 struct ifreq ifs[MAX_IFS];
2587 u_int32_t bestmask=0;
2588 int found_interface = 0;
2590 ifc.ifc_len = sizeof(ifs);
2592 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2593 if ( ! ok_error ( errno ))
2594 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2599 * Scan through looking for an interface with an Internet
2600 * address on the same subnet as `ipaddr'.
2602 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2603 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2604 if (ifr->ifr_addr.sa_family == AF_INET) {
2605 ina = SIN_ADDR(ifr->ifr_addr);
2606 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2608 * Check that the interface is up, and not point-to-point
2611 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2614 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2617 * Get its netmask and check that it's on the right subnet.
2619 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2622 mask = SIN_ADDR(ifreq.ifr_addr);
2624 if (((ipaddr ^ ina) & mask) != 0)
2625 continue; /* no match */
2627 if (mask >= bestmask) {
2628 /* Compare using >= instead of > -- it is possible for
2629 an interface to have a netmask of 0.0.0.0 */
2630 found_interface = 1;
2637 if (!found_interface) return 0;
2639 strlcpy(name, bestifreq.ifr_name, namelen);
2641 /* trim off the :1 in eth0:1 */
2642 aliasp = strchr(name, ':');
2646 info("found interface %s for proxy arp", name);
2648 * Now get the hardware address.
2650 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2651 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2652 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2657 &bestifreq.ifr_hwaddr,
2658 sizeof (struct sockaddr));
2664 * get_if_hwaddr - get the hardware address for the specified
2665 * network interface device.
2668 get_if_hwaddr(u_char *addr, char *name)
2673 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2676 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2677 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2678 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2681 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2686 * get_first_ether_hwaddr - get the hardware address for the first
2687 * ethernet-style interface on this system.
2690 get_first_ether_hwaddr(u_char *addr)
2692 struct if_nameindex *if_ni, *i;
2696 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2700 if_ni = if_nameindex();
2708 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2709 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2710 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2711 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2712 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2713 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2719 if_freenameindex(if_ni);
2725 /********************************************************************
2727 * Return user specified netmask, modified by any mask we might determine
2728 * for address `addr' (in network byte order).
2729 * Here we scan through the system's list of interfaces, looking for
2730 * any non-point-to-point interfaces which might appear to be on the same
2731 * network as `addr'. If we find any, we OR in their netmask to the
2732 * user-specified netmask.
2735 u_int32_t GetMask (u_int32_t addr)
2737 u_int32_t mask, nmask, ina;
2738 struct ifreq *ifr, *ifend, ifreq;
2740 struct ifreq ifs[MAX_IFS];
2744 if (IN_CLASSA(addr)) /* determine network mask for address class */
2745 nmask = IN_CLASSA_NET;
2746 else if (IN_CLASSB(addr))
2747 nmask = IN_CLASSB_NET;
2749 nmask = IN_CLASSC_NET;
2751 /* class D nets are disallowed by bad_ip_adrs */
2752 mask = netmask | htonl(nmask);
2754 * Scan through the system's network interfaces.
2756 ifc.ifc_len = sizeof(ifs);
2758 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2759 if ( ! ok_error ( errno ))
2760 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2764 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2765 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2767 * Check the interface's internet address.
2769 if (ifr->ifr_addr.sa_family != AF_INET)
2771 ina = SIN_ADDR(ifr->ifr_addr);
2772 if (((ntohl(ina) ^ addr) & nmask) != 0)
2775 * Check that the interface is up, and not point-to-point nor loopback.
2777 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2778 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2781 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2784 * Get its netmask and OR it into our mask.
2786 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2788 mask |= SIN_ADDR(ifreq.ifr_addr);
2794 /********************************************************************
2796 * Internal routine to decode the version.modification.patch level
2799 static void decode_version (char *buf, int *version,
2800 int *modification, int *patch)
2804 *version = (int) strtoul (buf, &endp, 10);
2808 if (endp != buf && *endp == '.') {
2810 *modification = (int) strtoul (buf, &endp, 10);
2811 if (endp != buf && *endp == '.') {
2813 *patch = (int) strtoul (buf, &buf, 10);
2818 /********************************************************************
2820 * Procedure to determine if the PPP line discipline is registered.
2824 ppp_registered(void)
2832 * We used to open the serial device and set it to the ppp line
2833 * discipline here, in order to create a ppp unit. But that is
2834 * not a good idea - the user might have specified a device that
2835 * they can't open (permission, or maybe it doesn't really exist).
2836 * So we grab a pty master/slave pair and use that.
2838 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2839 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2844 * Try to put the device into the PPP discipline.
2846 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2847 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2856 /********************************************************************
2858 * ppp_available - check whether the system has any ppp interfaces
2859 * (in fact we check whether we can do an ioctl on ppp0).
2862 int ppp_available(void)
2867 int my_version, my_modification, my_patch;
2868 int osmaj, osmin, ospatch;
2870 /* get the kernel version now, since we are called before sys_init */
2872 osmaj = osmin = ospatch = 0;
2873 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2874 kernel_version = KVERSION(osmaj, osmin, ospatch);
2876 fd = open("/dev/ppp", O_RDWR);
2878 new_style_driver = 1;
2880 /* XXX should get from driver */
2882 driver_modification = 4;
2888 if (kernel_version >= KVERSION(2,3,13)) {
2889 error("Couldn't open the /dev/ppp device: %m");
2890 if (errno == ENOENT)
2892 "You need to create the /dev/ppp device node by\n"
2893 "executing the following command as root:\n"
2894 " mknod /dev/ppp c 108 0\n";
2895 else if (errno == ENODEV || errno == ENXIO)
2897 "Please load the ppp_generic kernel module.\n";
2901 /* we are running on a really really old kernel */
2903 "This system lacks kernel support for PPP. This could be because\n"
2904 "the PPP kernel module could not be loaded, or because PPP was not\n"
2905 "included in the kernel configuration. If PPP was included as a\n"
2906 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2907 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2908 "See README.linux file in the ppp distribution for more details.\n";
2911 * Open a socket for doing the ioctl operations.
2913 s = socket(AF_INET, SOCK_DGRAM, 0);
2917 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2918 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2920 * If the device did not exist then attempt to create one by putting the
2921 * current tty into the PPP discipline. If this works then obtain the
2922 * flags for the device again.
2925 if (ppp_registered()) {
2926 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2927 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2931 * Ensure that the hardware address is for PPP and not something else
2934 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2936 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2940 * This is the PPP device. Validate the version of the driver at this
2941 * point to ensure that this program will work with the driver.
2944 char abBuffer [1024];
2946 ifr.ifr_data = abBuffer;
2947 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2949 error("Couldn't read driver version: %m");
2951 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2954 decode_version(abBuffer,
2956 &driver_modification,
2959 * Validate the version of the driver against the version that we used.
2961 decode_version(VERSION,
2966 /* The version numbers must match */
2967 if (driver_version != my_version)
2970 /* The modification levels must be legal */
2971 if (driver_modification < 3) {
2972 if (driver_modification >= 2) {
2973 /* we can cope with 2.2.0 and above */
2981 slprintf(route_buffer, sizeof(route_buffer),
2982 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2983 driver_version, driver_modification, driver_patch);
2985 no_ppp_msg = route_buffer;
2993 #ifndef HAVE_LOGWTMP
2994 /********************************************************************
2996 * Update the wtmp file with the appropriate user name and tty device.
2999 void logwtmp (const char *line, const char *name, const char *host)
3001 struct utmp ut, *utp;
3002 pid_t mypid = getpid();
3008 * Update the signon database for users.
3009 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
3011 utmpname(_PATH_UTMP);
3013 while ((utp = getutent()) && (utp->ut_pid != mypid))
3017 memcpy(&ut, utp, sizeof(ut));
3019 /* some gettys/telnetds don't initialize utmp... */
3020 memset(&ut, 0, sizeof(ut));
3022 if (ut.ut_id[0] == 0)
3023 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
3025 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
3026 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
3030 ut.ut_type = USER_PROCESS;
3033 /* Insert the host name if one is supplied */
3035 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
3037 /* Insert the IP address of the remote system if IP is enabled */
3038 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
3039 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
3040 sizeof(ut.ut_addr));
3042 /* CL: Makes sure that the logout works */
3043 if (*host == 0 && *name==0)
3049 * Update the wtmp file.
3052 updwtmp(_PATH_WTMP, &ut);
3054 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
3056 flock(wtmp, LOCK_EX);
3058 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
3059 warn("error writing %s: %m", _PATH_WTMP);
3061 flock(wtmp, LOCK_UN);
3067 #endif /* HAVE_LOGWTMP */
3069 /********************************************************************
3071 * sifvjcomp - config tcp header compression
3074 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
3079 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
3080 error("Couldn't set up TCP header compression: %m");
3085 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
3086 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
3091 /********************************************************************
3093 * sifup - Config the interface up and enable IP packets to pass.
3100 if ((ret = setifstate(u, 1)))
3106 /********************************************************************
3108 * sifdown - Disable the indicated protocol and config the interface
3109 * down if there are no remaining protocols.
3114 if (if_is_up && --if_is_up > 0)
3117 #ifdef PPP_WITH_IPV6CP
3120 #endif /* PPP_WITH_IPV6CP */
3122 return setifstate(u, 0);
3125 #ifdef PPP_WITH_IPV6CP
3126 /********************************************************************
3128 * sif6up - Config the interface up for IPv6
3135 if ((ret = setifstate(u, 1)))
3141 /********************************************************************
3143 * sif6down - Disable the IPv6CP protocol and config the interface
3144 * down if there are no remaining protocols.
3147 int sif6down (int u)
3154 return setifstate(u, 0);
3156 #endif /* PPP_WITH_IPV6CP */
3158 /********************************************************************
3160 * setifstate - Config the interface up or down
3163 static int setifstate (int u, int state)
3167 memset (&ifr, '\0', sizeof (ifr));
3168 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3169 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
3170 if (! ok_error (errno))
3171 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
3176 ifr.ifr_flags |= IFF_UP;
3178 ifr.ifr_flags &= ~IFF_UP;
3179 ifr.ifr_flags |= IFF_POINTOPOINT;
3180 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
3181 if (! ok_error (errno))
3182 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
3188 /********************************************************************
3190 * sifaddr - Config the interface IP addresses and netmask.
3193 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3199 memset (&ifr, '\0', sizeof (ifr));
3200 memset (&rt, '\0', sizeof (rt));
3202 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
3203 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3204 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3206 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3208 * Set our IP address
3210 SIN_ADDR(ifr.ifr_addr) = our_adr;
3211 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3212 if (errno != EEXIST) {
3213 if (! ok_error (errno))
3214 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3217 warn("ioctl(SIOCSIFADDR): Address already exists");
3222 * Set the gateway address
3225 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3226 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3227 if (! ok_error (errno))
3228 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3234 * For recent kernels, force the netmask to 255.255.255.255.
3236 if (kernel_version >= KVERSION(2,1,16))
3238 if (net_mask != 0) {
3239 SIN_ADDR(ifr.ifr_netmask) = net_mask;
3240 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3241 if (! ok_error (errno))
3242 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3247 * Add the device route
3249 if (kernel_version < KVERSION(2,1,16)) {
3250 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3251 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3254 SIN_ADDR(rt.rt_gateway) = 0L;
3255 SIN_ADDR(rt.rt_dst) = his_adr;
3256 rt.rt_flags = RTF_UP | RTF_HOST;
3258 if (kernel_version > KVERSION(2,1,0)) {
3259 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3260 SIN_ADDR(rt.rt_genmask) = -1L;
3263 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3264 if (! ok_error (errno))
3265 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3270 /* set ip_dynaddr in demand mode if address changes */
3271 if (demand && tune_kernel && !dynaddr_set
3272 && our_old_addr && our_old_addr != our_adr) {
3273 /* set ip_dynaddr if possible */
3277 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3278 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3279 if (write(fd, "1", 1) != 1)
3280 error("Couldn't enable dynamic IP addressing: %m");
3283 dynaddr_set = 1; /* only 1 attempt */
3290 /********************************************************************
3292 * cifaddr - Clear the interface IP addresses, and delete routes
3293 * through the interface if possible.
3296 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3300 if (kernel_version < KVERSION(2,1,16)) {
3302 * Delete the route through the device
3305 memset (&rt, '\0', sizeof (rt));
3307 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3308 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3311 SIN_ADDR(rt.rt_gateway) = 0;
3312 SIN_ADDR(rt.rt_dst) = his_adr;
3313 rt.rt_flags = RTF_UP | RTF_HOST;
3315 if (kernel_version > KVERSION(2,1,0)) {
3316 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3317 SIN_ADDR(rt.rt_genmask) = -1L;
3320 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3321 if (still_ppp() && ! ok_error (errno))
3322 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3327 /* This way it is possible to have an IPv6-only interface */
3328 memset(&ifr, 0, sizeof(ifr));
3329 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3330 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3332 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3333 if (! ok_error (errno)) {
3334 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3339 our_old_addr = our_adr;
3344 #ifdef PPP_WITH_IPV6CP
3345 /********************************************************************
3347 * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3349 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3352 struct nlmsghdr nlh;
3353 struct ifaddrmsg ifa;
3356 struct in6_addr addr;
3360 struct nlmsghdr nlh;
3361 struct nlmsgerr nlerr;
3363 struct sockaddr_nl nladdr;
3370 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
3372 error("sif6addr_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
3377 * Tell kernel to not send to us payload of acknowledgment error message.
3378 * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
3379 * older kernel versions always send full payload in acknowledgment netlink
3380 * message. We ignore payload of this message as we need only error code,
3381 * to check if our set remote peer address request succeeded or failed.
3382 * So ignore return value from the following setsockopt() call as setting
3383 * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
3386 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
3388 memset(&nladdr, 0, sizeof(nladdr));
3389 nladdr.nl_family = AF_NETLINK;
3391 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
3392 error("sif6addr_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
3397 memset(&nlreq, 0, sizeof(nlreq));
3398 nlreq.nlh.nlmsg_len = sizeof(nlreq);
3399 nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3400 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3401 nlreq.ifa.ifa_family = AF_INET6;
3402 nlreq.ifa.ifa_prefixlen = 128;
3403 nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3404 nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3405 nlreq.ifa.ifa_index = iface;
3406 nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3407 nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3408 IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3409 nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3410 nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3413 * To set only local address, older kernel expects that local address is
3414 * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3415 * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3416 * compatibility when setting only local address, set it via both IFA_LOCAL
3417 * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3418 * from iproute2 project.
3420 if (!eui64_iszero(his_eui64))
3421 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3423 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3425 memset(&nladdr, 0, sizeof(nladdr));
3426 nladdr.nl_family = AF_NETLINK;
3428 memset(&iov, 0, sizeof(iov));
3429 iov.iov_base = &nlreq;
3430 iov.iov_len = sizeof(nlreq);
3432 memset(&msg, 0, sizeof(msg));
3433 msg.msg_name = &nladdr;
3434 msg.msg_namelen = sizeof(nladdr);
3438 if (sendmsg(fd, &msg, 0) < 0) {
3439 error("sif6addr_rtnetlink: sendmsg(RTM_NEWADDR/NLM_F_CREATE): %m (line %d)", __LINE__);
3444 memset(&iov, 0, sizeof(iov));
3445 iov.iov_base = &nlresp;
3446 iov.iov_len = sizeof(nlresp);
3448 memset(&msg, 0, sizeof(msg));
3449 msg.msg_name = &nladdr;
3450 msg.msg_namelen = sizeof(nladdr);
3454 nlresplen = recvmsg(fd, &msg, 0);
3456 if (nlresplen < 0) {
3457 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
3464 if (nladdr.nl_family != AF_NETLINK) {
3465 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
3469 if ((size_t)nlresplen != sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
3470 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
3474 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
3475 if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
3476 error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
3480 /* error == 0 indicates success, negative value is errno code */
3481 if (nlresp.nlerr.error != 0) {
3483 * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3484 * addresses and error response is expected. On older kernel versions
3485 * do not show this error message. On error pppd tries to fallback to
3486 * the old IOCTL method.
3488 if (kernel_version >= KVERSION(3,11,0))
3489 error("sif6addr_rtnetlink: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
3496 /********************************************************************
3498 * sif6addr - Config the interface with an IPv6 link-local address
3500 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3502 struct in6_ifreq ifr6;
3504 struct in6_rtmsg rt6;
3509 error("IPv6 socket creation failed: %m");
3512 memset(&ifr, 0, sizeof (ifr));
3513 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3514 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3515 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3519 if (kernel_version >= KVERSION(2,1,16)) {
3520 /* Set both local address and remote peer address (with route for it) via rtnetlink */
3521 ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3527 * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3528 * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3531 /* Local interface */
3532 memset(&ifr6, 0, sizeof(ifr6));
3533 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3534 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3535 ifr6.ifr6_prefixlen = 128;
3537 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3538 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3543 if (!ret && !eui64_iszero(his_eui64)) {
3545 * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3546 * setting remote peer host address, so set only route to remote host.
3549 /* Route to remote host */
3550 memset(&rt6, 0, sizeof(rt6));
3551 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3552 rt6.rtmsg_flags = RTF_UP;
3553 rt6.rtmsg_dst_len = 128;
3554 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3555 rt6.rtmsg_metric = 1;
3557 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3558 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3567 /********************************************************************
3569 * cif6addr - Remove IPv6 address from interface
3571 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3574 struct in6_ifreq ifr6;
3578 error("IPv6 socket creation failed: %m");
3581 memset(&ifr, 0, sizeof(ifr));
3582 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3583 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3584 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3588 memset(&ifr6, 0, sizeof(ifr6));
3589 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3590 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3591 ifr6.ifr6_prefixlen = 128;
3593 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3594 if (errno != EADDRNOTAVAIL) {
3595 if (! ok_error (errno))
3596 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3599 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3605 #endif /* PPP_WITH_IPV6CP */
3608 * get_pty - get a pty master/slave pair and chown the slave side
3609 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
3612 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3614 int i, mfd, ret, sfd = -1;
3616 struct termios tios;
3620 * Try the unix98 way first.
3622 mfd = open("/dev/ptmx", O_RDWR);
3625 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3626 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3627 chmod(pty_name, S_IRUSR | S_IWUSR);
3630 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3631 warn("Couldn't unlock pty slave %s: %m", pty_name);
3633 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3635 warn("Couldn't open pty slave %s: %m", pty_name);
3640 #endif /* TIOCGPTN */
3643 /* the old way - scan through the pty name space */
3644 for (i = 0; i < 64; ++i) {
3645 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3646 'p' + i / 16, i % 16);
3647 mfd = open(pty_name, O_RDWR, 0);
3650 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3652 ret = fchown(sfd, uid, -1);
3654 warn("Couldn't change ownership of %s, %m", pty_name);
3656 ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3658 warn("Couldn't change permissions of %s, %m", pty_name);
3670 strlcpy(slave_name, pty_name, 16);
3673 if (tcgetattr(sfd, &tios) == 0) {
3674 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3675 tios.c_cflag |= CS8 | CREAD | CLOCAL;
3676 tios.c_iflag = IGNPAR;
3679 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3680 warn("couldn't set attributes on pty: %m");
3682 warn("couldn't get attributes on pty: %m");
3687 /********************************************************************
3689 * open_loopback - open the device we use for getting packets
3690 * in demand mode. Under Linux, we use a pty master/slave pair.
3693 open_ppp_loopback(void)
3698 if (new_style_driver) {
3699 /* allocate ourselves a ppp unit */
3700 if (make_ppp_unit() < 0)
3702 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3703 set_kdebugflag(kdebugflag);
3708 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3709 fatal("No free pty for loopback");
3711 set_ppp_fd(slave_fd);
3713 flags = fcntl(master_fd, F_GETFL);
3715 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3716 warn("couldn't set master loopback to nonblock: %m");
3718 flags = fcntl(ppp_fd, F_GETFL);
3720 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3721 warn("couldn't set slave loopback to nonblock: %m");
3723 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3724 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3726 * Find out which interface we were given.
3728 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3729 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3731 * Enable debug in the driver if requested.
3733 set_kdebugflag (kdebugflag);
3738 /********************************************************************
3740 * sifnpmode - Set the mode for handling packets for a given NP.
3744 sifnpmode(int u, int proto, enum NPmode mode)
3748 npi.protocol = proto;
3750 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3751 if (! ok_error (errno))
3752 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3759 * Use the hostname as part of the random number seed.
3768 for (p = hostname; *p != 0; ++p)
3773 /********************************************************************
3775 * sys_check_options - check the options that the user specified
3779 sys_check_options(void)
3781 if (demand && driver_is_old) {
3782 option_error("demand dialling is not supported by kernel driver "
3783 "version %d.%d.%d", driver_version, driver_modification,
3787 if (multilink && !new_style_driver) {
3788 warn("Warning: multilink is not supported by the kernel driver");
3794 /********************************************************************
3796 * get_time - Get current time, monotonic if possible.
3799 get_time(struct timeval *tv)
3801 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3802 * Runtime checking makes it safe. */
3803 #ifndef CLOCK_MONOTONIC
3804 #define CLOCK_MONOTONIC 1
3806 static int monotonic = -1;
3811 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3815 tv->tv_sec = ts.tv_sec;
3816 tv->tv_usec = ts.tv_nsec / 1000;
3819 } else if (monotonic > 0)
3823 warn("Couldn't use monotonic clock source: %m");
3826 return gettimeofday(tv, NULL);