2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
5 * Copyright (c) 1994-2024 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. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
20 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
22 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
24 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
25 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 * Derived from main.c and pppd.h, which are:
29 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in
40 * the documentation and/or other materials provided with the
43 * 3. The name "Carnegie Mellon University" must not be used to
44 * endorse or promote products derived from this software without
45 * prior written permission. For permission or any legal
46 * details, please contact
47 * Office of Technology Transfer
48 * Carnegie Mellon University
50 * Pittsburgh, PA 15213-3890
51 * (412) 268-4387, fax: (412) 268-7395
52 * tech-transfer@andrew.cmu.edu
54 * 4. Redistributions of any form whatsoever must retain the following
56 * "This product includes software developed by Computing Services
57 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
59 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
60 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
61 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
62 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
63 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
64 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
65 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
72 #include <sys/ioctl.h>
73 #include <sys/types.h>
74 #include <sys/socket.h>
78 #include <sys/utsname.h>
79 #include <sys/sysmacros.h>
80 #include <sys/param.h>
100 /* This is in netdevice.h. However, this compile will fail miserably if
101 you attempt to include netdevice.h because it has so many references
102 to __memcpy functions which it should not attempt to do. So, since I
103 really don't use it, but it must be defined, define it now. */
106 #define MAX_ADDR_LEN 7
109 #if !defined(__GLIBC__) || __GLIBC__ >= 2
110 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
112 #include <net/if_arp.h>
113 #include <net/route.h>
114 #include <netinet/if_ether.h>
116 #include <linux/types.h>
117 #include <linux/if.h>
118 #include <linux/if_arp.h>
119 #include <linux/route.h>
120 #include <linux/if_ether.h>
122 #include <netinet/in.h>
123 #include <arpa/inet.h>
125 #include <linux/ppp-ioctl.h>
127 #include <linux/netlink.h>
128 #include <linux/rtnetlink.h>
129 #include <linux/if_link.h>
130 #include <linux/if_addr.h>
132 /* glibc versions prior to 2.24 do not define SOL_NETLINK */
134 #define SOL_NETLINK 270
137 /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
138 #ifndef NETLINK_CAP_ACK
139 #define NETLINK_CAP_ACK 10
142 /* linux kernel versions prior to 4.7 do not define/support IFLA_PPP_DEV_FD */
144 /* IFLA_PPP_DEV_FD is declared as enum when IFLA_PPP_MAX is defined */
145 #define IFLA_PPP_DEV_FD 1
148 #include "pppd-private.h"
153 #ifdef PPP_WITH_IPV6CP
155 #endif /* PPP_WITH_IPV6CP */
157 #include "multilink.h"
159 #ifdef PPP_WITH_FILTER
160 #include <pcap-bpf.h>
161 #include <linux/filter.h>
162 #endif /* PPP_WITH_FILTER */
165 #include <sys/locks.h>
169 * Instead of system header file <termios.h> use local "termios_linux.h" header
170 * file as it provides additional support for arbitrary baud rates via BOTHER.
172 #include "termios_linux.h"
174 #ifdef PPP_WITH_IPV6CP
177 * This is in linux/include/net/ipv6.h.
181 struct in6_addr ifr6_addr;
182 __u32 ifr6_prefixlen;
183 unsigned int ifr6_ifindex;
187 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
188 memset(&(sin6).s6_addr, 0, sizeof(struct in6_addr)); \
189 (sin6).s6_addr16[0] = htons(0xfe80); \
190 eui64_copy(eui64, (sin6).s6_addr32[2]); \
193 static const eui64_t nulleui64;
194 #endif /* PPP_WITH_IPV6CP */
196 /* We can get an EIO error on an ioctl if the modem has hung up */
197 #define ok_error(num) ((num)==EIO)
199 static int tty_disc = N_TTY; /* The TTY discipline */
200 static int ppp_disc = N_PPP; /* The PPP discpline */
201 static int initfdflags = -1; /* Initial file descriptor flags for fd */
202 static int ppp_fd = -1; /* fd which is set to PPP discipline */
203 static int sock_fd = -1; /* socket for doing interface ioctls */
204 static int slave_fd = -1; /* pty for old-style demand mode, slave */
205 static int master_fd = -1; /* pty for old-style demand mode, master */
206 #ifdef PPP_WITH_IPV6CP
207 static int sock6_fd = -1;
208 #endif /* PPP_WITH_IPV6CP */
211 * For the old-style kernel driver, this is the same as ppp_fd.
212 * For the new-style driver, it is the fd of an instance of /dev/ppp
213 * which is attached to the ppp unit and is used for controlling it.
215 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
217 static int chindex; /* channel index (new style driver) */
219 static fd_set in_fds; /* set of fds that wait_input waits for */
220 static int max_in_fd; /* highest fd set in in_fds */
222 static int has_proxy_arp = 0;
223 static int driver_version = 0;
224 static int driver_modification = 0;
225 static int driver_patch = 0;
226 static int driver_is_old = 0;
227 static int restore_term = 0; /* 1 => we've munged the terminal */
228 static struct termios inittermios; /* Initial TTY termios */
230 int new_style_driver = 0;
232 static char loop_name[20];
233 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
235 static int if_is_up; /* Interface has been marked up */
236 static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
237 static int have_default_route; /* Gateway for default route added */
238 static int have_default_route6; /* Gateway for default IPv6 route added */
239 static struct rtentry old_def_rt; /* Old default route */
240 static int default_rt_repl_rest; /* replace and restore old default rt */
241 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
242 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
243 static u_int32_t our_old_addr; /* for detecting address changes */
244 static int dynaddr_set; /* 1 if ip_dynaddr set */
245 static int looped; /* 1 if using loop */
246 static int link_mtu; /* mtu for the link (not bundle) */
248 static struct utsname utsname; /* for the kernel version */
249 static int kernel_version;
250 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
254 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
255 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
256 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
258 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
260 /* Prototypes for procedures local to this file. */
261 static int modify_flags(int fd, int clear_bits, int set_bits);
262 static int translate_speed (int bps);
263 static int baud_rate_of (int speed);
264 static void close_route_table (void);
265 static int open_route_table (void);
266 static int read_route_table (struct rtentry *rt);
267 static int defaultroute_exists (struct rtentry *rt, int metric);
268 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
269 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
270 char *name, int namelen);
271 static void decode_version (char *buf, int *version, int *mod, int *patch);
272 static int set_kdebugflag(int level);
273 static int ppp_registered(void);
274 static int make_ppp_unit(void);
275 static int setifstate (int u, int state);
277 extern u_char inpacket_buf[]; /* borrowed from main.c */
279 extern int dfl_route_metric;
282 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
286 #define SET_SA_FAMILY(addr, family) \
287 memset ((char *) &(addr), '\0', sizeof(addr)); \
288 addr.sa_family = (family);
292 * rtnetlink_msg - send rtnetlink message, receive response
293 * and return received error code:
295 * positive value - error during sending / receiving message
296 * negative value - rtnetlink responce error code
298 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)
302 struct nlmsgerr nlerr;
304 struct sockaddr_nl nladdr;
311 if (shared_fd && *shared_fd >= 0) {
314 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
316 error("rtnetlink_msg: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
321 * Tell kernel to not send to us payload of acknowledgment error message.
322 * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
323 * older kernel versions always send full payload in acknowledgment netlink
324 * message. We ignore payload of this message as we need only error code,
325 * to check if our set remote peer address request succeeded or failed.
326 * So ignore return value from the following setsockopt() call as setting
327 * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
330 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
332 memset(&nladdr, 0, sizeof(nladdr));
333 nladdr.nl_family = AF_NETLINK;
335 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
336 error("rtnetlink_msg: bind(AF_NETLINK): %m (line %d)", __LINE__);
345 memset(&nladdr, 0, sizeof(nladdr));
346 nladdr.nl_family = AF_NETLINK;
348 memset(&iov[0], 0, sizeof(iov[0]));
349 iov[0].iov_base = nlreq;
350 iov[0].iov_len = nlreq_len;
352 memset(&msg, 0, sizeof(msg));
353 msg.msg_name = &nladdr;
354 msg.msg_namelen = sizeof(nladdr);
355 msg.msg_iov = &iov[0];
358 if (sendmsg(fd, &msg, 0) < 0) {
359 error("rtnetlink_msg: sendmsg(%s): %m (line %d)", desc, __LINE__);
365 memset(iov, 0, sizeof(iov));
366 iov[0].iov_base = &nlresp_hdr;
367 if (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) {
368 iov[0].iov_len = offsetof(struct nlresp_hdr, nlerr);
369 iov[1].iov_base = nlresp_data;
370 iov[1].iov_len = *nlresp_size;
372 iov[0].iov_len = sizeof(nlresp_hdr);
375 memset(&msg, 0, sizeof(msg));
376 msg.msg_name = &nladdr;
377 msg.msg_namelen = sizeof(nladdr);
379 msg.msg_iovlen = (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) ? 2 : 1;
381 nlresp_len = recvmsg(fd, &msg, 0);
386 if (nlresp_len < 0) {
387 error("rtnetlink_msg: recvmsg(%s): %m (line %d)", desc, __LINE__);
391 if (nladdr.nl_family != AF_NETLINK) {
392 error("rtnetlink_msg: recvmsg(%s): Not a netlink packet (line %d)", desc, __LINE__);
397 if ((size_t)nlresp_len < sizeof(nlresp_hdr) || nlresp_hdr.nlh.nlmsg_len < sizeof(nlresp_hdr)) {
398 error("rtnetlink_msg: recvmsg(%s): Acknowledgment netlink packet too short (line %d)", desc, __LINE__);
402 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
403 if (nlresp_hdr.nlh.nlmsg_type != NLMSG_ERROR) {
404 error("rtnetlink_msg: recvmsg(%s): Not an acknowledgment netlink packet (line %d)", desc, __LINE__);
410 if (*nlresp_size > sizeof(nlresp_hdr))
411 memcpy((unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), nlresp_data, sizeof(nlresp_hdr.nlerr));
413 memcpy(nlresp_data, (unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), *nlresp_size);
416 /* error == 0 indicates success, negative value is errno code */
417 if (nlresp_hdr.nlh.nlmsg_type == NLMSG_ERROR && nlresp_hdr.nlerr.error)
418 return nlresp_hdr.nlerr.error;
421 if (nlresp_hdr.nlh.nlmsg_type != nlresp_type) {
422 error("rtnetlink_msg: recvmsg(%s): Not a netlink packet of type 0x%x (line %d)", desc, nlresp_type, __LINE__);
425 *nlresp_size = nlresp_len - offsetof(struct nlresp_hdr, nlerr);
432 * Determine if the PPP connection should still be present.
437 /* new_fd is the fd of a tty */
438 static void set_ppp_fd (int new_fd)
441 if (!new_style_driver)
445 static int still_ppp(void)
447 if (new_style_driver)
448 return !hungup && ppp_fd >= 0;
449 if (!hungup || ppp_fd == slave_fd)
452 set_ppp_fd(slave_fd);
459 * modify_flags - set and clear flag bits controlling the kernel
462 static int modify_flags(int fd, int clear_bits, int set_bits)
466 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
468 flags = (flags & ~clear_bits) | set_bits;
469 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
476 error("Failed to set PPP kernel option flags: %m");
480 /********************************************************************
482 * sys_init - System-dependent initialization.
487 /* Get an internet socket for doing socket ioctls. */
488 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
490 fatal("Couldn't create IP socket: %m(%d)", errno);
492 #ifdef PPP_WITH_IPV6CP
493 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
495 sock6_fd = -errno; /* save errno for later */
502 /********************************************************************
504 * sys_cleanup - restore any system state we modified before exiting:
505 * mark the interface down, delete default route and/or proxy arp entry.
506 * This shouldn't call die() because it's called from die().
509 void sys_cleanup(void)
512 * Take down the device
518 #ifdef PPP_WITH_IPV6CP
524 * Delete any routes through the device.
526 if (have_default_route)
527 cifdefaultroute(0, 0, 0);
528 #ifdef PPP_WITH_IPV6CP
529 if (have_default_route6)
530 cif6defaultroute(0, nulleui64, nulleui64);
534 cifproxyarp(0, proxy_arp_addr);
537 /********************************************************************
539 * ppp_sys_close - Clean up in a child process before execing.
544 if (new_style_driver && ppp_dev_fd >= 0)
548 #ifdef PPP_WITH_IPV6CP
558 /********************************************************************
560 * set_kdebugflag - Define the debugging level for the kernel
563 static int set_kdebugflag (int requested_level)
567 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
568 if ( ! ok_error (errno) )
569 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
575 /********************************************************************
577 * tty_establish_ppp - Turn the serial port into a ppp interface.
580 int tty_establish_ppp (int tty_fd)
585 * Ensure that the tty device is in exclusive mode.
587 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
588 if ( ! ok_error ( errno ))
589 warn("Couldn't make tty exclusive: %m");
592 * Demand mode - prime the old ppp device to relinquish the unit.
594 if (!new_style_driver && looped
595 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
596 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
600 * Set the current tty to the PPP discpline
604 #define N_SYNC_PPP 14
606 ppp_disc = (new_style_driver && ppp_sync_serial())? N_SYNC_PPP: N_PPP;
607 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
608 if ( ! ok_error (errno) ) {
609 error("Couldn't set tty to PPP discipline: %m");
614 ret_fd = ppp_generic_establish(tty_fd);
616 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
617 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
621 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
622 (kdebugflag * SC_DEBUG) & SC_LOGB);
624 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
625 warn("Couldn't reset tty to normal line discipline: %m");
631 /********************************************************************
633 * generic_establish_ppp - Turn the fd into a ppp interface.
635 int ppp_generic_establish (int fd)
639 if (new_style_driver) {
642 /* If a ppp_fd is already open, close it first */
649 /* Open an instance of /dev/ppp and connect the channel to it */
650 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
651 error("Couldn't get channel number: %m");
654 dbglog("using channel %d", chindex);
655 fd = open("/dev/ppp", O_RDWR);
657 error("Couldn't reopen /dev/ppp: %m");
660 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
661 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
662 error("Couldn't attach to channel %d: %m", chindex);
665 flags = fcntl(fd, F_GETFL);
666 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
667 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
672 if (!looped && !multilink) {
674 * Create a new PPP unit.
676 if (make_ppp_unit() < 0)
681 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
685 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
686 error("Couldn't attach to PPP unit %d: %m", ifunit);
693 * Old-style driver: find out which interface we were given.
696 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
697 if (ok_error (errno))
699 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
701 /* Check that we got the same unit again. */
702 if (looped && x != ifunit)
703 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
707 * Fetch the initial file flags and reset blocking mode on the file.
709 initfdflags = fcntl(fd, F_GETFL);
710 if (initfdflags == -1 ||
711 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
712 if ( ! ok_error (errno))
713 warn("Couldn't set device to non-blocking mode: %m");
718 * Enable debug in the driver if requested.
721 set_kdebugflag (kdebugflag);
733 /********************************************************************
735 * tty_disestablish_ppp - Restore the serial port to normal operation.
736 * This shouldn't call die() because it's called from die().
739 void tty_disestablish_ppp(int tty_fd)
743 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
745 if (tcflush(tty_fd, TCIOFLUSH) < 0)
747 warn("tcflush failed: %m");
751 * Restore the previous line discipline
753 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
754 if ( ! ok_error (errno))
755 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
758 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
759 if ( ! ok_error (errno))
760 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
763 /* Reset non-blocking mode on fd. */
764 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
765 if ( ! ok_error (errno))
766 warn("Couldn't restore device fd flags: %m");
772 ppp_generic_disestablish(tty_fd);
775 /********************************************************************
777 * ppp_generic_disestablish - Restore device components to normal
778 * operation, and reconnect the ppp unit to the loopback if in demand
779 * mode. This shouldn't call die() because it's called from die().
781 void ppp_generic_disestablish(int dev_fd)
783 if (new_style_driver) {
787 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
789 } else if (!mp_on() && ppp_dev_fd >= 0) {
791 remove_fd(ppp_dev_fd);
795 /* old-style driver */
797 set_ppp_fd(slave_fd);
804 * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd
805 * with specified req_ifname via rtnetlink. Interface name req_ifname must not
806 * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free.
808 static int make_ppp_unit_rtnetlink(void)
812 struct ifinfomsg ifm;
815 char ifname[IFNAMSIZ];
821 char ifkind[sizeof("ppp")];
836 memset(&nlreq, 0, sizeof(nlreq));
837 nlreq.nlh.nlmsg_len = sizeof(nlreq);
838 nlreq.nlh.nlmsg_type = RTM_NEWLINK;
839 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
840 nlreq.ifm.ifi_family = AF_UNSPEC;
841 nlreq.ifm.ifi_type = ARPHRD_NETROM;
842 nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
843 nlreq.ifn.rta.rta_type = IFLA_IFNAME;
844 strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
845 nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
846 nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
847 nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
848 nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
849 strcpy(nlreq.ifli.ifik.ifkind, "ppp");
850 nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
851 nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
852 nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
853 nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
854 nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
857 * See kernel function ppp_nl_newlink(), which may return -EBUSY to prevent
858 * possible deadlock in kernel and ask userspace to retry request again.
861 resp = rtnetlink_msg("RTM_NEWLINK/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
862 } while (resp == -EBUSY);
866 * Linux kernel versions prior to 4.7 do not support creating ppp
867 * interfaces via rtnetlink API and therefore error response is
868 * expected. On older kernel versions do not show this error message.
869 * When error is different than EEXIST then pppd tries to fallback to
870 * the old ioctl method.
872 errno = (resp < 0) ? -resp : EINVAL;
873 if (kernel_version >= KVERSION(4,7,0))
874 error("Couldn't create ppp interface %s: %m", req_ifname);
882 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
883 * Assumes new_style_driver.
885 static int make_ppp_unit(void)
889 if (ppp_dev_fd >= 0) {
890 dbglog("in make_ppp_unit, already had /dev/ppp open?");
893 ppp_dev_fd = open("/dev/ppp", O_RDWR);
895 fatal("Couldn't open /dev/ppp: %m");
896 flags = fcntl(ppp_dev_fd, F_GETFL);
898 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
899 warn("Couldn't set /dev/ppp to nonblock: %m");
902 * Via rtnetlink it is possible to create ppp network interface with
903 * custom ifname atomically. But it is not possible to specify custom
906 * Tools like systemd, udev or NetworkManager are trying to query
907 * interface attributes based on interface name immediately when new
908 * network interface is created. And therefore immediate interface
909 * renaming is causing issues.
911 * So use rtnetlink API only when user requested custom ifname. It will
912 * avoid system issues with interface renaming.
914 if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) {
915 if (make_ppp_unit_rtnetlink()) {
916 if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit))
917 fatal("Couldn't retrieve PPP unit id: %m");
921 * If interface with requested name already exist return error
922 * otherwise fallback to old ioctl method.
929 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
930 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
931 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
933 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
935 if (x < 0 && errno == EEXIST) {
936 srand(time(NULL) * getpid());
937 ifunit = rand() % 10000;
938 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
941 error("Couldn't create new ppp unit: %m");
943 if (x == 0 && req_ifname[0] != '\0') {
946 memset(&ifr, 0, sizeof(struct ifreq));
947 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
948 strlcpy(ifr.ifr_name, t, IFNAMSIZ);
949 strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
950 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
952 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
954 info("Renamed interface %s to %s", t, req_ifname);
961 * cfg_bundle - configure the existing bundle.
962 * Used in demand mode.
964 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
966 if (!new_style_driver)
969 /* set the mrru, mtu and flags */
970 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
971 error("Couldn't set MRRU: %m");
973 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
974 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
975 | (mrru? SC_MULTILINK: 0)));
977 /* connect up the channel */
978 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
979 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
984 * make_new_bundle - create a new PPP unit (i.e. a bundle)
985 * and connect our channel to it. This should only get called
986 * if `multilink' was set at the time establish_ppp was called.
987 * In demand mode this uses our existing bundle instead of making
990 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
992 if (!new_style_driver)
995 /* make us a ppp unit */
996 if (make_ppp_unit() < 0)
999 /* set the mrru and flags */
1000 cfg_bundle(mrru, mtru, rssn, tssn);
1004 * bundle_attach - attach our link to a given PPP unit.
1005 * We assume the unit is controlled by another pppd.
1007 int bundle_attach(int ifnum)
1011 if (!new_style_driver)
1014 master_fd = open("/dev/ppp", O_RDWR);
1016 fatal("Couldn't open /dev/ppp: %m");
1017 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
1018 if (errno == ENXIO) {
1020 return 0; /* doesn't still exist */
1022 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
1024 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
1025 fatal("Couldn't connect to interface unit %d: %m", ifnum);
1026 modify_flags(master_fd, 0, SC_MULTILINK);
1034 * destroy_bundle - tell the driver to destroy our bundle.
1036 void destroy_bundle(void)
1038 if (ppp_dev_fd >= 0) {
1040 remove_fd(ppp_dev_fd);
1045 /********************************************************************
1047 * clean_check - Fetch the flags for the device and generate
1048 * appropriate error messages.
1050 void clean_check(void)
1056 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
1058 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
1060 s = "all had bit 7 set to 1";
1064 s = "all had bit 7 set to 0";
1068 s = "all had odd parity";
1072 s = "all had even parity";
1077 warn("Receive serial link is not 8-bit clean:");
1078 warn("Problem: %s", s);
1086 * List of valid speeds.
1090 int speed_int, speed_val;
1153 { 115200, B115200 },
1156 { 153600, B153600 },
1165 { 230400, B230400 },
1168 { 307200, B307200 },
1171 { 460800, B460800 },
1174 { 500000, B500000 },
1177 { 576000, B576000 },
1180 { 614400, B614400 },
1183 { 921600, B921600 },
1186 { 1000000, B1000000 },
1189 { 1152000, B1152000 },
1192 { 1500000, B1500000 },
1195 { 2000000, B2000000 },
1198 { 2500000, B2500000 },
1201 { 3000000, B3000000 },
1204 { 3500000, B3500000 },
1207 { 4000000, B4000000 },
1212 /********************************************************************
1214 * Translate from bits/second to a speed_t.
1217 static int translate_speed (int bps)
1219 struct speed *speedp;
1222 for (speedp = speeds; speedp->speed_int; speedp++) {
1223 if (bps == speedp->speed_int)
1224 return speedp->speed_val;
1230 /********************************************************************
1232 * Translate from a speed_t to bits/second.
1235 static int baud_rate_of (int speed)
1237 struct speed *speedp;
1240 for (speedp = speeds; speedp->speed_int; speedp++) {
1241 if (speed == speedp->speed_val)
1242 return speedp->speed_int;
1248 /********************************************************************
1250 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
1251 * at the requested speed, etc. If `local' is true, set CLOCAL
1252 * regardless of whether the modem option was specified.
1255 void set_up_tty(int tty_fd, int local)
1258 struct termios tios;
1261 if (tcgetattr(tty_fd, &tios) < 0) {
1262 if (!ok_error(errno))
1263 fatal("tcgetattr: %m (line %d)", __LINE__);
1270 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1271 tios.c_cflag |= CS8 | CREAD | HUPCL;
1273 tios.c_iflag = IGNBRK | IGNPAR;
1276 tios.c_cc[VMIN] = 1;
1277 tios.c_cc[VTIME] = 0;
1279 if (local || !modem)
1280 tios.c_cflag ^= (CLOCAL | HUPCL);
1284 tios.c_cflag |= CRTSCTS;
1288 tios.c_iflag |= IXON | IXOFF;
1289 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
1290 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1294 tios.c_cflag &= ~CRTSCTS;
1302 tios.c_cflag |= CSTOPB;
1305 speed = translate_speed(inspeed);
1307 cfsetospeed (&tios, speed);
1308 cfsetispeed (&tios, speed);
1309 speed = cfgetospeed(&tios);
1310 baud_rate = baud_rate_of(speed);
1313 tios.c_cflag &= ~CBAUD;
1314 tios.c_cflag |= BOTHER;
1315 tios.c_ospeed = inspeed;
1317 /* B0 sets input baudrate to the output baudrate */
1318 tios.c_cflag &= ~(CBAUD << IBSHIFT);
1319 tios.c_cflag |= B0 << IBSHIFT;
1320 tios.c_ispeed = inspeed;
1322 baud_rate = inspeed;
1329 speed = cfgetospeed(&tios);
1330 baud_rate = baud_rate_of(speed);
1333 baud_rate = tios.c_ospeed;
1338 * We can't proceed if the serial port baud rate is unknown,
1339 * since that implies that the serial port is disabled.
1343 fatal("speed %d not supported", inspeed);
1345 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1348 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1350 fatal("tcsetattr: %m (line %d)", __LINE__);
1354 /********************************************************************
1356 * setdtr - control the DTR line on the serial port.
1357 * This is called from die(), so it shouldn't call die().
1360 void setdtr (int tty_fd, int on)
1362 int modembits = TIOCM_DTR;
1364 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1367 /********************************************************************
1369 * restore_tty - restore the terminal to the saved settings.
1372 void restore_tty (int tty_fd)
1377 * Turn off echoing, because otherwise we can get into
1378 * a loop with the tty and the modem echoing to each other.
1379 * We presume we are the sole user of this tty device, so
1380 * when we close it, it will revert to its defaults anyway.
1382 if (!default_device)
1383 inittermios.c_lflag &= ~(ECHO | ECHONL);
1385 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1386 if (! ok_error (errno))
1387 warn("tcsetattr: %m (line %d)", __LINE__);
1392 /********************************************************************
1394 * output - Output PPP packet.
1397 void output (int unit, unsigned char *p, int len)
1402 dump_packet("sent", p, len);
1403 if (snoop_send_hook) snoop_send_hook(p, len);
1405 if (len < PPP_HDRLEN)
1407 if (new_style_driver) {
1410 proto = (p[0] << 8) + p[1];
1411 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1414 if (write(fd, p, len) < 0) {
1415 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1416 || errno == ENXIO || errno == EIO || errno == EINTR)
1417 warn("write: warning: %m (%d)", errno);
1419 error("write: %m (%d)", errno);
1423 /********************************************************************
1425 * wait_input - wait until there is data available,
1426 * for the length of time specified by *timo (indefinite
1430 void wait_input(struct timeval *timo)
1437 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1438 if (n < 0 && errno != EINTR)
1439 fatal("select: %m");
1443 * add_fd - add an fd to the set that wait_input waits for.
1447 if (fd >= FD_SETSIZE)
1448 fatal("internal error: file descriptor too large (%d)", fd);
1449 FD_SET(fd, &in_fds);
1455 * remove_fd - remove an fd from the set that wait_input waits for.
1457 void remove_fd(int fd)
1459 FD_CLR(fd, &in_fds);
1463 /********************************************************************
1465 * read_packet - get a PPP packet from the serial device.
1468 int read_packet (unsigned char *buf)
1472 len = PPP_MRU + PPP_HDRLEN;
1473 if (new_style_driver) {
1474 *buf++ = PPP_ALLSTATIONS;
1480 nr = read(ppp_fd, buf, len);
1481 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1482 && errno != EIO && errno != EINTR)
1484 if (nr < 0 && errno == ENXIO)
1487 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1488 /* N.B. we read ppp_fd first since LCP packets come in there. */
1489 nr = read(ppp_dev_fd, buf, len);
1490 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1491 && errno != EIO && errno != EINTR)
1492 error("read /dev/ppp: %m");
1493 if (nr < 0 && errno == ENXIO)
1495 if (nr == 0 && mp_on()) {
1496 remove_fd(ppp_dev_fd);
1500 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1502 return (new_style_driver && nr > 0)? nr+2: nr;
1505 /********************************************************************
1507 * get_loop_output - get outgoing packets from the ppp device,
1508 * and detect when we want to bring the real link up.
1509 * Return value is 1 if we need to bring up the link, 0 otherwise.
1512 get_loop_output(void)
1517 if (new_style_driver) {
1518 while ((n = read_packet(inpacket_buf)) > 0)
1519 if (loop_frame(inpacket_buf, n))
1524 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1525 if (loop_chars(inbuf, n))
1529 fatal("eof on loopback");
1531 if (errno != EWOULDBLOCK && errno != EAGAIN)
1532 fatal("read from loopback: %m(%d)", errno);
1538 * netif_set_mtu - set the MTU on the PPP network interface.
1541 ppp_set_mtu(int unit, int mtu)
1545 memset (&ifr, '\0', sizeof (ifr));
1546 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1549 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1550 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1554 * netif_get_mtu - get the MTU on the PPP network interface.
1557 ppp_get_mtu(int unit)
1561 memset (&ifr, '\0', sizeof (ifr));
1562 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1564 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1565 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1571 /********************************************************************
1573 * tty_send_config - configure the transmit characteristics of
1574 * the ppp interface.
1577 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1584 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1585 if (errno != EIO && errno != ENOTTY)
1586 error("Couldn't set transmit async character map: %m");
1591 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1592 | (ppp_sync_serial()? SC_SYNC: 0);
1593 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1596 /********************************************************************
1598 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1601 void tty_set_xaccm (ext_accm accm)
1605 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1606 if ( ! ok_error (errno))
1607 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1611 /********************************************************************
1613 * tty_recv_config - configure the receive-side characteristics of
1614 * the ppp interface.
1617 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1620 * If we were called because the link has gone down then there is nothing
1621 * which may be done. Just return without incident.
1626 * Set the receiver parameters
1628 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1629 if (errno != EIO && errno != ENOTTY)
1630 error("Couldn't set channel receive MRU: %m");
1632 if (new_style_driver && ppp_dev_fd >= 0
1633 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1634 error("Couldn't set MRU in generic PPP layer: %m");
1636 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1637 if (errno != EIO && errno != ENOTTY)
1638 error("Couldn't set channel receive asyncmap: %m");
1642 /********************************************************************
1644 * ccp_test - ask kernel whether a given compression method
1645 * is acceptable for use.
1649 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1651 struct ppp_option_data data;
1653 memset (&data, '\0', sizeof (data));
1655 data.length = opt_len;
1656 data.transmit = for_transmit;
1658 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1661 return (errno == ENOBUFS)? 0: -1;
1664 /********************************************************************
1666 * ccp_flags_set - inform kernel about the current state of CCP.
1669 void ccp_flags_set (int unit, int isopen, int isup)
1673 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1674 if (still_ppp() && ppp_dev_fd >= 0)
1675 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1678 #ifdef PPP_WITH_FILTER
1680 * set_filters - set the active and pass filters in the kernel driver.
1682 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1684 struct sock_fprog fp;
1686 fp.len = pass->bf_len;
1687 fp.filter = (struct sock_filter *) pass->bf_insns;
1688 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1689 if (errno == ENOTTY)
1690 warn("kernel does not support PPP filtering");
1692 error("Couldn't set pass-filter in kernel: %m");
1695 fp.len = active->bf_len;
1696 fp.filter = (struct sock_filter *) active->bf_insns;
1697 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1698 error("Couldn't set active-filter in kernel: %m");
1703 #endif /* PPP_WITH_FILTER */
1705 /********************************************************************
1707 * get_idle_time - return how long the link has been idle.
1710 get_idle_time(int u, struct ppp_idle *ip)
1712 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1715 /********************************************************************
1717 * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1718 * this only supports 32-bit counters, so need to count the wraps.
1721 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1723 static u_int32_t previbytes = 0;
1724 static u_int32_t prevobytes = 0;
1725 static u_int32_t iwraps = 0;
1726 static u_int32_t owraps = 0;
1729 struct ppp_stats data;
1731 memset (&req, 0, sizeof (req));
1733 req.ifr_data = (caddr_t) &data;
1734 strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
1735 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1736 error("Couldn't get PPP statistics: %m");
1739 stats->bytes_in = data.p.ppp_ibytes;
1740 stats->bytes_out = data.p.ppp_obytes;
1741 stats->pkts_in = data.p.ppp_ipackets;
1742 stats->pkts_out = data.p.ppp_opackets;
1744 if (stats->bytes_in < previbytes)
1746 if (stats->bytes_out < prevobytes)
1749 previbytes = stats->bytes_in;
1750 prevobytes = stats->bytes_out;
1752 stats->bytes_in += (uint64_t)iwraps << 32;
1753 stats->bytes_out += (uint64_t)owraps << 32;
1758 /********************************************************************
1759 * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1760 * This provides native 64-bit counters.
1763 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1769 struct nlmsghdr nlh;
1770 struct if_stats_msg ifsm;
1775 /* We only case about these first fields from rtnl_link_stats64 */
1776 uint64_t rx_packets;
1777 uint64_t tx_packets;
1785 memset(&nlreq, 0, sizeof(nlreq));
1786 nlreq.nlh.nlmsg_len = sizeof(nlreq);
1787 nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1788 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1789 nlreq.ifsm.ifindex = if_nametoindex(ifname);
1790 nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1792 nlresp_size = sizeof(nlresp_data);
1793 resp = rtnetlink_msg("RTM_GETSTATS/NLM_F_REQUEST", &fd, &nlreq, sizeof(nlreq), &nlresp_data, &nlresp_size, RTM_NEWSTATS);
1795 errno = (resp < 0) ? -resp : EINVAL;
1796 if (kernel_version >= KVERSION(4,7,0))
1797 error("get_ppp_stats_rtnetlink: %m (line %d)", __LINE__);
1801 if (nlresp_size < sizeof(nlresp_data)) {
1802 error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1806 stats->bytes_in = nlresp_data.stats.rx_bytes;
1807 stats->bytes_out = nlresp_data.stats.tx_bytes;
1808 stats->pkts_in = nlresp_data.stats.rx_packets;
1809 stats->pkts_out = nlresp_data.stats.tx_packets;
1819 /********************************************************************
1820 * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1821 * this provides native 64-bit counters.
1824 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1826 char fname[PATH_MAX+1];
1827 char buf[21], *err; /* 2^64 < 10^20 */
1829 unsigned long long val;
1836 #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1837 statfield(rx_bytes, bytes_in),
1838 statfield(tx_bytes, bytes_out),
1839 statfield(rx_packets, pkts_in),
1840 statfield(tx_packets, pkts_out),
1844 blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1845 if (blen >= sizeof(fname))
1846 return 0; /* ifname max 15, so this should be impossible */
1848 for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1849 if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1851 error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1855 fd = open(fname, O_RDONLY);
1857 error("%s: %m", fname);
1861 rlen = read(fd, buf, sizeof(buf) - 1);
1864 error("%s: %m", fname);
1867 /* trim trailing \n if present */
1868 while (rlen > 0 && buf[rlen-1] == '\n')
1873 val = strtoull(buf, &err, 10);
1874 if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1875 error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1876 buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1879 switch (slist[i].size) {
1880 #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1887 error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1895 /********************************************************************
1896 * Periodic timer function to be used to keep stats up to date in case of ioctl
1899 * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1900 * If you do change the timer, remember to also bring the get_ppp_stats (which
1901 * sets up the initial trigger) as well.
1904 ppp_stats_poller(void* u)
1906 struct pppd_stats dummy;
1907 get_ppp_stats_ioctl((long)u, &dummy);
1908 TIMEOUT(ppp_stats_poller, u, 25);
1911 /********************************************************************
1912 * get_ppp_stats - return statistics for the link.
1914 int get_ppp_stats(int u, struct pppd_stats *stats)
1916 static int (*func)(int, struct pppd_stats*) = NULL;
1919 if (get_ppp_stats_rtnetlink(u, stats)) {
1920 func = get_ppp_stats_rtnetlink;
1923 if (get_ppp_stats_sysfs(u, stats)) {
1924 func = get_ppp_stats_sysfs;
1927 warn("statistics falling back to ioctl which only supports 32-bit counters");
1928 func = get_ppp_stats_ioctl;
1929 TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1932 return func(u, stats);
1935 /********************************************************************
1937 * ccp_fatal_error - returns 1 if decompression was disabled as a
1938 * result of an error detected after decompression of a packet,
1939 * 0 otherwise. This is necessary because of patent nonsense.
1942 int ccp_fatal_error (int unit)
1946 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1947 error("Couldn't read compression error flags: %m");
1950 return flags & SC_DC_FERROR;
1953 /********************************************************************
1955 * path_to_procfs - find the path to the proc file system mount point
1957 static char proc_path[MAXPATHLEN];
1958 static int proc_path_len;
1960 static char *path_to_procfs(const char *tail)
1962 struct mntent *mntent;
1965 if (proc_path_len == 0) {
1966 /* Default the mount location of /proc */
1967 strlcpy (proc_path, "/proc", sizeof(proc_path));
1969 fp = fopen(MOUNTED, "r");
1971 while ((mntent = getmntent(fp)) != NULL) {
1972 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1974 if (strcmp(mntent->mnt_type, "proc") == 0) {
1975 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1976 proc_path_len = strlen(proc_path);
1984 strlcpy(proc_path + proc_path_len, tail,
1985 sizeof(proc_path) - proc_path_len);
1990 * /proc/net/route parsing stuff.
1992 #define ROUTE_MAX_COLS 12
1993 FILE *route_fd = (FILE *) 0;
1994 static char route_buffer[512];
1995 static int route_dev_col, route_dest_col, route_gw_col;
1996 static int route_flags_col, route_metric_col, route_mask_col;
1997 static int route_num_cols;
1999 static int open_route_table (void);
2000 static void close_route_table (void);
2001 static int read_route_table (struct rtentry *rt);
2003 /********************************************************************
2005 * close_route_table - close the interface to the route table
2008 static void close_route_table (void)
2010 if (route_fd != (FILE *) 0) {
2012 route_fd = (FILE *) 0;
2016 /********************************************************************
2018 * open_route_table - open the interface to the route table
2020 static char route_delims[] = " \t\n";
2022 static int open_route_table (void)
2026 close_route_table();
2028 path = path_to_procfs("/net/route");
2029 route_fd = fopen (path, "r");
2030 if (route_fd == NULL) {
2031 error("can't open routing table %s: %m", path);
2035 route_dev_col = 0; /* default to usual columns */
2038 route_flags_col = 3;
2039 route_metric_col = 6;
2043 /* parse header line */
2044 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
2045 char *p = route_buffer, *q;
2047 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
2049 if ((q = strtok(p, route_delims)) == 0)
2051 if (strcasecmp(q, "iface") == 0)
2052 route_dev_col = col;
2053 else if (strcasecmp(q, "destination") == 0)
2054 route_dest_col = col;
2055 else if (strcasecmp(q, "gateway") == 0)
2057 else if (strcasecmp(q, "flags") == 0)
2058 route_flags_col = col;
2059 else if (strcasecmp(q, "mask") == 0)
2060 route_mask_col = col;
2063 if (used && col >= route_num_cols)
2064 route_num_cols = col + 1;
2072 /********************************************************************
2074 * read_route_table - read the next entry from the route table
2077 static int read_route_table(struct rtentry *rt)
2079 char *cols[ROUTE_MAX_COLS], *p;
2082 memset (rt, '\0', sizeof (struct rtentry));
2084 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2088 for (col = 0; col < route_num_cols; ++col) {
2089 cols[col] = strtok(p, route_delims);
2090 if (cols[col] == NULL)
2091 return 0; /* didn't get enough columns */
2095 SET_SA_FAMILY (rt->rt_dst, AF_INET);
2096 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
2098 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
2099 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
2100 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
2102 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
2103 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
2104 rt->rt_dev = cols[route_dev_col];
2109 /********************************************************************
2111 * defaultroute_exists - determine if there is a default route
2112 * with the given metric (or negative for any)
2115 static int defaultroute_exists (struct rtentry *rt, int metric)
2119 if (!open_route_table())
2122 while (read_route_table(rt) != 0) {
2123 if ((rt->rt_flags & RTF_UP) == 0)
2126 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
2128 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
2129 || rt->rt_metric == metric)) {
2135 close_route_table();
2140 * have_route_to - determine if the system has any route to
2141 * a given IP address. `addr' is in network byte order.
2142 * Return value is 1 if yes, 0 if no, -1 if don't know.
2143 * For demand mode to work properly, we have to ignore routes
2144 * through our own interface.
2146 int have_route_to(u_int32_t addr)
2151 if (!open_route_table())
2152 return -1; /* don't know */
2154 while (read_route_table(&rt)) {
2155 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
2157 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
2163 close_route_table();
2167 /********************************************************************
2169 * sifdefaultroute - assign a default route through the address given.
2171 * If the global default_rt_repl_rest flag is set, then this function
2172 * already replaced the original system defaultroute with some other
2173 * route and it should just replace the current defaultroute with
2174 * another one, without saving the current route. Use: demand mode,
2175 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2176 * and then changes the temporary addresses to the addresses for the real
2177 * ppp connection when it has come up.
2180 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
2182 struct rtentry rt, tmp_rt;
2183 struct rtentry *del_rt = NULL;
2185 if (default_rt_repl_rest) {
2186 /* We have already replaced the original defaultroute, if we
2187 * are called again, we will delete the current default route
2188 * and set the new default route in this function.
2189 * - this is normally only the case the doing demand: */
2190 if (defaultroute_exists(&tmp_rt, -1))
2192 } else if (!replace) {
2194 * We don't want to replace an existing route.
2195 * We may however add our route along an existing route with a different
2198 if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) {
2199 if (rt.rt_flags & RTF_GATEWAY)
2200 error("not replacing existing default route via %I with metric %d",
2201 SIN_ADDR(rt.rt_gateway), dfl_route_metric);
2203 error("not replacing existing default route through %s with metric %d",
2204 rt.rt_dev, dfl_route_metric);
2207 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
2208 strcmp( old_def_rt.rt_dev, ifname) != 0) {
2210 * We want to replace an existing route and did not replace an existing
2211 * default route yet, let's check if we should save and replace an
2212 * existing default route:
2214 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2216 if (old_gateway != gateway) {
2218 error("not replacing default route to %s [%I]",
2219 old_def_rt.rt_dev, old_gateway);
2222 /* we need to copy rt_dev because we need it permanent too: */
2223 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2224 strcpy(tmp_dev, old_def_rt.rt_dev);
2225 old_def_rt.rt_dev = tmp_dev;
2227 notice("replacing old default route to %s [%I]",
2228 old_def_rt.rt_dev, old_gateway);
2229 default_rt_repl_rest = 1;
2230 del_rt = &old_def_rt;
2235 memset (&rt, 0, sizeof (rt));
2236 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2239 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2241 if (kernel_version > KVERSION(2,1,0)) {
2242 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2243 SIN_ADDR(rt.rt_genmask) = 0L;
2246 rt.rt_flags = RTF_UP;
2247 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2248 if ( ! ok_error ( errno ))
2249 error("default route ioctl(SIOCADDRT): %m");
2252 if (default_rt_repl_rest && del_rt)
2253 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2254 if ( ! ok_error ( errno ))
2255 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2259 have_default_route = 1;
2263 /********************************************************************
2265 * cifdefaultroute - delete a default route through the address given.
2268 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2272 have_default_route = 0;
2274 memset (&rt, '\0', sizeof (rt));
2275 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2276 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2279 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2281 if (kernel_version > KVERSION(2,1,0)) {
2282 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2283 SIN_ADDR(rt.rt_genmask) = 0L;
2286 rt.rt_flags = RTF_UP;
2287 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2289 if ( ! ok_error ( errno ))
2290 error("default route ioctl(SIOCDELRT): %m");
2294 if (default_rt_repl_rest) {
2295 notice("restoring old default route to %s [%I]",
2296 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2297 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2298 if ( ! ok_error ( errno ))
2299 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2302 default_rt_repl_rest = 0;
2308 #ifdef PPP_WITH_IPV6CP
2310 * /proc/net/ipv6_route parsing stuff.
2312 static int route_dest_plen_col;
2313 static int open_route6_table (void);
2314 static int read_route6_table (struct in6_rtmsg *rt);
2316 /********************************************************************
2318 * open_route6_table - open the interface to the route table
2320 static int open_route6_table (void)
2324 close_route_table();
2326 path = path_to_procfs("/net/ipv6_route");
2327 route_fd = fopen (path, "r");
2328 if (route_fd == NULL) {
2329 error("can't open routing table %s: %m", path);
2333 /* default to usual columns */
2335 route_dest_plen_col = 1;
2337 route_metric_col = 5;
2338 route_flags_col = 8;
2340 route_num_cols = 10;
2345 /********************************************************************
2347 * read_route6_table - read the next entry from the route table
2350 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2357 for (i = 0; i < 4; i++) {
2358 memcpy(hex8, s + 8*i, 8);
2359 v = strtoul(hex8, NULL, 16);
2360 addr->s6_addr32[i] = v;
2364 static int read_route6_table(struct in6_rtmsg *rt)
2366 char *cols[ROUTE_MAX_COLS], *p;
2369 memset (rt, '\0', sizeof (struct in6_rtmsg));
2371 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2375 for (col = 0; col < route_num_cols; ++col) {
2376 cols[col] = strtok(p, route_delims);
2377 if (cols[col] == NULL)
2378 return 0; /* didn't get enough columns */
2382 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2383 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2384 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2386 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2387 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2388 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2393 /********************************************************************
2395 * defaultroute6_exists - determine if there is a default route
2398 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2402 if (!open_route6_table())
2405 while (read_route6_table(rt) != 0) {
2406 if ((rt->rtmsg_flags & RTF_UP) == 0)
2409 if (rt->rtmsg_dst_len != 0)
2411 if (rt->rtmsg_dst.s6_addr32[0] == 0L
2412 && rt->rtmsg_dst.s6_addr32[1] == 0L
2413 && rt->rtmsg_dst.s6_addr32[2] == 0L
2414 && rt->rtmsg_dst.s6_addr32[3] == 0L
2415 && (metric < 0 || rt->rtmsg_metric == metric)) {
2421 close_route_table();
2425 /********************************************************************
2427 * sif6defaultroute - assign a default route through the address given.
2429 * If the global default_rt_repl_rest flag is set, then this function
2430 * already replaced the original system defaultroute with some other
2431 * route and it should just replace the current defaultroute with
2432 * another one, without saving the current route. Use: demand mode,
2433 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2434 * and then changes the temporary addresses to the addresses for the real
2435 * ppp connection when it has come up.
2438 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2440 struct in6_rtmsg rt;
2441 char buf[IF_NAMESIZE];
2443 if (defaultroute6_exists(&rt, dfl_route_metric) &&
2444 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2445 if (rt.rtmsg_flags & RTF_GATEWAY)
2446 error("not replacing existing default route via gateway");
2448 error("not replacing existing default route through %s",
2449 if_indextoname(rt.rtmsg_ifindex, buf));
2453 memset (&rt, 0, sizeof (rt));
2455 rt.rtmsg_ifindex = if_nametoindex(ifname);
2456 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2457 rt.rtmsg_dst_len = 0;
2459 rt.rtmsg_flags = RTF_UP;
2460 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2461 if ( ! ok_error ( errno ))
2462 error("default route ioctl(SIOCADDRT): %m");
2466 have_default_route6 = 1;
2470 /********************************************************************
2472 * cif6defaultroute - delete a default route through the address given.
2475 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2477 struct in6_rtmsg rt;
2479 have_default_route6 = 0;
2481 memset (&rt, '\0', sizeof (rt));
2483 rt.rtmsg_ifindex = if_nametoindex(ifname);
2484 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2485 rt.rtmsg_dst_len = 0;
2487 rt.rtmsg_flags = RTF_UP;
2488 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2490 if ( ! ok_error ( errno ))
2491 error("default route ioctl(SIOCDELRT): %m");
2498 #endif /* PPP_WITH_IPV6CP */
2500 /********************************************************************
2502 * sifproxyarp - Make a proxy ARP entry for the peer.
2505 int sifproxyarp (int unit, u_int32_t his_adr)
2507 struct arpreq arpreq;
2510 if (has_proxy_arp == 0) {
2511 memset (&arpreq, '\0', sizeof(arpreq));
2513 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2514 SIN_ADDR(arpreq.arp_pa) = his_adr;
2515 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2517 * Get the hardware address of an interface on the same subnet
2518 * as our local address.
2520 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2521 sizeof(proxy_arp_dev))) {
2522 error("Cannot determine ethernet address for proxy ARP");
2525 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2527 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2528 if ( ! ok_error ( errno ))
2529 error("ioctl(SIOCSARP): %m");
2532 proxy_arp_addr = his_adr;
2536 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2537 if (forw_path != 0) {
2538 int fd = open(forw_path, O_WRONLY);
2540 if (write(fd, "1", 1) != 1)
2541 error("Couldn't enable IP forwarding: %m");
2551 /********************************************************************
2553 * cifproxyarp - Delete the proxy ARP entry for the peer.
2556 int cifproxyarp (int unit, u_int32_t his_adr)
2558 struct arpreq arpreq;
2560 if (has_proxy_arp) {
2562 memset (&arpreq, '\0', sizeof(arpreq));
2563 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2564 SIN_ADDR(arpreq.arp_pa) = his_adr;
2565 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2566 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2568 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2569 if ( ! ok_error ( errno ))
2570 warn("ioctl(SIOCDARP): %m");
2577 /********************************************************************
2579 * get_ether_addr - get the hardware address of an interface on the
2580 * the same subnet as ipaddr.
2583 static int get_ether_addr (u_int32_t ipaddr,
2584 struct sockaddr *hwaddr,
2585 char *name, int namelen)
2587 struct ifreq *ifr, *ifend;
2588 u_int32_t ina, mask;
2590 struct ifreq ifreq, bestifreq;
2592 struct ifreq ifs[MAX_IFS];
2594 u_int32_t bestmask=0;
2595 int found_interface = 0;
2597 ifc.ifc_len = sizeof(ifs);
2599 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2600 if ( ! ok_error ( errno ))
2601 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2606 * Scan through looking for an interface with an Internet
2607 * address on the same subnet as `ipaddr'.
2609 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2610 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2611 if (ifr->ifr_addr.sa_family == AF_INET) {
2612 ina = SIN_ADDR(ifr->ifr_addr);
2613 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2615 * Check that the interface is up, and not point-to-point
2618 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2621 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2624 * Get its netmask and check that it's on the right subnet.
2626 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2629 mask = SIN_ADDR(ifreq.ifr_addr);
2631 if (((ipaddr ^ ina) & mask) != 0)
2632 continue; /* no match */
2634 if (mask >= bestmask) {
2635 /* Compare using >= instead of > -- it is possible for
2636 an interface to have a netmask of 0.0.0.0 */
2637 found_interface = 1;
2644 if (!found_interface) return 0;
2646 strlcpy(name, bestifreq.ifr_name, namelen);
2648 /* trim off the :1 in eth0:1 */
2649 aliasp = strchr(name, ':');
2653 info("found interface %s for proxy arp", name);
2655 * Now get the hardware address.
2657 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2658 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2659 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2664 &bestifreq.ifr_hwaddr,
2665 sizeof (struct sockaddr));
2671 * get_if_hwaddr - get the hardware address for the specified
2672 * network interface device.
2675 get_if_hwaddr(u_char *addr, char *name)
2680 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2683 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2684 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2685 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2688 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2693 * get_first_ether_hwaddr - get the hardware address for the first
2694 * ethernet-style interface on this system.
2697 get_first_ether_hwaddr(u_char *addr)
2699 struct if_nameindex *if_ni, *i;
2703 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2707 if_ni = if_nameindex();
2715 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2716 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2717 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2718 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2719 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2720 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2726 if_freenameindex(if_ni);
2732 /********************************************************************
2734 * Return user specified netmask, modified by any mask we might determine
2735 * for address `addr' (in network byte order).
2736 * Here we scan through the system's list of interfaces, looking for
2737 * any non-point-to-point interfaces which might appear to be on the same
2738 * network as `addr'. If we find any, we OR in their netmask to the
2739 * user-specified netmask.
2742 u_int32_t GetMask (u_int32_t addr)
2744 u_int32_t mask, nmask, ina;
2745 struct ifreq *ifr, *ifend, ifreq;
2747 struct ifreq ifs[MAX_IFS];
2751 if (IN_CLASSA(addr)) /* determine network mask for address class */
2752 nmask = IN_CLASSA_NET;
2753 else if (IN_CLASSB(addr))
2754 nmask = IN_CLASSB_NET;
2756 nmask = IN_CLASSC_NET;
2758 /* class D nets are disallowed by bad_ip_adrs */
2759 mask = netmask | htonl(nmask);
2761 * Scan through the system's network interfaces.
2763 ifc.ifc_len = sizeof(ifs);
2765 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2766 if ( ! ok_error ( errno ))
2767 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2771 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2772 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2774 * Check the interface's internet address.
2776 if (ifr->ifr_addr.sa_family != AF_INET)
2778 ina = SIN_ADDR(ifr->ifr_addr);
2779 if (((ntohl(ina) ^ addr) & nmask) != 0)
2782 * Check that the interface is up, and not point-to-point nor loopback.
2784 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2785 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2788 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2791 * Get its netmask and OR it into our mask.
2793 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2795 mask |= SIN_ADDR(ifreq.ifr_addr);
2801 /********************************************************************
2803 * Internal routine to decode the version.modification.patch level
2806 static void decode_version (char *buf, int *version,
2807 int *modification, int *patch)
2811 *version = (int) strtoul (buf, &endp, 10);
2815 if (endp != buf && *endp == '.') {
2817 *modification = (int) strtoul (buf, &endp, 10);
2818 if (endp != buf && *endp == '.') {
2820 *patch = (int) strtoul (buf, &buf, 10);
2825 /********************************************************************
2827 * Procedure to determine if the PPP line discipline is registered.
2831 ppp_registered(void)
2839 * We used to open the serial device and set it to the ppp line
2840 * discipline here, in order to create a ppp unit. But that is
2841 * not a good idea - the user might have specified a device that
2842 * they can't open (permission, or maybe it doesn't really exist).
2843 * So we grab a pty master/slave pair and use that.
2845 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2846 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2851 * Try to put the device into the PPP discipline.
2853 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2854 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2863 /********************************************************************
2865 * ppp_check_kernel_support - check whether the system has any ppp interfaces
2866 * (in fact we check whether we can do an ioctl on ppp0).
2869 int ppp_check_kernel_support(void)
2874 int my_version, my_modification, my_patch;
2875 int osmaj, osmin, ospatch;
2877 /* get the kernel version now, since we are called before sys_init */
2879 osmaj = osmin = ospatch = 0;
2880 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2881 kernel_version = KVERSION(osmaj, osmin, ospatch);
2883 fd = open("/dev/ppp", O_RDWR);
2885 new_style_driver = 1;
2887 /* XXX should get from driver */
2889 driver_modification = 4;
2895 if (kernel_version >= KVERSION(2,3,13)) {
2896 error("Couldn't open the /dev/ppp device: %m");
2897 if (errno == ENOENT)
2899 "You need to create the /dev/ppp device node by\n"
2900 "executing the following command as root:\n"
2901 " mknod /dev/ppp c 108 0\n";
2902 else if (errno == ENODEV || errno == ENXIO)
2904 "Please load the ppp_generic kernel module.\n";
2908 /* we are running on a really really old kernel */
2910 "This system lacks kernel support for PPP. This could be because\n"
2911 "the PPP kernel module could not be loaded, or because PPP was not\n"
2912 "included in the kernel configuration. If PPP was included as a\n"
2913 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2914 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2915 "See README.linux file in the ppp distribution for more details.\n";
2918 * Open a socket for doing the ioctl operations.
2920 s = socket(AF_INET, SOCK_DGRAM, 0);
2924 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2925 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2927 * If the device did not exist then attempt to create one by putting the
2928 * current tty into the PPP discipline. If this works then obtain the
2929 * flags for the device again.
2932 if (ppp_registered()) {
2933 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2934 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2938 * Ensure that the hardware address is for PPP and not something else
2941 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2943 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2947 * This is the PPP device. Validate the version of the driver at this
2948 * point to ensure that this program will work with the driver.
2951 char abBuffer [1024];
2953 ifr.ifr_data = abBuffer;
2954 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2956 error("Couldn't read driver version: %m");
2958 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2961 decode_version(abBuffer,
2963 &driver_modification,
2966 * Validate the version of the driver against the version that we used.
2968 decode_version(VERSION,
2973 /* The version numbers must match */
2974 if (driver_version != my_version)
2977 /* The modification levels must be legal */
2978 if (driver_modification < 3) {
2979 if (driver_modification >= 2) {
2980 /* we can cope with 2.2.0 and above */
2988 slprintf(route_buffer, sizeof(route_buffer),
2989 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2990 driver_version, driver_modification, driver_patch);
2992 no_ppp_msg = route_buffer;
3000 #ifndef HAVE_LOGWTMP
3001 /********************************************************************
3003 * Update the wtmp file with the appropriate user name and tty device.
3006 void logwtmp (const char *line, const char *name, const char *host)
3008 struct utmp ut, *utp;
3009 pid_t mypid = getpid();
3015 * Update the signon database for users.
3016 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
3018 utmpname(_PATH_UTMP);
3020 while ((utp = getutent()) && (utp->ut_pid != mypid))
3024 memcpy(&ut, utp, sizeof(ut));
3026 /* some gettys/telnetds don't initialize utmp... */
3027 memset(&ut, 0, sizeof(ut));
3029 if (ut.ut_id[0] == 0)
3030 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
3032 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
3033 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
3037 ut.ut_type = USER_PROCESS;
3040 /* Insert the host name if one is supplied */
3042 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
3044 /* Insert the IP address of the remote system if IP is enabled */
3045 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
3046 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
3047 sizeof(ut.ut_addr));
3049 /* CL: Makes sure that the logout works */
3050 if (*host == 0 && *name==0)
3056 * Update the wtmp file.
3059 updwtmp(_PATH_WTMP, &ut);
3061 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
3063 flock(wtmp, LOCK_EX);
3065 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
3066 warn("error writing %s: %m", _PATH_WTMP);
3068 flock(wtmp, LOCK_UN);
3074 #endif /* HAVE_LOGWTMP */
3076 /********************************************************************
3078 * sifvjcomp - config tcp header compression
3081 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
3086 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
3087 error("Couldn't set up TCP header compression: %m");
3092 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
3093 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
3098 /********************************************************************
3100 * sifup - Config the interface up and enable IP packets to pass.
3107 if ((ret = setifstate(u, 1)))
3113 /********************************************************************
3115 * sifdown - Disable the indicated protocol and config the interface
3116 * down if there are no remaining protocols.
3121 if (if_is_up && --if_is_up > 0)
3124 #ifdef PPP_WITH_IPV6CP
3127 #endif /* PPP_WITH_IPV6CP */
3129 return setifstate(u, 0);
3132 #ifdef PPP_WITH_IPV6CP
3133 /********************************************************************
3135 * sif6up - Config the interface up for IPv6
3142 if ((ret = setifstate(u, 1)))
3148 /********************************************************************
3150 * sif6down - Disable the IPv6CP protocol and config the interface
3151 * down if there are no remaining protocols.
3154 int sif6down (int u)
3161 return setifstate(u, 0);
3163 #endif /* PPP_WITH_IPV6CP */
3165 /********************************************************************
3167 * setifstate - Config the interface up or down
3170 static int setifstate (int u, int state)
3174 memset (&ifr, '\0', sizeof (ifr));
3175 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3176 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
3177 if (! ok_error (errno))
3178 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
3183 ifr.ifr_flags |= IFF_UP;
3185 ifr.ifr_flags &= ~IFF_UP;
3186 ifr.ifr_flags |= IFF_POINTOPOINT;
3187 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
3188 if (! ok_error (errno))
3189 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
3195 /********************************************************************
3197 * sifaddr - Config the interface IP addresses and netmask.
3200 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3206 memset (&ifr, '\0', sizeof (ifr));
3207 memset (&rt, '\0', sizeof (rt));
3209 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
3210 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3211 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3213 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3215 * Set our IP address
3217 SIN_ADDR(ifr.ifr_addr) = our_adr;
3218 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3219 if (errno != EEXIST) {
3220 if (! ok_error (errno))
3221 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3224 warn("ioctl(SIOCSIFADDR): Address already exists");
3229 * Set the gateway address
3232 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3233 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3234 if (! ok_error (errno))
3235 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3241 * For recent kernels, force the netmask to 255.255.255.255.
3243 if (kernel_version >= KVERSION(2,1,16))
3245 if (net_mask != 0) {
3246 SIN_ADDR(ifr.ifr_netmask) = net_mask;
3247 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3248 if (! ok_error (errno))
3249 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3254 * Add the device route
3256 if (kernel_version < KVERSION(2,1,16)) {
3257 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3258 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3261 SIN_ADDR(rt.rt_gateway) = 0L;
3262 SIN_ADDR(rt.rt_dst) = his_adr;
3263 rt.rt_flags = RTF_UP | RTF_HOST;
3265 if (kernel_version > KVERSION(2,1,0)) {
3266 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3267 SIN_ADDR(rt.rt_genmask) = -1L;
3270 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3271 if (! ok_error (errno))
3272 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3277 /* set ip_dynaddr in demand mode if address changes */
3278 if (demand && tune_kernel && !dynaddr_set
3279 && our_old_addr && our_old_addr != our_adr) {
3280 /* set ip_dynaddr if possible */
3284 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3285 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3286 if (write(fd, "1", 1) != 1)
3287 error("Couldn't enable dynamic IP addressing: %m");
3290 dynaddr_set = 1; /* only 1 attempt */
3297 /********************************************************************
3299 * cifaddr - Clear the interface IP addresses, and delete routes
3300 * through the interface if possible.
3303 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3307 if (kernel_version < KVERSION(2,1,16)) {
3309 * Delete the route through the device
3312 memset (&rt, '\0', sizeof (rt));
3314 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3315 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3318 SIN_ADDR(rt.rt_gateway) = 0;
3319 SIN_ADDR(rt.rt_dst) = his_adr;
3320 rt.rt_flags = RTF_UP | RTF_HOST;
3322 if (kernel_version > KVERSION(2,1,0)) {
3323 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3324 SIN_ADDR(rt.rt_genmask) = -1L;
3327 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3328 if (still_ppp() && ! ok_error (errno))
3329 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3334 /* This way it is possible to have an IPv6-only interface */
3335 memset(&ifr, 0, sizeof(ifr));
3336 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3337 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3339 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3340 if (! ok_error (errno)) {
3341 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3346 our_old_addr = our_adr;
3351 #ifdef PPP_WITH_IPV6CP
3352 /********************************************************************
3354 * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3356 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3359 struct nlmsghdr nlh;
3360 struct ifaddrmsg ifa;
3363 struct in6_addr addr;
3368 memset(&nlreq, 0, sizeof(nlreq));
3369 nlreq.nlh.nlmsg_len = sizeof(nlreq);
3370 nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3371 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3372 nlreq.ifa.ifa_family = AF_INET6;
3373 nlreq.ifa.ifa_prefixlen = 128;
3374 nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3375 nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3376 nlreq.ifa.ifa_index = iface;
3377 nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3378 nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3379 IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3380 nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3381 nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3384 * To set only local address, older kernel expects that local address is
3385 * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3386 * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3387 * compatibility when setting only local address, set it via both IFA_LOCAL
3388 * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3389 * from iproute2 project.
3391 if (!eui64_iszero(his_eui64))
3392 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3394 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3396 resp = rtnetlink_msg("RTM_NEWADDR/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
3399 * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3400 * addresses and error response is expected. On older kernel versions
3401 * do not show this error message. On error pppd tries to fallback to
3402 * the old IOCTL method.
3404 errno = (resp < 0) ? -resp : EINVAL;
3405 if (kernel_version >= KVERSION(3,11,0))
3406 error("sif6addr_rtnetlink: %m (line %d)", __LINE__);
3413 /********************************************************************
3415 * sif6addr - Config the interface with an IPv6 link-local address
3417 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3419 struct in6_ifreq ifr6;
3421 struct in6_rtmsg rt6;
3426 error("IPv6 socket creation failed: %m");
3429 memset(&ifr, 0, sizeof (ifr));
3430 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3431 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3432 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3436 if (kernel_version >= KVERSION(2,1,16)) {
3437 /* Set both local address and remote peer address (with route for it) via rtnetlink */
3438 ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3444 * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3445 * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3448 /* Local interface */
3449 memset(&ifr6, 0, sizeof(ifr6));
3450 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3451 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3452 ifr6.ifr6_prefixlen = 128;
3454 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3455 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3460 if (!ret && !eui64_iszero(his_eui64)) {
3462 * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3463 * setting remote peer host address, so set only route to remote host.
3466 /* Route to remote host */
3467 memset(&rt6, 0, sizeof(rt6));
3468 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3469 rt6.rtmsg_flags = RTF_UP;
3470 rt6.rtmsg_dst_len = 128;
3471 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3472 rt6.rtmsg_metric = 1;
3474 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3475 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3484 /********************************************************************
3486 * cif6addr - Remove IPv6 address from interface
3488 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3491 struct in6_ifreq ifr6;
3495 error("IPv6 socket creation failed: %m");
3498 memset(&ifr, 0, sizeof(ifr));
3499 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3500 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3501 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3505 memset(&ifr6, 0, sizeof(ifr6));
3506 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3507 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3508 ifr6.ifr6_prefixlen = 128;
3510 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3511 if (errno != EADDRNOTAVAIL) {
3512 if (! ok_error (errno))
3513 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3516 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3522 #endif /* PPP_WITH_IPV6CP */
3525 * get_pty - get a pty master/slave pair and chown the slave side
3526 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
3529 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3531 int i, mfd, ret, sfd = -1;
3533 struct termios tios;
3537 * Try the unix98 way first.
3539 mfd = open("/dev/ptmx", O_RDWR);
3542 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3543 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3544 chmod(pty_name, S_IRUSR | S_IWUSR);
3547 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3548 warn("Couldn't unlock pty slave %s: %m", pty_name);
3550 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3552 warn("Couldn't open pty slave %s: %m", pty_name);
3557 #endif /* TIOCGPTN */
3560 /* the old way - scan through the pty name space */
3561 for (i = 0; i < 64; ++i) {
3562 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3563 'p' + i / 16, i % 16);
3564 mfd = open(pty_name, O_RDWR, 0);
3567 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3569 ret = fchown(sfd, uid, -1);
3571 warn("Couldn't change ownership of %s, %m", pty_name);
3573 ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3575 warn("Couldn't change permissions of %s, %m", pty_name);
3587 strlcpy(slave_name, pty_name, 16);
3590 if (tcgetattr(sfd, &tios) == 0) {
3591 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3592 tios.c_cflag |= CS8 | CREAD | CLOCAL;
3593 tios.c_iflag = IGNPAR;
3596 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3597 warn("couldn't set attributes on pty: %m");
3599 warn("couldn't get attributes on pty: %m");
3604 /********************************************************************
3606 * open_loopback - open the device we use for getting packets
3607 * in demand mode. Under Linux, we use a pty master/slave pair.
3610 open_ppp_loopback(void)
3615 if (new_style_driver) {
3616 /* allocate ourselves a ppp unit */
3617 if (make_ppp_unit() < 0)
3619 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3620 set_kdebugflag(kdebugflag);
3625 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3626 fatal("No free pty for loopback");
3628 set_ppp_fd(slave_fd);
3630 flags = fcntl(master_fd, F_GETFL);
3632 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3633 warn("couldn't set master loopback to nonblock: %m");
3635 flags = fcntl(ppp_fd, F_GETFL);
3637 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3638 warn("couldn't set slave loopback to nonblock: %m");
3640 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3641 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3643 * Find out which interface we were given.
3645 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3646 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3648 * Enable debug in the driver if requested.
3650 set_kdebugflag (kdebugflag);
3655 /********************************************************************
3657 * sifnpmode - Set the mode for handling packets for a given NP.
3661 sifnpmode(int u, int proto, enum NPmode mode)
3665 npi.protocol = proto;
3667 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3668 if (! ok_error (errno))
3669 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3676 * Use the hostname as part of the random number seed.
3685 for (p = hostname; *p != 0; ++p)
3690 /********************************************************************
3692 * sys_check_options - check the options that the user specified
3696 sys_check_options(void)
3698 if (demand && driver_is_old) {
3699 ppp_option_error("demand dialling is not supported by kernel driver "
3700 "version %d.%d.%d", driver_version, driver_modification,
3704 if (multilink && !new_style_driver) {
3705 warn("Warning: multilink is not supported by the kernel driver");
3711 /********************************************************************
3713 * get_time - Get current time, monotonic if possible.
3716 ppp_get_time(struct timeval *tv)
3718 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3719 * Runtime checking makes it safe. */
3720 #ifndef CLOCK_MONOTONIC
3721 #define CLOCK_MONOTONIC 1
3723 static int monotonic = -1;
3728 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3732 tv->tv_sec = ts.tv_sec;
3733 tv->tv_usec = ts.tv_nsec / 1000;
3736 } else if (monotonic > 0)
3740 warn("Couldn't use monotonic clock source: %m");
3743 return gettimeofday(tv, NULL);