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 * send_rtnetlink_msg - send rtnetlink message and return received error code:
305 * positive value - error during sending / receiving message
306 * negative value - rtnetlink responce error code
308 static int send_rtnetlink_msg(const char *desc, void *nlreq, size_t nlreq_len)
312 struct nlmsgerr nlerr;
314 struct sockaddr_nl nladdr;
321 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
323 error("send_rtnetlink_msg: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
328 * Tell kernel to not send to us payload of acknowledgment error message.
329 * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
330 * older kernel versions always send full payload in acknowledgment netlink
331 * message. We ignore payload of this message as we need only error code,
332 * to check if our set remote peer address request succeeded or failed.
333 * So ignore return value from the following setsockopt() call as setting
334 * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
337 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
339 memset(&nladdr, 0, sizeof(nladdr));
340 nladdr.nl_family = AF_NETLINK;
342 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
343 error("send_rtnetlink_msg: bind(AF_NETLINK): %m (line %d)", __LINE__);
348 memset(&nladdr, 0, sizeof(nladdr));
349 nladdr.nl_family = AF_NETLINK;
351 memset(&iov, 0, sizeof(iov));
352 iov.iov_base = nlreq;
353 iov.iov_len = nlreq_len;
355 memset(&msg, 0, sizeof(msg));
356 msg.msg_name = &nladdr;
357 msg.msg_namelen = sizeof(nladdr);
361 if (sendmsg(fd, &msg, 0) < 0) {
362 error("send_rtnetlink_msg: sendmsg(%s): %m (line %d)", desc, __LINE__);
367 memset(&iov, 0, sizeof(iov));
368 iov.iov_base = &nlresp;
369 iov.iov_len = sizeof(nlresp);
371 memset(&msg, 0, sizeof(msg));
372 msg.msg_name = &nladdr;
373 msg.msg_namelen = sizeof(nladdr);
377 nlresp_len = recvmsg(fd, &msg, 0);
379 if (nlresp_len < 0) {
380 error("send_rtnetlink_msg: recvmsg(%s): %m (line %d)", desc, __LINE__);
387 if (nladdr.nl_family != AF_NETLINK) {
388 error("send_rtnetlink_msg: recvmsg(%s): Not a netlink packet (line %d)", desc, __LINE__);
392 if ((size_t)nlresp_len < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
393 error("send_rtnetlink_msg: recvmsg(%s): Acknowledgment netlink packet too short (line %d)", desc, __LINE__);
397 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
398 if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
399 error("send_rtnetlink_msg: recvmsg(%s): Not an acknowledgment netlink packet (line %d)", desc, __LINE__);
403 /* error == 0 indicates success, negative value is errno code */
404 return nlresp.nlerr.error;
408 * Determine if the PPP connection should still be present.
413 /* new_fd is the fd of a tty */
414 static void set_ppp_fd (int new_fd)
417 if (!new_style_driver)
421 static int still_ppp(void)
423 if (new_style_driver)
424 return !hungup && ppp_fd >= 0;
425 if (!hungup || ppp_fd == slave_fd)
428 set_ppp_fd(slave_fd);
435 * modify_flags - set and clear flag bits controlling the kernel
438 static int modify_flags(int fd, int clear_bits, int set_bits)
442 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
444 flags = (flags & ~clear_bits) | set_bits;
445 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
452 error("Failed to set PPP kernel option flags: %m");
456 /********************************************************************
458 * sys_init - System-dependent initialization.
463 /* Get an internet socket for doing socket ioctls. */
464 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
466 fatal("Couldn't create IP socket: %m(%d)", errno);
468 #ifdef PPP_WITH_IPV6CP
469 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
471 sock6_fd = -errno; /* save errno for later */
478 /********************************************************************
480 * sys_cleanup - restore any system state we modified before exiting:
481 * mark the interface down, delete default route and/or proxy arp entry.
482 * This shouldn't call die() because it's called from die().
485 void sys_cleanup(void)
488 * Take down the device
494 #ifdef PPP_WITH_IPV6CP
500 * Delete any routes through the device.
502 if (have_default_route)
503 cifdefaultroute(0, 0, 0);
504 #ifdef PPP_WITH_IPV6CP
505 if (have_default_route6)
506 cif6defaultroute(0, nulleui64, nulleui64);
510 cifproxyarp(0, proxy_arp_addr);
513 /********************************************************************
515 * sys_close - Clean up in a child process before execing.
520 if (new_style_driver && ppp_dev_fd >= 0)
524 #ifdef PPP_WITH_IPV6CP
534 /********************************************************************
536 * set_kdebugflag - Define the debugging level for the kernel
539 static int set_kdebugflag (int requested_level)
543 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
544 if ( ! ok_error (errno) )
545 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
551 /********************************************************************
553 * tty_establish_ppp - Turn the serial port into a ppp interface.
556 int tty_establish_ppp (int tty_fd)
561 * Ensure that the tty device is in exclusive mode.
563 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
564 if ( ! ok_error ( errno ))
565 warn("Couldn't make tty exclusive: %m");
568 * Demand mode - prime the old ppp device to relinquish the unit.
570 if (!new_style_driver && looped
571 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
572 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
576 * Set the current tty to the PPP discpline
580 #define N_SYNC_PPP 14
582 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
583 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
584 if ( ! ok_error (errno) ) {
585 error("Couldn't set tty to PPP discipline: %m");
590 ret_fd = generic_establish_ppp(tty_fd);
592 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
593 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
597 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
598 (kdebugflag * SC_DEBUG) & SC_LOGB);
600 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
601 warn("Couldn't reset tty to normal line discipline: %m");
607 /********************************************************************
609 * generic_establish_ppp - Turn the fd into a ppp interface.
611 int generic_establish_ppp (int fd)
615 if (new_style_driver) {
618 /* If a ppp_fd is already open, close it first */
625 /* Open an instance of /dev/ppp and connect the channel to it */
626 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
627 error("Couldn't get channel number: %m");
630 dbglog("using channel %d", chindex);
631 fd = open("/dev/ppp", O_RDWR);
633 error("Couldn't reopen /dev/ppp: %m");
636 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
637 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
638 error("Couldn't attach to channel %d: %m", chindex);
641 flags = fcntl(fd, F_GETFL);
642 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
643 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
648 if (!looped && !multilink) {
650 * Create a new PPP unit.
652 if (make_ppp_unit() < 0)
657 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
661 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
662 error("Couldn't attach to PPP unit %d: %m", ifunit);
669 * Old-style driver: find out which interface we were given.
672 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
673 if (ok_error (errno))
675 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
677 /* Check that we got the same unit again. */
678 if (looped && x != ifunit)
679 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
683 * Fetch the initial file flags and reset blocking mode on the file.
685 initfdflags = fcntl(fd, F_GETFL);
686 if (initfdflags == -1 ||
687 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
688 if ( ! ok_error (errno))
689 warn("Couldn't set device to non-blocking mode: %m");
694 * Enable debug in the driver if requested.
697 set_kdebugflag (kdebugflag);
709 /********************************************************************
711 * tty_disestablish_ppp - Restore the serial port to normal operation.
712 * This shouldn't call die() because it's called from die().
715 void tty_disestablish_ppp(int tty_fd)
719 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
721 if (tcflush(tty_fd, TCIOFLUSH) < 0)
723 warn("tcflush failed: %m");
727 * Restore the previous line discipline
729 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
730 if ( ! ok_error (errno))
731 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
734 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
735 if ( ! ok_error (errno))
736 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
739 /* Reset non-blocking mode on fd. */
740 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
741 if ( ! ok_error (errno))
742 warn("Couldn't restore device fd flags: %m");
748 generic_disestablish_ppp(tty_fd);
751 /********************************************************************
753 * generic_disestablish_ppp - Restore device components to normal
754 * operation, and reconnect the ppp unit to the loopback if in demand
755 * mode. This shouldn't call die() because it's called from die().
757 void generic_disestablish_ppp(int dev_fd)
759 if (new_style_driver) {
763 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
765 } else if (!doing_multilink && ppp_dev_fd >= 0) {
767 remove_fd(ppp_dev_fd);
771 /* old-style driver */
773 set_ppp_fd(slave_fd);
780 * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd
781 * with specified req_ifname via rtnetlink. Interface name req_ifname must not
782 * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free.
784 static int make_ppp_unit_rtnetlink(void)
788 struct ifinfomsg ifm;
791 char ifname[IFNAMSIZ];
797 char ifkind[sizeof("ppp")];
812 memset(&nlreq, 0, sizeof(nlreq));
813 nlreq.nlh.nlmsg_len = sizeof(nlreq);
814 nlreq.nlh.nlmsg_type = RTM_NEWLINK;
815 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
816 nlreq.ifm.ifi_family = AF_UNSPEC;
817 nlreq.ifm.ifi_type = ARPHRD_NETROM;
818 nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
819 nlreq.ifn.rta.rta_type = IFLA_IFNAME;
820 strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
821 nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
822 nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
823 nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
824 nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
825 strcpy(nlreq.ifli.ifik.ifkind, "ppp");
826 nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
827 nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
828 nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
829 nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
830 nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
832 resp = send_rtnetlink_msg("RTM_NEWLINK/NLM_F_CREATE", &nlreq, sizeof(nlreq));
835 * Linux kernel versions prior to 4.7 do not support creating ppp
836 * interfaces via rtnetlink API and therefore error response is
837 * expected. On older kernel versions do not show this error message.
838 * When error is different than EEXIST then pppd tries to fallback to
839 * the old ioctl method.
841 errno = (resp < 0) ? -resp : EINVAL;
842 if (kernel_version >= KVERSION(4,7,0))
843 error("Couldn't create ppp interface %s: %m", req_ifname);
851 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
852 * Assumes new_style_driver.
854 static int make_ppp_unit(void)
858 if (ppp_dev_fd >= 0) {
859 dbglog("in make_ppp_unit, already had /dev/ppp open?");
862 ppp_dev_fd = open("/dev/ppp", O_RDWR);
864 fatal("Couldn't open /dev/ppp: %m");
865 flags = fcntl(ppp_dev_fd, F_GETFL);
867 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
868 warn("Couldn't set /dev/ppp to nonblock: %m");
871 * Via rtnetlink it is possible to create ppp network interface with
872 * custom ifname atomically. But it is not possible to specify custom
875 * Tools like systemd, udev or NetworkManager are trying to query
876 * interface attributes based on interface name immediately when new
877 * network interface is created. And therefore immediate interface
878 * renaming is causing issues.
880 * So use rtnetlink API only when user requested custom ifname. It will
881 * avoid system issues with interface renaming.
883 if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) {
884 if (make_ppp_unit_rtnetlink()) {
885 if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit))
886 fatal("Couldn't retrieve PPP unit id: %m");
890 * If interface with requested name already exist return error
891 * otherwise fallback to old ioctl method.
898 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
899 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
900 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
902 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
904 if (x < 0 && errno == EEXIST) {
905 srand(time(NULL) * getpid());
906 ifunit = rand() % 10000;
907 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
910 error("Couldn't create new ppp unit: %m");
912 if (x == 0 && req_ifname[0] != '\0') {
915 memset(&ifr, 0, sizeof(struct ifreq));
916 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
917 strlcpy(ifr.ifr_name, t, IFNAMSIZ);
918 strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
919 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
921 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
923 info("Renamed interface %s to %s", t, req_ifname);
930 * cfg_bundle - configure the existing bundle.
931 * Used in demand mode.
933 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
935 if (!new_style_driver)
938 /* set the mrru, mtu and flags */
939 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
940 error("Couldn't set MRRU: %m");
942 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
943 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
944 | (mrru? SC_MULTILINK: 0)));
946 /* connect up the channel */
947 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
948 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
953 * make_new_bundle - create a new PPP unit (i.e. a bundle)
954 * and connect our channel to it. This should only get called
955 * if `multilink' was set at the time establish_ppp was called.
956 * In demand mode this uses our existing bundle instead of making
959 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
961 if (!new_style_driver)
964 /* make us a ppp unit */
965 if (make_ppp_unit() < 0)
968 /* set the mrru and flags */
969 cfg_bundle(mrru, mtru, rssn, tssn);
973 * bundle_attach - attach our link to a given PPP unit.
974 * We assume the unit is controlled by another pppd.
976 int bundle_attach(int ifnum)
980 if (!new_style_driver)
983 master_fd = open("/dev/ppp", O_RDWR);
985 fatal("Couldn't open /dev/ppp: %m");
986 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
987 if (errno == ENXIO) {
989 return 0; /* doesn't still exist */
991 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
993 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
994 fatal("Couldn't connect to interface unit %d: %m", ifnum);
995 modify_flags(master_fd, 0, SC_MULTILINK);
1003 * destroy_bundle - tell the driver to destroy our bundle.
1005 void destroy_bundle(void)
1007 if (ppp_dev_fd >= 0) {
1009 remove_fd(ppp_dev_fd);
1014 /********************************************************************
1016 * clean_check - Fetch the flags for the device and generate
1017 * appropriate error messages.
1019 void clean_check(void)
1025 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
1027 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
1029 s = "all had bit 7 set to 1";
1033 s = "all had bit 7 set to 0";
1037 s = "all had odd parity";
1041 s = "all had even parity";
1046 warn("Receive serial link is not 8-bit clean:");
1047 warn("Problem: %s", s);
1055 * List of valid speeds.
1059 int speed_int, speed_val;
1122 { 115200, B115200 },
1125 { 153600, B153600 },
1134 { 230400, B230400 },
1137 { 307200, B307200 },
1140 { 460800, B460800 },
1143 { 500000, B500000 },
1146 { 576000, B576000 },
1149 { 614400, B614400 },
1152 { 921600, B921600 },
1155 { 1000000, B1000000 },
1158 { 1152000, B1152000 },
1161 { 1500000, B1500000 },
1164 { 2000000, B2000000 },
1167 { 2500000, B2500000 },
1170 { 3000000, B3000000 },
1173 { 3500000, B3500000 },
1176 { 4000000, B4000000 },
1181 /********************************************************************
1183 * Translate from bits/second to a speed_t.
1186 static int translate_speed (int bps)
1188 struct speed *speedp;
1191 for (speedp = speeds; speedp->speed_int; speedp++) {
1192 if (bps == speedp->speed_int)
1193 return speedp->speed_val;
1199 /********************************************************************
1201 * Translate from a speed_t to bits/second.
1204 static int baud_rate_of (int speed)
1206 struct speed *speedp;
1209 for (speedp = speeds; speedp->speed_int; speedp++) {
1210 if (speed == speedp->speed_val)
1211 return speedp->speed_int;
1217 /********************************************************************
1219 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
1220 * at the requested speed, etc. If `local' is true, set CLOCAL
1221 * regardless of whether the modem option was specified.
1224 void set_up_tty(int tty_fd, int local)
1227 struct termios tios;
1230 if (tcgetattr(tty_fd, &tios) < 0) {
1231 if (!ok_error(errno))
1232 fatal("tcgetattr: %m (line %d)", __LINE__);
1239 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1240 tios.c_cflag |= CS8 | CREAD | HUPCL;
1242 tios.c_iflag = IGNBRK | IGNPAR;
1245 tios.c_cc[VMIN] = 1;
1246 tios.c_cc[VTIME] = 0;
1248 if (local || !modem)
1249 tios.c_cflag ^= (CLOCAL | HUPCL);
1253 tios.c_cflag |= CRTSCTS;
1257 tios.c_iflag |= IXON | IXOFF;
1258 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
1259 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1263 tios.c_cflag &= ~CRTSCTS;
1271 tios.c_cflag |= CSTOPB;
1274 speed = translate_speed(inspeed);
1276 cfsetospeed (&tios, speed);
1277 cfsetispeed (&tios, speed);
1278 speed = cfgetospeed(&tios);
1279 baud_rate = baud_rate_of(speed);
1282 tios.c_cflag &= ~CBAUD;
1283 tios.c_cflag |= BOTHER;
1284 tios.c_ospeed = inspeed;
1286 /* B0 sets input baudrate to the output baudrate */
1287 tios.c_cflag &= ~(CBAUD << IBSHIFT);
1288 tios.c_cflag |= B0 << IBSHIFT;
1289 tios.c_ispeed = inspeed;
1291 baud_rate = inspeed;
1298 speed = cfgetospeed(&tios);
1299 baud_rate = baud_rate_of(speed);
1302 baud_rate = tios.c_ospeed;
1307 * We can't proceed if the serial port baud rate is unknown,
1308 * since that implies that the serial port is disabled.
1312 fatal("speed %d not supported", inspeed);
1314 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1317 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1319 fatal("tcsetattr: %m (line %d)", __LINE__);
1323 /********************************************************************
1325 * setdtr - control the DTR line on the serial port.
1326 * This is called from die(), so it shouldn't call die().
1329 void setdtr (int tty_fd, int on)
1331 int modembits = TIOCM_DTR;
1333 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1336 /********************************************************************
1338 * restore_tty - restore the terminal to the saved settings.
1341 void restore_tty (int tty_fd)
1346 * Turn off echoing, because otherwise we can get into
1347 * a loop with the tty and the modem echoing to each other.
1348 * We presume we are the sole user of this tty device, so
1349 * when we close it, it will revert to its defaults anyway.
1351 if (!default_device)
1352 inittermios.c_lflag &= ~(ECHO | ECHONL);
1354 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1355 if (! ok_error (errno))
1356 warn("tcsetattr: %m (line %d)", __LINE__);
1361 /********************************************************************
1363 * output - Output PPP packet.
1366 void output (int unit, unsigned char *p, int len)
1371 dump_packet("sent", p, len);
1372 if (snoop_send_hook) snoop_send_hook(p, len);
1374 if (len < PPP_HDRLEN)
1376 if (new_style_driver) {
1379 proto = (p[0] << 8) + p[1];
1380 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1383 if (write(fd, p, len) < 0) {
1384 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1385 || errno == ENXIO || errno == EIO || errno == EINTR)
1386 warn("write: warning: %m (%d)", errno);
1388 error("write: %m (%d)", errno);
1392 /********************************************************************
1394 * wait_input - wait until there is data available,
1395 * for the length of time specified by *timo (indefinite
1399 void wait_input(struct timeval *timo)
1406 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1407 if (n < 0 && errno != EINTR)
1408 fatal("select: %m");
1412 * add_fd - add an fd to the set that wait_input waits for.
1416 if (fd >= FD_SETSIZE)
1417 fatal("internal error: file descriptor too large (%d)", fd);
1418 FD_SET(fd, &in_fds);
1424 * remove_fd - remove an fd from the set that wait_input waits for.
1426 void remove_fd(int fd)
1428 FD_CLR(fd, &in_fds);
1432 /********************************************************************
1434 * read_packet - get a PPP packet from the serial device.
1437 int read_packet (unsigned char *buf)
1441 len = PPP_MRU + PPP_HDRLEN;
1442 if (new_style_driver) {
1443 *buf++ = PPP_ALLSTATIONS;
1449 nr = read(ppp_fd, buf, len);
1450 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1451 && errno != EIO && errno != EINTR)
1453 if (nr < 0 && errno == ENXIO)
1456 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1457 /* N.B. we read ppp_fd first since LCP packets come in there. */
1458 nr = read(ppp_dev_fd, buf, len);
1459 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1460 && errno != EIO && errno != EINTR)
1461 error("read /dev/ppp: %m");
1462 if (nr < 0 && errno == ENXIO)
1464 if (nr == 0 && doing_multilink) {
1465 remove_fd(ppp_dev_fd);
1469 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1471 return (new_style_driver && nr > 0)? nr+2: nr;
1474 /********************************************************************
1476 * get_loop_output - get outgoing packets from the ppp device,
1477 * and detect when we want to bring the real link up.
1478 * Return value is 1 if we need to bring up the link, 0 otherwise.
1481 get_loop_output(void)
1486 if (new_style_driver) {
1487 while ((n = read_packet(inpacket_buf)) > 0)
1488 if (loop_frame(inpacket_buf, n))
1493 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1494 if (loop_chars(inbuf, n))
1498 fatal("eof on loopback");
1500 if (errno != EWOULDBLOCK && errno != EAGAIN)
1501 fatal("read from loopback: %m(%d)", errno);
1507 * netif_set_mtu - set the MTU on the PPP network interface.
1510 netif_set_mtu(int unit, int mtu)
1514 memset (&ifr, '\0', sizeof (ifr));
1515 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1518 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1519 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1523 * netif_get_mtu - get the MTU on the PPP network interface.
1526 netif_get_mtu(int unit)
1530 memset (&ifr, '\0', sizeof (ifr));
1531 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1533 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1534 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1540 /********************************************************************
1542 * tty_send_config - configure the transmit characteristics of
1543 * the ppp interface.
1546 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1553 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1554 if (errno != EIO && errno != ENOTTY)
1555 error("Couldn't set transmit async character map: %m");
1560 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1561 | (sync_serial? SC_SYNC: 0);
1562 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1565 /********************************************************************
1567 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1570 void tty_set_xaccm (ext_accm accm)
1574 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1575 if ( ! ok_error (errno))
1576 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1580 /********************************************************************
1582 * tty_recv_config - configure the receive-side characteristics of
1583 * the ppp interface.
1586 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1589 * If we were called because the link has gone down then there is nothing
1590 * which may be done. Just return without incident.
1595 * Set the receiver parameters
1597 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1598 if (errno != EIO && errno != ENOTTY)
1599 error("Couldn't set channel receive MRU: %m");
1601 if (new_style_driver && ppp_dev_fd >= 0
1602 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1603 error("Couldn't set MRU in generic PPP layer: %m");
1605 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1606 if (errno != EIO && errno != ENOTTY)
1607 error("Couldn't set channel receive asyncmap: %m");
1611 /********************************************************************
1613 * ccp_test - ask kernel whether a given compression method
1614 * is acceptable for use.
1618 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1620 struct ppp_option_data data;
1622 memset (&data, '\0', sizeof (data));
1624 data.length = opt_len;
1625 data.transmit = for_transmit;
1627 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1630 return (errno == ENOBUFS)? 0: -1;
1633 /********************************************************************
1635 * ccp_flags_set - inform kernel about the current state of CCP.
1638 void ccp_flags_set (int unit, int isopen, int isup)
1642 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1643 if (still_ppp() && ppp_dev_fd >= 0)
1644 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1647 #ifdef PPP_WITH_FILTER
1649 * set_filters - set the active and pass filters in the kernel driver.
1651 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1653 struct sock_fprog fp;
1655 fp.len = pass->bf_len;
1656 fp.filter = (struct sock_filter *) pass->bf_insns;
1657 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1658 if (errno == ENOTTY)
1659 warn("kernel does not support PPP filtering");
1661 error("Couldn't set pass-filter in kernel: %m");
1664 fp.len = active->bf_len;
1665 fp.filter = (struct sock_filter *) active->bf_insns;
1666 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1667 error("Couldn't set active-filter in kernel: %m");
1672 #endif /* PPP_WITH_FILTER */
1674 /********************************************************************
1676 * get_idle_time - return how long the link has been idle.
1679 get_idle_time(int u, struct ppp_idle *ip)
1681 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1684 /********************************************************************
1686 * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1687 * this only supports 32-bit counters, so need to count the wraps.
1690 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1692 static u_int32_t previbytes = 0;
1693 static u_int32_t prevobytes = 0;
1694 static u_int32_t iwraps = 0;
1695 static u_int32_t owraps = 0;
1698 struct ppp_stats data;
1700 memset (&req, 0, sizeof (req));
1702 req.ifr_data = (caddr_t) &data;
1703 strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
1704 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1705 error("Couldn't get PPP statistics: %m");
1708 stats->bytes_in = data.p.ppp_ibytes;
1709 stats->bytes_out = data.p.ppp_obytes;
1710 stats->pkts_in = data.p.ppp_ipackets;
1711 stats->pkts_out = data.p.ppp_opackets;
1713 if (stats->bytes_in < previbytes)
1715 if (stats->bytes_out < prevobytes)
1718 previbytes = stats->bytes_in;
1719 prevobytes = stats->bytes_out;
1721 stats->bytes_in += (uint64_t)iwraps << 32;
1722 stats->bytes_out += (uint64_t)owraps << 32;
1727 /********************************************************************
1728 * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1729 * This provides native 64-bit counters.
1732 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1734 static int rtnl_fd = -1;
1736 struct sockaddr_nl nladdr;
1738 struct nlmsghdr nlh;
1739 struct if_stats_msg ifsm;
1742 struct nlmsghdr nlh;
1745 struct nlmsgerr nlerr;
1751 /* We only case about these first fields from rtnl_link_stats64 */
1752 uint64_t rx_packets;
1753 uint64_t tx_packets;
1757 char __end_stats[0];
1765 memset(&nladdr, 0, sizeof(nladdr));
1766 nladdr.nl_family = AF_NETLINK;
1769 rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1771 error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__);
1775 if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
1776 error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
1781 memset(&nlreq, 0, sizeof(nlreq));
1782 nlreq.nlh.nlmsg_len = sizeof(nlreq);
1783 nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1784 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1786 nlreq.ifsm.ifindex = if_nametoindex(ifname);
1787 nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1789 memset(&iov, 0, sizeof(iov));
1790 iov.iov_base = &nlreq;
1791 iov.iov_len = sizeof(nlreq);
1793 memset(&msg, 0, sizeof(msg));
1794 msg.msg_name = &nladdr;
1795 msg.msg_namelen = sizeof(nladdr);
1799 if (sendmsg(rtnl_fd, &msg, 0) < 0) {
1800 error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1804 /* We just need to repoint to IOV ... everything else stays the same */
1805 iov.iov_base = &nlresp;
1806 iov.iov_len = sizeof(nlresp);
1808 nlresplen = recvmsg(rtnl_fd, &msg, 0);
1810 if (nlresplen < 0) {
1811 error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1815 if (nlresplen < sizeof(nlresp.nlh)) {
1816 error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__);
1820 if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) {
1821 if (nlresplen < offsetof(struct nlresp, __end_err))
1822 error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).", __LINE__);
1823 else if (kernel_version >= KVERSION(4,7,0))
1824 error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
1828 if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) {
1829 error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)",
1830 nlresp.nlh.nlmsg_type, __LINE__);
1834 if (nlresplen < offsetof(struct nlresp, __end_stats)) {
1835 error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1839 stats->bytes_in = nlresp.stats.rx_bytes;
1840 stats->bytes_out = nlresp.stats.tx_bytes;
1841 stats->pkts_in = nlresp.stats.rx_packets;
1842 stats->pkts_out = nlresp.stats.tx_packets;
1851 /********************************************************************
1852 * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1853 * this provides native 64-bit counters.
1856 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1858 char fname[PATH_MAX+1];
1859 char buf[21], *err; /* 2^64 < 10^20 */
1861 unsigned long long val;
1868 #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1869 statfield(rx_bytes, bytes_in),
1870 statfield(tx_bytes, bytes_out),
1871 statfield(rx_packets, pkts_in),
1872 statfield(tx_packets, pkts_out),
1876 blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1877 if (blen >= sizeof(fname))
1878 return 0; /* ifname max 15, so this should be impossible */
1880 for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1881 if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1883 error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1887 fd = open(fname, O_RDONLY);
1889 error("%s: %m", fname);
1893 rlen = read(fd, buf, sizeof(buf) - 1);
1896 error("%s: %m", fname);
1899 /* trim trailing \n if present */
1900 while (rlen > 0 && buf[rlen-1] == '\n')
1905 val = strtoull(buf, &err, 10);
1906 if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1907 error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1908 buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1911 switch (slist[i].size) {
1912 #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1919 error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1927 /********************************************************************
1928 * Periodic timer function to be used to keep stats up to date in case of ioctl
1931 * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1932 * If you do change the timer, remember to also bring the get_ppp_stats (which
1933 * sets up the initial trigger) as well.
1936 ppp_stats_poller(void* u)
1938 struct pppd_stats dummy;
1939 get_ppp_stats_ioctl((long)u, &dummy);
1940 TIMEOUT(ppp_stats_poller, u, 25);
1943 /********************************************************************
1944 * get_ppp_stats - return statistics for the link.
1946 int get_ppp_stats(int u, struct pppd_stats *stats)
1948 static int (*func)(int, struct pppd_stats*) = NULL;
1951 if (get_ppp_stats_rtnetlink(u, stats)) {
1952 func = get_ppp_stats_rtnetlink;
1955 if (get_ppp_stats_sysfs(u, stats)) {
1956 func = get_ppp_stats_sysfs;
1959 warn("statistics falling back to ioctl which only supports 32-bit counters");
1960 func = get_ppp_stats_ioctl;
1961 TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1964 return func(u, stats);
1967 /********************************************************************
1969 * ccp_fatal_error - returns 1 if decompression was disabled as a
1970 * result of an error detected after decompression of a packet,
1971 * 0 otherwise. This is necessary because of patent nonsense.
1974 int ccp_fatal_error (int unit)
1978 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1979 error("Couldn't read compression error flags: %m");
1982 return flags & SC_DC_FERROR;
1985 /********************************************************************
1987 * path_to_procfs - find the path to the proc file system mount point
1989 static char proc_path[MAXPATHLEN];
1990 static int proc_path_len;
1992 static char *path_to_procfs(const char *tail)
1994 struct mntent *mntent;
1997 if (proc_path_len == 0) {
1998 /* Default the mount location of /proc */
1999 strlcpy (proc_path, "/proc", sizeof(proc_path));
2001 fp = fopen(MOUNTED, "r");
2003 while ((mntent = getmntent(fp)) != NULL) {
2004 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
2006 if (strcmp(mntent->mnt_type, "proc") == 0) {
2007 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
2008 proc_path_len = strlen(proc_path);
2016 strlcpy(proc_path + proc_path_len, tail,
2017 sizeof(proc_path) - proc_path_len);
2022 * /proc/net/route parsing stuff.
2024 #define ROUTE_MAX_COLS 12
2025 FILE *route_fd = (FILE *) 0;
2026 static char route_buffer[512];
2027 static int route_dev_col, route_dest_col, route_gw_col;
2028 static int route_flags_col, route_metric_col, route_mask_col;
2029 static int route_num_cols;
2031 static int open_route_table (void);
2032 static void close_route_table (void);
2033 static int read_route_table (struct rtentry *rt);
2035 /********************************************************************
2037 * close_route_table - close the interface to the route table
2040 static void close_route_table (void)
2042 if (route_fd != (FILE *) 0) {
2044 route_fd = (FILE *) 0;
2048 /********************************************************************
2050 * open_route_table - open the interface to the route table
2052 static char route_delims[] = " \t\n";
2054 static int open_route_table (void)
2058 close_route_table();
2060 path = path_to_procfs("/net/route");
2061 route_fd = fopen (path, "r");
2062 if (route_fd == NULL) {
2063 error("can't open routing table %s: %m", path);
2067 route_dev_col = 0; /* default to usual columns */
2070 route_flags_col = 3;
2071 route_metric_col = 6;
2075 /* parse header line */
2076 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
2077 char *p = route_buffer, *q;
2079 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
2081 if ((q = strtok(p, route_delims)) == 0)
2083 if (strcasecmp(q, "iface") == 0)
2084 route_dev_col = col;
2085 else if (strcasecmp(q, "destination") == 0)
2086 route_dest_col = col;
2087 else if (strcasecmp(q, "gateway") == 0)
2089 else if (strcasecmp(q, "flags") == 0)
2090 route_flags_col = col;
2091 else if (strcasecmp(q, "mask") == 0)
2092 route_mask_col = col;
2095 if (used && col >= route_num_cols)
2096 route_num_cols = col + 1;
2104 /********************************************************************
2106 * read_route_table - read the next entry from the route table
2109 static int read_route_table(struct rtentry *rt)
2111 char *cols[ROUTE_MAX_COLS], *p;
2114 memset (rt, '\0', sizeof (struct rtentry));
2116 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2120 for (col = 0; col < route_num_cols; ++col) {
2121 cols[col] = strtok(p, route_delims);
2122 if (cols[col] == NULL)
2123 return 0; /* didn't get enough columns */
2127 SET_SA_FAMILY (rt->rt_dst, AF_INET);
2128 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
2130 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
2131 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
2132 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
2134 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
2135 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
2136 rt->rt_dev = cols[route_dev_col];
2141 /********************************************************************
2143 * defaultroute_exists - determine if there is a default route
2144 * with the given metric (or negative for any)
2147 static int defaultroute_exists (struct rtentry *rt, int metric)
2151 if (!open_route_table())
2154 while (read_route_table(rt) != 0) {
2155 if ((rt->rt_flags & RTF_UP) == 0)
2158 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
2160 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
2161 || rt->rt_metric == metric)) {
2167 close_route_table();
2172 * have_route_to - determine if the system has any route to
2173 * a given IP address. `addr' is in network byte order.
2174 * Return value is 1 if yes, 0 if no, -1 if don't know.
2175 * For demand mode to work properly, we have to ignore routes
2176 * through our own interface.
2178 int have_route_to(u_int32_t addr)
2183 if (!open_route_table())
2184 return -1; /* don't know */
2186 while (read_route_table(&rt)) {
2187 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
2189 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
2195 close_route_table();
2199 /********************************************************************
2201 * sifdefaultroute - assign a default route through the address given.
2203 * If the global default_rt_repl_rest flag is set, then this function
2204 * already replaced the original system defaultroute with some other
2205 * route and it should just replace the current defaultroute with
2206 * another one, without saving the current route. Use: demand mode,
2207 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2208 * and then changes the temporary addresses to the addresses for the real
2209 * ppp connection when it has come up.
2212 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
2214 struct rtentry rt, tmp_rt;
2215 struct rtentry *del_rt = NULL;
2217 if (default_rt_repl_rest) {
2218 /* We have already replaced the original defaultroute, if we
2219 * are called again, we will delete the current default route
2220 * and set the new default route in this function.
2221 * - this is normally only the case the doing demand: */
2222 if (defaultroute_exists(&tmp_rt, -1))
2224 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
2225 strcmp( old_def_rt.rt_dev, ifname) != 0) {
2227 * We did not yet replace an existing default route, let's
2228 * check if we should save and replace a default route:
2230 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2232 if (old_gateway != gateway) {
2234 error("not replacing default route to %s [%I]",
2235 old_def_rt.rt_dev, old_gateway);
2238 /* we need to copy rt_dev because we need it permanent too: */
2239 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2240 strcpy(tmp_dev, old_def_rt.rt_dev);
2241 old_def_rt.rt_dev = tmp_dev;
2243 notice("replacing old default route to %s [%I]",
2244 old_def_rt.rt_dev, old_gateway);
2245 default_rt_repl_rest = 1;
2246 del_rt = &old_def_rt;
2251 memset (&rt, 0, sizeof (rt));
2252 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2255 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2257 if (kernel_version > KVERSION(2,1,0)) {
2258 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2259 SIN_ADDR(rt.rt_genmask) = 0L;
2262 rt.rt_flags = RTF_UP;
2263 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2264 if ( ! ok_error ( errno ))
2265 error("default route ioctl(SIOCADDRT): %m");
2268 if (default_rt_repl_rest && del_rt)
2269 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2270 if ( ! ok_error ( errno ))
2271 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2275 have_default_route = 1;
2279 /********************************************************************
2281 * cifdefaultroute - delete a default route through the address given.
2284 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2288 have_default_route = 0;
2290 memset (&rt, '\0', sizeof (rt));
2291 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2292 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2297 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2299 if (kernel_version > KVERSION(2,1,0)) {
2300 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2301 SIN_ADDR(rt.rt_genmask) = 0L;
2304 rt.rt_flags = RTF_UP;
2305 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2307 if ( ! ok_error ( errno ))
2308 error("default route ioctl(SIOCDELRT): %m");
2312 if (default_rt_repl_rest) {
2313 notice("restoring old default route to %s [%I]",
2314 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2315 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2316 if ( ! ok_error ( errno ))
2317 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2320 default_rt_repl_rest = 0;
2326 #ifdef PPP_WITH_IPV6CP
2328 * /proc/net/ipv6_route parsing stuff.
2330 static int route_dest_plen_col;
2331 static int open_route6_table (void);
2332 static int read_route6_table (struct in6_rtmsg *rt);
2334 /********************************************************************
2336 * open_route6_table - open the interface to the route table
2338 static int open_route6_table (void)
2342 close_route_table();
2344 path = path_to_procfs("/net/ipv6_route");
2345 route_fd = fopen (path, "r");
2346 if (route_fd == NULL) {
2347 error("can't open routing table %s: %m", path);
2351 /* default to usual columns */
2353 route_dest_plen_col = 1;
2355 route_metric_col = 5;
2356 route_flags_col = 8;
2358 route_num_cols = 10;
2363 /********************************************************************
2365 * read_route6_table - read the next entry from the route table
2368 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2375 for (i = 0; i < 4; i++) {
2376 memcpy(hex8, s + 8*i, 8);
2377 v = strtoul(hex8, NULL, 16);
2378 addr->s6_addr32[i] = v;
2382 static int read_route6_table(struct in6_rtmsg *rt)
2384 char *cols[ROUTE_MAX_COLS], *p;
2387 memset (rt, '\0', sizeof (struct in6_rtmsg));
2389 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2393 for (col = 0; col < route_num_cols; ++col) {
2394 cols[col] = strtok(p, route_delims);
2395 if (cols[col] == NULL)
2396 return 0; /* didn't get enough columns */
2400 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2401 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2402 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2404 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2405 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2406 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2411 /********************************************************************
2413 * defaultroute6_exists - determine if there is a default route
2416 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2420 if (!open_route6_table())
2423 while (read_route6_table(rt) != 0) {
2424 if ((rt->rtmsg_flags & RTF_UP) == 0)
2427 if (rt->rtmsg_dst_len != 0)
2429 if (rt->rtmsg_dst.s6_addr32[0] == 0L
2430 && rt->rtmsg_dst.s6_addr32[1] == 0L
2431 && rt->rtmsg_dst.s6_addr32[2] == 0L
2432 && rt->rtmsg_dst.s6_addr32[3] == 0L
2433 && (metric < 0 || rt->rtmsg_metric == metric)) {
2439 close_route_table();
2443 /********************************************************************
2445 * sif6defaultroute - assign a default route through the address given.
2447 * If the global default_rt_repl_rest flag is set, then this function
2448 * already replaced the original system defaultroute with some other
2449 * route and it should just replace the current defaultroute with
2450 * another one, without saving the current route. Use: demand mode,
2451 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2452 * and then changes the temporary addresses to the addresses for the real
2453 * ppp connection when it has come up.
2456 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2458 struct in6_rtmsg rt;
2459 char buf[IF_NAMESIZE];
2461 if (defaultroute6_exists(&rt, dfl_route_metric) &&
2462 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2463 if (rt.rtmsg_flags & RTF_GATEWAY)
2464 error("not replacing existing default route via gateway");
2466 error("not replacing existing default route through %s",
2467 if_indextoname(rt.rtmsg_ifindex, buf));
2471 memset (&rt, 0, sizeof (rt));
2473 rt.rtmsg_ifindex = if_nametoindex(ifname);
2474 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2475 rt.rtmsg_dst_len = 0;
2477 rt.rtmsg_flags = RTF_UP;
2478 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2479 if ( ! ok_error ( errno ))
2480 error("default route ioctl(SIOCADDRT): %m");
2484 have_default_route6 = 1;
2488 /********************************************************************
2490 * cif6defaultroute - delete a default route through the address given.
2493 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2495 struct in6_rtmsg rt;
2497 have_default_route6 = 0;
2499 memset (&rt, '\0', sizeof (rt));
2501 rt.rtmsg_ifindex = if_nametoindex(ifname);
2502 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2503 rt.rtmsg_dst_len = 0;
2505 rt.rtmsg_flags = RTF_UP;
2506 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2508 if ( ! ok_error ( errno ))
2509 error("default route ioctl(SIOCDELRT): %m");
2516 #endif /* PPP_WITH_IPV6CP */
2518 /********************************************************************
2520 * sifproxyarp - Make a proxy ARP entry for the peer.
2523 int sifproxyarp (int unit, u_int32_t his_adr)
2525 struct arpreq arpreq;
2528 if (has_proxy_arp == 0) {
2529 memset (&arpreq, '\0', sizeof(arpreq));
2531 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2532 SIN_ADDR(arpreq.arp_pa) = his_adr;
2533 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2535 * Get the hardware address of an interface on the same subnet
2536 * as our local address.
2538 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2539 sizeof(proxy_arp_dev))) {
2540 error("Cannot determine ethernet address for proxy ARP");
2543 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2545 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2546 if ( ! ok_error ( errno ))
2547 error("ioctl(SIOCSARP): %m");
2550 proxy_arp_addr = his_adr;
2554 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2555 if (forw_path != 0) {
2556 int fd = open(forw_path, O_WRONLY);
2558 if (write(fd, "1", 1) != 1)
2559 error("Couldn't enable IP forwarding: %m");
2569 /********************************************************************
2571 * cifproxyarp - Delete the proxy ARP entry for the peer.
2574 int cifproxyarp (int unit, u_int32_t his_adr)
2576 struct arpreq arpreq;
2578 if (has_proxy_arp) {
2580 memset (&arpreq, '\0', sizeof(arpreq));
2581 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2582 SIN_ADDR(arpreq.arp_pa) = his_adr;
2583 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2584 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2586 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2587 if ( ! ok_error ( errno ))
2588 warn("ioctl(SIOCDARP): %m");
2595 /********************************************************************
2597 * get_ether_addr - get the hardware address of an interface on the
2598 * the same subnet as ipaddr.
2601 static int get_ether_addr (u_int32_t ipaddr,
2602 struct sockaddr *hwaddr,
2603 char *name, int namelen)
2605 struct ifreq *ifr, *ifend;
2606 u_int32_t ina, mask;
2608 struct ifreq ifreq, bestifreq;
2610 struct ifreq ifs[MAX_IFS];
2612 u_int32_t bestmask=0;
2613 int found_interface = 0;
2615 ifc.ifc_len = sizeof(ifs);
2617 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2618 if ( ! ok_error ( errno ))
2619 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2624 * Scan through looking for an interface with an Internet
2625 * address on the same subnet as `ipaddr'.
2627 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2628 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2629 if (ifr->ifr_addr.sa_family == AF_INET) {
2630 ina = SIN_ADDR(ifr->ifr_addr);
2631 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2633 * Check that the interface is up, and not point-to-point
2636 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2639 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2642 * Get its netmask and check that it's on the right subnet.
2644 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2647 mask = SIN_ADDR(ifreq.ifr_addr);
2649 if (((ipaddr ^ ina) & mask) != 0)
2650 continue; /* no match */
2652 if (mask >= bestmask) {
2653 /* Compare using >= instead of > -- it is possible for
2654 an interface to have a netmask of 0.0.0.0 */
2655 found_interface = 1;
2662 if (!found_interface) return 0;
2664 strlcpy(name, bestifreq.ifr_name, namelen);
2666 /* trim off the :1 in eth0:1 */
2667 aliasp = strchr(name, ':');
2671 info("found interface %s for proxy arp", name);
2673 * Now get the hardware address.
2675 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2676 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2677 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2682 &bestifreq.ifr_hwaddr,
2683 sizeof (struct sockaddr));
2689 * get_if_hwaddr - get the hardware address for the specified
2690 * network interface device.
2693 get_if_hwaddr(u_char *addr, char *name)
2698 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2701 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2702 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2703 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2706 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2711 * get_first_ether_hwaddr - get the hardware address for the first
2712 * ethernet-style interface on this system.
2715 get_first_ether_hwaddr(u_char *addr)
2717 struct if_nameindex *if_ni, *i;
2721 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2725 if_ni = if_nameindex();
2733 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2734 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2735 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2736 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2737 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2738 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2744 if_freenameindex(if_ni);
2750 /********************************************************************
2752 * Return user specified netmask, modified by any mask we might determine
2753 * for address `addr' (in network byte order).
2754 * Here we scan through the system's list of interfaces, looking for
2755 * any non-point-to-point interfaces which might appear to be on the same
2756 * network as `addr'. If we find any, we OR in their netmask to the
2757 * user-specified netmask.
2760 u_int32_t GetMask (u_int32_t addr)
2762 u_int32_t mask, nmask, ina;
2763 struct ifreq *ifr, *ifend, ifreq;
2765 struct ifreq ifs[MAX_IFS];
2769 if (IN_CLASSA(addr)) /* determine network mask for address class */
2770 nmask = IN_CLASSA_NET;
2771 else if (IN_CLASSB(addr))
2772 nmask = IN_CLASSB_NET;
2774 nmask = IN_CLASSC_NET;
2776 /* class D nets are disallowed by bad_ip_adrs */
2777 mask = netmask | htonl(nmask);
2779 * Scan through the system's network interfaces.
2781 ifc.ifc_len = sizeof(ifs);
2783 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2784 if ( ! ok_error ( errno ))
2785 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2789 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2790 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2792 * Check the interface's internet address.
2794 if (ifr->ifr_addr.sa_family != AF_INET)
2796 ina = SIN_ADDR(ifr->ifr_addr);
2797 if (((ntohl(ina) ^ addr) & nmask) != 0)
2800 * Check that the interface is up, and not point-to-point nor loopback.
2802 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2803 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2806 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2809 * Get its netmask and OR it into our mask.
2811 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2813 mask |= SIN_ADDR(ifreq.ifr_addr);
2819 /********************************************************************
2821 * Internal routine to decode the version.modification.patch level
2824 static void decode_version (char *buf, int *version,
2825 int *modification, int *patch)
2829 *version = (int) strtoul (buf, &endp, 10);
2833 if (endp != buf && *endp == '.') {
2835 *modification = (int) strtoul (buf, &endp, 10);
2836 if (endp != buf && *endp == '.') {
2838 *patch = (int) strtoul (buf, &buf, 10);
2843 /********************************************************************
2845 * Procedure to determine if the PPP line discipline is registered.
2849 ppp_registered(void)
2857 * We used to open the serial device and set it to the ppp line
2858 * discipline here, in order to create a ppp unit. But that is
2859 * not a good idea - the user might have specified a device that
2860 * they can't open (permission, or maybe it doesn't really exist).
2861 * So we grab a pty master/slave pair and use that.
2863 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2864 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2869 * Try to put the device into the PPP discipline.
2871 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2872 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2881 /********************************************************************
2883 * ppp_available - check whether the system has any ppp interfaces
2884 * (in fact we check whether we can do an ioctl on ppp0).
2887 int ppp_available(void)
2892 int my_version, my_modification, my_patch;
2893 int osmaj, osmin, ospatch;
2895 /* get the kernel version now, since we are called before sys_init */
2897 osmaj = osmin = ospatch = 0;
2898 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2899 kernel_version = KVERSION(osmaj, osmin, ospatch);
2901 fd = open("/dev/ppp", O_RDWR);
2903 new_style_driver = 1;
2905 /* XXX should get from driver */
2907 driver_modification = 4;
2913 if (kernel_version >= KVERSION(2,3,13)) {
2914 error("Couldn't open the /dev/ppp device: %m");
2915 if (errno == ENOENT)
2917 "You need to create the /dev/ppp device node by\n"
2918 "executing the following command as root:\n"
2919 " mknod /dev/ppp c 108 0\n";
2920 else if (errno == ENODEV || errno == ENXIO)
2922 "Please load the ppp_generic kernel module.\n";
2926 /* we are running on a really really old kernel */
2928 "This system lacks kernel support for PPP. This could be because\n"
2929 "the PPP kernel module could not be loaded, or because PPP was not\n"
2930 "included in the kernel configuration. If PPP was included as a\n"
2931 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2932 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2933 "See README.linux file in the ppp distribution for more details.\n";
2936 * Open a socket for doing the ioctl operations.
2938 s = socket(AF_INET, SOCK_DGRAM, 0);
2942 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2943 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2945 * If the device did not exist then attempt to create one by putting the
2946 * current tty into the PPP discipline. If this works then obtain the
2947 * flags for the device again.
2950 if (ppp_registered()) {
2951 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2952 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2956 * Ensure that the hardware address is for PPP and not something else
2959 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2961 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2965 * This is the PPP device. Validate the version of the driver at this
2966 * point to ensure that this program will work with the driver.
2969 char abBuffer [1024];
2971 ifr.ifr_data = abBuffer;
2972 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2974 error("Couldn't read driver version: %m");
2976 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2979 decode_version(abBuffer,
2981 &driver_modification,
2984 * Validate the version of the driver against the version that we used.
2986 decode_version(VERSION,
2991 /* The version numbers must match */
2992 if (driver_version != my_version)
2995 /* The modification levels must be legal */
2996 if (driver_modification < 3) {
2997 if (driver_modification >= 2) {
2998 /* we can cope with 2.2.0 and above */
3006 slprintf(route_buffer, sizeof(route_buffer),
3007 "Sorry - PPP driver version %d.%d.%d is out of date\n",
3008 driver_version, driver_modification, driver_patch);
3010 no_ppp_msg = route_buffer;
3018 #ifndef HAVE_LOGWTMP
3019 /********************************************************************
3021 * Update the wtmp file with the appropriate user name and tty device.
3024 void logwtmp (const char *line, const char *name, const char *host)
3026 struct utmp ut, *utp;
3027 pid_t mypid = getpid();
3033 * Update the signon database for users.
3034 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
3036 utmpname(_PATH_UTMP);
3038 while ((utp = getutent()) && (utp->ut_pid != mypid))
3042 memcpy(&ut, utp, sizeof(ut));
3044 /* some gettys/telnetds don't initialize utmp... */
3045 memset(&ut, 0, sizeof(ut));
3047 if (ut.ut_id[0] == 0)
3048 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
3050 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
3051 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
3055 ut.ut_type = USER_PROCESS;
3058 /* Insert the host name if one is supplied */
3060 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
3062 /* Insert the IP address of the remote system if IP is enabled */
3063 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
3064 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
3065 sizeof(ut.ut_addr));
3067 /* CL: Makes sure that the logout works */
3068 if (*host == 0 && *name==0)
3074 * Update the wtmp file.
3077 updwtmp(_PATH_WTMP, &ut);
3079 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
3081 flock(wtmp, LOCK_EX);
3083 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
3084 warn("error writing %s: %m", _PATH_WTMP);
3086 flock(wtmp, LOCK_UN);
3092 #endif /* HAVE_LOGWTMP */
3094 /********************************************************************
3096 * sifvjcomp - config tcp header compression
3099 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
3104 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
3105 error("Couldn't set up TCP header compression: %m");
3110 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
3111 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
3116 /********************************************************************
3118 * sifup - Config the interface up and enable IP packets to pass.
3125 if ((ret = setifstate(u, 1)))
3131 /********************************************************************
3133 * sifdown - Disable the indicated protocol and config the interface
3134 * down if there are no remaining protocols.
3139 if (if_is_up && --if_is_up > 0)
3142 #ifdef PPP_WITH_IPV6CP
3145 #endif /* PPP_WITH_IPV6CP */
3147 return setifstate(u, 0);
3150 #ifdef PPP_WITH_IPV6CP
3151 /********************************************************************
3153 * sif6up - Config the interface up for IPv6
3160 if ((ret = setifstate(u, 1)))
3166 /********************************************************************
3168 * sif6down - Disable the IPv6CP protocol and config the interface
3169 * down if there are no remaining protocols.
3172 int sif6down (int u)
3179 return setifstate(u, 0);
3181 #endif /* PPP_WITH_IPV6CP */
3183 /********************************************************************
3185 * setifstate - Config the interface up or down
3188 static int setifstate (int u, int state)
3192 memset (&ifr, '\0', sizeof (ifr));
3193 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3194 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
3195 if (! ok_error (errno))
3196 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
3201 ifr.ifr_flags |= IFF_UP;
3203 ifr.ifr_flags &= ~IFF_UP;
3204 ifr.ifr_flags |= IFF_POINTOPOINT;
3205 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
3206 if (! ok_error (errno))
3207 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
3213 /********************************************************************
3215 * sifaddr - Config the interface IP addresses and netmask.
3218 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3224 memset (&ifr, '\0', sizeof (ifr));
3225 memset (&rt, '\0', sizeof (rt));
3227 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
3228 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3229 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3231 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3233 * Set our IP address
3235 SIN_ADDR(ifr.ifr_addr) = our_adr;
3236 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3237 if (errno != EEXIST) {
3238 if (! ok_error (errno))
3239 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3242 warn("ioctl(SIOCSIFADDR): Address already exists");
3247 * Set the gateway address
3250 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3251 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3252 if (! ok_error (errno))
3253 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3259 * For recent kernels, force the netmask to 255.255.255.255.
3261 if (kernel_version >= KVERSION(2,1,16))
3263 if (net_mask != 0) {
3264 SIN_ADDR(ifr.ifr_netmask) = net_mask;
3265 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3266 if (! ok_error (errno))
3267 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3272 * Add the device route
3274 if (kernel_version < KVERSION(2,1,16)) {
3275 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3276 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3279 SIN_ADDR(rt.rt_gateway) = 0L;
3280 SIN_ADDR(rt.rt_dst) = his_adr;
3281 rt.rt_flags = RTF_UP | RTF_HOST;
3283 if (kernel_version > KVERSION(2,1,0)) {
3284 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3285 SIN_ADDR(rt.rt_genmask) = -1L;
3288 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3289 if (! ok_error (errno))
3290 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3295 /* set ip_dynaddr in demand mode if address changes */
3296 if (demand && tune_kernel && !dynaddr_set
3297 && our_old_addr && our_old_addr != our_adr) {
3298 /* set ip_dynaddr if possible */
3302 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3303 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3304 if (write(fd, "1", 1) != 1)
3305 error("Couldn't enable dynamic IP addressing: %m");
3308 dynaddr_set = 1; /* only 1 attempt */
3315 /********************************************************************
3317 * cifaddr - Clear the interface IP addresses, and delete routes
3318 * through the interface if possible.
3321 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3325 if (kernel_version < KVERSION(2,1,16)) {
3327 * Delete the route through the device
3330 memset (&rt, '\0', sizeof (rt));
3332 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3333 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3336 SIN_ADDR(rt.rt_gateway) = 0;
3337 SIN_ADDR(rt.rt_dst) = his_adr;
3338 rt.rt_flags = RTF_UP | RTF_HOST;
3340 if (kernel_version > KVERSION(2,1,0)) {
3341 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3342 SIN_ADDR(rt.rt_genmask) = -1L;
3345 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3346 if (still_ppp() && ! ok_error (errno))
3347 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3352 /* This way it is possible to have an IPv6-only interface */
3353 memset(&ifr, 0, sizeof(ifr));
3354 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3355 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3357 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3358 if (! ok_error (errno)) {
3359 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3364 our_old_addr = our_adr;
3369 #ifdef PPP_WITH_IPV6CP
3370 /********************************************************************
3372 * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3374 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3377 struct nlmsghdr nlh;
3378 struct ifaddrmsg ifa;
3381 struct in6_addr addr;
3386 memset(&nlreq, 0, sizeof(nlreq));
3387 nlreq.nlh.nlmsg_len = sizeof(nlreq);
3388 nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3389 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3390 nlreq.ifa.ifa_family = AF_INET6;
3391 nlreq.ifa.ifa_prefixlen = 128;
3392 nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3393 nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3394 nlreq.ifa.ifa_index = iface;
3395 nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3396 nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3397 IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3398 nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3399 nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3402 * To set only local address, older kernel expects that local address is
3403 * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3404 * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3405 * compatibility when setting only local address, set it via both IFA_LOCAL
3406 * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3407 * from iproute2 project.
3409 if (!eui64_iszero(his_eui64))
3410 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3412 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3414 resp = send_rtnetlink_msg("RTM_NEWADDR/NLM_F_CREATE", &nlreq, sizeof(nlreq));
3417 * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3418 * addresses and error response is expected. On older kernel versions
3419 * do not show this error message. On error pppd tries to fallback to
3420 * the old IOCTL method.
3422 errno = (resp < 0) ? -resp : EINVAL;
3423 if (kernel_version >= KVERSION(3,11,0))
3424 error("sif6addr_rtnetlink: %m (line %d)", __LINE__);
3431 /********************************************************************
3433 * sif6addr - Config the interface with an IPv6 link-local address
3435 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3437 struct in6_ifreq ifr6;
3439 struct in6_rtmsg rt6;
3444 error("IPv6 socket creation failed: %m");
3447 memset(&ifr, 0, sizeof (ifr));
3448 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3449 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3450 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3454 if (kernel_version >= KVERSION(2,1,16)) {
3455 /* Set both local address and remote peer address (with route for it) via rtnetlink */
3456 ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3462 * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3463 * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3466 /* Local interface */
3467 memset(&ifr6, 0, sizeof(ifr6));
3468 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3469 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3470 ifr6.ifr6_prefixlen = 128;
3472 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3473 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3478 if (!ret && !eui64_iszero(his_eui64)) {
3480 * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3481 * setting remote peer host address, so set only route to remote host.
3484 /* Route to remote host */
3485 memset(&rt6, 0, sizeof(rt6));
3486 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3487 rt6.rtmsg_flags = RTF_UP;
3488 rt6.rtmsg_dst_len = 128;
3489 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3490 rt6.rtmsg_metric = 1;
3492 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3493 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3502 /********************************************************************
3504 * cif6addr - Remove IPv6 address from interface
3506 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3509 struct in6_ifreq ifr6;
3513 error("IPv6 socket creation failed: %m");
3516 memset(&ifr, 0, sizeof(ifr));
3517 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3518 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3519 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3523 memset(&ifr6, 0, sizeof(ifr6));
3524 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3525 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3526 ifr6.ifr6_prefixlen = 128;
3528 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3529 if (errno != EADDRNOTAVAIL) {
3530 if (! ok_error (errno))
3531 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3534 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3540 #endif /* PPP_WITH_IPV6CP */
3543 * get_pty - get a pty master/slave pair and chown the slave side
3544 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
3547 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3549 int i, mfd, ret, sfd = -1;
3551 struct termios tios;
3555 * Try the unix98 way first.
3557 mfd = open("/dev/ptmx", O_RDWR);
3560 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3561 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3562 chmod(pty_name, S_IRUSR | S_IWUSR);
3565 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3566 warn("Couldn't unlock pty slave %s: %m", pty_name);
3568 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3570 warn("Couldn't open pty slave %s: %m", pty_name);
3575 #endif /* TIOCGPTN */
3578 /* the old way - scan through the pty name space */
3579 for (i = 0; i < 64; ++i) {
3580 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3581 'p' + i / 16, i % 16);
3582 mfd = open(pty_name, O_RDWR, 0);
3585 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3587 ret = fchown(sfd, uid, -1);
3589 warn("Couldn't change ownership of %s, %m", pty_name);
3591 ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3593 warn("Couldn't change permissions of %s, %m", pty_name);
3605 strlcpy(slave_name, pty_name, 16);
3608 if (tcgetattr(sfd, &tios) == 0) {
3609 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3610 tios.c_cflag |= CS8 | CREAD | CLOCAL;
3611 tios.c_iflag = IGNPAR;
3614 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3615 warn("couldn't set attributes on pty: %m");
3617 warn("couldn't get attributes on pty: %m");
3622 /********************************************************************
3624 * open_loopback - open the device we use for getting packets
3625 * in demand mode. Under Linux, we use a pty master/slave pair.
3628 open_ppp_loopback(void)
3633 if (new_style_driver) {
3634 /* allocate ourselves a ppp unit */
3635 if (make_ppp_unit() < 0)
3637 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3638 set_kdebugflag(kdebugflag);
3643 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3644 fatal("No free pty for loopback");
3646 set_ppp_fd(slave_fd);
3648 flags = fcntl(master_fd, F_GETFL);
3650 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3651 warn("couldn't set master loopback to nonblock: %m");
3653 flags = fcntl(ppp_fd, F_GETFL);
3655 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3656 warn("couldn't set slave loopback to nonblock: %m");
3658 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3659 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3661 * Find out which interface we were given.
3663 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3664 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3666 * Enable debug in the driver if requested.
3668 set_kdebugflag (kdebugflag);
3673 /********************************************************************
3675 * sifnpmode - Set the mode for handling packets for a given NP.
3679 sifnpmode(int u, int proto, enum NPmode mode)
3683 npi.protocol = proto;
3685 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3686 if (! ok_error (errno))
3687 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3694 * Use the hostname as part of the random number seed.
3703 for (p = hostname; *p != 0; ++p)
3708 /********************************************************************
3710 * sys_check_options - check the options that the user specified
3714 sys_check_options(void)
3716 if (demand && driver_is_old) {
3717 option_error("demand dialling is not supported by kernel driver "
3718 "version %d.%d.%d", driver_version, driver_modification,
3722 if (multilink && !new_style_driver) {
3723 warn("Warning: multilink is not supported by the kernel driver");
3729 /********************************************************************
3731 * get_time - Get current time, monotonic if possible.
3734 get_time(struct timeval *tv)
3736 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3737 * Runtime checking makes it safe. */
3738 #ifndef CLOCK_MONOTONIC
3739 #define CLOCK_MONOTONIC 1
3741 static int monotonic = -1;
3746 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3750 tv->tv_sec = ts.tv_sec;
3751 tv->tv_usec = ts.tv_nsec / 1000;
3754 } else if (monotonic > 0)
3758 warn("Couldn't use monotonic clock source: %m");
3761 return gettimeofday(tv, NULL);