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);
303 * rtnetlink_msg - send rtnetlink message, receive response
304 * and return received error code:
306 * positive value - error during sending / receiving message
307 * negative value - rtnetlink responce error code
309 static int rtnetlink_msg(const char *desc, int *shared_fd, void *nlreq, size_t nlreq_len, void *nlresp_data, size_t *nlresp_size, unsigned nlresp_type)
313 struct nlmsgerr nlerr;
315 struct sockaddr_nl nladdr;
322 if (shared_fd && *shared_fd >= 0) {
325 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
327 error("rtnetlink_msg: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
332 * Tell kernel to not send to us payload of acknowledgment error message.
333 * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
334 * older kernel versions always send full payload in acknowledgment netlink
335 * message. We ignore payload of this message as we need only error code,
336 * to check if our set remote peer address request succeeded or failed.
337 * So ignore return value from the following setsockopt() call as setting
338 * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
341 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
343 memset(&nladdr, 0, sizeof(nladdr));
344 nladdr.nl_family = AF_NETLINK;
346 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
347 error("rtnetlink_msg: bind(AF_NETLINK): %m (line %d)", __LINE__);
356 memset(&nladdr, 0, sizeof(nladdr));
357 nladdr.nl_family = AF_NETLINK;
359 memset(&iov[0], 0, sizeof(iov[0]));
360 iov[0].iov_base = nlreq;
361 iov[0].iov_len = nlreq_len;
363 memset(&msg, 0, sizeof(msg));
364 msg.msg_name = &nladdr;
365 msg.msg_namelen = sizeof(nladdr);
366 msg.msg_iov = &iov[0];
369 if (sendmsg(fd, &msg, 0) < 0) {
370 error("rtnetlink_msg: sendmsg(%s): %m (line %d)", desc, __LINE__);
376 memset(iov, 0, sizeof(iov));
377 iov[0].iov_base = &nlresp_hdr;
378 if (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) {
379 iov[0].iov_len = offsetof(struct nlresp_hdr, nlerr);
380 iov[1].iov_base = nlresp_data;
381 iov[1].iov_len = *nlresp_size;
383 iov[0].iov_len = sizeof(nlresp_hdr);
386 memset(&msg, 0, sizeof(msg));
387 msg.msg_name = &nladdr;
388 msg.msg_namelen = sizeof(nladdr);
390 msg.msg_iovlen = (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) ? 2 : 1;
392 nlresp_len = recvmsg(fd, &msg, 0);
397 if (nlresp_len < 0) {
398 error("rtnetlink_msg: recvmsg(%s): %m (line %d)", desc, __LINE__);
402 if (nladdr.nl_family != AF_NETLINK) {
403 error("rtnetlink_msg: recvmsg(%s): Not a netlink packet (line %d)", desc, __LINE__);
408 if ((size_t)nlresp_len < sizeof(nlresp_hdr) || nlresp_hdr.nlh.nlmsg_len < sizeof(nlresp_hdr)) {
409 error("rtnetlink_msg: recvmsg(%s): Acknowledgment netlink packet too short (line %d)", desc, __LINE__);
413 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
414 if (nlresp_hdr.nlh.nlmsg_type != NLMSG_ERROR) {
415 error("rtnetlink_msg: recvmsg(%s): Not an acknowledgment netlink packet (line %d)", desc, __LINE__);
421 if (*nlresp_size > sizeof(nlresp_hdr))
422 memcpy((unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), nlresp_data, sizeof(nlresp_hdr.nlerr));
424 memcpy(nlresp_data, (unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), *nlresp_size);
427 /* error == 0 indicates success, negative value is errno code */
428 if (nlresp_hdr.nlh.nlmsg_type == NLMSG_ERROR && nlresp_hdr.nlerr.error)
429 return nlresp_hdr.nlerr.error;
432 if (nlresp_hdr.nlh.nlmsg_type != nlresp_type) {
433 error("rtnetlink_msg: recvmsg(%s): Not a netlink packet of type 0x%x (line %d)", desc, nlresp_type, __LINE__);
436 *nlresp_size = nlresp_len - offsetof(struct nlresp_hdr, nlerr);
443 * Determine if the PPP connection should still be present.
448 /* new_fd is the fd of a tty */
449 static void set_ppp_fd (int new_fd)
452 if (!new_style_driver)
456 static int still_ppp(void)
458 if (new_style_driver)
459 return !hungup && ppp_fd >= 0;
460 if (!hungup || ppp_fd == slave_fd)
463 set_ppp_fd(slave_fd);
470 * modify_flags - set and clear flag bits controlling the kernel
473 static int modify_flags(int fd, int clear_bits, int set_bits)
477 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
479 flags = (flags & ~clear_bits) | set_bits;
480 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
487 error("Failed to set PPP kernel option flags: %m");
491 /********************************************************************
493 * sys_init - System-dependent initialization.
498 /* Get an internet socket for doing socket ioctls. */
499 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
501 fatal("Couldn't create IP socket: %m(%d)", errno);
503 #ifdef PPP_WITH_IPV6CP
504 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
506 sock6_fd = -errno; /* save errno for later */
513 /********************************************************************
515 * sys_cleanup - restore any system state we modified before exiting:
516 * mark the interface down, delete default route and/or proxy arp entry.
517 * This shouldn't call die() because it's called from die().
520 void sys_cleanup(void)
523 * Take down the device
529 #ifdef PPP_WITH_IPV6CP
535 * Delete any routes through the device.
537 if (have_default_route)
538 cifdefaultroute(0, 0, 0);
539 #ifdef PPP_WITH_IPV6CP
540 if (have_default_route6)
541 cif6defaultroute(0, nulleui64, nulleui64);
545 cifproxyarp(0, proxy_arp_addr);
548 /********************************************************************
550 * sys_close - Clean up in a child process before execing.
555 if (new_style_driver && ppp_dev_fd >= 0)
559 #ifdef PPP_WITH_IPV6CP
569 /********************************************************************
571 * set_kdebugflag - Define the debugging level for the kernel
574 static int set_kdebugflag (int requested_level)
578 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
579 if ( ! ok_error (errno) )
580 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
586 /********************************************************************
588 * tty_establish_ppp - Turn the serial port into a ppp interface.
591 int tty_establish_ppp (int tty_fd)
596 * Ensure that the tty device is in exclusive mode.
598 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
599 if ( ! ok_error ( errno ))
600 warn("Couldn't make tty exclusive: %m");
603 * Demand mode - prime the old ppp device to relinquish the unit.
605 if (!new_style_driver && looped
606 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
607 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
611 * Set the current tty to the PPP discpline
615 #define N_SYNC_PPP 14
617 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
618 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
619 if ( ! ok_error (errno) ) {
620 error("Couldn't set tty to PPP discipline: %m");
625 ret_fd = generic_establish_ppp(tty_fd);
627 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
628 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
632 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
633 (kdebugflag * SC_DEBUG) & SC_LOGB);
635 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
636 warn("Couldn't reset tty to normal line discipline: %m");
642 /********************************************************************
644 * generic_establish_ppp - Turn the fd into a ppp interface.
646 int generic_establish_ppp (int fd)
650 if (new_style_driver) {
653 /* If a ppp_fd is already open, close it first */
660 /* Open an instance of /dev/ppp and connect the channel to it */
661 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
662 error("Couldn't get channel number: %m");
665 dbglog("using channel %d", chindex);
666 fd = open("/dev/ppp", O_RDWR);
668 error("Couldn't reopen /dev/ppp: %m");
671 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
672 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
673 error("Couldn't attach to channel %d: %m", chindex);
676 flags = fcntl(fd, F_GETFL);
677 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
678 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
683 if (!looped && !multilink) {
685 * Create a new PPP unit.
687 if (make_ppp_unit() < 0)
692 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
696 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
697 error("Couldn't attach to PPP unit %d: %m", ifunit);
704 * Old-style driver: find out which interface we were given.
707 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
708 if (ok_error (errno))
710 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
712 /* Check that we got the same unit again. */
713 if (looped && x != ifunit)
714 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
718 * Fetch the initial file flags and reset blocking mode on the file.
720 initfdflags = fcntl(fd, F_GETFL);
721 if (initfdflags == -1 ||
722 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
723 if ( ! ok_error (errno))
724 warn("Couldn't set device to non-blocking mode: %m");
729 * Enable debug in the driver if requested.
732 set_kdebugflag (kdebugflag);
744 /********************************************************************
746 * tty_disestablish_ppp - Restore the serial port to normal operation.
747 * This shouldn't call die() because it's called from die().
750 void tty_disestablish_ppp(int tty_fd)
754 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
756 if (tcflush(tty_fd, TCIOFLUSH) < 0)
758 warn("tcflush failed: %m");
762 * Restore the previous line discipline
764 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
765 if ( ! ok_error (errno))
766 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
769 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
770 if ( ! ok_error (errno))
771 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
774 /* Reset non-blocking mode on fd. */
775 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
776 if ( ! ok_error (errno))
777 warn("Couldn't restore device fd flags: %m");
783 generic_disestablish_ppp(tty_fd);
786 /********************************************************************
788 * generic_disestablish_ppp - Restore device components to normal
789 * operation, and reconnect the ppp unit to the loopback if in demand
790 * mode. This shouldn't call die() because it's called from die().
792 void generic_disestablish_ppp(int dev_fd)
794 if (new_style_driver) {
798 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
800 } else if (!doing_multilink && ppp_dev_fd >= 0) {
802 remove_fd(ppp_dev_fd);
806 /* old-style driver */
808 set_ppp_fd(slave_fd);
815 * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd
816 * with specified req_ifname via rtnetlink. Interface name req_ifname must not
817 * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free.
819 static int make_ppp_unit_rtnetlink(void)
823 struct ifinfomsg ifm;
826 char ifname[IFNAMSIZ];
832 char ifkind[sizeof("ppp")];
847 memset(&nlreq, 0, sizeof(nlreq));
848 nlreq.nlh.nlmsg_len = sizeof(nlreq);
849 nlreq.nlh.nlmsg_type = RTM_NEWLINK;
850 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
851 nlreq.ifm.ifi_family = AF_UNSPEC;
852 nlreq.ifm.ifi_type = ARPHRD_NETROM;
853 nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
854 nlreq.ifn.rta.rta_type = IFLA_IFNAME;
855 strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
856 nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
857 nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
858 nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
859 nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
860 strcpy(nlreq.ifli.ifik.ifkind, "ppp");
861 nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
862 nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
863 nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
864 nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
865 nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
867 resp = rtnetlink_msg("RTM_NEWLINK/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
870 * Linux kernel versions prior to 4.7 do not support creating ppp
871 * interfaces via rtnetlink API and therefore error response is
872 * expected. On older kernel versions do not show this error message.
873 * When error is different than EEXIST then pppd tries to fallback to
874 * the old ioctl method.
876 errno = (resp < 0) ? -resp : EINVAL;
877 if (kernel_version >= KVERSION(4,7,0))
878 error("Couldn't create ppp interface %s: %m", req_ifname);
886 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
887 * Assumes new_style_driver.
889 static int make_ppp_unit(void)
893 if (ppp_dev_fd >= 0) {
894 dbglog("in make_ppp_unit, already had /dev/ppp open?");
897 ppp_dev_fd = open("/dev/ppp", O_RDWR);
899 fatal("Couldn't open /dev/ppp: %m");
900 flags = fcntl(ppp_dev_fd, F_GETFL);
902 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
903 warn("Couldn't set /dev/ppp to nonblock: %m");
906 * Via rtnetlink it is possible to create ppp network interface with
907 * custom ifname atomically. But it is not possible to specify custom
910 * Tools like systemd, udev or NetworkManager are trying to query
911 * interface attributes based on interface name immediately when new
912 * network interface is created. And therefore immediate interface
913 * renaming is causing issues.
915 * So use rtnetlink API only when user requested custom ifname. It will
916 * avoid system issues with interface renaming.
918 if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) {
919 if (make_ppp_unit_rtnetlink()) {
920 if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit))
921 fatal("Couldn't retrieve PPP unit id: %m");
925 * If interface with requested name already exist return error
926 * otherwise fallback to old ioctl method.
933 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
934 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
935 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
937 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
939 if (x < 0 && errno == EEXIST) {
940 srand(time(NULL) * getpid());
941 ifunit = rand() % 10000;
942 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
945 error("Couldn't create new ppp unit: %m");
947 if (x == 0 && req_ifname[0] != '\0') {
950 memset(&ifr, 0, sizeof(struct ifreq));
951 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
952 strlcpy(ifr.ifr_name, t, IFNAMSIZ);
953 strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
954 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
956 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
958 info("Renamed interface %s to %s", t, req_ifname);
965 * cfg_bundle - configure the existing bundle.
966 * Used in demand mode.
968 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
970 if (!new_style_driver)
973 /* set the mrru, mtu and flags */
974 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
975 error("Couldn't set MRRU: %m");
977 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
978 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
979 | (mrru? SC_MULTILINK: 0)));
981 /* connect up the channel */
982 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
983 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
988 * make_new_bundle - create a new PPP unit (i.e. a bundle)
989 * and connect our channel to it. This should only get called
990 * if `multilink' was set at the time establish_ppp was called.
991 * In demand mode this uses our existing bundle instead of making
994 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
996 if (!new_style_driver)
999 /* make us a ppp unit */
1000 if (make_ppp_unit() < 0)
1003 /* set the mrru and flags */
1004 cfg_bundle(mrru, mtru, rssn, tssn);
1008 * bundle_attach - attach our link to a given PPP unit.
1009 * We assume the unit is controlled by another pppd.
1011 int bundle_attach(int ifnum)
1015 if (!new_style_driver)
1018 master_fd = open("/dev/ppp", O_RDWR);
1020 fatal("Couldn't open /dev/ppp: %m");
1021 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
1022 if (errno == ENXIO) {
1024 return 0; /* doesn't still exist */
1026 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
1028 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
1029 fatal("Couldn't connect to interface unit %d: %m", ifnum);
1030 modify_flags(master_fd, 0, SC_MULTILINK);
1038 * destroy_bundle - tell the driver to destroy our bundle.
1040 void destroy_bundle(void)
1042 if (ppp_dev_fd >= 0) {
1044 remove_fd(ppp_dev_fd);
1049 /********************************************************************
1051 * clean_check - Fetch the flags for the device and generate
1052 * appropriate error messages.
1054 void clean_check(void)
1060 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
1062 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
1064 s = "all had bit 7 set to 1";
1068 s = "all had bit 7 set to 0";
1072 s = "all had odd parity";
1076 s = "all had even parity";
1081 warn("Receive serial link is not 8-bit clean:");
1082 warn("Problem: %s", s);
1090 * List of valid speeds.
1094 int speed_int, speed_val;
1157 { 115200, B115200 },
1160 { 153600, B153600 },
1169 { 230400, B230400 },
1172 { 307200, B307200 },
1175 { 460800, B460800 },
1178 { 500000, B500000 },
1181 { 576000, B576000 },
1184 { 614400, B614400 },
1187 { 921600, B921600 },
1190 { 1000000, B1000000 },
1193 { 1152000, B1152000 },
1196 { 1500000, B1500000 },
1199 { 2000000, B2000000 },
1202 { 2500000, B2500000 },
1205 { 3000000, B3000000 },
1208 { 3500000, B3500000 },
1211 { 4000000, B4000000 },
1216 /********************************************************************
1218 * Translate from bits/second to a speed_t.
1221 static int translate_speed (int bps)
1223 struct speed *speedp;
1226 for (speedp = speeds; speedp->speed_int; speedp++) {
1227 if (bps == speedp->speed_int)
1228 return speedp->speed_val;
1234 /********************************************************************
1236 * Translate from a speed_t to bits/second.
1239 static int baud_rate_of (int speed)
1241 struct speed *speedp;
1244 for (speedp = speeds; speedp->speed_int; speedp++) {
1245 if (speed == speedp->speed_val)
1246 return speedp->speed_int;
1252 /********************************************************************
1254 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
1255 * at the requested speed, etc. If `local' is true, set CLOCAL
1256 * regardless of whether the modem option was specified.
1259 void set_up_tty(int tty_fd, int local)
1262 struct termios tios;
1265 if (tcgetattr(tty_fd, &tios) < 0) {
1266 if (!ok_error(errno))
1267 fatal("tcgetattr: %m (line %d)", __LINE__);
1274 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1275 tios.c_cflag |= CS8 | CREAD | HUPCL;
1277 tios.c_iflag = IGNBRK | IGNPAR;
1280 tios.c_cc[VMIN] = 1;
1281 tios.c_cc[VTIME] = 0;
1283 if (local || !modem)
1284 tios.c_cflag ^= (CLOCAL | HUPCL);
1288 tios.c_cflag |= CRTSCTS;
1292 tios.c_iflag |= IXON | IXOFF;
1293 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
1294 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1298 tios.c_cflag &= ~CRTSCTS;
1306 tios.c_cflag |= CSTOPB;
1309 speed = translate_speed(inspeed);
1311 cfsetospeed (&tios, speed);
1312 cfsetispeed (&tios, speed);
1313 speed = cfgetospeed(&tios);
1314 baud_rate = baud_rate_of(speed);
1317 tios.c_cflag &= ~CBAUD;
1318 tios.c_cflag |= BOTHER;
1319 tios.c_ospeed = inspeed;
1321 /* B0 sets input baudrate to the output baudrate */
1322 tios.c_cflag &= ~(CBAUD << IBSHIFT);
1323 tios.c_cflag |= B0 << IBSHIFT;
1324 tios.c_ispeed = inspeed;
1326 baud_rate = inspeed;
1333 speed = cfgetospeed(&tios);
1334 baud_rate = baud_rate_of(speed);
1337 baud_rate = tios.c_ospeed;
1342 * We can't proceed if the serial port baud rate is unknown,
1343 * since that implies that the serial port is disabled.
1347 fatal("speed %d not supported", inspeed);
1349 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1352 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1354 fatal("tcsetattr: %m (line %d)", __LINE__);
1358 /********************************************************************
1360 * setdtr - control the DTR line on the serial port.
1361 * This is called from die(), so it shouldn't call die().
1364 void setdtr (int tty_fd, int on)
1366 int modembits = TIOCM_DTR;
1368 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1371 /********************************************************************
1373 * restore_tty - restore the terminal to the saved settings.
1376 void restore_tty (int tty_fd)
1381 * Turn off echoing, because otherwise we can get into
1382 * a loop with the tty and the modem echoing to each other.
1383 * We presume we are the sole user of this tty device, so
1384 * when we close it, it will revert to its defaults anyway.
1386 if (!default_device)
1387 inittermios.c_lflag &= ~(ECHO | ECHONL);
1389 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1390 if (! ok_error (errno))
1391 warn("tcsetattr: %m (line %d)", __LINE__);
1396 /********************************************************************
1398 * output - Output PPP packet.
1401 void output (int unit, unsigned char *p, int len)
1406 dump_packet("sent", p, len);
1407 if (snoop_send_hook) snoop_send_hook(p, len);
1409 if (len < PPP_HDRLEN)
1411 if (new_style_driver) {
1414 proto = (p[0] << 8) + p[1];
1415 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1418 if (write(fd, p, len) < 0) {
1419 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1420 || errno == ENXIO || errno == EIO || errno == EINTR)
1421 warn("write: warning: %m (%d)", errno);
1423 error("write: %m (%d)", errno);
1427 /********************************************************************
1429 * wait_input - wait until there is data available,
1430 * for the length of time specified by *timo (indefinite
1434 void wait_input(struct timeval *timo)
1441 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1442 if (n < 0 && errno != EINTR)
1443 fatal("select: %m");
1447 * add_fd - add an fd to the set that wait_input waits for.
1451 if (fd >= FD_SETSIZE)
1452 fatal("internal error: file descriptor too large (%d)", fd);
1453 FD_SET(fd, &in_fds);
1459 * remove_fd - remove an fd from the set that wait_input waits for.
1461 void remove_fd(int fd)
1463 FD_CLR(fd, &in_fds);
1467 /********************************************************************
1469 * read_packet - get a PPP packet from the serial device.
1472 int read_packet (unsigned char *buf)
1476 len = PPP_MRU + PPP_HDRLEN;
1477 if (new_style_driver) {
1478 *buf++ = PPP_ALLSTATIONS;
1484 nr = read(ppp_fd, buf, len);
1485 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1486 && errno != EIO && errno != EINTR)
1488 if (nr < 0 && errno == ENXIO)
1491 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1492 /* N.B. we read ppp_fd first since LCP packets come in there. */
1493 nr = read(ppp_dev_fd, buf, len);
1494 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1495 && errno != EIO && errno != EINTR)
1496 error("read /dev/ppp: %m");
1497 if (nr < 0 && errno == ENXIO)
1499 if (nr == 0 && doing_multilink) {
1500 remove_fd(ppp_dev_fd);
1504 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1506 return (new_style_driver && nr > 0)? nr+2: nr;
1509 /********************************************************************
1511 * get_loop_output - get outgoing packets from the ppp device,
1512 * and detect when we want to bring the real link up.
1513 * Return value is 1 if we need to bring up the link, 0 otherwise.
1516 get_loop_output(void)
1521 if (new_style_driver) {
1522 while ((n = read_packet(inpacket_buf)) > 0)
1523 if (loop_frame(inpacket_buf, n))
1528 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1529 if (loop_chars(inbuf, n))
1533 fatal("eof on loopback");
1535 if (errno != EWOULDBLOCK && errno != EAGAIN)
1536 fatal("read from loopback: %m(%d)", errno);
1542 * netif_set_mtu - set the MTU on the PPP network interface.
1545 netif_set_mtu(int unit, int mtu)
1549 memset (&ifr, '\0', sizeof (ifr));
1550 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1553 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1554 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1558 * netif_get_mtu - get the MTU on the PPP network interface.
1561 netif_get_mtu(int unit)
1565 memset (&ifr, '\0', sizeof (ifr));
1566 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1568 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1569 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1575 /********************************************************************
1577 * tty_send_config - configure the transmit characteristics of
1578 * the ppp interface.
1581 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1588 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1589 if (errno != EIO && errno != ENOTTY)
1590 error("Couldn't set transmit async character map: %m");
1595 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1596 | (sync_serial? SC_SYNC: 0);
1597 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1600 /********************************************************************
1602 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1605 void tty_set_xaccm (ext_accm accm)
1609 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1610 if ( ! ok_error (errno))
1611 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1615 /********************************************************************
1617 * tty_recv_config - configure the receive-side characteristics of
1618 * the ppp interface.
1621 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1624 * If we were called because the link has gone down then there is nothing
1625 * which may be done. Just return without incident.
1630 * Set the receiver parameters
1632 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1633 if (errno != EIO && errno != ENOTTY)
1634 error("Couldn't set channel receive MRU: %m");
1636 if (new_style_driver && ppp_dev_fd >= 0
1637 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1638 error("Couldn't set MRU in generic PPP layer: %m");
1640 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1641 if (errno != EIO && errno != ENOTTY)
1642 error("Couldn't set channel receive asyncmap: %m");
1646 /********************************************************************
1648 * ccp_test - ask kernel whether a given compression method
1649 * is acceptable for use.
1653 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1655 struct ppp_option_data data;
1657 memset (&data, '\0', sizeof (data));
1659 data.length = opt_len;
1660 data.transmit = for_transmit;
1662 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1665 return (errno == ENOBUFS)? 0: -1;
1668 /********************************************************************
1670 * ccp_flags_set - inform kernel about the current state of CCP.
1673 void ccp_flags_set (int unit, int isopen, int isup)
1677 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1678 if (still_ppp() && ppp_dev_fd >= 0)
1679 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1682 #ifdef PPP_WITH_FILTER
1684 * set_filters - set the active and pass filters in the kernel driver.
1686 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1688 struct sock_fprog fp;
1690 fp.len = pass->bf_len;
1691 fp.filter = (struct sock_filter *) pass->bf_insns;
1692 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1693 if (errno == ENOTTY)
1694 warn("kernel does not support PPP filtering");
1696 error("Couldn't set pass-filter in kernel: %m");
1699 fp.len = active->bf_len;
1700 fp.filter = (struct sock_filter *) active->bf_insns;
1701 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1702 error("Couldn't set active-filter in kernel: %m");
1707 #endif /* PPP_WITH_FILTER */
1709 /********************************************************************
1711 * get_idle_time - return how long the link has been idle.
1714 get_idle_time(int u, struct ppp_idle *ip)
1716 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1719 /********************************************************************
1721 * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1722 * this only supports 32-bit counters, so need to count the wraps.
1725 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1727 static u_int32_t previbytes = 0;
1728 static u_int32_t prevobytes = 0;
1729 static u_int32_t iwraps = 0;
1730 static u_int32_t owraps = 0;
1733 struct ppp_stats data;
1735 memset (&req, 0, sizeof (req));
1737 req.ifr_data = (caddr_t) &data;
1738 strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
1739 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1740 error("Couldn't get PPP statistics: %m");
1743 stats->bytes_in = data.p.ppp_ibytes;
1744 stats->bytes_out = data.p.ppp_obytes;
1745 stats->pkts_in = data.p.ppp_ipackets;
1746 stats->pkts_out = data.p.ppp_opackets;
1748 if (stats->bytes_in < previbytes)
1750 if (stats->bytes_out < prevobytes)
1753 previbytes = stats->bytes_in;
1754 prevobytes = stats->bytes_out;
1756 stats->bytes_in += (uint64_t)iwraps << 32;
1757 stats->bytes_out += (uint64_t)owraps << 32;
1762 /********************************************************************
1763 * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1764 * This provides native 64-bit counters.
1767 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1772 struct nlmsghdr nlh;
1773 struct if_stats_msg ifsm;
1778 /* We only case about these first fields from rtnl_link_stats64 */
1779 uint64_t rx_packets;
1780 uint64_t tx_packets;
1788 memset(&nlreq, 0, sizeof(nlreq));
1789 nlreq.nlh.nlmsg_len = sizeof(nlreq);
1790 nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1791 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1792 nlreq.ifsm.ifindex = if_nametoindex(ifname);
1793 nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1795 nlresp_size = sizeof(nlresp_data);
1796 resp = rtnetlink_msg("RTM_GETSTATS/NLM_F_REQUEST", &fd, &nlreq, sizeof(nlreq), &nlresp_data, &nlresp_size, RTM_NEWSTATS);
1798 errno = (resp < 0) ? -resp : EINVAL;
1799 if (kernel_version >= KVERSION(4,7,0))
1800 error("get_ppp_stats_rtnetlink: %m (line %d)", __LINE__);
1804 if (nlresp_size < sizeof(nlresp_data)) {
1805 error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1809 stats->bytes_in = nlresp_data.stats.rx_bytes;
1810 stats->bytes_out = nlresp_data.stats.tx_bytes;
1811 stats->pkts_in = nlresp_data.stats.rx_packets;
1812 stats->pkts_out = nlresp_data.stats.tx_packets;
1821 /********************************************************************
1822 * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1823 * this provides native 64-bit counters.
1826 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1828 char fname[PATH_MAX+1];
1829 char buf[21], *err; /* 2^64 < 10^20 */
1831 unsigned long long val;
1838 #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1839 statfield(rx_bytes, bytes_in),
1840 statfield(tx_bytes, bytes_out),
1841 statfield(rx_packets, pkts_in),
1842 statfield(tx_packets, pkts_out),
1846 blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1847 if (blen >= sizeof(fname))
1848 return 0; /* ifname max 15, so this should be impossible */
1850 for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1851 if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1853 error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1857 fd = open(fname, O_RDONLY);
1859 error("%s: %m", fname);
1863 rlen = read(fd, buf, sizeof(buf) - 1);
1866 error("%s: %m", fname);
1869 /* trim trailing \n if present */
1870 while (rlen > 0 && buf[rlen-1] == '\n')
1875 val = strtoull(buf, &err, 10);
1876 if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1877 error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1878 buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1881 switch (slist[i].size) {
1882 #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1889 error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1897 /********************************************************************
1898 * Periodic timer function to be used to keep stats up to date in case of ioctl
1901 * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1902 * If you do change the timer, remember to also bring the get_ppp_stats (which
1903 * sets up the initial trigger) as well.
1906 ppp_stats_poller(void* u)
1908 struct pppd_stats dummy;
1909 get_ppp_stats_ioctl((long)u, &dummy);
1910 TIMEOUT(ppp_stats_poller, u, 25);
1913 /********************************************************************
1914 * get_ppp_stats - return statistics for the link.
1916 int get_ppp_stats(int u, struct pppd_stats *stats)
1918 static int (*func)(int, struct pppd_stats*) = NULL;
1921 if (get_ppp_stats_rtnetlink(u, stats)) {
1922 func = get_ppp_stats_rtnetlink;
1925 if (get_ppp_stats_sysfs(u, stats)) {
1926 func = get_ppp_stats_sysfs;
1929 warn("statistics falling back to ioctl which only supports 32-bit counters");
1930 func = get_ppp_stats_ioctl;
1931 TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1934 return func(u, stats);
1937 /********************************************************************
1939 * ccp_fatal_error - returns 1 if decompression was disabled as a
1940 * result of an error detected after decompression of a packet,
1941 * 0 otherwise. This is necessary because of patent nonsense.
1944 int ccp_fatal_error (int unit)
1948 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1949 error("Couldn't read compression error flags: %m");
1952 return flags & SC_DC_FERROR;
1955 /********************************************************************
1957 * path_to_procfs - find the path to the proc file system mount point
1959 static char proc_path[MAXPATHLEN];
1960 static int proc_path_len;
1962 static char *path_to_procfs(const char *tail)
1964 struct mntent *mntent;
1967 if (proc_path_len == 0) {
1968 /* Default the mount location of /proc */
1969 strlcpy (proc_path, "/proc", sizeof(proc_path));
1971 fp = fopen(MOUNTED, "r");
1973 while ((mntent = getmntent(fp)) != NULL) {
1974 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1976 if (strcmp(mntent->mnt_type, "proc") == 0) {
1977 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1978 proc_path_len = strlen(proc_path);
1986 strlcpy(proc_path + proc_path_len, tail,
1987 sizeof(proc_path) - proc_path_len);
1992 * /proc/net/route parsing stuff.
1994 #define ROUTE_MAX_COLS 12
1995 FILE *route_fd = (FILE *) 0;
1996 static char route_buffer[512];
1997 static int route_dev_col, route_dest_col, route_gw_col;
1998 static int route_flags_col, route_metric_col, route_mask_col;
1999 static int route_num_cols;
2001 static int open_route_table (void);
2002 static void close_route_table (void);
2003 static int read_route_table (struct rtentry *rt);
2005 /********************************************************************
2007 * close_route_table - close the interface to the route table
2010 static void close_route_table (void)
2012 if (route_fd != (FILE *) 0) {
2014 route_fd = (FILE *) 0;
2018 /********************************************************************
2020 * open_route_table - open the interface to the route table
2022 static char route_delims[] = " \t\n";
2024 static int open_route_table (void)
2028 close_route_table();
2030 path = path_to_procfs("/net/route");
2031 route_fd = fopen (path, "r");
2032 if (route_fd == NULL) {
2033 error("can't open routing table %s: %m", path);
2037 route_dev_col = 0; /* default to usual columns */
2040 route_flags_col = 3;
2041 route_metric_col = 6;
2045 /* parse header line */
2046 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
2047 char *p = route_buffer, *q;
2049 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
2051 if ((q = strtok(p, route_delims)) == 0)
2053 if (strcasecmp(q, "iface") == 0)
2054 route_dev_col = col;
2055 else if (strcasecmp(q, "destination") == 0)
2056 route_dest_col = col;
2057 else if (strcasecmp(q, "gateway") == 0)
2059 else if (strcasecmp(q, "flags") == 0)
2060 route_flags_col = col;
2061 else if (strcasecmp(q, "mask") == 0)
2062 route_mask_col = col;
2065 if (used && col >= route_num_cols)
2066 route_num_cols = col + 1;
2074 /********************************************************************
2076 * read_route_table - read the next entry from the route table
2079 static int read_route_table(struct rtentry *rt)
2081 char *cols[ROUTE_MAX_COLS], *p;
2084 memset (rt, '\0', sizeof (struct rtentry));
2086 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2090 for (col = 0; col < route_num_cols; ++col) {
2091 cols[col] = strtok(p, route_delims);
2092 if (cols[col] == NULL)
2093 return 0; /* didn't get enough columns */
2097 SET_SA_FAMILY (rt->rt_dst, AF_INET);
2098 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
2100 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
2101 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
2102 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
2104 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
2105 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
2106 rt->rt_dev = cols[route_dev_col];
2111 /********************************************************************
2113 * defaultroute_exists - determine if there is a default route
2114 * with the given metric (or negative for any)
2117 static int defaultroute_exists (struct rtentry *rt, int metric)
2121 if (!open_route_table())
2124 while (read_route_table(rt) != 0) {
2125 if ((rt->rt_flags & RTF_UP) == 0)
2128 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
2130 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
2131 || rt->rt_metric == metric)) {
2137 close_route_table();
2142 * have_route_to - determine if the system has any route to
2143 * a given IP address. `addr' is in network byte order.
2144 * Return value is 1 if yes, 0 if no, -1 if don't know.
2145 * For demand mode to work properly, we have to ignore routes
2146 * through our own interface.
2148 int have_route_to(u_int32_t addr)
2153 if (!open_route_table())
2154 return -1; /* don't know */
2156 while (read_route_table(&rt)) {
2157 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
2159 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
2165 close_route_table();
2169 /********************************************************************
2171 * sifdefaultroute - assign a default route through the address given.
2173 * If the global default_rt_repl_rest flag is set, then this function
2174 * already replaced the original system defaultroute with some other
2175 * route and it should just replace the current defaultroute with
2176 * another one, without saving the current route. Use: demand mode,
2177 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2178 * and then changes the temporary addresses to the addresses for the real
2179 * ppp connection when it has come up.
2182 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
2184 struct rtentry rt, tmp_rt;
2185 struct rtentry *del_rt = NULL;
2187 if (default_rt_repl_rest) {
2188 /* We have already replaced the original defaultroute, if we
2189 * are called again, we will delete the current default route
2190 * and set the new default route in this function.
2191 * - this is normally only the case the doing demand: */
2192 if (defaultroute_exists(&tmp_rt, -1))
2194 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
2195 strcmp( old_def_rt.rt_dev, ifname) != 0) {
2197 * We did not yet replace an existing default route, let's
2198 * check if we should save and replace a default route:
2200 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2202 if (old_gateway != gateway) {
2204 error("not replacing default route to %s [%I]",
2205 old_def_rt.rt_dev, old_gateway);
2208 /* we need to copy rt_dev because we need it permanent too: */
2209 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2210 strcpy(tmp_dev, old_def_rt.rt_dev);
2211 old_def_rt.rt_dev = tmp_dev;
2213 notice("replacing old default route to %s [%I]",
2214 old_def_rt.rt_dev, old_gateway);
2215 default_rt_repl_rest = 1;
2216 del_rt = &old_def_rt;
2221 memset (&rt, 0, sizeof (rt));
2222 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2225 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2227 if (kernel_version > KVERSION(2,1,0)) {
2228 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2229 SIN_ADDR(rt.rt_genmask) = 0L;
2232 rt.rt_flags = RTF_UP;
2233 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2234 if ( ! ok_error ( errno ))
2235 error("default route ioctl(SIOCADDRT): %m");
2238 if (default_rt_repl_rest && del_rt)
2239 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2240 if ( ! ok_error ( errno ))
2241 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2245 have_default_route = 1;
2249 /********************************************************************
2251 * cifdefaultroute - delete a default route through the address given.
2254 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2258 have_default_route = 0;
2260 memset (&rt, '\0', sizeof (rt));
2261 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2262 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2267 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2269 if (kernel_version > KVERSION(2,1,0)) {
2270 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2271 SIN_ADDR(rt.rt_genmask) = 0L;
2274 rt.rt_flags = RTF_UP;
2275 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2277 if ( ! ok_error ( errno ))
2278 error("default route ioctl(SIOCDELRT): %m");
2282 if (default_rt_repl_rest) {
2283 notice("restoring old default route to %s [%I]",
2284 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2285 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2286 if ( ! ok_error ( errno ))
2287 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2290 default_rt_repl_rest = 0;
2296 #ifdef PPP_WITH_IPV6CP
2298 * /proc/net/ipv6_route parsing stuff.
2300 static int route_dest_plen_col;
2301 static int open_route6_table (void);
2302 static int read_route6_table (struct in6_rtmsg *rt);
2304 /********************************************************************
2306 * open_route6_table - open the interface to the route table
2308 static int open_route6_table (void)
2312 close_route_table();
2314 path = path_to_procfs("/net/ipv6_route");
2315 route_fd = fopen (path, "r");
2316 if (route_fd == NULL) {
2317 error("can't open routing table %s: %m", path);
2321 /* default to usual columns */
2323 route_dest_plen_col = 1;
2325 route_metric_col = 5;
2326 route_flags_col = 8;
2328 route_num_cols = 10;
2333 /********************************************************************
2335 * read_route6_table - read the next entry from the route table
2338 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2345 for (i = 0; i < 4; i++) {
2346 memcpy(hex8, s + 8*i, 8);
2347 v = strtoul(hex8, NULL, 16);
2348 addr->s6_addr32[i] = v;
2352 static int read_route6_table(struct in6_rtmsg *rt)
2354 char *cols[ROUTE_MAX_COLS], *p;
2357 memset (rt, '\0', sizeof (struct in6_rtmsg));
2359 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2363 for (col = 0; col < route_num_cols; ++col) {
2364 cols[col] = strtok(p, route_delims);
2365 if (cols[col] == NULL)
2366 return 0; /* didn't get enough columns */
2370 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2371 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2372 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2374 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2375 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2376 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2381 /********************************************************************
2383 * defaultroute6_exists - determine if there is a default route
2386 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2390 if (!open_route6_table())
2393 while (read_route6_table(rt) != 0) {
2394 if ((rt->rtmsg_flags & RTF_UP) == 0)
2397 if (rt->rtmsg_dst_len != 0)
2399 if (rt->rtmsg_dst.s6_addr32[0] == 0L
2400 && rt->rtmsg_dst.s6_addr32[1] == 0L
2401 && rt->rtmsg_dst.s6_addr32[2] == 0L
2402 && rt->rtmsg_dst.s6_addr32[3] == 0L
2403 && (metric < 0 || rt->rtmsg_metric == metric)) {
2409 close_route_table();
2413 /********************************************************************
2415 * sif6defaultroute - assign a default route through the address given.
2417 * If the global default_rt_repl_rest flag is set, then this function
2418 * already replaced the original system defaultroute with some other
2419 * route and it should just replace the current defaultroute with
2420 * another one, without saving the current route. Use: demand mode,
2421 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2422 * and then changes the temporary addresses to the addresses for the real
2423 * ppp connection when it has come up.
2426 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2428 struct in6_rtmsg rt;
2429 char buf[IF_NAMESIZE];
2431 if (defaultroute6_exists(&rt, dfl_route_metric) &&
2432 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2433 if (rt.rtmsg_flags & RTF_GATEWAY)
2434 error("not replacing existing default route via gateway");
2436 error("not replacing existing default route through %s",
2437 if_indextoname(rt.rtmsg_ifindex, buf));
2441 memset (&rt, 0, sizeof (rt));
2443 rt.rtmsg_ifindex = if_nametoindex(ifname);
2444 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2445 rt.rtmsg_dst_len = 0;
2447 rt.rtmsg_flags = RTF_UP;
2448 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2449 if ( ! ok_error ( errno ))
2450 error("default route ioctl(SIOCADDRT): %m");
2454 have_default_route6 = 1;
2458 /********************************************************************
2460 * cif6defaultroute - delete a default route through the address given.
2463 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2465 struct in6_rtmsg rt;
2467 have_default_route6 = 0;
2469 memset (&rt, '\0', sizeof (rt));
2471 rt.rtmsg_ifindex = if_nametoindex(ifname);
2472 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2473 rt.rtmsg_dst_len = 0;
2475 rt.rtmsg_flags = RTF_UP;
2476 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2478 if ( ! ok_error ( errno ))
2479 error("default route ioctl(SIOCDELRT): %m");
2486 #endif /* PPP_WITH_IPV6CP */
2488 /********************************************************************
2490 * sifproxyarp - Make a proxy ARP entry for the peer.
2493 int sifproxyarp (int unit, u_int32_t his_adr)
2495 struct arpreq arpreq;
2498 if (has_proxy_arp == 0) {
2499 memset (&arpreq, '\0', sizeof(arpreq));
2501 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2502 SIN_ADDR(arpreq.arp_pa) = his_adr;
2503 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2505 * Get the hardware address of an interface on the same subnet
2506 * as our local address.
2508 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2509 sizeof(proxy_arp_dev))) {
2510 error("Cannot determine ethernet address for proxy ARP");
2513 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2515 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2516 if ( ! ok_error ( errno ))
2517 error("ioctl(SIOCSARP): %m");
2520 proxy_arp_addr = his_adr;
2524 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2525 if (forw_path != 0) {
2526 int fd = open(forw_path, O_WRONLY);
2528 if (write(fd, "1", 1) != 1)
2529 error("Couldn't enable IP forwarding: %m");
2539 /********************************************************************
2541 * cifproxyarp - Delete the proxy ARP entry for the peer.
2544 int cifproxyarp (int unit, u_int32_t his_adr)
2546 struct arpreq arpreq;
2548 if (has_proxy_arp) {
2550 memset (&arpreq, '\0', sizeof(arpreq));
2551 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2552 SIN_ADDR(arpreq.arp_pa) = his_adr;
2553 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2554 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2556 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2557 if ( ! ok_error ( errno ))
2558 warn("ioctl(SIOCDARP): %m");
2565 /********************************************************************
2567 * get_ether_addr - get the hardware address of an interface on the
2568 * the same subnet as ipaddr.
2571 static int get_ether_addr (u_int32_t ipaddr,
2572 struct sockaddr *hwaddr,
2573 char *name, int namelen)
2575 struct ifreq *ifr, *ifend;
2576 u_int32_t ina, mask;
2578 struct ifreq ifreq, bestifreq;
2580 struct ifreq ifs[MAX_IFS];
2582 u_int32_t bestmask=0;
2583 int found_interface = 0;
2585 ifc.ifc_len = sizeof(ifs);
2587 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2588 if ( ! ok_error ( errno ))
2589 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2594 * Scan through looking for an interface with an Internet
2595 * address on the same subnet as `ipaddr'.
2597 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2598 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2599 if (ifr->ifr_addr.sa_family == AF_INET) {
2600 ina = SIN_ADDR(ifr->ifr_addr);
2601 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2603 * Check that the interface is up, and not point-to-point
2606 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2609 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2612 * Get its netmask and check that it's on the right subnet.
2614 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2617 mask = SIN_ADDR(ifreq.ifr_addr);
2619 if (((ipaddr ^ ina) & mask) != 0)
2620 continue; /* no match */
2622 if (mask >= bestmask) {
2623 /* Compare using >= instead of > -- it is possible for
2624 an interface to have a netmask of 0.0.0.0 */
2625 found_interface = 1;
2632 if (!found_interface) return 0;
2634 strlcpy(name, bestifreq.ifr_name, namelen);
2636 /* trim off the :1 in eth0:1 */
2637 aliasp = strchr(name, ':');
2641 info("found interface %s for proxy arp", name);
2643 * Now get the hardware address.
2645 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2646 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2647 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2652 &bestifreq.ifr_hwaddr,
2653 sizeof (struct sockaddr));
2659 * get_if_hwaddr - get the hardware address for the specified
2660 * network interface device.
2663 get_if_hwaddr(u_char *addr, char *name)
2668 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2671 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2672 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2673 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2676 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2681 * get_first_ether_hwaddr - get the hardware address for the first
2682 * ethernet-style interface on this system.
2685 get_first_ether_hwaddr(u_char *addr)
2687 struct if_nameindex *if_ni, *i;
2691 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2695 if_ni = if_nameindex();
2703 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2704 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2705 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2706 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2707 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2708 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2714 if_freenameindex(if_ni);
2720 /********************************************************************
2722 * Return user specified netmask, modified by any mask we might determine
2723 * for address `addr' (in network byte order).
2724 * Here we scan through the system's list of interfaces, looking for
2725 * any non-point-to-point interfaces which might appear to be on the same
2726 * network as `addr'. If we find any, we OR in their netmask to the
2727 * user-specified netmask.
2730 u_int32_t GetMask (u_int32_t addr)
2732 u_int32_t mask, nmask, ina;
2733 struct ifreq *ifr, *ifend, ifreq;
2735 struct ifreq ifs[MAX_IFS];
2739 if (IN_CLASSA(addr)) /* determine network mask for address class */
2740 nmask = IN_CLASSA_NET;
2741 else if (IN_CLASSB(addr))
2742 nmask = IN_CLASSB_NET;
2744 nmask = IN_CLASSC_NET;
2746 /* class D nets are disallowed by bad_ip_adrs */
2747 mask = netmask | htonl(nmask);
2749 * Scan through the system's network interfaces.
2751 ifc.ifc_len = sizeof(ifs);
2753 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2754 if ( ! ok_error ( errno ))
2755 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2759 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2760 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2762 * Check the interface's internet address.
2764 if (ifr->ifr_addr.sa_family != AF_INET)
2766 ina = SIN_ADDR(ifr->ifr_addr);
2767 if (((ntohl(ina) ^ addr) & nmask) != 0)
2770 * Check that the interface is up, and not point-to-point nor loopback.
2772 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2773 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2776 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2779 * Get its netmask and OR it into our mask.
2781 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2783 mask |= SIN_ADDR(ifreq.ifr_addr);
2789 /********************************************************************
2791 * Internal routine to decode the version.modification.patch level
2794 static void decode_version (char *buf, int *version,
2795 int *modification, int *patch)
2799 *version = (int) strtoul (buf, &endp, 10);
2803 if (endp != buf && *endp == '.') {
2805 *modification = (int) strtoul (buf, &endp, 10);
2806 if (endp != buf && *endp == '.') {
2808 *patch = (int) strtoul (buf, &buf, 10);
2813 /********************************************************************
2815 * Procedure to determine if the PPP line discipline is registered.
2819 ppp_registered(void)
2827 * We used to open the serial device and set it to the ppp line
2828 * discipline here, in order to create a ppp unit. But that is
2829 * not a good idea - the user might have specified a device that
2830 * they can't open (permission, or maybe it doesn't really exist).
2831 * So we grab a pty master/slave pair and use that.
2833 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2834 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2839 * Try to put the device into the PPP discipline.
2841 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2842 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2851 /********************************************************************
2853 * ppp_available - check whether the system has any ppp interfaces
2854 * (in fact we check whether we can do an ioctl on ppp0).
2857 int ppp_available(void)
2862 int my_version, my_modification, my_patch;
2863 int osmaj, osmin, ospatch;
2865 /* get the kernel version now, since we are called before sys_init */
2867 osmaj = osmin = ospatch = 0;
2868 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2869 kernel_version = KVERSION(osmaj, osmin, ospatch);
2871 fd = open("/dev/ppp", O_RDWR);
2873 new_style_driver = 1;
2875 /* XXX should get from driver */
2877 driver_modification = 4;
2883 if (kernel_version >= KVERSION(2,3,13)) {
2884 error("Couldn't open the /dev/ppp device: %m");
2885 if (errno == ENOENT)
2887 "You need to create the /dev/ppp device node by\n"
2888 "executing the following command as root:\n"
2889 " mknod /dev/ppp c 108 0\n";
2890 else if (errno == ENODEV || errno == ENXIO)
2892 "Please load the ppp_generic kernel module.\n";
2896 /* we are running on a really really old kernel */
2898 "This system lacks kernel support for PPP. This could be because\n"
2899 "the PPP kernel module could not be loaded, or because PPP was not\n"
2900 "included in the kernel configuration. If PPP was included as a\n"
2901 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2902 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2903 "See README.linux file in the ppp distribution for more details.\n";
2906 * Open a socket for doing the ioctl operations.
2908 s = socket(AF_INET, SOCK_DGRAM, 0);
2912 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2913 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2915 * If the device did not exist then attempt to create one by putting the
2916 * current tty into the PPP discipline. If this works then obtain the
2917 * flags for the device again.
2920 if (ppp_registered()) {
2921 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2922 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2926 * Ensure that the hardware address is for PPP and not something else
2929 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2931 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2935 * This is the PPP device. Validate the version of the driver at this
2936 * point to ensure that this program will work with the driver.
2939 char abBuffer [1024];
2941 ifr.ifr_data = abBuffer;
2942 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2944 error("Couldn't read driver version: %m");
2946 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2949 decode_version(abBuffer,
2951 &driver_modification,
2954 * Validate the version of the driver against the version that we used.
2956 decode_version(VERSION,
2961 /* The version numbers must match */
2962 if (driver_version != my_version)
2965 /* The modification levels must be legal */
2966 if (driver_modification < 3) {
2967 if (driver_modification >= 2) {
2968 /* we can cope with 2.2.0 and above */
2976 slprintf(route_buffer, sizeof(route_buffer),
2977 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2978 driver_version, driver_modification, driver_patch);
2980 no_ppp_msg = route_buffer;
2988 #ifndef HAVE_LOGWTMP
2989 /********************************************************************
2991 * Update the wtmp file with the appropriate user name and tty device.
2994 void logwtmp (const char *line, const char *name, const char *host)
2996 struct utmp ut, *utp;
2997 pid_t mypid = getpid();
3003 * Update the signon database for users.
3004 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
3006 utmpname(_PATH_UTMP);
3008 while ((utp = getutent()) && (utp->ut_pid != mypid))
3012 memcpy(&ut, utp, sizeof(ut));
3014 /* some gettys/telnetds don't initialize utmp... */
3015 memset(&ut, 0, sizeof(ut));
3017 if (ut.ut_id[0] == 0)
3018 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
3020 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
3021 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
3025 ut.ut_type = USER_PROCESS;
3028 /* Insert the host name if one is supplied */
3030 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
3032 /* Insert the IP address of the remote system if IP is enabled */
3033 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
3034 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
3035 sizeof(ut.ut_addr));
3037 /* CL: Makes sure that the logout works */
3038 if (*host == 0 && *name==0)
3044 * Update the wtmp file.
3047 updwtmp(_PATH_WTMP, &ut);
3049 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
3051 flock(wtmp, LOCK_EX);
3053 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
3054 warn("error writing %s: %m", _PATH_WTMP);
3056 flock(wtmp, LOCK_UN);
3062 #endif /* HAVE_LOGWTMP */
3064 /********************************************************************
3066 * sifvjcomp - config tcp header compression
3069 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
3074 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
3075 error("Couldn't set up TCP header compression: %m");
3080 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
3081 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
3086 /********************************************************************
3088 * sifup - Config the interface up and enable IP packets to pass.
3095 if ((ret = setifstate(u, 1)))
3101 /********************************************************************
3103 * sifdown - Disable the indicated protocol and config the interface
3104 * down if there are no remaining protocols.
3109 if (if_is_up && --if_is_up > 0)
3112 #ifdef PPP_WITH_IPV6CP
3115 #endif /* PPP_WITH_IPV6CP */
3117 return setifstate(u, 0);
3120 #ifdef PPP_WITH_IPV6CP
3121 /********************************************************************
3123 * sif6up - Config the interface up for IPv6
3130 if ((ret = setifstate(u, 1)))
3136 /********************************************************************
3138 * sif6down - Disable the IPv6CP protocol and config the interface
3139 * down if there are no remaining protocols.
3142 int sif6down (int u)
3149 return setifstate(u, 0);
3151 #endif /* PPP_WITH_IPV6CP */
3153 /********************************************************************
3155 * setifstate - Config the interface up or down
3158 static int setifstate (int u, int state)
3162 memset (&ifr, '\0', sizeof (ifr));
3163 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3164 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
3165 if (! ok_error (errno))
3166 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
3171 ifr.ifr_flags |= IFF_UP;
3173 ifr.ifr_flags &= ~IFF_UP;
3174 ifr.ifr_flags |= IFF_POINTOPOINT;
3175 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
3176 if (! ok_error (errno))
3177 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
3183 /********************************************************************
3185 * sifaddr - Config the interface IP addresses and netmask.
3188 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3194 memset (&ifr, '\0', sizeof (ifr));
3195 memset (&rt, '\0', sizeof (rt));
3197 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
3198 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3199 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3201 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3203 * Set our IP address
3205 SIN_ADDR(ifr.ifr_addr) = our_adr;
3206 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3207 if (errno != EEXIST) {
3208 if (! ok_error (errno))
3209 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3212 warn("ioctl(SIOCSIFADDR): Address already exists");
3217 * Set the gateway address
3220 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3221 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3222 if (! ok_error (errno))
3223 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3229 * For recent kernels, force the netmask to 255.255.255.255.
3231 if (kernel_version >= KVERSION(2,1,16))
3233 if (net_mask != 0) {
3234 SIN_ADDR(ifr.ifr_netmask) = net_mask;
3235 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3236 if (! ok_error (errno))
3237 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3242 * Add the device route
3244 if (kernel_version < KVERSION(2,1,16)) {
3245 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3246 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3249 SIN_ADDR(rt.rt_gateway) = 0L;
3250 SIN_ADDR(rt.rt_dst) = his_adr;
3251 rt.rt_flags = RTF_UP | RTF_HOST;
3253 if (kernel_version > KVERSION(2,1,0)) {
3254 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3255 SIN_ADDR(rt.rt_genmask) = -1L;
3258 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3259 if (! ok_error (errno))
3260 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3265 /* set ip_dynaddr in demand mode if address changes */
3266 if (demand && tune_kernel && !dynaddr_set
3267 && our_old_addr && our_old_addr != our_adr) {
3268 /* set ip_dynaddr if possible */
3272 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3273 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3274 if (write(fd, "1", 1) != 1)
3275 error("Couldn't enable dynamic IP addressing: %m");
3278 dynaddr_set = 1; /* only 1 attempt */
3285 /********************************************************************
3287 * cifaddr - Clear the interface IP addresses, and delete routes
3288 * through the interface if possible.
3291 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3295 if (kernel_version < KVERSION(2,1,16)) {
3297 * Delete the route through the device
3300 memset (&rt, '\0', sizeof (rt));
3302 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3303 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3306 SIN_ADDR(rt.rt_gateway) = 0;
3307 SIN_ADDR(rt.rt_dst) = his_adr;
3308 rt.rt_flags = RTF_UP | RTF_HOST;
3310 if (kernel_version > KVERSION(2,1,0)) {
3311 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3312 SIN_ADDR(rt.rt_genmask) = -1L;
3315 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3316 if (still_ppp() && ! ok_error (errno))
3317 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3322 /* This way it is possible to have an IPv6-only interface */
3323 memset(&ifr, 0, sizeof(ifr));
3324 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3325 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3327 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3328 if (! ok_error (errno)) {
3329 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3334 our_old_addr = our_adr;
3339 #ifdef PPP_WITH_IPV6CP
3340 /********************************************************************
3342 * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3344 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3347 struct nlmsghdr nlh;
3348 struct ifaddrmsg ifa;
3351 struct in6_addr addr;
3356 memset(&nlreq, 0, sizeof(nlreq));
3357 nlreq.nlh.nlmsg_len = sizeof(nlreq);
3358 nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3359 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3360 nlreq.ifa.ifa_family = AF_INET6;
3361 nlreq.ifa.ifa_prefixlen = 128;
3362 nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3363 nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3364 nlreq.ifa.ifa_index = iface;
3365 nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3366 nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3367 IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3368 nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3369 nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3372 * To set only local address, older kernel expects that local address is
3373 * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3374 * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3375 * compatibility when setting only local address, set it via both IFA_LOCAL
3376 * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3377 * from iproute2 project.
3379 if (!eui64_iszero(his_eui64))
3380 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3382 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3384 resp = rtnetlink_msg("RTM_NEWADDR/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
3387 * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3388 * addresses and error response is expected. On older kernel versions
3389 * do not show this error message. On error pppd tries to fallback to
3390 * the old IOCTL method.
3392 errno = (resp < 0) ? -resp : EINVAL;
3393 if (kernel_version >= KVERSION(3,11,0))
3394 error("sif6addr_rtnetlink: %m (line %d)", __LINE__);
3401 /********************************************************************
3403 * sif6addr - Config the interface with an IPv6 link-local address
3405 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3407 struct in6_ifreq ifr6;
3409 struct in6_rtmsg rt6;
3414 error("IPv6 socket creation failed: %m");
3417 memset(&ifr, 0, sizeof (ifr));
3418 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3419 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3420 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3424 if (kernel_version >= KVERSION(2,1,16)) {
3425 /* Set both local address and remote peer address (with route for it) via rtnetlink */
3426 ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3432 * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3433 * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3436 /* Local interface */
3437 memset(&ifr6, 0, sizeof(ifr6));
3438 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3439 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3440 ifr6.ifr6_prefixlen = 128;
3442 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3443 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3448 if (!ret && !eui64_iszero(his_eui64)) {
3450 * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3451 * setting remote peer host address, so set only route to remote host.
3454 /* Route to remote host */
3455 memset(&rt6, 0, sizeof(rt6));
3456 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3457 rt6.rtmsg_flags = RTF_UP;
3458 rt6.rtmsg_dst_len = 128;
3459 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3460 rt6.rtmsg_metric = 1;
3462 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3463 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3472 /********************************************************************
3474 * cif6addr - Remove IPv6 address from interface
3476 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3479 struct in6_ifreq ifr6;
3483 error("IPv6 socket creation failed: %m");
3486 memset(&ifr, 0, sizeof(ifr));
3487 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3488 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3489 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3493 memset(&ifr6, 0, sizeof(ifr6));
3494 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3495 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3496 ifr6.ifr6_prefixlen = 128;
3498 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3499 if (errno != EADDRNOTAVAIL) {
3500 if (! ok_error (errno))
3501 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3504 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3510 #endif /* PPP_WITH_IPV6CP */
3513 * get_pty - get a pty master/slave pair and chown the slave side
3514 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
3517 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3519 int i, mfd, ret, sfd = -1;
3521 struct termios tios;
3525 * Try the unix98 way first.
3527 mfd = open("/dev/ptmx", O_RDWR);
3530 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3531 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3532 chmod(pty_name, S_IRUSR | S_IWUSR);
3535 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3536 warn("Couldn't unlock pty slave %s: %m", pty_name);
3538 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3540 warn("Couldn't open pty slave %s: %m", pty_name);
3545 #endif /* TIOCGPTN */
3548 /* the old way - scan through the pty name space */
3549 for (i = 0; i < 64; ++i) {
3550 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3551 'p' + i / 16, i % 16);
3552 mfd = open(pty_name, O_RDWR, 0);
3555 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3557 ret = fchown(sfd, uid, -1);
3559 warn("Couldn't change ownership of %s, %m", pty_name);
3561 ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3563 warn("Couldn't change permissions of %s, %m", pty_name);
3575 strlcpy(slave_name, pty_name, 16);
3578 if (tcgetattr(sfd, &tios) == 0) {
3579 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3580 tios.c_cflag |= CS8 | CREAD | CLOCAL;
3581 tios.c_iflag = IGNPAR;
3584 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3585 warn("couldn't set attributes on pty: %m");
3587 warn("couldn't get attributes on pty: %m");
3592 /********************************************************************
3594 * open_loopback - open the device we use for getting packets
3595 * in demand mode. Under Linux, we use a pty master/slave pair.
3598 open_ppp_loopback(void)
3603 if (new_style_driver) {
3604 /* allocate ourselves a ppp unit */
3605 if (make_ppp_unit() < 0)
3607 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3608 set_kdebugflag(kdebugflag);
3613 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3614 fatal("No free pty for loopback");
3616 set_ppp_fd(slave_fd);
3618 flags = fcntl(master_fd, F_GETFL);
3620 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3621 warn("couldn't set master loopback to nonblock: %m");
3623 flags = fcntl(ppp_fd, F_GETFL);
3625 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3626 warn("couldn't set slave loopback to nonblock: %m");
3628 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3629 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3631 * Find out which interface we were given.
3633 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3634 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3636 * Enable debug in the driver if requested.
3638 set_kdebugflag (kdebugflag);
3643 /********************************************************************
3645 * sifnpmode - Set the mode for handling packets for a given NP.
3649 sifnpmode(int u, int proto, enum NPmode mode)
3653 npi.protocol = proto;
3655 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3656 if (! ok_error (errno))
3657 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3664 * Use the hostname as part of the random number seed.
3673 for (p = hostname; *p != 0; ++p)
3678 /********************************************************************
3680 * sys_check_options - check the options that the user specified
3684 sys_check_options(void)
3686 if (demand && driver_is_old) {
3687 option_error("demand dialling is not supported by kernel driver "
3688 "version %d.%d.%d", driver_version, driver_modification,
3692 if (multilink && !new_style_driver) {
3693 warn("Warning: multilink is not supported by the kernel driver");
3699 /********************************************************************
3701 * get_time - Get current time, monotonic if possible.
3704 get_time(struct timeval *tv)
3706 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3707 * Runtime checking makes it safe. */
3708 #ifndef CLOCK_MONOTONIC
3709 #define CLOCK_MONOTONIC 1
3711 static int monotonic = -1;
3716 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3720 tv->tv_sec = ts.tv_sec;
3721 tv->tv_usec = ts.tv_nsec / 1000;
3724 } else if (monotonic > 0)
3728 warn("Couldn't use monotonic clock source: %m");
3731 return gettimeofday(tv, NULL);