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
162 #include "pppd-private.h"
167 #ifdef PPP_WITH_IPV6CP
169 #endif /* PPP_WITH_IPV6CP */
171 #include "multilink.h"
173 #ifdef PPP_WITH_FILTER
174 #include <pcap-bpf.h>
175 #include <linux/filter.h>
176 #endif /* PPP_WITH_FILTER */
179 #include <sys/locks.h>
183 * Instead of system header file <termios.h> use local "termios_linux.h" header
184 * file as it provides additional support for arbitrary baud rates via BOTHER.
186 #include "termios_linux.h"
188 #ifdef PPP_WITH_IPV6CP
191 * This is in linux/include/net/ipv6.h.
195 struct in6_addr ifr6_addr;
196 __u32 ifr6_prefixlen;
197 unsigned int ifr6_ifindex;
201 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
202 memset(&(sin6).s6_addr, 0, sizeof(struct in6_addr)); \
203 (sin6).s6_addr16[0] = htons(0xfe80); \
204 eui64_copy(eui64, (sin6).s6_addr32[2]); \
207 static const eui64_t nulleui64;
208 #endif /* PPP_WITH_IPV6CP */
210 /* We can get an EIO error on an ioctl if the modem has hung up */
211 #define ok_error(num) ((num)==EIO)
213 static int tty_disc = N_TTY; /* The TTY discipline */
214 static int ppp_disc = N_PPP; /* The PPP discpline */
215 static int initfdflags = -1; /* Initial file descriptor flags for fd */
216 static int ppp_fd = -1; /* fd which is set to PPP discipline */
217 static int sock_fd = -1; /* socket for doing interface ioctls */
218 static int slave_fd = -1; /* pty for old-style demand mode, slave */
219 static int master_fd = -1; /* pty for old-style demand mode, master */
220 #ifdef PPP_WITH_IPV6CP
221 static int sock6_fd = -1;
222 #endif /* PPP_WITH_IPV6CP */
225 * For the old-style kernel driver, this is the same as ppp_fd.
226 * For the new-style driver, it is the fd of an instance of /dev/ppp
227 * which is attached to the ppp unit and is used for controlling it.
229 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
231 static int chindex; /* channel index (new style driver) */
233 static fd_set in_fds; /* set of fds that wait_input waits for */
234 static int max_in_fd; /* highest fd set in in_fds */
236 static int has_proxy_arp = 0;
237 static int driver_version = 0;
238 static int driver_modification = 0;
239 static int driver_patch = 0;
240 static int driver_is_old = 0;
241 static int restore_term = 0; /* 1 => we've munged the terminal */
242 static struct termios inittermios; /* Initial TTY termios */
244 int new_style_driver = 0;
246 static char loop_name[20];
247 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
249 static int if_is_up; /* Interface has been marked up */
250 static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
251 static int have_default_route; /* Gateway for default route added */
252 static int have_default_route6; /* Gateway for default IPv6 route added */
253 static struct rtentry old_def_rt; /* Old default route */
254 static int default_rt_repl_rest; /* replace and restore old default rt */
255 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
256 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
257 static u_int32_t our_old_addr; /* for detecting address changes */
258 static int dynaddr_set; /* 1 if ip_dynaddr set */
259 static int looped; /* 1 if using loop */
260 static int link_mtu; /* mtu for the link (not bundle) */
262 static struct utsname utsname; /* for the kernel version */
263 static int kernel_version;
264 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
268 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
269 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
270 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
272 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
274 /* Prototypes for procedures local to this file. */
275 static int modify_flags(int fd, int clear_bits, int set_bits);
276 static int translate_speed (int bps);
277 static int baud_rate_of (int speed);
278 static void close_route_table (void);
279 static int open_route_table (void);
280 static int read_route_table (struct rtentry *rt);
281 static int defaultroute_exists (struct rtentry *rt, int metric);
282 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
283 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
284 char *name, int namelen);
285 static void decode_version (char *buf, int *version, int *mod, int *patch);
286 static int set_kdebugflag(int level);
287 static int ppp_registered(void);
288 static int make_ppp_unit(void);
289 static int setifstate (int u, int state);
291 extern u_char inpacket_buf[]; /* borrowed from main.c */
293 extern int dfl_route_metric;
296 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
300 #define SET_SA_FAMILY(addr, family) \
301 memset ((char *) &(addr), '\0', sizeof(addr)); \
302 addr.sa_family = (family);
306 * rtnetlink_msg - send rtnetlink message, receive response
307 * and return received error code:
309 * positive value - error during sending / receiving message
310 * negative value - rtnetlink responce error code
312 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)
316 struct nlmsgerr nlerr;
318 struct sockaddr_nl nladdr;
325 if (shared_fd && *shared_fd >= 0) {
328 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
330 error("rtnetlink_msg: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
335 * Tell kernel to not send to us payload of acknowledgment error message.
336 * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
337 * older kernel versions always send full payload in acknowledgment netlink
338 * message. We ignore payload of this message as we need only error code,
339 * to check if our set remote peer address request succeeded or failed.
340 * So ignore return value from the following setsockopt() call as setting
341 * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
344 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
346 memset(&nladdr, 0, sizeof(nladdr));
347 nladdr.nl_family = AF_NETLINK;
349 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
350 error("rtnetlink_msg: bind(AF_NETLINK): %m (line %d)", __LINE__);
359 memset(&nladdr, 0, sizeof(nladdr));
360 nladdr.nl_family = AF_NETLINK;
362 memset(&iov[0], 0, sizeof(iov[0]));
363 iov[0].iov_base = nlreq;
364 iov[0].iov_len = nlreq_len;
366 memset(&msg, 0, sizeof(msg));
367 msg.msg_name = &nladdr;
368 msg.msg_namelen = sizeof(nladdr);
369 msg.msg_iov = &iov[0];
372 if (sendmsg(fd, &msg, 0) < 0) {
373 error("rtnetlink_msg: sendmsg(%s): %m (line %d)", desc, __LINE__);
379 memset(iov, 0, sizeof(iov));
380 iov[0].iov_base = &nlresp_hdr;
381 if (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) {
382 iov[0].iov_len = offsetof(struct nlresp_hdr, nlerr);
383 iov[1].iov_base = nlresp_data;
384 iov[1].iov_len = *nlresp_size;
386 iov[0].iov_len = sizeof(nlresp_hdr);
389 memset(&msg, 0, sizeof(msg));
390 msg.msg_name = &nladdr;
391 msg.msg_namelen = sizeof(nladdr);
393 msg.msg_iovlen = (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) ? 2 : 1;
395 nlresp_len = recvmsg(fd, &msg, 0);
400 if (nlresp_len < 0) {
401 error("rtnetlink_msg: recvmsg(%s): %m (line %d)", desc, __LINE__);
405 if (nladdr.nl_family != AF_NETLINK) {
406 error("rtnetlink_msg: recvmsg(%s): Not a netlink packet (line %d)", desc, __LINE__);
411 if ((size_t)nlresp_len < sizeof(nlresp_hdr) || nlresp_hdr.nlh.nlmsg_len < sizeof(nlresp_hdr)) {
412 error("rtnetlink_msg: recvmsg(%s): Acknowledgment netlink packet too short (line %d)", desc, __LINE__);
416 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
417 if (nlresp_hdr.nlh.nlmsg_type != NLMSG_ERROR) {
418 error("rtnetlink_msg: recvmsg(%s): Not an acknowledgment netlink packet (line %d)", desc, __LINE__);
424 if (*nlresp_size > sizeof(nlresp_hdr))
425 memcpy((unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), nlresp_data, sizeof(nlresp_hdr.nlerr));
427 memcpy(nlresp_data, (unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), *nlresp_size);
430 /* error == 0 indicates success, negative value is errno code */
431 if (nlresp_hdr.nlh.nlmsg_type == NLMSG_ERROR && nlresp_hdr.nlerr.error)
432 return nlresp_hdr.nlerr.error;
435 if (nlresp_hdr.nlh.nlmsg_type != nlresp_type) {
436 error("rtnetlink_msg: recvmsg(%s): Not a netlink packet of type 0x%x (line %d)", desc, nlresp_type, __LINE__);
439 *nlresp_size = nlresp_len - offsetof(struct nlresp_hdr, nlerr);
446 * Determine if the PPP connection should still be present.
451 /* new_fd is the fd of a tty */
452 static void set_ppp_fd (int new_fd)
455 if (!new_style_driver)
459 static int still_ppp(void)
461 if (new_style_driver)
462 return !hungup && ppp_fd >= 0;
463 if (!hungup || ppp_fd == slave_fd)
466 set_ppp_fd(slave_fd);
473 * modify_flags - set and clear flag bits controlling the kernel
476 static int modify_flags(int fd, int clear_bits, int set_bits)
480 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
482 flags = (flags & ~clear_bits) | set_bits;
483 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
490 error("Failed to set PPP kernel option flags: %m");
494 /********************************************************************
496 * sys_init - System-dependent initialization.
501 /* Get an internet socket for doing socket ioctls. */
502 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
504 fatal("Couldn't create IP socket: %m(%d)", errno);
506 #ifdef PPP_WITH_IPV6CP
507 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
509 sock6_fd = -errno; /* save errno for later */
516 /********************************************************************
518 * sys_cleanup - restore any system state we modified before exiting:
519 * mark the interface down, delete default route and/or proxy arp entry.
520 * This shouldn't call die() because it's called from die().
523 void sys_cleanup(void)
526 * Take down the device
532 #ifdef PPP_WITH_IPV6CP
538 * Delete any routes through the device.
540 if (have_default_route)
541 cifdefaultroute(0, 0, 0);
542 #ifdef PPP_WITH_IPV6CP
543 if (have_default_route6)
544 cif6defaultroute(0, nulleui64, nulleui64);
548 cifproxyarp(0, proxy_arp_addr);
551 /********************************************************************
553 * ppp_sys_close - Clean up in a child process before execing.
558 if (new_style_driver && ppp_dev_fd >= 0)
562 #ifdef PPP_WITH_IPV6CP
572 /********************************************************************
574 * set_kdebugflag - Define the debugging level for the kernel
577 static int set_kdebugflag (int requested_level)
581 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
582 if ( ! ok_error (errno) )
583 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
589 /********************************************************************
591 * tty_establish_ppp - Turn the serial port into a ppp interface.
594 int tty_establish_ppp (int tty_fd)
599 * Ensure that the tty device is in exclusive mode.
601 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
602 if ( ! ok_error ( errno ))
603 warn("Couldn't make tty exclusive: %m");
606 * Demand mode - prime the old ppp device to relinquish the unit.
608 if (!new_style_driver && looped
609 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
610 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
614 * Set the current tty to the PPP discpline
618 #define N_SYNC_PPP 14
620 ppp_disc = (new_style_driver && ppp_sync_serial())? N_SYNC_PPP: N_PPP;
621 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
622 if ( ! ok_error (errno) ) {
623 error("Couldn't set tty to PPP discipline: %m");
628 ret_fd = ppp_generic_establish(tty_fd);
630 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
631 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
635 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
636 (kdebugflag * SC_DEBUG) & SC_LOGB);
638 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
639 warn("Couldn't reset tty to normal line discipline: %m");
645 /********************************************************************
647 * generic_establish_ppp - Turn the fd into a ppp interface.
649 int ppp_generic_establish (int fd)
653 if (new_style_driver) {
656 /* If a ppp_fd is already open, close it first */
663 /* Open an instance of /dev/ppp and connect the channel to it */
664 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
665 error("Couldn't get channel number: %m");
668 dbglog("using channel %d", chindex);
669 fd = open("/dev/ppp", O_RDWR);
671 error("Couldn't reopen /dev/ppp: %m");
674 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
675 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
676 error("Couldn't attach to channel %d: %m", chindex);
679 flags = fcntl(fd, F_GETFL);
680 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
681 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
686 if (!looped && !multilink) {
688 * Create a new PPP unit.
690 if (make_ppp_unit() < 0)
695 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
699 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
700 error("Couldn't attach to PPP unit %d: %m", ifunit);
707 * Old-style driver: find out which interface we were given.
710 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
711 if (ok_error (errno))
713 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
715 /* Check that we got the same unit again. */
716 if (looped && x != ifunit)
717 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
721 * Fetch the initial file flags and reset blocking mode on the file.
723 initfdflags = fcntl(fd, F_GETFL);
724 if (initfdflags == -1 ||
725 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
726 if ( ! ok_error (errno))
727 warn("Couldn't set device to non-blocking mode: %m");
732 * Enable debug in the driver if requested.
735 set_kdebugflag (kdebugflag);
747 /********************************************************************
749 * tty_disestablish_ppp - Restore the serial port to normal operation.
750 * This shouldn't call die() because it's called from die().
753 void tty_disestablish_ppp(int tty_fd)
757 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
759 if (tcflush(tty_fd, TCIOFLUSH) < 0)
761 warn("tcflush failed: %m");
765 * Restore the previous line discipline
767 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
768 if ( ! ok_error (errno))
769 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
772 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
773 if ( ! ok_error (errno))
774 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
777 /* Reset non-blocking mode on fd. */
778 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
779 if ( ! ok_error (errno))
780 warn("Couldn't restore device fd flags: %m");
786 ppp_generic_disestablish(tty_fd);
789 /********************************************************************
791 * ppp_generic_disestablish - Restore device components to normal
792 * operation, and reconnect the ppp unit to the loopback if in demand
793 * mode. This shouldn't call die() because it's called from die().
795 void ppp_generic_disestablish(int dev_fd)
797 if (new_style_driver) {
801 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
803 } else if (!mp_on() && ppp_dev_fd >= 0) {
805 remove_fd(ppp_dev_fd);
809 /* old-style driver */
811 set_ppp_fd(slave_fd);
818 * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd
819 * with specified req_ifname via rtnetlink. Interface name req_ifname must not
820 * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free.
822 static int make_ppp_unit_rtnetlink(void)
826 struct ifinfomsg ifm;
829 char ifname[IFNAMSIZ];
835 char ifkind[sizeof("ppp")];
850 memset(&nlreq, 0, sizeof(nlreq));
851 nlreq.nlh.nlmsg_len = sizeof(nlreq);
852 nlreq.nlh.nlmsg_type = RTM_NEWLINK;
853 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
854 nlreq.ifm.ifi_family = AF_UNSPEC;
855 nlreq.ifm.ifi_type = ARPHRD_NETROM;
856 nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
857 nlreq.ifn.rta.rta_type = IFLA_IFNAME;
858 strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
859 nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
860 nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
861 nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
862 nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
863 strcpy(nlreq.ifli.ifik.ifkind, "ppp");
864 nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
865 nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
866 nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
867 nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
868 nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
871 * See kernel function ppp_nl_newlink(), which may return -EBUSY to prevent
872 * possible deadlock in kernel and ask userspace to retry request again.
875 resp = rtnetlink_msg("RTM_NEWLINK/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
876 } while (resp == -EBUSY);
880 * Linux kernel versions prior to 4.7 do not support creating ppp
881 * interfaces via rtnetlink API and therefore error response is
882 * expected. On older kernel versions do not show this error message.
883 * When error is different than EEXIST then pppd tries to fallback to
884 * the old ioctl method.
886 errno = (resp < 0) ? -resp : EINVAL;
887 if (kernel_version >= KVERSION(4,7,0))
888 error("Couldn't create ppp interface %s: %m", req_ifname);
896 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
897 * Assumes new_style_driver.
899 static int make_ppp_unit(void)
903 if (ppp_dev_fd >= 0) {
904 dbglog("in make_ppp_unit, already had /dev/ppp open?");
907 ppp_dev_fd = open("/dev/ppp", O_RDWR);
909 fatal("Couldn't open /dev/ppp: %m");
910 flags = fcntl(ppp_dev_fd, F_GETFL);
912 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
913 warn("Couldn't set /dev/ppp to nonblock: %m");
916 * Via rtnetlink it is possible to create ppp network interface with
917 * custom ifname atomically. But it is not possible to specify custom
920 * Tools like systemd, udev or NetworkManager are trying to query
921 * interface attributes based on interface name immediately when new
922 * network interface is created. And therefore immediate interface
923 * renaming is causing issues.
925 * So use rtnetlink API only when user requested custom ifname. It will
926 * avoid system issues with interface renaming.
928 if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) {
929 if (make_ppp_unit_rtnetlink()) {
930 if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit))
931 fatal("Couldn't retrieve PPP unit id: %m");
935 * If interface with requested name already exist return error
936 * otherwise fallback to old ioctl method.
943 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
944 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
945 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
947 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
949 if (x < 0 && errno == EEXIST) {
950 srand(time(NULL) * getpid());
951 ifunit = rand() % 10000;
952 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
955 error("Couldn't create new ppp unit: %m");
957 if (x == 0 && req_ifname[0] != '\0') {
960 memset(&ifr, 0, sizeof(struct ifreq));
961 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
962 strlcpy(ifr.ifr_name, t, IFNAMSIZ);
963 strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
964 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
966 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
968 info("Renamed interface %s to %s", t, req_ifname);
975 * cfg_bundle - configure the existing bundle.
976 * Used in demand mode.
978 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
980 if (!new_style_driver)
983 /* set the mrru, mtu and flags */
984 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
985 error("Couldn't set MRRU: %m");
987 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
988 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
989 | (mrru? SC_MULTILINK: 0)));
991 /* connect up the channel */
992 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
993 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
998 * make_new_bundle - create a new PPP unit (i.e. a bundle)
999 * and connect our channel to it. This should only get called
1000 * if `multilink' was set at the time establish_ppp was called.
1001 * In demand mode this uses our existing bundle instead of making
1004 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
1006 if (!new_style_driver)
1009 /* make us a ppp unit */
1010 if (make_ppp_unit() < 0)
1013 /* set the mrru and flags */
1014 cfg_bundle(mrru, mtru, rssn, tssn);
1018 * bundle_attach - attach our link to a given PPP unit.
1019 * We assume the unit is controlled by another pppd.
1021 int bundle_attach(int ifnum)
1025 if (!new_style_driver)
1028 master_fd = open("/dev/ppp", O_RDWR);
1030 fatal("Couldn't open /dev/ppp: %m");
1031 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
1032 if (errno == ENXIO) {
1034 return 0; /* doesn't still exist */
1036 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
1038 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
1039 fatal("Couldn't connect to interface unit %d: %m", ifnum);
1040 modify_flags(master_fd, 0, SC_MULTILINK);
1048 * destroy_bundle - tell the driver to destroy our bundle.
1050 void destroy_bundle(void)
1052 if (ppp_dev_fd >= 0) {
1054 remove_fd(ppp_dev_fd);
1059 /********************************************************************
1061 * clean_check - Fetch the flags for the device and generate
1062 * appropriate error messages.
1064 void clean_check(void)
1070 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
1072 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
1074 s = "all had bit 7 set to 1";
1078 s = "all had bit 7 set to 0";
1082 s = "all had odd parity";
1086 s = "all had even parity";
1091 warn("Receive serial link is not 8-bit clean:");
1092 warn("Problem: %s", s);
1100 * List of valid speeds.
1104 int speed_int, speed_val;
1167 { 115200, B115200 },
1170 { 153600, B153600 },
1179 { 230400, B230400 },
1182 { 307200, B307200 },
1185 { 460800, B460800 },
1188 { 500000, B500000 },
1191 { 576000, B576000 },
1194 { 614400, B614400 },
1197 { 921600, B921600 },
1200 { 1000000, B1000000 },
1203 { 1152000, B1152000 },
1206 { 1500000, B1500000 },
1209 { 2000000, B2000000 },
1212 { 2500000, B2500000 },
1215 { 3000000, B3000000 },
1218 { 3500000, B3500000 },
1221 { 4000000, B4000000 },
1226 /********************************************************************
1228 * Translate from bits/second to a speed_t.
1231 static int translate_speed (int bps)
1233 struct speed *speedp;
1236 for (speedp = speeds; speedp->speed_int; speedp++) {
1237 if (bps == speedp->speed_int)
1238 return speedp->speed_val;
1244 /********************************************************************
1246 * Translate from a speed_t to bits/second.
1249 static int baud_rate_of (int speed)
1251 struct speed *speedp;
1254 for (speedp = speeds; speedp->speed_int; speedp++) {
1255 if (speed == speedp->speed_val)
1256 return speedp->speed_int;
1262 /********************************************************************
1264 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
1265 * at the requested speed, etc. If `local' is true, set CLOCAL
1266 * regardless of whether the modem option was specified.
1269 void set_up_tty(int tty_fd, int local)
1272 struct termios tios;
1275 if (tcgetattr(tty_fd, &tios) < 0) {
1276 if (!ok_error(errno))
1277 fatal("tcgetattr: %m (line %d)", __LINE__);
1284 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1285 tios.c_cflag |= CS8 | CREAD | HUPCL;
1287 tios.c_iflag = IGNBRK | IGNPAR;
1290 tios.c_cc[VMIN] = 1;
1291 tios.c_cc[VTIME] = 0;
1293 if (local || !modem)
1294 tios.c_cflag ^= (CLOCAL | HUPCL);
1298 tios.c_cflag |= CRTSCTS;
1302 tios.c_iflag |= IXON | IXOFF;
1303 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
1304 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1308 tios.c_cflag &= ~CRTSCTS;
1316 tios.c_cflag |= CSTOPB;
1319 speed = translate_speed(inspeed);
1321 cfsetospeed (&tios, speed);
1322 cfsetispeed (&tios, speed);
1323 speed = cfgetospeed(&tios);
1324 baud_rate = baud_rate_of(speed);
1327 tios.c_cflag &= ~CBAUD;
1328 tios.c_cflag |= BOTHER;
1329 tios.c_ospeed = inspeed;
1331 /* B0 sets input baudrate to the output baudrate */
1332 tios.c_cflag &= ~(CBAUD << IBSHIFT);
1333 tios.c_cflag |= B0 << IBSHIFT;
1334 tios.c_ispeed = inspeed;
1336 baud_rate = inspeed;
1343 speed = cfgetospeed(&tios);
1344 baud_rate = baud_rate_of(speed);
1347 baud_rate = tios.c_ospeed;
1352 * We can't proceed if the serial port baud rate is unknown,
1353 * since that implies that the serial port is disabled.
1357 fatal("speed %d not supported", inspeed);
1359 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1362 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1364 fatal("tcsetattr: %m (line %d)", __LINE__);
1368 /********************************************************************
1370 * setdtr - control the DTR line on the serial port.
1371 * This is called from die(), so it shouldn't call die().
1374 void setdtr (int tty_fd, int on)
1376 int modembits = TIOCM_DTR;
1378 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1381 /********************************************************************
1383 * restore_tty - restore the terminal to the saved settings.
1386 void restore_tty (int tty_fd)
1391 * Turn off echoing, because otherwise we can get into
1392 * a loop with the tty and the modem echoing to each other.
1393 * We presume we are the sole user of this tty device, so
1394 * when we close it, it will revert to its defaults anyway.
1396 if (!default_device)
1397 inittermios.c_lflag &= ~(ECHO | ECHONL);
1399 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1400 if (! ok_error (errno))
1401 warn("tcsetattr: %m (line %d)", __LINE__);
1406 /********************************************************************
1408 * output - Output PPP packet.
1411 void output (int unit, unsigned char *p, int len)
1416 dump_packet("sent", p, len);
1417 if (snoop_send_hook) snoop_send_hook(p, len);
1419 if (len < PPP_HDRLEN)
1421 if (new_style_driver) {
1424 proto = (p[0] << 8) + p[1];
1425 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1428 if (write(fd, p, len) < 0) {
1429 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1430 || errno == ENXIO || errno == EIO || errno == EINTR)
1431 warn("write: warning: %m (%d)", errno);
1433 error("write: %m (%d)", errno);
1437 /********************************************************************
1439 * wait_input - wait until there is data available,
1440 * for the length of time specified by *timo (indefinite
1444 void wait_input(struct timeval *timo)
1451 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1452 if (n < 0 && errno != EINTR)
1453 fatal("select: %m");
1457 * add_fd - add an fd to the set that wait_input waits for.
1461 if (fd >= FD_SETSIZE)
1462 fatal("internal error: file descriptor too large (%d)", fd);
1463 FD_SET(fd, &in_fds);
1469 * remove_fd - remove an fd from the set that wait_input waits for.
1471 void remove_fd(int fd)
1473 FD_CLR(fd, &in_fds);
1477 /********************************************************************
1479 * read_packet - get a PPP packet from the serial device.
1482 int read_packet (unsigned char *buf)
1486 len = PPP_MRU + PPP_HDRLEN;
1487 if (new_style_driver) {
1488 *buf++ = PPP_ALLSTATIONS;
1494 nr = read(ppp_fd, buf, len);
1495 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1496 && errno != EIO && errno != EINTR)
1498 if (nr < 0 && errno == ENXIO)
1501 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1502 /* N.B. we read ppp_fd first since LCP packets come in there. */
1503 nr = read(ppp_dev_fd, buf, len);
1504 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1505 && errno != EIO && errno != EINTR)
1506 error("read /dev/ppp: %m");
1507 if (nr < 0 && errno == ENXIO)
1509 if (nr == 0 && mp_on()) {
1510 remove_fd(ppp_dev_fd);
1514 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1516 return (new_style_driver && nr > 0)? nr+2: nr;
1519 /********************************************************************
1521 * get_loop_output - get outgoing packets from the ppp device,
1522 * and detect when we want to bring the real link up.
1523 * Return value is 1 if we need to bring up the link, 0 otherwise.
1526 get_loop_output(void)
1531 if (new_style_driver) {
1532 while ((n = read_packet(inpacket_buf)) > 0)
1533 if (loop_frame(inpacket_buf, n))
1538 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1539 if (loop_chars(inbuf, n))
1543 fatal("eof on loopback");
1545 if (errno != EWOULDBLOCK && errno != EAGAIN)
1546 fatal("read from loopback: %m(%d)", errno);
1552 * netif_set_mtu - set the MTU on the PPP network interface.
1555 ppp_set_mtu(int unit, int mtu)
1559 memset (&ifr, '\0', sizeof (ifr));
1560 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1563 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1564 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1568 * netif_get_mtu - get the MTU on the PPP network interface.
1571 ppp_get_mtu(int unit)
1575 memset (&ifr, '\0', sizeof (ifr));
1576 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1578 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1579 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1585 /********************************************************************
1587 * tty_send_config - configure the transmit characteristics of
1588 * the ppp interface.
1591 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1598 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1599 if (errno != EIO && errno != ENOTTY)
1600 error("Couldn't set transmit async character map: %m");
1605 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1606 | (ppp_sync_serial()? SC_SYNC: 0);
1607 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1610 /********************************************************************
1612 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1615 void tty_set_xaccm (ext_accm accm)
1619 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1620 if ( ! ok_error (errno))
1621 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1625 /********************************************************************
1627 * tty_recv_config - configure the receive-side characteristics of
1628 * the ppp interface.
1631 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1634 * If we were called because the link has gone down then there is nothing
1635 * which may be done. Just return without incident.
1640 * Set the receiver parameters
1642 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1643 if (errno != EIO && errno != ENOTTY)
1644 error("Couldn't set channel receive MRU: %m");
1646 if (new_style_driver && ppp_dev_fd >= 0
1647 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1648 error("Couldn't set MRU in generic PPP layer: %m");
1650 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1651 if (errno != EIO && errno != ENOTTY)
1652 error("Couldn't set channel receive asyncmap: %m");
1656 /********************************************************************
1658 * ccp_test - ask kernel whether a given compression method
1659 * is acceptable for use.
1663 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1665 struct ppp_option_data data;
1667 memset (&data, '\0', sizeof (data));
1669 data.length = opt_len;
1670 data.transmit = for_transmit;
1672 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1675 return (errno == ENOBUFS)? 0: -1;
1678 /********************************************************************
1680 * ccp_flags_set - inform kernel about the current state of CCP.
1683 void ccp_flags_set (int unit, int isopen, int isup)
1687 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1688 if (still_ppp() && ppp_dev_fd >= 0)
1689 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1692 #ifdef PPP_WITH_FILTER
1694 * set_filters - set the active and pass filters in the kernel driver.
1696 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1698 struct sock_fprog fp;
1700 fp.len = pass->bf_len;
1701 fp.filter = (struct sock_filter *) pass->bf_insns;
1702 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1703 if (errno == ENOTTY)
1704 warn("kernel does not support PPP filtering");
1706 error("Couldn't set pass-filter in kernel: %m");
1709 fp.len = active->bf_len;
1710 fp.filter = (struct sock_filter *) active->bf_insns;
1711 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1712 error("Couldn't set active-filter in kernel: %m");
1717 #endif /* PPP_WITH_FILTER */
1719 /********************************************************************
1721 * get_idle_time - return how long the link has been idle.
1724 get_idle_time(int u, struct ppp_idle *ip)
1726 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1729 /********************************************************************
1731 * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1732 * this only supports 32-bit counters, so need to count the wraps.
1735 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1737 static u_int32_t previbytes = 0;
1738 static u_int32_t prevobytes = 0;
1739 static u_int32_t iwraps = 0;
1740 static u_int32_t owraps = 0;
1743 struct ppp_stats data;
1745 memset (&req, 0, sizeof (req));
1747 req.ifr_data = (caddr_t) &data;
1748 strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
1749 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1750 error("Couldn't get PPP statistics: %m");
1753 stats->bytes_in = data.p.ppp_ibytes;
1754 stats->bytes_out = data.p.ppp_obytes;
1755 stats->pkts_in = data.p.ppp_ipackets;
1756 stats->pkts_out = data.p.ppp_opackets;
1758 if (stats->bytes_in < previbytes)
1760 if (stats->bytes_out < prevobytes)
1763 previbytes = stats->bytes_in;
1764 prevobytes = stats->bytes_out;
1766 stats->bytes_in += (uint64_t)iwraps << 32;
1767 stats->bytes_out += (uint64_t)owraps << 32;
1772 /********************************************************************
1773 * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1774 * This provides native 64-bit counters.
1777 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1782 struct nlmsghdr nlh;
1783 struct if_stats_msg ifsm;
1788 /* We only case about these first fields from rtnl_link_stats64 */
1789 uint64_t rx_packets;
1790 uint64_t tx_packets;
1798 memset(&nlreq, 0, sizeof(nlreq));
1799 nlreq.nlh.nlmsg_len = sizeof(nlreq);
1800 nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1801 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1802 nlreq.ifsm.ifindex = if_nametoindex(ifname);
1803 nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1805 nlresp_size = sizeof(nlresp_data);
1806 resp = rtnetlink_msg("RTM_GETSTATS/NLM_F_REQUEST", &fd, &nlreq, sizeof(nlreq), &nlresp_data, &nlresp_size, RTM_NEWSTATS);
1808 errno = (resp < 0) ? -resp : EINVAL;
1809 if (kernel_version >= KVERSION(4,7,0))
1810 error("get_ppp_stats_rtnetlink: %m (line %d)", __LINE__);
1814 if (nlresp_size < sizeof(nlresp_data)) {
1815 error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1819 stats->bytes_in = nlresp_data.stats.rx_bytes;
1820 stats->bytes_out = nlresp_data.stats.tx_bytes;
1821 stats->pkts_in = nlresp_data.stats.rx_packets;
1822 stats->pkts_out = nlresp_data.stats.tx_packets;
1831 /********************************************************************
1832 * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1833 * this provides native 64-bit counters.
1836 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1838 char fname[PATH_MAX+1];
1839 char buf[21], *err; /* 2^64 < 10^20 */
1841 unsigned long long val;
1848 #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1849 statfield(rx_bytes, bytes_in),
1850 statfield(tx_bytes, bytes_out),
1851 statfield(rx_packets, pkts_in),
1852 statfield(tx_packets, pkts_out),
1856 blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1857 if (blen >= sizeof(fname))
1858 return 0; /* ifname max 15, so this should be impossible */
1860 for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1861 if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1863 error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1867 fd = open(fname, O_RDONLY);
1869 error("%s: %m", fname);
1873 rlen = read(fd, buf, sizeof(buf) - 1);
1876 error("%s: %m", fname);
1879 /* trim trailing \n if present */
1880 while (rlen > 0 && buf[rlen-1] == '\n')
1885 val = strtoull(buf, &err, 10);
1886 if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1887 error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1888 buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1891 switch (slist[i].size) {
1892 #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1899 error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1907 /********************************************************************
1908 * Periodic timer function to be used to keep stats up to date in case of ioctl
1911 * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1912 * If you do change the timer, remember to also bring the get_ppp_stats (which
1913 * sets up the initial trigger) as well.
1916 ppp_stats_poller(void* u)
1918 struct pppd_stats dummy;
1919 get_ppp_stats_ioctl((long)u, &dummy);
1920 TIMEOUT(ppp_stats_poller, u, 25);
1923 /********************************************************************
1924 * get_ppp_stats - return statistics for the link.
1926 int get_ppp_stats(int u, struct pppd_stats *stats)
1928 static int (*func)(int, struct pppd_stats*) = NULL;
1931 if (get_ppp_stats_rtnetlink(u, stats)) {
1932 func = get_ppp_stats_rtnetlink;
1935 if (get_ppp_stats_sysfs(u, stats)) {
1936 func = get_ppp_stats_sysfs;
1939 warn("statistics falling back to ioctl which only supports 32-bit counters");
1940 func = get_ppp_stats_ioctl;
1941 TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1944 return func(u, stats);
1947 /********************************************************************
1949 * ccp_fatal_error - returns 1 if decompression was disabled as a
1950 * result of an error detected after decompression of a packet,
1951 * 0 otherwise. This is necessary because of patent nonsense.
1954 int ccp_fatal_error (int unit)
1958 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1959 error("Couldn't read compression error flags: %m");
1962 return flags & SC_DC_FERROR;
1965 /********************************************************************
1967 * path_to_procfs - find the path to the proc file system mount point
1969 static char proc_path[MAXPATHLEN];
1970 static int proc_path_len;
1972 static char *path_to_procfs(const char *tail)
1974 struct mntent *mntent;
1977 if (proc_path_len == 0) {
1978 /* Default the mount location of /proc */
1979 strlcpy (proc_path, "/proc", sizeof(proc_path));
1981 fp = fopen(MOUNTED, "r");
1983 while ((mntent = getmntent(fp)) != NULL) {
1984 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1986 if (strcmp(mntent->mnt_type, "proc") == 0) {
1987 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1988 proc_path_len = strlen(proc_path);
1996 strlcpy(proc_path + proc_path_len, tail,
1997 sizeof(proc_path) - proc_path_len);
2002 * /proc/net/route parsing stuff.
2004 #define ROUTE_MAX_COLS 12
2005 FILE *route_fd = (FILE *) 0;
2006 static char route_buffer[512];
2007 static int route_dev_col, route_dest_col, route_gw_col;
2008 static int route_flags_col, route_metric_col, route_mask_col;
2009 static int route_num_cols;
2011 static int open_route_table (void);
2012 static void close_route_table (void);
2013 static int read_route_table (struct rtentry *rt);
2015 /********************************************************************
2017 * close_route_table - close the interface to the route table
2020 static void close_route_table (void)
2022 if (route_fd != (FILE *) 0) {
2024 route_fd = (FILE *) 0;
2028 /********************************************************************
2030 * open_route_table - open the interface to the route table
2032 static char route_delims[] = " \t\n";
2034 static int open_route_table (void)
2038 close_route_table();
2040 path = path_to_procfs("/net/route");
2041 route_fd = fopen (path, "r");
2042 if (route_fd == NULL) {
2043 error("can't open routing table %s: %m", path);
2047 route_dev_col = 0; /* default to usual columns */
2050 route_flags_col = 3;
2051 route_metric_col = 6;
2055 /* parse header line */
2056 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
2057 char *p = route_buffer, *q;
2059 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
2061 if ((q = strtok(p, route_delims)) == 0)
2063 if (strcasecmp(q, "iface") == 0)
2064 route_dev_col = col;
2065 else if (strcasecmp(q, "destination") == 0)
2066 route_dest_col = col;
2067 else if (strcasecmp(q, "gateway") == 0)
2069 else if (strcasecmp(q, "flags") == 0)
2070 route_flags_col = col;
2071 else if (strcasecmp(q, "mask") == 0)
2072 route_mask_col = col;
2075 if (used && col >= route_num_cols)
2076 route_num_cols = col + 1;
2084 /********************************************************************
2086 * read_route_table - read the next entry from the route table
2089 static int read_route_table(struct rtentry *rt)
2091 char *cols[ROUTE_MAX_COLS], *p;
2094 memset (rt, '\0', sizeof (struct rtentry));
2096 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2100 for (col = 0; col < route_num_cols; ++col) {
2101 cols[col] = strtok(p, route_delims);
2102 if (cols[col] == NULL)
2103 return 0; /* didn't get enough columns */
2107 SET_SA_FAMILY (rt->rt_dst, AF_INET);
2108 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
2110 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
2111 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
2112 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
2114 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
2115 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
2116 rt->rt_dev = cols[route_dev_col];
2121 /********************************************************************
2123 * defaultroute_exists - determine if there is a default route
2124 * with the given metric (or negative for any)
2127 static int defaultroute_exists (struct rtentry *rt, int metric)
2131 if (!open_route_table())
2134 while (read_route_table(rt) != 0) {
2135 if ((rt->rt_flags & RTF_UP) == 0)
2138 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
2140 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
2141 || rt->rt_metric == metric)) {
2147 close_route_table();
2152 * have_route_to - determine if the system has any route to
2153 * a given IP address. `addr' is in network byte order.
2154 * Return value is 1 if yes, 0 if no, -1 if don't know.
2155 * For demand mode to work properly, we have to ignore routes
2156 * through our own interface.
2158 int have_route_to(u_int32_t addr)
2163 if (!open_route_table())
2164 return -1; /* don't know */
2166 while (read_route_table(&rt)) {
2167 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
2169 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
2175 close_route_table();
2179 /********************************************************************
2181 * sifdefaultroute - assign a default route through the address given.
2183 * If the global default_rt_repl_rest flag is set, then this function
2184 * already replaced the original system defaultroute with some other
2185 * route and it should just replace the current defaultroute with
2186 * another one, without saving the current route. Use: demand mode,
2187 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2188 * and then changes the temporary addresses to the addresses for the real
2189 * ppp connection when it has come up.
2192 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
2194 struct rtentry rt, tmp_rt;
2195 struct rtentry *del_rt = NULL;
2197 if (default_rt_repl_rest) {
2198 /* We have already replaced the original defaultroute, if we
2199 * are called again, we will delete the current default route
2200 * and set the new default route in this function.
2201 * - this is normally only the case the doing demand: */
2202 if (defaultroute_exists(&tmp_rt, -1))
2204 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
2205 strcmp( old_def_rt.rt_dev, ifname) != 0) {
2207 * We did not yet replace an existing default route, let's
2208 * check if we should save and replace a default route:
2210 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2212 if (old_gateway != gateway) {
2214 error("not replacing default route to %s [%I]",
2215 old_def_rt.rt_dev, old_gateway);
2218 /* we need to copy rt_dev because we need it permanent too: */
2219 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2220 strcpy(tmp_dev, old_def_rt.rt_dev);
2221 old_def_rt.rt_dev = tmp_dev;
2223 notice("replacing old default route to %s [%I]",
2224 old_def_rt.rt_dev, old_gateway);
2225 default_rt_repl_rest = 1;
2226 del_rt = &old_def_rt;
2231 memset (&rt, 0, sizeof (rt));
2232 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2235 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2237 if (kernel_version > KVERSION(2,1,0)) {
2238 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2239 SIN_ADDR(rt.rt_genmask) = 0L;
2242 rt.rt_flags = RTF_UP;
2243 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2244 if ( ! ok_error ( errno ))
2245 error("default route ioctl(SIOCADDRT): %m");
2248 if (default_rt_repl_rest && del_rt)
2249 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2250 if ( ! ok_error ( errno ))
2251 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2255 have_default_route = 1;
2259 /********************************************************************
2261 * cifdefaultroute - delete a default route through the address given.
2264 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2268 have_default_route = 0;
2270 memset (&rt, '\0', sizeof (rt));
2271 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2272 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2277 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2279 if (kernel_version > KVERSION(2,1,0)) {
2280 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2281 SIN_ADDR(rt.rt_genmask) = 0L;
2284 rt.rt_flags = RTF_UP;
2285 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2287 if ( ! ok_error ( errno ))
2288 error("default route ioctl(SIOCDELRT): %m");
2292 if (default_rt_repl_rest) {
2293 notice("restoring old default route to %s [%I]",
2294 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2295 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2296 if ( ! ok_error ( errno ))
2297 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2300 default_rt_repl_rest = 0;
2306 #ifdef PPP_WITH_IPV6CP
2308 * /proc/net/ipv6_route parsing stuff.
2310 static int route_dest_plen_col;
2311 static int open_route6_table (void);
2312 static int read_route6_table (struct in6_rtmsg *rt);
2314 /********************************************************************
2316 * open_route6_table - open the interface to the route table
2318 static int open_route6_table (void)
2322 close_route_table();
2324 path = path_to_procfs("/net/ipv6_route");
2325 route_fd = fopen (path, "r");
2326 if (route_fd == NULL) {
2327 error("can't open routing table %s: %m", path);
2331 /* default to usual columns */
2333 route_dest_plen_col = 1;
2335 route_metric_col = 5;
2336 route_flags_col = 8;
2338 route_num_cols = 10;
2343 /********************************************************************
2345 * read_route6_table - read the next entry from the route table
2348 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2355 for (i = 0; i < 4; i++) {
2356 memcpy(hex8, s + 8*i, 8);
2357 v = strtoul(hex8, NULL, 16);
2358 addr->s6_addr32[i] = v;
2362 static int read_route6_table(struct in6_rtmsg *rt)
2364 char *cols[ROUTE_MAX_COLS], *p;
2367 memset (rt, '\0', sizeof (struct in6_rtmsg));
2369 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2373 for (col = 0; col < route_num_cols; ++col) {
2374 cols[col] = strtok(p, route_delims);
2375 if (cols[col] == NULL)
2376 return 0; /* didn't get enough columns */
2380 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2381 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2382 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2384 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2385 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2386 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2391 /********************************************************************
2393 * defaultroute6_exists - determine if there is a default route
2396 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2400 if (!open_route6_table())
2403 while (read_route6_table(rt) != 0) {
2404 if ((rt->rtmsg_flags & RTF_UP) == 0)
2407 if (rt->rtmsg_dst_len != 0)
2409 if (rt->rtmsg_dst.s6_addr32[0] == 0L
2410 && rt->rtmsg_dst.s6_addr32[1] == 0L
2411 && rt->rtmsg_dst.s6_addr32[2] == 0L
2412 && rt->rtmsg_dst.s6_addr32[3] == 0L
2413 && (metric < 0 || rt->rtmsg_metric == metric)) {
2419 close_route_table();
2423 /********************************************************************
2425 * sif6defaultroute - assign a default route through the address given.
2427 * If the global default_rt_repl_rest flag is set, then this function
2428 * already replaced the original system defaultroute with some other
2429 * route and it should just replace the current defaultroute with
2430 * another one, without saving the current route. Use: demand mode,
2431 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2432 * and then changes the temporary addresses to the addresses for the real
2433 * ppp connection when it has come up.
2436 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2438 struct in6_rtmsg rt;
2439 char buf[IF_NAMESIZE];
2441 if (defaultroute6_exists(&rt, dfl_route_metric) &&
2442 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2443 if (rt.rtmsg_flags & RTF_GATEWAY)
2444 error("not replacing existing default route via gateway");
2446 error("not replacing existing default route through %s",
2447 if_indextoname(rt.rtmsg_ifindex, buf));
2451 memset (&rt, 0, sizeof (rt));
2453 rt.rtmsg_ifindex = if_nametoindex(ifname);
2454 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2455 rt.rtmsg_dst_len = 0;
2457 rt.rtmsg_flags = RTF_UP;
2458 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2459 if ( ! ok_error ( errno ))
2460 error("default route ioctl(SIOCADDRT): %m");
2464 have_default_route6 = 1;
2468 /********************************************************************
2470 * cif6defaultroute - delete a default route through the address given.
2473 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2475 struct in6_rtmsg rt;
2477 have_default_route6 = 0;
2479 memset (&rt, '\0', sizeof (rt));
2481 rt.rtmsg_ifindex = if_nametoindex(ifname);
2482 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2483 rt.rtmsg_dst_len = 0;
2485 rt.rtmsg_flags = RTF_UP;
2486 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2488 if ( ! ok_error ( errno ))
2489 error("default route ioctl(SIOCDELRT): %m");
2496 #endif /* PPP_WITH_IPV6CP */
2498 /********************************************************************
2500 * sifproxyarp - Make a proxy ARP entry for the peer.
2503 int sifproxyarp (int unit, u_int32_t his_adr)
2505 struct arpreq arpreq;
2508 if (has_proxy_arp == 0) {
2509 memset (&arpreq, '\0', sizeof(arpreq));
2511 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2512 SIN_ADDR(arpreq.arp_pa) = his_adr;
2513 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2515 * Get the hardware address of an interface on the same subnet
2516 * as our local address.
2518 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2519 sizeof(proxy_arp_dev))) {
2520 error("Cannot determine ethernet address for proxy ARP");
2523 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2525 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2526 if ( ! ok_error ( errno ))
2527 error("ioctl(SIOCSARP): %m");
2530 proxy_arp_addr = his_adr;
2534 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2535 if (forw_path != 0) {
2536 int fd = open(forw_path, O_WRONLY);
2538 if (write(fd, "1", 1) != 1)
2539 error("Couldn't enable IP forwarding: %m");
2549 /********************************************************************
2551 * cifproxyarp - Delete the proxy ARP entry for the peer.
2554 int cifproxyarp (int unit, u_int32_t his_adr)
2556 struct arpreq arpreq;
2558 if (has_proxy_arp) {
2560 memset (&arpreq, '\0', sizeof(arpreq));
2561 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2562 SIN_ADDR(arpreq.arp_pa) = his_adr;
2563 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2564 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2566 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2567 if ( ! ok_error ( errno ))
2568 warn("ioctl(SIOCDARP): %m");
2575 /********************************************************************
2577 * get_ether_addr - get the hardware address of an interface on the
2578 * the same subnet as ipaddr.
2581 static int get_ether_addr (u_int32_t ipaddr,
2582 struct sockaddr *hwaddr,
2583 char *name, int namelen)
2585 struct ifreq *ifr, *ifend;
2586 u_int32_t ina, mask;
2588 struct ifreq ifreq, bestifreq;
2590 struct ifreq ifs[MAX_IFS];
2592 u_int32_t bestmask=0;
2593 int found_interface = 0;
2595 ifc.ifc_len = sizeof(ifs);
2597 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2598 if ( ! ok_error ( errno ))
2599 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2604 * Scan through looking for an interface with an Internet
2605 * address on the same subnet as `ipaddr'.
2607 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2608 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2609 if (ifr->ifr_addr.sa_family == AF_INET) {
2610 ina = SIN_ADDR(ifr->ifr_addr);
2611 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2613 * Check that the interface is up, and not point-to-point
2616 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2619 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2622 * Get its netmask and check that it's on the right subnet.
2624 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2627 mask = SIN_ADDR(ifreq.ifr_addr);
2629 if (((ipaddr ^ ina) & mask) != 0)
2630 continue; /* no match */
2632 if (mask >= bestmask) {
2633 /* Compare using >= instead of > -- it is possible for
2634 an interface to have a netmask of 0.0.0.0 */
2635 found_interface = 1;
2642 if (!found_interface) return 0;
2644 strlcpy(name, bestifreq.ifr_name, namelen);
2646 /* trim off the :1 in eth0:1 */
2647 aliasp = strchr(name, ':');
2651 info("found interface %s for proxy arp", name);
2653 * Now get the hardware address.
2655 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2656 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2657 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2662 &bestifreq.ifr_hwaddr,
2663 sizeof (struct sockaddr));
2669 * get_if_hwaddr - get the hardware address for the specified
2670 * network interface device.
2673 get_if_hwaddr(u_char *addr, char *name)
2678 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2681 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2682 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2683 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2686 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2691 * get_first_ether_hwaddr - get the hardware address for the first
2692 * ethernet-style interface on this system.
2695 get_first_ether_hwaddr(u_char *addr)
2697 struct if_nameindex *if_ni, *i;
2701 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2705 if_ni = if_nameindex();
2713 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2714 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2715 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2716 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2717 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2718 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2724 if_freenameindex(if_ni);
2730 /********************************************************************
2732 * Return user specified netmask, modified by any mask we might determine
2733 * for address `addr' (in network byte order).
2734 * Here we scan through the system's list of interfaces, looking for
2735 * any non-point-to-point interfaces which might appear to be on the same
2736 * network as `addr'. If we find any, we OR in their netmask to the
2737 * user-specified netmask.
2740 u_int32_t GetMask (u_int32_t addr)
2742 u_int32_t mask, nmask, ina;
2743 struct ifreq *ifr, *ifend, ifreq;
2745 struct ifreq ifs[MAX_IFS];
2749 if (IN_CLASSA(addr)) /* determine network mask for address class */
2750 nmask = IN_CLASSA_NET;
2751 else if (IN_CLASSB(addr))
2752 nmask = IN_CLASSB_NET;
2754 nmask = IN_CLASSC_NET;
2756 /* class D nets are disallowed by bad_ip_adrs */
2757 mask = netmask | htonl(nmask);
2759 * Scan through the system's network interfaces.
2761 ifc.ifc_len = sizeof(ifs);
2763 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2764 if ( ! ok_error ( errno ))
2765 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2769 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2770 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2772 * Check the interface's internet address.
2774 if (ifr->ifr_addr.sa_family != AF_INET)
2776 ina = SIN_ADDR(ifr->ifr_addr);
2777 if (((ntohl(ina) ^ addr) & nmask) != 0)
2780 * Check that the interface is up, and not point-to-point nor loopback.
2782 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2783 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2786 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2789 * Get its netmask and OR it into our mask.
2791 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2793 mask |= SIN_ADDR(ifreq.ifr_addr);
2799 /********************************************************************
2801 * Internal routine to decode the version.modification.patch level
2804 static void decode_version (char *buf, int *version,
2805 int *modification, int *patch)
2809 *version = (int) strtoul (buf, &endp, 10);
2813 if (endp != buf && *endp == '.') {
2815 *modification = (int) strtoul (buf, &endp, 10);
2816 if (endp != buf && *endp == '.') {
2818 *patch = (int) strtoul (buf, &buf, 10);
2823 /********************************************************************
2825 * Procedure to determine if the PPP line discipline is registered.
2829 ppp_registered(void)
2837 * We used to open the serial device and set it to the ppp line
2838 * discipline here, in order to create a ppp unit. But that is
2839 * not a good idea - the user might have specified a device that
2840 * they can't open (permission, or maybe it doesn't really exist).
2841 * So we grab a pty master/slave pair and use that.
2843 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2844 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2849 * Try to put the device into the PPP discipline.
2851 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2852 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2861 /********************************************************************
2863 * ppp_check_kernel_support - check whether the system has any ppp interfaces
2864 * (in fact we check whether we can do an ioctl on ppp0).
2867 int ppp_check_kernel_support(void)
2872 int my_version, my_modification, my_patch;
2873 int osmaj, osmin, ospatch;
2875 /* get the kernel version now, since we are called before sys_init */
2877 osmaj = osmin = ospatch = 0;
2878 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2879 kernel_version = KVERSION(osmaj, osmin, ospatch);
2881 fd = open("/dev/ppp", O_RDWR);
2883 new_style_driver = 1;
2885 /* XXX should get from driver */
2887 driver_modification = 4;
2893 if (kernel_version >= KVERSION(2,3,13)) {
2894 error("Couldn't open the /dev/ppp device: %m");
2895 if (errno == ENOENT)
2897 "You need to create the /dev/ppp device node by\n"
2898 "executing the following command as root:\n"
2899 " mknod /dev/ppp c 108 0\n";
2900 else if (errno == ENODEV || errno == ENXIO)
2902 "Please load the ppp_generic kernel module.\n";
2906 /* we are running on a really really old kernel */
2908 "This system lacks kernel support for PPP. This could be because\n"
2909 "the PPP kernel module could not be loaded, or because PPP was not\n"
2910 "included in the kernel configuration. If PPP was included as a\n"
2911 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2912 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2913 "See README.linux file in the ppp distribution for more details.\n";
2916 * Open a socket for doing the ioctl operations.
2918 s = socket(AF_INET, SOCK_DGRAM, 0);
2922 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2923 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2925 * If the device did not exist then attempt to create one by putting the
2926 * current tty into the PPP discipline. If this works then obtain the
2927 * flags for the device again.
2930 if (ppp_registered()) {
2931 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2932 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2936 * Ensure that the hardware address is for PPP and not something else
2939 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2941 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2945 * This is the PPP device. Validate the version of the driver at this
2946 * point to ensure that this program will work with the driver.
2949 char abBuffer [1024];
2951 ifr.ifr_data = abBuffer;
2952 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2954 error("Couldn't read driver version: %m");
2956 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2959 decode_version(abBuffer,
2961 &driver_modification,
2964 * Validate the version of the driver against the version that we used.
2966 decode_version(VERSION,
2971 /* The version numbers must match */
2972 if (driver_version != my_version)
2975 /* The modification levels must be legal */
2976 if (driver_modification < 3) {
2977 if (driver_modification >= 2) {
2978 /* we can cope with 2.2.0 and above */
2986 slprintf(route_buffer, sizeof(route_buffer),
2987 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2988 driver_version, driver_modification, driver_patch);
2990 no_ppp_msg = route_buffer;
2998 #ifndef HAVE_LOGWTMP
2999 /********************************************************************
3001 * Update the wtmp file with the appropriate user name and tty device.
3004 void logwtmp (const char *line, const char *name, const char *host)
3006 struct utmp ut, *utp;
3007 pid_t mypid = getpid();
3013 * Update the signon database for users.
3014 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
3016 utmpname(_PATH_UTMP);
3018 while ((utp = getutent()) && (utp->ut_pid != mypid))
3022 memcpy(&ut, utp, sizeof(ut));
3024 /* some gettys/telnetds don't initialize utmp... */
3025 memset(&ut, 0, sizeof(ut));
3027 if (ut.ut_id[0] == 0)
3028 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
3030 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
3031 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
3035 ut.ut_type = USER_PROCESS;
3038 /* Insert the host name if one is supplied */
3040 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
3042 /* Insert the IP address of the remote system if IP is enabled */
3043 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
3044 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
3045 sizeof(ut.ut_addr));
3047 /* CL: Makes sure that the logout works */
3048 if (*host == 0 && *name==0)
3054 * Update the wtmp file.
3057 updwtmp(_PATH_WTMP, &ut);
3059 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
3061 flock(wtmp, LOCK_EX);
3063 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
3064 warn("error writing %s: %m", _PATH_WTMP);
3066 flock(wtmp, LOCK_UN);
3072 #endif /* HAVE_LOGWTMP */
3074 /********************************************************************
3076 * sifvjcomp - config tcp header compression
3079 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
3084 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
3085 error("Couldn't set up TCP header compression: %m");
3090 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
3091 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
3096 /********************************************************************
3098 * sifup - Config the interface up and enable IP packets to pass.
3105 if ((ret = setifstate(u, 1)))
3111 /********************************************************************
3113 * sifdown - Disable the indicated protocol and config the interface
3114 * down if there are no remaining protocols.
3119 if (if_is_up && --if_is_up > 0)
3122 #ifdef PPP_WITH_IPV6CP
3125 #endif /* PPP_WITH_IPV6CP */
3127 return setifstate(u, 0);
3130 #ifdef PPP_WITH_IPV6CP
3131 /********************************************************************
3133 * sif6up - Config the interface up for IPv6
3140 if ((ret = setifstate(u, 1)))
3146 /********************************************************************
3148 * sif6down - Disable the IPv6CP protocol and config the interface
3149 * down if there are no remaining protocols.
3152 int sif6down (int u)
3159 return setifstate(u, 0);
3161 #endif /* PPP_WITH_IPV6CP */
3163 /********************************************************************
3165 * setifstate - Config the interface up or down
3168 static int setifstate (int u, int state)
3172 memset (&ifr, '\0', sizeof (ifr));
3173 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3174 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
3175 if (! ok_error (errno))
3176 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
3181 ifr.ifr_flags |= IFF_UP;
3183 ifr.ifr_flags &= ~IFF_UP;
3184 ifr.ifr_flags |= IFF_POINTOPOINT;
3185 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
3186 if (! ok_error (errno))
3187 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
3193 /********************************************************************
3195 * sifaddr - Config the interface IP addresses and netmask.
3198 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3204 memset (&ifr, '\0', sizeof (ifr));
3205 memset (&rt, '\0', sizeof (rt));
3207 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
3208 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3209 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3211 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3213 * Set our IP address
3215 SIN_ADDR(ifr.ifr_addr) = our_adr;
3216 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3217 if (errno != EEXIST) {
3218 if (! ok_error (errno))
3219 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3222 warn("ioctl(SIOCSIFADDR): Address already exists");
3227 * Set the gateway address
3230 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3231 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3232 if (! ok_error (errno))
3233 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3239 * For recent kernels, force the netmask to 255.255.255.255.
3241 if (kernel_version >= KVERSION(2,1,16))
3243 if (net_mask != 0) {
3244 SIN_ADDR(ifr.ifr_netmask) = net_mask;
3245 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3246 if (! ok_error (errno))
3247 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3252 * Add the device route
3254 if (kernel_version < KVERSION(2,1,16)) {
3255 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3256 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3259 SIN_ADDR(rt.rt_gateway) = 0L;
3260 SIN_ADDR(rt.rt_dst) = his_adr;
3261 rt.rt_flags = RTF_UP | RTF_HOST;
3263 if (kernel_version > KVERSION(2,1,0)) {
3264 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3265 SIN_ADDR(rt.rt_genmask) = -1L;
3268 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3269 if (! ok_error (errno))
3270 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3275 /* set ip_dynaddr in demand mode if address changes */
3276 if (demand && tune_kernel && !dynaddr_set
3277 && our_old_addr && our_old_addr != our_adr) {
3278 /* set ip_dynaddr if possible */
3282 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3283 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3284 if (write(fd, "1", 1) != 1)
3285 error("Couldn't enable dynamic IP addressing: %m");
3288 dynaddr_set = 1; /* only 1 attempt */
3295 /********************************************************************
3297 * cifaddr - Clear the interface IP addresses, and delete routes
3298 * through the interface if possible.
3301 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3305 if (kernel_version < KVERSION(2,1,16)) {
3307 * Delete the route through the device
3310 memset (&rt, '\0', sizeof (rt));
3312 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3313 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3316 SIN_ADDR(rt.rt_gateway) = 0;
3317 SIN_ADDR(rt.rt_dst) = his_adr;
3318 rt.rt_flags = RTF_UP | RTF_HOST;
3320 if (kernel_version > KVERSION(2,1,0)) {
3321 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3322 SIN_ADDR(rt.rt_genmask) = -1L;
3325 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3326 if (still_ppp() && ! ok_error (errno))
3327 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3332 /* This way it is possible to have an IPv6-only interface */
3333 memset(&ifr, 0, sizeof(ifr));
3334 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3335 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3337 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3338 if (! ok_error (errno)) {
3339 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3344 our_old_addr = our_adr;
3349 #ifdef PPP_WITH_IPV6CP
3350 /********************************************************************
3352 * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3354 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3357 struct nlmsghdr nlh;
3358 struct ifaddrmsg ifa;
3361 struct in6_addr addr;
3366 memset(&nlreq, 0, sizeof(nlreq));
3367 nlreq.nlh.nlmsg_len = sizeof(nlreq);
3368 nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3369 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3370 nlreq.ifa.ifa_family = AF_INET6;
3371 nlreq.ifa.ifa_prefixlen = 128;
3372 nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3373 nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3374 nlreq.ifa.ifa_index = iface;
3375 nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3376 nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3377 IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3378 nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3379 nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3382 * To set only local address, older kernel expects that local address is
3383 * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3384 * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3385 * compatibility when setting only local address, set it via both IFA_LOCAL
3386 * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3387 * from iproute2 project.
3389 if (!eui64_iszero(his_eui64))
3390 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3392 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3394 resp = rtnetlink_msg("RTM_NEWADDR/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
3397 * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3398 * addresses and error response is expected. On older kernel versions
3399 * do not show this error message. On error pppd tries to fallback to
3400 * the old IOCTL method.
3402 errno = (resp < 0) ? -resp : EINVAL;
3403 if (kernel_version >= KVERSION(3,11,0))
3404 error("sif6addr_rtnetlink: %m (line %d)", __LINE__);
3411 /********************************************************************
3413 * sif6addr - Config the interface with an IPv6 link-local address
3415 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3417 struct in6_ifreq ifr6;
3419 struct in6_rtmsg rt6;
3424 error("IPv6 socket creation failed: %m");
3427 memset(&ifr, 0, sizeof (ifr));
3428 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3429 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3430 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3434 if (kernel_version >= KVERSION(2,1,16)) {
3435 /* Set both local address and remote peer address (with route for it) via rtnetlink */
3436 ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3442 * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3443 * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3446 /* Local interface */
3447 memset(&ifr6, 0, sizeof(ifr6));
3448 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3449 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3450 ifr6.ifr6_prefixlen = 128;
3452 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3453 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3458 if (!ret && !eui64_iszero(his_eui64)) {
3460 * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3461 * setting remote peer host address, so set only route to remote host.
3464 /* Route to remote host */
3465 memset(&rt6, 0, sizeof(rt6));
3466 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3467 rt6.rtmsg_flags = RTF_UP;
3468 rt6.rtmsg_dst_len = 128;
3469 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3470 rt6.rtmsg_metric = 1;
3472 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3473 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3482 /********************************************************************
3484 * cif6addr - Remove IPv6 address from interface
3486 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3489 struct in6_ifreq ifr6;
3493 error("IPv6 socket creation failed: %m");
3496 memset(&ifr, 0, sizeof(ifr));
3497 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3498 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3499 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3503 memset(&ifr6, 0, sizeof(ifr6));
3504 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3505 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3506 ifr6.ifr6_prefixlen = 128;
3508 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3509 if (errno != EADDRNOTAVAIL) {
3510 if (! ok_error (errno))
3511 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3514 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3520 #endif /* PPP_WITH_IPV6CP */
3523 * get_pty - get a pty master/slave pair and chown the slave side
3524 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
3527 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3529 int i, mfd, ret, sfd = -1;
3531 struct termios tios;
3535 * Try the unix98 way first.
3537 mfd = open("/dev/ptmx", O_RDWR);
3540 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3541 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3542 chmod(pty_name, S_IRUSR | S_IWUSR);
3545 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3546 warn("Couldn't unlock pty slave %s: %m", pty_name);
3548 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3550 warn("Couldn't open pty slave %s: %m", pty_name);
3555 #endif /* TIOCGPTN */
3558 /* the old way - scan through the pty name space */
3559 for (i = 0; i < 64; ++i) {
3560 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3561 'p' + i / 16, i % 16);
3562 mfd = open(pty_name, O_RDWR, 0);
3565 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3567 ret = fchown(sfd, uid, -1);
3569 warn("Couldn't change ownership of %s, %m", pty_name);
3571 ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3573 warn("Couldn't change permissions of %s, %m", pty_name);
3585 strlcpy(slave_name, pty_name, 16);
3588 if (tcgetattr(sfd, &tios) == 0) {
3589 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3590 tios.c_cflag |= CS8 | CREAD | CLOCAL;
3591 tios.c_iflag = IGNPAR;
3594 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3595 warn("couldn't set attributes on pty: %m");
3597 warn("couldn't get attributes on pty: %m");
3602 /********************************************************************
3604 * open_loopback - open the device we use for getting packets
3605 * in demand mode. Under Linux, we use a pty master/slave pair.
3608 open_ppp_loopback(void)
3613 if (new_style_driver) {
3614 /* allocate ourselves a ppp unit */
3615 if (make_ppp_unit() < 0)
3617 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3618 set_kdebugflag(kdebugflag);
3623 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3624 fatal("No free pty for loopback");
3626 set_ppp_fd(slave_fd);
3628 flags = fcntl(master_fd, F_GETFL);
3630 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3631 warn("couldn't set master loopback to nonblock: %m");
3633 flags = fcntl(ppp_fd, F_GETFL);
3635 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3636 warn("couldn't set slave loopback to nonblock: %m");
3638 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3639 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3641 * Find out which interface we were given.
3643 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3644 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3646 * Enable debug in the driver if requested.
3648 set_kdebugflag (kdebugflag);
3653 /********************************************************************
3655 * sifnpmode - Set the mode for handling packets for a given NP.
3659 sifnpmode(int u, int proto, enum NPmode mode)
3663 npi.protocol = proto;
3665 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3666 if (! ok_error (errno))
3667 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3674 * Use the hostname as part of the random number seed.
3683 for (p = hostname; *p != 0; ++p)
3688 /********************************************************************
3690 * sys_check_options - check the options that the user specified
3694 sys_check_options(void)
3696 if (demand && driver_is_old) {
3697 ppp_option_error("demand dialling is not supported by kernel driver "
3698 "version %d.%d.%d", driver_version, driver_modification,
3702 if (multilink && !new_style_driver) {
3703 warn("Warning: multilink is not supported by the kernel driver");
3709 /********************************************************************
3711 * get_time - Get current time, monotonic if possible.
3714 ppp_get_time(struct timeval *tv)
3716 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3717 * Runtime checking makes it safe. */
3718 #ifndef CLOCK_MONOTONIC
3719 #define CLOCK_MONOTONIC 1
3721 static int monotonic = -1;
3726 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3730 tv->tv_sec = ts.tv_sec;
3731 tv->tv_usec = ts.tv_nsec / 1000;
3734 } else if (monotonic > 0)
3738 warn("Couldn't use monotonic clock source: %m");
3741 return gettimeofday(tv, NULL);