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@ozlabs.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>
134 #include <linux/if_addr.h>
136 /* glibc versions prior to 2.24 do not define SOL_NETLINK */
138 #define SOL_NETLINK 270
141 /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
142 #ifndef NETLINK_CAP_ACK
143 #define NETLINK_CAP_ACK 10
146 /* linux kernel versions prior to 4.7 do not define/support IFLA_PPP_DEV_FD */
148 /* IFLA_PPP_DEV_FD is declared as enum when IFLA_PPP_MAX is defined */
149 #define IFLA_PPP_DEV_FD 1
152 #include "pppd-private.h"
157 #ifdef PPP_WITH_IPV6CP
159 #endif /* PPP_WITH_IPV6CP */
161 #include "multilink.h"
163 #ifdef PPP_WITH_FILTER
164 #include <pcap-bpf.h>
165 #include <linux/filter.h>
166 #endif /* PPP_WITH_FILTER */
169 #include <sys/locks.h>
173 * Instead of system header file <termios.h> use local "termios_linux.h" header
174 * file as it provides additional support for arbitrary baud rates via BOTHER.
176 #include "termios_linux.h"
178 #ifdef PPP_WITH_IPV6CP
181 * This is in linux/include/net/ipv6.h.
185 struct in6_addr ifr6_addr;
186 __u32 ifr6_prefixlen;
187 unsigned int ifr6_ifindex;
191 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
192 memset(&(sin6).s6_addr, 0, sizeof(struct in6_addr)); \
193 (sin6).s6_addr16[0] = htons(0xfe80); \
194 eui64_copy(eui64, (sin6).s6_addr32[2]); \
197 static const eui64_t nulleui64;
198 #endif /* PPP_WITH_IPV6CP */
200 /* We can get an EIO error on an ioctl if the modem has hung up */
201 #define ok_error(num) ((num)==EIO)
203 static int tty_disc = N_TTY; /* The TTY discipline */
204 static int ppp_disc = N_PPP; /* The PPP discpline */
205 static int initfdflags = -1; /* Initial file descriptor flags for fd */
206 static int ppp_fd = -1; /* fd which is set to PPP discipline */
207 static int sock_fd = -1; /* socket for doing interface ioctls */
208 static int slave_fd = -1; /* pty for old-style demand mode, slave */
209 static int master_fd = -1; /* pty for old-style demand mode, master */
210 #ifdef PPP_WITH_IPV6CP
211 static int sock6_fd = -1;
212 #endif /* PPP_WITH_IPV6CP */
215 * For the old-style kernel driver, this is the same as ppp_fd.
216 * For the new-style driver, it is the fd of an instance of /dev/ppp
217 * which is attached to the ppp unit and is used for controlling it.
219 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
221 static int chindex; /* channel index (new style driver) */
223 static fd_set in_fds; /* set of fds that wait_input waits for */
224 static int max_in_fd; /* highest fd set in in_fds */
226 static int has_proxy_arp = 0;
227 static int driver_version = 0;
228 static int driver_modification = 0;
229 static int driver_patch = 0;
230 static int driver_is_old = 0;
231 static int restore_term = 0; /* 1 => we've munged the terminal */
232 static struct termios inittermios; /* Initial TTY termios */
234 int new_style_driver = 0;
236 static char loop_name[20];
237 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
239 static int if_is_up; /* Interface has been marked up */
240 static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
241 static int have_default_route; /* Gateway for default route added */
242 static int have_default_route6; /* Gateway for default IPv6 route added */
243 static struct rtentry old_def_rt; /* Old default route */
244 static int default_rt_repl_rest; /* replace and restore old default rt */
245 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
246 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
247 static u_int32_t our_old_addr; /* for detecting address changes */
248 static int dynaddr_set; /* 1 if ip_dynaddr set */
249 static int looped; /* 1 if using loop */
250 static int link_mtu; /* mtu for the link (not bundle) */
252 static struct utsname utsname; /* for the kernel version */
253 static int kernel_version;
254 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
258 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
259 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
260 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
262 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
264 /* Prototypes for procedures local to this file. */
265 static int modify_flags(int fd, int clear_bits, int set_bits);
266 static int translate_speed (int bps);
267 static int baud_rate_of (int speed);
268 static void close_route_table (void);
269 static int open_route_table (void);
270 static int read_route_table (struct rtentry *rt);
271 static int defaultroute_exists (struct rtentry *rt, int metric);
272 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
273 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
274 char *name, int namelen);
275 static void decode_version (char *buf, int *version, int *mod, int *patch);
276 static int set_kdebugflag(int level);
277 static int ppp_registered(void);
278 static int make_ppp_unit(void);
279 static int setifstate (int u, int state);
281 extern u_char inpacket_buf[]; /* borrowed from main.c */
283 extern int dfl_route_metric;
286 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
290 #define SET_SA_FAMILY(addr, family) \
291 memset ((char *) &(addr), '\0', sizeof(addr)); \
292 addr.sa_family = (family);
296 * rtnetlink_msg - send rtnetlink message, receive response
297 * and return received error code:
299 * positive value - error during sending / receiving message
300 * negative value - rtnetlink responce error code
302 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)
306 struct nlmsgerr nlerr;
308 struct sockaddr_nl nladdr;
315 if (shared_fd && *shared_fd >= 0) {
318 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
320 error("rtnetlink_msg: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
325 * Tell kernel to not send to us payload of acknowledgment error message.
326 * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
327 * older kernel versions always send full payload in acknowledgment netlink
328 * message. We ignore payload of this message as we need only error code,
329 * to check if our set remote peer address request succeeded or failed.
330 * So ignore return value from the following setsockopt() call as setting
331 * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
334 setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
336 memset(&nladdr, 0, sizeof(nladdr));
337 nladdr.nl_family = AF_NETLINK;
339 if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
340 error("rtnetlink_msg: bind(AF_NETLINK): %m (line %d)", __LINE__);
349 memset(&nladdr, 0, sizeof(nladdr));
350 nladdr.nl_family = AF_NETLINK;
352 memset(&iov[0], 0, sizeof(iov[0]));
353 iov[0].iov_base = nlreq;
354 iov[0].iov_len = nlreq_len;
356 memset(&msg, 0, sizeof(msg));
357 msg.msg_name = &nladdr;
358 msg.msg_namelen = sizeof(nladdr);
359 msg.msg_iov = &iov[0];
362 if (sendmsg(fd, &msg, 0) < 0) {
363 error("rtnetlink_msg: sendmsg(%s): %m (line %d)", desc, __LINE__);
369 memset(iov, 0, sizeof(iov));
370 iov[0].iov_base = &nlresp_hdr;
371 if (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) {
372 iov[0].iov_len = offsetof(struct nlresp_hdr, nlerr);
373 iov[1].iov_base = nlresp_data;
374 iov[1].iov_len = *nlresp_size;
376 iov[0].iov_len = sizeof(nlresp_hdr);
379 memset(&msg, 0, sizeof(msg));
380 msg.msg_name = &nladdr;
381 msg.msg_namelen = sizeof(nladdr);
383 msg.msg_iovlen = (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) ? 2 : 1;
385 nlresp_len = recvmsg(fd, &msg, 0);
390 if (nlresp_len < 0) {
391 error("rtnetlink_msg: recvmsg(%s): %m (line %d)", desc, __LINE__);
395 if (nladdr.nl_family != AF_NETLINK) {
396 error("rtnetlink_msg: recvmsg(%s): Not a netlink packet (line %d)", desc, __LINE__);
401 if ((size_t)nlresp_len < sizeof(nlresp_hdr) || nlresp_hdr.nlh.nlmsg_len < sizeof(nlresp_hdr)) {
402 error("rtnetlink_msg: recvmsg(%s): Acknowledgment netlink packet too short (line %d)", desc, __LINE__);
406 /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
407 if (nlresp_hdr.nlh.nlmsg_type != NLMSG_ERROR) {
408 error("rtnetlink_msg: recvmsg(%s): Not an acknowledgment netlink packet (line %d)", desc, __LINE__);
414 if (*nlresp_size > sizeof(nlresp_hdr))
415 memcpy((unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), nlresp_data, sizeof(nlresp_hdr.nlerr));
417 memcpy(nlresp_data, (unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), *nlresp_size);
420 /* error == 0 indicates success, negative value is errno code */
421 if (nlresp_hdr.nlh.nlmsg_type == NLMSG_ERROR && nlresp_hdr.nlerr.error)
422 return nlresp_hdr.nlerr.error;
425 if (nlresp_hdr.nlh.nlmsg_type != nlresp_type) {
426 error("rtnetlink_msg: recvmsg(%s): Not a netlink packet of type 0x%x (line %d)", desc, nlresp_type, __LINE__);
429 *nlresp_size = nlresp_len - offsetof(struct nlresp_hdr, nlerr);
436 * Determine if the PPP connection should still be present.
441 /* new_fd is the fd of a tty */
442 static void set_ppp_fd (int new_fd)
445 if (!new_style_driver)
449 static int still_ppp(void)
451 if (new_style_driver)
452 return !hungup && ppp_fd >= 0;
453 if (!hungup || ppp_fd == slave_fd)
456 set_ppp_fd(slave_fd);
463 * modify_flags - set and clear flag bits controlling the kernel
466 static int modify_flags(int fd, int clear_bits, int set_bits)
470 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
472 flags = (flags & ~clear_bits) | set_bits;
473 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
480 error("Failed to set PPP kernel option flags: %m");
484 /********************************************************************
486 * sys_init - System-dependent initialization.
491 /* Get an internet socket for doing socket ioctls. */
492 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
494 fatal("Couldn't create IP socket: %m(%d)", errno);
496 #ifdef PPP_WITH_IPV6CP
497 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
499 sock6_fd = -errno; /* save errno for later */
506 /********************************************************************
508 * sys_cleanup - restore any system state we modified before exiting:
509 * mark the interface down, delete default route and/or proxy arp entry.
510 * This shouldn't call die() because it's called from die().
513 void sys_cleanup(void)
516 * Take down the device
522 #ifdef PPP_WITH_IPV6CP
528 * Delete any routes through the device.
530 if (have_default_route)
531 cifdefaultroute(0, 0, 0);
532 #ifdef PPP_WITH_IPV6CP
533 if (have_default_route6)
534 cif6defaultroute(0, nulleui64, nulleui64);
538 cifproxyarp(0, proxy_arp_addr);
541 /********************************************************************
543 * ppp_sys_close - Clean up in a child process before execing.
548 if (new_style_driver && ppp_dev_fd >= 0)
552 #ifdef PPP_WITH_IPV6CP
562 /********************************************************************
564 * set_kdebugflag - Define the debugging level for the kernel
567 static int set_kdebugflag (int requested_level)
571 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
572 if ( ! ok_error (errno) )
573 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
579 /********************************************************************
581 * tty_establish_ppp - Turn the serial port into a ppp interface.
584 int tty_establish_ppp (int tty_fd)
589 * Ensure that the tty device is in exclusive mode.
591 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
592 if ( ! ok_error ( errno ))
593 warn("Couldn't make tty exclusive: %m");
596 * Demand mode - prime the old ppp device to relinquish the unit.
598 if (!new_style_driver && looped
599 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
600 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
604 * Set the current tty to the PPP discpline
608 #define N_SYNC_PPP 14
610 ppp_disc = (new_style_driver && ppp_sync_serial())? N_SYNC_PPP: N_PPP;
611 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
612 if ( ! ok_error (errno) ) {
613 error("Couldn't set tty to PPP discipline: %m");
618 ret_fd = ppp_generic_establish(tty_fd);
620 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
621 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
625 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
626 (kdebugflag * SC_DEBUG) & SC_LOGB);
628 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
629 warn("Couldn't reset tty to normal line discipline: %m");
635 /********************************************************************
637 * generic_establish_ppp - Turn the fd into a ppp interface.
639 int ppp_generic_establish (int fd)
643 if (new_style_driver) {
646 /* If a ppp_fd is already open, close it first */
653 /* Open an instance of /dev/ppp and connect the channel to it */
654 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
655 error("Couldn't get channel number: %m");
658 dbglog("using channel %d", chindex);
659 fd = open("/dev/ppp", O_RDWR);
661 error("Couldn't reopen /dev/ppp: %m");
664 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
665 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
666 error("Couldn't attach to channel %d: %m", chindex);
669 flags = fcntl(fd, F_GETFL);
670 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
671 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
676 if (!looped && !multilink) {
678 * Create a new PPP unit.
680 if (make_ppp_unit() < 0)
685 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
689 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
690 error("Couldn't attach to PPP unit %d: %m", ifunit);
697 * Old-style driver: find out which interface we were given.
700 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
701 if (ok_error (errno))
703 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
705 /* Check that we got the same unit again. */
706 if (looped && x != ifunit)
707 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
711 * Fetch the initial file flags and reset blocking mode on the file.
713 initfdflags = fcntl(fd, F_GETFL);
714 if (initfdflags == -1 ||
715 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
716 if ( ! ok_error (errno))
717 warn("Couldn't set device to non-blocking mode: %m");
722 * Enable debug in the driver if requested.
725 set_kdebugflag (kdebugflag);
737 /********************************************************************
739 * tty_disestablish_ppp - Restore the serial port to normal operation.
740 * This shouldn't call die() because it's called from die().
743 void tty_disestablish_ppp(int tty_fd)
747 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
749 if (tcflush(tty_fd, TCIOFLUSH) < 0)
751 warn("tcflush failed: %m");
755 * Restore the previous line discipline
757 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
758 if ( ! ok_error (errno))
759 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
762 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
763 if ( ! ok_error (errno))
764 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
767 /* Reset non-blocking mode on fd. */
768 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
769 if ( ! ok_error (errno))
770 warn("Couldn't restore device fd flags: %m");
776 ppp_generic_disestablish(tty_fd);
779 /********************************************************************
781 * ppp_generic_disestablish - Restore device components to normal
782 * operation, and reconnect the ppp unit to the loopback if in demand
783 * mode. This shouldn't call die() because it's called from die().
785 void ppp_generic_disestablish(int dev_fd)
787 if (new_style_driver) {
791 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
793 } else if (!mp_on() && ppp_dev_fd >= 0) {
795 remove_fd(ppp_dev_fd);
799 /* old-style driver */
801 set_ppp_fd(slave_fd);
808 * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd
809 * with specified req_ifname via rtnetlink. Interface name req_ifname must not
810 * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free.
812 static int make_ppp_unit_rtnetlink(void)
816 struct ifinfomsg ifm;
819 char ifname[IFNAMSIZ];
825 char ifkind[sizeof("ppp")];
840 memset(&nlreq, 0, sizeof(nlreq));
841 nlreq.nlh.nlmsg_len = sizeof(nlreq);
842 nlreq.nlh.nlmsg_type = RTM_NEWLINK;
843 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
844 nlreq.ifm.ifi_family = AF_UNSPEC;
845 nlreq.ifm.ifi_type = ARPHRD_NETROM;
846 nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
847 nlreq.ifn.rta.rta_type = IFLA_IFNAME;
848 strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
849 nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
850 nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
851 nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
852 nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
853 strcpy(nlreq.ifli.ifik.ifkind, "ppp");
854 nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
855 nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
856 nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
857 nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
858 nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
861 * See kernel function ppp_nl_newlink(), which may return -EBUSY to prevent
862 * possible deadlock in kernel and ask userspace to retry request again.
865 resp = rtnetlink_msg("RTM_NEWLINK/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
866 } while (resp == -EBUSY);
870 * Linux kernel versions prior to 4.7 do not support creating ppp
871 * interfaces via rtnetlink API and therefore error response is
872 * expected. On older kernel versions do not show this error message.
873 * When error is different than EEXIST then pppd tries to fallback to
874 * the old ioctl method.
876 errno = (resp < 0) ? -resp : EINVAL;
877 if (kernel_version >= KVERSION(4,7,0))
878 error("Couldn't create ppp interface %s: %m", req_ifname);
886 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
887 * Assumes new_style_driver.
889 static int make_ppp_unit(void)
893 if (ppp_dev_fd >= 0) {
894 dbglog("in make_ppp_unit, already had /dev/ppp open?");
897 ppp_dev_fd = open("/dev/ppp", O_RDWR);
899 fatal("Couldn't open /dev/ppp: %m");
900 flags = fcntl(ppp_dev_fd, F_GETFL);
902 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
903 warn("Couldn't set /dev/ppp to nonblock: %m");
906 * Via rtnetlink it is possible to create ppp network interface with
907 * custom ifname atomically. But it is not possible to specify custom
910 * Tools like systemd, udev or NetworkManager are trying to query
911 * interface attributes based on interface name immediately when new
912 * network interface is created. And therefore immediate interface
913 * renaming is causing issues.
915 * So use rtnetlink API only when user requested custom ifname. It will
916 * avoid system issues with interface renaming.
918 if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) {
919 if (make_ppp_unit_rtnetlink()) {
920 if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit))
921 fatal("Couldn't retrieve PPP unit id: %m");
925 * If interface with requested name already exist return error
926 * otherwise fallback to old ioctl method.
933 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
934 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
935 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
937 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
939 if (x < 0 && errno == EEXIST) {
940 srand(time(NULL) * getpid());
941 ifunit = rand() % 10000;
942 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
945 error("Couldn't create new ppp unit: %m");
947 if (x == 0 && req_ifname[0] != '\0') {
950 memset(&ifr, 0, sizeof(struct ifreq));
951 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
952 strlcpy(ifr.ifr_name, t, IFNAMSIZ);
953 strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
954 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
956 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
958 info("Renamed interface %s to %s", t, req_ifname);
965 * cfg_bundle - configure the existing bundle.
966 * Used in demand mode.
968 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
970 if (!new_style_driver)
973 /* set the mrru, mtu and flags */
974 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
975 error("Couldn't set MRRU: %m");
977 modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
978 ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
979 | (mrru? SC_MULTILINK: 0)));
981 /* connect up the channel */
982 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
983 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
988 * make_new_bundle - create a new PPP unit (i.e. a bundle)
989 * and connect our channel to it. This should only get called
990 * if `multilink' was set at the time establish_ppp was called.
991 * In demand mode this uses our existing bundle instead of making
994 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
996 if (!new_style_driver)
999 /* make us a ppp unit */
1000 if (make_ppp_unit() < 0)
1003 /* set the mrru and flags */
1004 cfg_bundle(mrru, mtru, rssn, tssn);
1008 * bundle_attach - attach our link to a given PPP unit.
1009 * We assume the unit is controlled by another pppd.
1011 int bundle_attach(int ifnum)
1015 if (!new_style_driver)
1018 master_fd = open("/dev/ppp", O_RDWR);
1020 fatal("Couldn't open /dev/ppp: %m");
1021 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
1022 if (errno == ENXIO) {
1024 return 0; /* doesn't still exist */
1026 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
1028 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
1029 fatal("Couldn't connect to interface unit %d: %m", ifnum);
1030 modify_flags(master_fd, 0, SC_MULTILINK);
1038 * destroy_bundle - tell the driver to destroy our bundle.
1040 void destroy_bundle(void)
1042 if (ppp_dev_fd >= 0) {
1044 remove_fd(ppp_dev_fd);
1049 /********************************************************************
1051 * clean_check - Fetch the flags for the device and generate
1052 * appropriate error messages.
1054 void clean_check(void)
1060 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
1062 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
1064 s = "all had bit 7 set to 1";
1068 s = "all had bit 7 set to 0";
1072 s = "all had odd parity";
1076 s = "all had even parity";
1081 warn("Receive serial link is not 8-bit clean:");
1082 warn("Problem: %s", s);
1090 * List of valid speeds.
1094 int speed_int, speed_val;
1157 { 115200, B115200 },
1160 { 153600, B153600 },
1169 { 230400, B230400 },
1172 { 307200, B307200 },
1175 { 460800, B460800 },
1178 { 500000, B500000 },
1181 { 576000, B576000 },
1184 { 614400, B614400 },
1187 { 921600, B921600 },
1190 { 1000000, B1000000 },
1193 { 1152000, B1152000 },
1196 { 1500000, B1500000 },
1199 { 2000000, B2000000 },
1202 { 2500000, B2500000 },
1205 { 3000000, B3000000 },
1208 { 3500000, B3500000 },
1211 { 4000000, B4000000 },
1216 /********************************************************************
1218 * Translate from bits/second to a speed_t.
1221 static int translate_speed (int bps)
1223 struct speed *speedp;
1226 for (speedp = speeds; speedp->speed_int; speedp++) {
1227 if (bps == speedp->speed_int)
1228 return speedp->speed_val;
1234 /********************************************************************
1236 * Translate from a speed_t to bits/second.
1239 static int baud_rate_of (int speed)
1241 struct speed *speedp;
1244 for (speedp = speeds; speedp->speed_int; speedp++) {
1245 if (speed == speedp->speed_val)
1246 return speedp->speed_int;
1252 /********************************************************************
1254 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
1255 * at the requested speed, etc. If `local' is true, set CLOCAL
1256 * regardless of whether the modem option was specified.
1259 void set_up_tty(int tty_fd, int local)
1262 struct termios tios;
1265 if (tcgetattr(tty_fd, &tios) < 0) {
1266 if (!ok_error(errno))
1267 fatal("tcgetattr: %m (line %d)", __LINE__);
1274 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1275 tios.c_cflag |= CS8 | CREAD | HUPCL;
1277 tios.c_iflag = IGNBRK | IGNPAR;
1280 tios.c_cc[VMIN] = 1;
1281 tios.c_cc[VTIME] = 0;
1283 if (local || !modem)
1284 tios.c_cflag ^= (CLOCAL | HUPCL);
1288 tios.c_cflag |= CRTSCTS;
1292 tios.c_iflag |= IXON | IXOFF;
1293 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
1294 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
1298 tios.c_cflag &= ~CRTSCTS;
1306 tios.c_cflag |= CSTOPB;
1309 speed = translate_speed(inspeed);
1311 cfsetospeed (&tios, speed);
1312 cfsetispeed (&tios, speed);
1313 speed = cfgetospeed(&tios);
1314 baud_rate = baud_rate_of(speed);
1317 tios.c_cflag &= ~CBAUD;
1318 tios.c_cflag |= BOTHER;
1319 tios.c_ospeed = inspeed;
1321 /* B0 sets input baudrate to the output baudrate */
1322 tios.c_cflag &= ~(CBAUD << IBSHIFT);
1323 tios.c_cflag |= B0 << IBSHIFT;
1324 tios.c_ispeed = inspeed;
1326 baud_rate = inspeed;
1333 speed = cfgetospeed(&tios);
1334 baud_rate = baud_rate_of(speed);
1337 baud_rate = tios.c_ospeed;
1342 * We can't proceed if the serial port baud rate is unknown,
1343 * since that implies that the serial port is disabled.
1347 fatal("speed %d not supported", inspeed);
1349 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1352 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1354 fatal("tcsetattr: %m (line %d)", __LINE__);
1358 /********************************************************************
1360 * setdtr - control the DTR line on the serial port.
1361 * This is called from die(), so it shouldn't call die().
1364 void setdtr (int tty_fd, int on)
1366 int modembits = TIOCM_DTR;
1368 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1371 /********************************************************************
1373 * restore_tty - restore the terminal to the saved settings.
1376 void restore_tty (int tty_fd)
1381 * Turn off echoing, because otherwise we can get into
1382 * a loop with the tty and the modem echoing to each other.
1383 * We presume we are the sole user of this tty device, so
1384 * when we close it, it will revert to its defaults anyway.
1386 if (!default_device)
1387 inittermios.c_lflag &= ~(ECHO | ECHONL);
1389 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1390 if (! ok_error (errno))
1391 warn("tcsetattr: %m (line %d)", __LINE__);
1396 /********************************************************************
1398 * output - Output PPP packet.
1401 void output (int unit, unsigned char *p, int len)
1406 dump_packet("sent", p, len);
1407 if (snoop_send_hook) snoop_send_hook(p, len);
1409 if (len < PPP_HDRLEN)
1411 if (new_style_driver) {
1414 proto = (p[0] << 8) + p[1];
1415 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1418 if (write(fd, p, len) < 0) {
1419 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1420 || errno == ENXIO || errno == EIO || errno == EINTR)
1421 warn("write: warning: %m (%d)", errno);
1423 error("write: %m (%d)", errno);
1427 /********************************************************************
1429 * wait_input - wait until there is data available,
1430 * for the length of time specified by *timo (indefinite
1434 void wait_input(struct timeval *timo)
1441 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1442 if (n < 0 && errno != EINTR)
1443 fatal("select: %m");
1447 * add_fd - add an fd to the set that wait_input waits for.
1451 if (fd >= FD_SETSIZE)
1452 fatal("internal error: file descriptor too large (%d)", fd);
1453 FD_SET(fd, &in_fds);
1459 * remove_fd - remove an fd from the set that wait_input waits for.
1461 void remove_fd(int fd)
1463 FD_CLR(fd, &in_fds);
1467 /********************************************************************
1469 * read_packet - get a PPP packet from the serial device.
1472 int read_packet (unsigned char *buf)
1476 len = PPP_MRU + PPP_HDRLEN;
1477 if (new_style_driver) {
1478 *buf++ = PPP_ALLSTATIONS;
1484 nr = read(ppp_fd, buf, len);
1485 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1486 && errno != EIO && errno != EINTR)
1488 if (nr < 0 && errno == ENXIO)
1491 if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1492 /* N.B. we read ppp_fd first since LCP packets come in there. */
1493 nr = read(ppp_dev_fd, buf, len);
1494 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1495 && errno != EIO && errno != EINTR)
1496 error("read /dev/ppp: %m");
1497 if (nr < 0 && errno == ENXIO)
1499 if (nr == 0 && mp_on()) {
1500 remove_fd(ppp_dev_fd);
1504 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1506 return (new_style_driver && nr > 0)? nr+2: nr;
1509 /********************************************************************
1511 * get_loop_output - get outgoing packets from the ppp device,
1512 * and detect when we want to bring the real link up.
1513 * Return value is 1 if we need to bring up the link, 0 otherwise.
1516 get_loop_output(void)
1521 if (new_style_driver) {
1522 while ((n = read_packet(inpacket_buf)) > 0)
1523 if (loop_frame(inpacket_buf, n))
1528 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1529 if (loop_chars(inbuf, n))
1533 fatal("eof on loopback");
1535 if (errno != EWOULDBLOCK && errno != EAGAIN)
1536 fatal("read from loopback: %m(%d)", errno);
1542 * netif_set_mtu - set the MTU on the PPP network interface.
1545 ppp_set_mtu(int unit, int mtu)
1549 memset (&ifr, '\0', sizeof (ifr));
1550 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1553 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1554 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1558 * netif_get_mtu - get the MTU on the PPP network interface.
1561 ppp_get_mtu(int unit)
1565 memset (&ifr, '\0', sizeof (ifr));
1566 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1568 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1569 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1575 /********************************************************************
1577 * tty_send_config - configure the transmit characteristics of
1578 * the ppp interface.
1581 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1588 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1589 if (errno != EIO && errno != ENOTTY)
1590 error("Couldn't set transmit async character map: %m");
1595 x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1596 | (ppp_sync_serial()? SC_SYNC: 0);
1597 modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1600 /********************************************************************
1602 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1605 void tty_set_xaccm (ext_accm accm)
1609 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1610 if ( ! ok_error (errno))
1611 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1615 /********************************************************************
1617 * tty_recv_config - configure the receive-side characteristics of
1618 * the ppp interface.
1621 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1624 * If we were called because the link has gone down then there is nothing
1625 * which may be done. Just return without incident.
1630 * Set the receiver parameters
1632 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1633 if (errno != EIO && errno != ENOTTY)
1634 error("Couldn't set channel receive MRU: %m");
1636 if (new_style_driver && ppp_dev_fd >= 0
1637 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1638 error("Couldn't set MRU in generic PPP layer: %m");
1640 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1641 if (errno != EIO && errno != ENOTTY)
1642 error("Couldn't set channel receive asyncmap: %m");
1646 /********************************************************************
1648 * ccp_test - ask kernel whether a given compression method
1649 * is acceptable for use.
1653 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1655 struct ppp_option_data data;
1657 memset (&data, '\0', sizeof (data));
1659 data.length = opt_len;
1660 data.transmit = for_transmit;
1662 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1665 return (errno == ENOBUFS)? 0: -1;
1668 /********************************************************************
1670 * ccp_flags_set - inform kernel about the current state of CCP.
1673 void ccp_flags_set (int unit, int isopen, int isup)
1677 x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1678 if (still_ppp() && ppp_dev_fd >= 0)
1679 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1682 #ifdef PPP_WITH_FILTER
1684 * set_filters - set the active and pass filters in the kernel driver.
1686 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1688 struct sock_fprog fp;
1690 fp.len = pass->bf_len;
1691 fp.filter = (struct sock_filter *) pass->bf_insns;
1692 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1693 if (errno == ENOTTY)
1694 warn("kernel does not support PPP filtering");
1696 error("Couldn't set pass-filter in kernel: %m");
1699 fp.len = active->bf_len;
1700 fp.filter = (struct sock_filter *) active->bf_insns;
1701 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1702 error("Couldn't set active-filter in kernel: %m");
1707 #endif /* PPP_WITH_FILTER */
1709 /********************************************************************
1711 * get_idle_time - return how long the link has been idle.
1714 get_idle_time(int u, struct ppp_idle *ip)
1716 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1719 /********************************************************************
1721 * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1722 * this only supports 32-bit counters, so need to count the wraps.
1725 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1727 static u_int32_t previbytes = 0;
1728 static u_int32_t prevobytes = 0;
1729 static u_int32_t iwraps = 0;
1730 static u_int32_t owraps = 0;
1733 struct ppp_stats data;
1735 memset (&req, 0, sizeof (req));
1737 req.ifr_data = (caddr_t) &data;
1738 strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
1739 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1740 error("Couldn't get PPP statistics: %m");
1743 stats->bytes_in = data.p.ppp_ibytes;
1744 stats->bytes_out = data.p.ppp_obytes;
1745 stats->pkts_in = data.p.ppp_ipackets;
1746 stats->pkts_out = data.p.ppp_opackets;
1748 if (stats->bytes_in < previbytes)
1750 if (stats->bytes_out < prevobytes)
1753 previbytes = stats->bytes_in;
1754 prevobytes = stats->bytes_out;
1756 stats->bytes_in += (uint64_t)iwraps << 32;
1757 stats->bytes_out += (uint64_t)owraps << 32;
1762 /********************************************************************
1763 * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1764 * This provides native 64-bit counters.
1767 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1773 struct nlmsghdr nlh;
1774 struct if_stats_msg ifsm;
1779 /* We only case about these first fields from rtnl_link_stats64 */
1780 uint64_t rx_packets;
1781 uint64_t tx_packets;
1789 memset(&nlreq, 0, sizeof(nlreq));
1790 nlreq.nlh.nlmsg_len = sizeof(nlreq);
1791 nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1792 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1793 nlreq.ifsm.ifindex = if_nametoindex(ifname);
1794 nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1796 nlresp_size = sizeof(nlresp_data);
1797 resp = rtnetlink_msg("RTM_GETSTATS/NLM_F_REQUEST", &fd, &nlreq, sizeof(nlreq), &nlresp_data, &nlresp_size, RTM_NEWSTATS);
1799 errno = (resp < 0) ? -resp : EINVAL;
1800 if (kernel_version >= KVERSION(4,7,0))
1801 error("get_ppp_stats_rtnetlink: %m (line %d)", __LINE__);
1805 if (nlresp_size < sizeof(nlresp_data)) {
1806 error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1810 stats->bytes_in = nlresp_data.stats.rx_bytes;
1811 stats->bytes_out = nlresp_data.stats.tx_bytes;
1812 stats->pkts_in = nlresp_data.stats.rx_packets;
1813 stats->pkts_out = nlresp_data.stats.tx_packets;
1823 /********************************************************************
1824 * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1825 * this provides native 64-bit counters.
1828 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1830 char fname[PATH_MAX+1];
1831 char buf[21], *err; /* 2^64 < 10^20 */
1833 unsigned long long val;
1840 #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1841 statfield(rx_bytes, bytes_in),
1842 statfield(tx_bytes, bytes_out),
1843 statfield(rx_packets, pkts_in),
1844 statfield(tx_packets, pkts_out),
1848 blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1849 if (blen >= sizeof(fname))
1850 return 0; /* ifname max 15, so this should be impossible */
1852 for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1853 if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1855 error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1859 fd = open(fname, O_RDONLY);
1861 error("%s: %m", fname);
1865 rlen = read(fd, buf, sizeof(buf) - 1);
1868 error("%s: %m", fname);
1871 /* trim trailing \n if present */
1872 while (rlen > 0 && buf[rlen-1] == '\n')
1877 val = strtoull(buf, &err, 10);
1878 if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1879 error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1880 buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1883 switch (slist[i].size) {
1884 #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1891 error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1899 /********************************************************************
1900 * Periodic timer function to be used to keep stats up to date in case of ioctl
1903 * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1904 * If you do change the timer, remember to also bring the get_ppp_stats (which
1905 * sets up the initial trigger) as well.
1908 ppp_stats_poller(void* u)
1910 struct pppd_stats dummy;
1911 get_ppp_stats_ioctl((long)u, &dummy);
1912 TIMEOUT(ppp_stats_poller, u, 25);
1915 /********************************************************************
1916 * get_ppp_stats - return statistics for the link.
1918 int get_ppp_stats(int u, struct pppd_stats *stats)
1920 static int (*func)(int, struct pppd_stats*) = NULL;
1923 if (get_ppp_stats_rtnetlink(u, stats)) {
1924 func = get_ppp_stats_rtnetlink;
1927 if (get_ppp_stats_sysfs(u, stats)) {
1928 func = get_ppp_stats_sysfs;
1931 warn("statistics falling back to ioctl which only supports 32-bit counters");
1932 func = get_ppp_stats_ioctl;
1933 TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1936 return func(u, stats);
1939 /********************************************************************
1941 * ccp_fatal_error - returns 1 if decompression was disabled as a
1942 * result of an error detected after decompression of a packet,
1943 * 0 otherwise. This is necessary because of patent nonsense.
1946 int ccp_fatal_error (int unit)
1950 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1951 error("Couldn't read compression error flags: %m");
1954 return flags & SC_DC_FERROR;
1957 /********************************************************************
1959 * path_to_procfs - find the path to the proc file system mount point
1961 static char proc_path[MAXPATHLEN];
1962 static int proc_path_len;
1964 static char *path_to_procfs(const char *tail)
1966 struct mntent *mntent;
1969 if (proc_path_len == 0) {
1970 /* Default the mount location of /proc */
1971 strlcpy (proc_path, "/proc", sizeof(proc_path));
1973 fp = fopen(MOUNTED, "r");
1975 while ((mntent = getmntent(fp)) != NULL) {
1976 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1978 if (strcmp(mntent->mnt_type, "proc") == 0) {
1979 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1980 proc_path_len = strlen(proc_path);
1988 strlcpy(proc_path + proc_path_len, tail,
1989 sizeof(proc_path) - proc_path_len);
1994 * /proc/net/route parsing stuff.
1996 #define ROUTE_MAX_COLS 12
1997 FILE *route_fd = (FILE *) 0;
1998 static char route_buffer[512];
1999 static int route_dev_col, route_dest_col, route_gw_col;
2000 static int route_flags_col, route_metric_col, route_mask_col;
2001 static int route_num_cols;
2003 static int open_route_table (void);
2004 static void close_route_table (void);
2005 static int read_route_table (struct rtentry *rt);
2007 /********************************************************************
2009 * close_route_table - close the interface to the route table
2012 static void close_route_table (void)
2014 if (route_fd != (FILE *) 0) {
2016 route_fd = (FILE *) 0;
2020 /********************************************************************
2022 * open_route_table - open the interface to the route table
2024 static char route_delims[] = " \t\n";
2026 static int open_route_table (void)
2030 close_route_table();
2032 path = path_to_procfs("/net/route");
2033 route_fd = fopen (path, "r");
2034 if (route_fd == NULL) {
2035 error("can't open routing table %s: %m", path);
2039 route_dev_col = 0; /* default to usual columns */
2042 route_flags_col = 3;
2043 route_metric_col = 6;
2047 /* parse header line */
2048 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
2049 char *p = route_buffer, *q;
2051 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
2053 if ((q = strtok(p, route_delims)) == 0)
2055 if (strcasecmp(q, "iface") == 0)
2056 route_dev_col = col;
2057 else if (strcasecmp(q, "destination") == 0)
2058 route_dest_col = col;
2059 else if (strcasecmp(q, "gateway") == 0)
2061 else if (strcasecmp(q, "flags") == 0)
2062 route_flags_col = col;
2063 else if (strcasecmp(q, "mask") == 0)
2064 route_mask_col = col;
2067 if (used && col >= route_num_cols)
2068 route_num_cols = col + 1;
2076 /********************************************************************
2078 * read_route_table - read the next entry from the route table
2081 static int read_route_table(struct rtentry *rt)
2083 char *cols[ROUTE_MAX_COLS], *p;
2086 memset (rt, '\0', sizeof (struct rtentry));
2088 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2092 for (col = 0; col < route_num_cols; ++col) {
2093 cols[col] = strtok(p, route_delims);
2094 if (cols[col] == NULL)
2095 return 0; /* didn't get enough columns */
2099 SET_SA_FAMILY (rt->rt_dst, AF_INET);
2100 SET_SA_FAMILY (rt->rt_gateway, AF_INET);
2102 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
2103 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
2104 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
2106 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
2107 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
2108 rt->rt_dev = cols[route_dev_col];
2113 /********************************************************************
2115 * defaultroute_exists - determine if there is a default route
2116 * with the given metric (or negative for any)
2119 static int defaultroute_exists (struct rtentry *rt, int metric)
2123 if (!open_route_table())
2126 while (read_route_table(rt) != 0) {
2127 if ((rt->rt_flags & RTF_UP) == 0)
2130 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
2132 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
2133 || rt->rt_metric == metric)) {
2139 close_route_table();
2144 * have_route_to - determine if the system has any route to
2145 * a given IP address. `addr' is in network byte order.
2146 * Return value is 1 if yes, 0 if no, -1 if don't know.
2147 * For demand mode to work properly, we have to ignore routes
2148 * through our own interface.
2150 int have_route_to(u_int32_t addr)
2155 if (!open_route_table())
2156 return -1; /* don't know */
2158 while (read_route_table(&rt)) {
2159 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
2161 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
2167 close_route_table();
2171 /********************************************************************
2173 * sifdefaultroute - assign a default route through the address given.
2175 * If the global default_rt_repl_rest flag is set, then this function
2176 * already replaced the original system defaultroute with some other
2177 * route and it should just replace the current defaultroute with
2178 * another one, without saving the current route. Use: demand mode,
2179 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2180 * and then changes the temporary addresses to the addresses for the real
2181 * ppp connection when it has come up.
2184 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
2186 struct rtentry rt, tmp_rt;
2187 struct rtentry *del_rt = NULL;
2189 if (default_rt_repl_rest) {
2190 /* We have already replaced the original defaultroute, if we
2191 * are called again, we will delete the current default route
2192 * and set the new default route in this function.
2193 * - this is normally only the case the doing demand: */
2194 if (defaultroute_exists(&tmp_rt, -1))
2196 } else if (!replace) {
2198 * We don't want to replace an existing route.
2199 * We may however add our route along an existing route with a different
2202 if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) {
2203 if (rt.rt_flags & RTF_GATEWAY)
2204 error("not replacing existing default route via %I with metric %d",
2205 SIN_ADDR(rt.rt_gateway), dfl_route_metric);
2207 error("not replacing existing default route through %s with metric %d",
2208 rt.rt_dev, dfl_route_metric);
2211 } else if (defaultroute_exists(&old_def_rt, -1 ) &&
2212 strcmp( old_def_rt.rt_dev, ifname) != 0) {
2214 * We want to replace an existing route and did not replace an existing
2215 * default route yet, let's check if we should save and replace an
2216 * existing default route:
2218 u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2220 if (old_gateway != gateway) {
2222 error("not replacing default route to %s [%I]",
2223 old_def_rt.rt_dev, old_gateway);
2226 /* we need to copy rt_dev because we need it permanent too: */
2227 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2228 strcpy(tmp_dev, old_def_rt.rt_dev);
2229 old_def_rt.rt_dev = tmp_dev;
2231 notice("replacing old default route to %s [%I]",
2232 old_def_rt.rt_dev, old_gateway);
2233 default_rt_repl_rest = 1;
2234 del_rt = &old_def_rt;
2239 memset (&rt, 0, sizeof (rt));
2240 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2243 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2245 if (kernel_version > KVERSION(2,1,0)) {
2246 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2247 SIN_ADDR(rt.rt_genmask) = 0L;
2250 rt.rt_flags = RTF_UP;
2251 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2252 if ( ! ok_error ( errno ))
2253 error("default route ioctl(SIOCADDRT): %m");
2256 if (default_rt_repl_rest && del_rt)
2257 if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2258 if ( ! ok_error ( errno ))
2259 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2263 have_default_route = 1;
2267 /********************************************************************
2269 * cifdefaultroute - delete a default route through the address given.
2272 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2276 have_default_route = 0;
2278 memset (&rt, '\0', sizeof (rt));
2279 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2280 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2285 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2287 if (kernel_version > KVERSION(2,1,0)) {
2288 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2289 SIN_ADDR(rt.rt_genmask) = 0L;
2292 rt.rt_flags = RTF_UP;
2293 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2295 if ( ! ok_error ( errno ))
2296 error("default route ioctl(SIOCDELRT): %m");
2300 if (default_rt_repl_rest) {
2301 notice("restoring old default route to %s [%I]",
2302 old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2303 if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2304 if ( ! ok_error ( errno ))
2305 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2308 default_rt_repl_rest = 0;
2314 #ifdef PPP_WITH_IPV6CP
2316 * /proc/net/ipv6_route parsing stuff.
2318 static int route_dest_plen_col;
2319 static int open_route6_table (void);
2320 static int read_route6_table (struct in6_rtmsg *rt);
2322 /********************************************************************
2324 * open_route6_table - open the interface to the route table
2326 static int open_route6_table (void)
2330 close_route_table();
2332 path = path_to_procfs("/net/ipv6_route");
2333 route_fd = fopen (path, "r");
2334 if (route_fd == NULL) {
2335 error("can't open routing table %s: %m", path);
2339 /* default to usual columns */
2341 route_dest_plen_col = 1;
2343 route_metric_col = 5;
2344 route_flags_col = 8;
2346 route_num_cols = 10;
2351 /********************************************************************
2353 * read_route6_table - read the next entry from the route table
2356 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2363 for (i = 0; i < 4; i++) {
2364 memcpy(hex8, s + 8*i, 8);
2365 v = strtoul(hex8, NULL, 16);
2366 addr->s6_addr32[i] = v;
2370 static int read_route6_table(struct in6_rtmsg *rt)
2372 char *cols[ROUTE_MAX_COLS], *p;
2375 memset (rt, '\0', sizeof (struct in6_rtmsg));
2377 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2381 for (col = 0; col < route_num_cols; ++col) {
2382 cols[col] = strtok(p, route_delims);
2383 if (cols[col] == NULL)
2384 return 0; /* didn't get enough columns */
2388 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2389 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2390 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2392 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2393 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2394 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2399 /********************************************************************
2401 * defaultroute6_exists - determine if there is a default route
2404 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2408 if (!open_route6_table())
2411 while (read_route6_table(rt) != 0) {
2412 if ((rt->rtmsg_flags & RTF_UP) == 0)
2415 if (rt->rtmsg_dst_len != 0)
2417 if (rt->rtmsg_dst.s6_addr32[0] == 0L
2418 && rt->rtmsg_dst.s6_addr32[1] == 0L
2419 && rt->rtmsg_dst.s6_addr32[2] == 0L
2420 && rt->rtmsg_dst.s6_addr32[3] == 0L
2421 && (metric < 0 || rt->rtmsg_metric == metric)) {
2427 close_route_table();
2431 /********************************************************************
2433 * sif6defaultroute - assign a default route through the address given.
2435 * If the global default_rt_repl_rest flag is set, then this function
2436 * already replaced the original system defaultroute with some other
2437 * route and it should just replace the current defaultroute with
2438 * another one, without saving the current route. Use: demand mode,
2439 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2440 * and then changes the temporary addresses to the addresses for the real
2441 * ppp connection when it has come up.
2444 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2446 struct in6_rtmsg rt;
2447 char buf[IF_NAMESIZE];
2449 if (defaultroute6_exists(&rt, dfl_route_metric) &&
2450 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2451 if (rt.rtmsg_flags & RTF_GATEWAY)
2452 error("not replacing existing default route via gateway");
2454 error("not replacing existing default route through %s",
2455 if_indextoname(rt.rtmsg_ifindex, buf));
2459 memset (&rt, 0, sizeof (rt));
2461 rt.rtmsg_ifindex = if_nametoindex(ifname);
2462 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2463 rt.rtmsg_dst_len = 0;
2465 rt.rtmsg_flags = RTF_UP;
2466 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2467 if ( ! ok_error ( errno ))
2468 error("default route ioctl(SIOCADDRT): %m");
2472 have_default_route6 = 1;
2476 /********************************************************************
2478 * cif6defaultroute - delete a default route through the address given.
2481 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2483 struct in6_rtmsg rt;
2485 have_default_route6 = 0;
2487 memset (&rt, '\0', sizeof (rt));
2489 rt.rtmsg_ifindex = if_nametoindex(ifname);
2490 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2491 rt.rtmsg_dst_len = 0;
2493 rt.rtmsg_flags = RTF_UP;
2494 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2496 if ( ! ok_error ( errno ))
2497 error("default route ioctl(SIOCDELRT): %m");
2504 #endif /* PPP_WITH_IPV6CP */
2506 /********************************************************************
2508 * sifproxyarp - Make a proxy ARP entry for the peer.
2511 int sifproxyarp (int unit, u_int32_t his_adr)
2513 struct arpreq arpreq;
2516 if (has_proxy_arp == 0) {
2517 memset (&arpreq, '\0', sizeof(arpreq));
2519 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2520 SIN_ADDR(arpreq.arp_pa) = his_adr;
2521 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2523 * Get the hardware address of an interface on the same subnet
2524 * as our local address.
2526 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2527 sizeof(proxy_arp_dev))) {
2528 error("Cannot determine ethernet address for proxy ARP");
2531 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2533 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2534 if ( ! ok_error ( errno ))
2535 error("ioctl(SIOCSARP): %m");
2538 proxy_arp_addr = his_adr;
2542 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2543 if (forw_path != 0) {
2544 int fd = open(forw_path, O_WRONLY);
2546 if (write(fd, "1", 1) != 1)
2547 error("Couldn't enable IP forwarding: %m");
2557 /********************************************************************
2559 * cifproxyarp - Delete the proxy ARP entry for the peer.
2562 int cifproxyarp (int unit, u_int32_t his_adr)
2564 struct arpreq arpreq;
2566 if (has_proxy_arp) {
2568 memset (&arpreq, '\0', sizeof(arpreq));
2569 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2570 SIN_ADDR(arpreq.arp_pa) = his_adr;
2571 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2572 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2574 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2575 if ( ! ok_error ( errno ))
2576 warn("ioctl(SIOCDARP): %m");
2583 /********************************************************************
2585 * get_ether_addr - get the hardware address of an interface on the
2586 * the same subnet as ipaddr.
2589 static int get_ether_addr (u_int32_t ipaddr,
2590 struct sockaddr *hwaddr,
2591 char *name, int namelen)
2593 struct ifreq *ifr, *ifend;
2594 u_int32_t ina, mask;
2596 struct ifreq ifreq, bestifreq;
2598 struct ifreq ifs[MAX_IFS];
2600 u_int32_t bestmask=0;
2601 int found_interface = 0;
2603 ifc.ifc_len = sizeof(ifs);
2605 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2606 if ( ! ok_error ( errno ))
2607 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2612 * Scan through looking for an interface with an Internet
2613 * address on the same subnet as `ipaddr'.
2615 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2616 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2617 if (ifr->ifr_addr.sa_family == AF_INET) {
2618 ina = SIN_ADDR(ifr->ifr_addr);
2619 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2621 * Check that the interface is up, and not point-to-point
2624 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2627 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2630 * Get its netmask and check that it's on the right subnet.
2632 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2635 mask = SIN_ADDR(ifreq.ifr_addr);
2637 if (((ipaddr ^ ina) & mask) != 0)
2638 continue; /* no match */
2640 if (mask >= bestmask) {
2641 /* Compare using >= instead of > -- it is possible for
2642 an interface to have a netmask of 0.0.0.0 */
2643 found_interface = 1;
2650 if (!found_interface) return 0;
2652 strlcpy(name, bestifreq.ifr_name, namelen);
2654 /* trim off the :1 in eth0:1 */
2655 aliasp = strchr(name, ':');
2659 info("found interface %s for proxy arp", name);
2661 * Now get the hardware address.
2663 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2664 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2665 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2670 &bestifreq.ifr_hwaddr,
2671 sizeof (struct sockaddr));
2677 * get_if_hwaddr - get the hardware address for the specified
2678 * network interface device.
2681 get_if_hwaddr(u_char *addr, char *name)
2686 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2689 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2690 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2691 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2694 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2699 * get_first_ether_hwaddr - get the hardware address for the first
2700 * ethernet-style interface on this system.
2703 get_first_ether_hwaddr(u_char *addr)
2705 struct if_nameindex *if_ni, *i;
2709 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2713 if_ni = if_nameindex();
2721 for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2722 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2723 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2724 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2725 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2726 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2732 if_freenameindex(if_ni);
2738 /********************************************************************
2740 * Return user specified netmask, modified by any mask we might determine
2741 * for address `addr' (in network byte order).
2742 * Here we scan through the system's list of interfaces, looking for
2743 * any non-point-to-point interfaces which might appear to be on the same
2744 * network as `addr'. If we find any, we OR in their netmask to the
2745 * user-specified netmask.
2748 u_int32_t GetMask (u_int32_t addr)
2750 u_int32_t mask, nmask, ina;
2751 struct ifreq *ifr, *ifend, ifreq;
2753 struct ifreq ifs[MAX_IFS];
2757 if (IN_CLASSA(addr)) /* determine network mask for address class */
2758 nmask = IN_CLASSA_NET;
2759 else if (IN_CLASSB(addr))
2760 nmask = IN_CLASSB_NET;
2762 nmask = IN_CLASSC_NET;
2764 /* class D nets are disallowed by bad_ip_adrs */
2765 mask = netmask | htonl(nmask);
2767 * Scan through the system's network interfaces.
2769 ifc.ifc_len = sizeof(ifs);
2771 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2772 if ( ! ok_error ( errno ))
2773 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2777 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2778 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2780 * Check the interface's internet address.
2782 if (ifr->ifr_addr.sa_family != AF_INET)
2784 ina = SIN_ADDR(ifr->ifr_addr);
2785 if (((ntohl(ina) ^ addr) & nmask) != 0)
2788 * Check that the interface is up, and not point-to-point nor loopback.
2790 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2791 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2794 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2797 * Get its netmask and OR it into our mask.
2799 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2801 mask |= SIN_ADDR(ifreq.ifr_addr);
2807 /********************************************************************
2809 * Internal routine to decode the version.modification.patch level
2812 static void decode_version (char *buf, int *version,
2813 int *modification, int *patch)
2817 *version = (int) strtoul (buf, &endp, 10);
2821 if (endp != buf && *endp == '.') {
2823 *modification = (int) strtoul (buf, &endp, 10);
2824 if (endp != buf && *endp == '.') {
2826 *patch = (int) strtoul (buf, &buf, 10);
2831 /********************************************************************
2833 * Procedure to determine if the PPP line discipline is registered.
2837 ppp_registered(void)
2845 * We used to open the serial device and set it to the ppp line
2846 * discipline here, in order to create a ppp unit. But that is
2847 * not a good idea - the user might have specified a device that
2848 * they can't open (permission, or maybe it doesn't really exist).
2849 * So we grab a pty master/slave pair and use that.
2851 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2852 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2857 * Try to put the device into the PPP discipline.
2859 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2860 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2869 /********************************************************************
2871 * ppp_check_kernel_support - check whether the system has any ppp interfaces
2872 * (in fact we check whether we can do an ioctl on ppp0).
2875 int ppp_check_kernel_support(void)
2880 int my_version, my_modification, my_patch;
2881 int osmaj, osmin, ospatch;
2883 /* get the kernel version now, since we are called before sys_init */
2885 osmaj = osmin = ospatch = 0;
2886 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2887 kernel_version = KVERSION(osmaj, osmin, ospatch);
2889 fd = open("/dev/ppp", O_RDWR);
2891 new_style_driver = 1;
2893 /* XXX should get from driver */
2895 driver_modification = 4;
2901 if (kernel_version >= KVERSION(2,3,13)) {
2902 error("Couldn't open the /dev/ppp device: %m");
2903 if (errno == ENOENT)
2905 "You need to create the /dev/ppp device node by\n"
2906 "executing the following command as root:\n"
2907 " mknod /dev/ppp c 108 0\n";
2908 else if (errno == ENODEV || errno == ENXIO)
2910 "Please load the ppp_generic kernel module.\n";
2914 /* we are running on a really really old kernel */
2916 "This system lacks kernel support for PPP. This could be because\n"
2917 "the PPP kernel module could not be loaded, or because PPP was not\n"
2918 "included in the kernel configuration. If PPP was included as a\n"
2919 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2920 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2921 "See README.linux file in the ppp distribution for more details.\n";
2924 * Open a socket for doing the ioctl operations.
2926 s = socket(AF_INET, SOCK_DGRAM, 0);
2930 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2931 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2933 * If the device did not exist then attempt to create one by putting the
2934 * current tty into the PPP discipline. If this works then obtain the
2935 * flags for the device again.
2938 if (ppp_registered()) {
2939 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2940 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2944 * Ensure that the hardware address is for PPP and not something else
2947 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2949 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2953 * This is the PPP device. Validate the version of the driver at this
2954 * point to ensure that this program will work with the driver.
2957 char abBuffer [1024];
2959 ifr.ifr_data = abBuffer;
2960 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2962 error("Couldn't read driver version: %m");
2964 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2967 decode_version(abBuffer,
2969 &driver_modification,
2972 * Validate the version of the driver against the version that we used.
2974 decode_version(VERSION,
2979 /* The version numbers must match */
2980 if (driver_version != my_version)
2983 /* The modification levels must be legal */
2984 if (driver_modification < 3) {
2985 if (driver_modification >= 2) {
2986 /* we can cope with 2.2.0 and above */
2994 slprintf(route_buffer, sizeof(route_buffer),
2995 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2996 driver_version, driver_modification, driver_patch);
2998 no_ppp_msg = route_buffer;
3006 #ifndef HAVE_LOGWTMP
3007 /********************************************************************
3009 * Update the wtmp file with the appropriate user name and tty device.
3012 void logwtmp (const char *line, const char *name, const char *host)
3014 struct utmp ut, *utp;
3015 pid_t mypid = getpid();
3021 * Update the signon database for users.
3022 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
3024 utmpname(_PATH_UTMP);
3026 while ((utp = getutent()) && (utp->ut_pid != mypid))
3030 memcpy(&ut, utp, sizeof(ut));
3032 /* some gettys/telnetds don't initialize utmp... */
3033 memset(&ut, 0, sizeof(ut));
3035 if (ut.ut_id[0] == 0)
3036 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
3038 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
3039 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
3043 ut.ut_type = USER_PROCESS;
3046 /* Insert the host name if one is supplied */
3048 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
3050 /* Insert the IP address of the remote system if IP is enabled */
3051 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
3052 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
3053 sizeof(ut.ut_addr));
3055 /* CL: Makes sure that the logout works */
3056 if (*host == 0 && *name==0)
3062 * Update the wtmp file.
3065 updwtmp(_PATH_WTMP, &ut);
3067 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
3069 flock(wtmp, LOCK_EX);
3071 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
3072 warn("error writing %s: %m", _PATH_WTMP);
3074 flock(wtmp, LOCK_UN);
3080 #endif /* HAVE_LOGWTMP */
3082 /********************************************************************
3084 * sifvjcomp - config tcp header compression
3087 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
3092 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
3093 error("Couldn't set up TCP header compression: %m");
3098 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
3099 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
3104 /********************************************************************
3106 * sifup - Config the interface up and enable IP packets to pass.
3113 if ((ret = setifstate(u, 1)))
3119 /********************************************************************
3121 * sifdown - Disable the indicated protocol and config the interface
3122 * down if there are no remaining protocols.
3127 if (if_is_up && --if_is_up > 0)
3130 #ifdef PPP_WITH_IPV6CP
3133 #endif /* PPP_WITH_IPV6CP */
3135 return setifstate(u, 0);
3138 #ifdef PPP_WITH_IPV6CP
3139 /********************************************************************
3141 * sif6up - Config the interface up for IPv6
3148 if ((ret = setifstate(u, 1)))
3154 /********************************************************************
3156 * sif6down - Disable the IPv6CP protocol and config the interface
3157 * down if there are no remaining protocols.
3160 int sif6down (int u)
3167 return setifstate(u, 0);
3169 #endif /* PPP_WITH_IPV6CP */
3171 /********************************************************************
3173 * setifstate - Config the interface up or down
3176 static int setifstate (int u, int state)
3180 memset (&ifr, '\0', sizeof (ifr));
3181 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3182 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
3183 if (! ok_error (errno))
3184 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
3189 ifr.ifr_flags |= IFF_UP;
3191 ifr.ifr_flags &= ~IFF_UP;
3192 ifr.ifr_flags |= IFF_POINTOPOINT;
3193 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
3194 if (! ok_error (errno))
3195 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
3201 /********************************************************************
3203 * sifaddr - Config the interface IP addresses and netmask.
3206 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3212 memset (&ifr, '\0', sizeof (ifr));
3213 memset (&rt, '\0', sizeof (rt));
3215 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
3216 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3217 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3219 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3221 * Set our IP address
3223 SIN_ADDR(ifr.ifr_addr) = our_adr;
3224 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3225 if (errno != EEXIST) {
3226 if (! ok_error (errno))
3227 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3230 warn("ioctl(SIOCSIFADDR): Address already exists");
3235 * Set the gateway address
3238 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3239 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3240 if (! ok_error (errno))
3241 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3247 * For recent kernels, force the netmask to 255.255.255.255.
3249 if (kernel_version >= KVERSION(2,1,16))
3251 if (net_mask != 0) {
3252 SIN_ADDR(ifr.ifr_netmask) = net_mask;
3253 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3254 if (! ok_error (errno))
3255 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3260 * Add the device route
3262 if (kernel_version < KVERSION(2,1,16)) {
3263 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3264 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3267 SIN_ADDR(rt.rt_gateway) = 0L;
3268 SIN_ADDR(rt.rt_dst) = his_adr;
3269 rt.rt_flags = RTF_UP | RTF_HOST;
3271 if (kernel_version > KVERSION(2,1,0)) {
3272 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3273 SIN_ADDR(rt.rt_genmask) = -1L;
3276 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3277 if (! ok_error (errno))
3278 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3283 /* set ip_dynaddr in demand mode if address changes */
3284 if (demand && tune_kernel && !dynaddr_set
3285 && our_old_addr && our_old_addr != our_adr) {
3286 /* set ip_dynaddr if possible */
3290 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3291 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3292 if (write(fd, "1", 1) != 1)
3293 error("Couldn't enable dynamic IP addressing: %m");
3296 dynaddr_set = 1; /* only 1 attempt */
3303 /********************************************************************
3305 * cifaddr - Clear the interface IP addresses, and delete routes
3306 * through the interface if possible.
3309 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3313 if (kernel_version < KVERSION(2,1,16)) {
3315 * Delete the route through the device
3318 memset (&rt, '\0', sizeof (rt));
3320 SET_SA_FAMILY (rt.rt_dst, AF_INET);
3321 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3324 SIN_ADDR(rt.rt_gateway) = 0;
3325 SIN_ADDR(rt.rt_dst) = his_adr;
3326 rt.rt_flags = RTF_UP | RTF_HOST;
3328 if (kernel_version > KVERSION(2,1,0)) {
3329 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3330 SIN_ADDR(rt.rt_genmask) = -1L;
3333 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3334 if (still_ppp() && ! ok_error (errno))
3335 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3340 /* This way it is possible to have an IPv6-only interface */
3341 memset(&ifr, 0, sizeof(ifr));
3342 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3343 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3345 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3346 if (! ok_error (errno)) {
3347 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3352 our_old_addr = our_adr;
3357 #ifdef PPP_WITH_IPV6CP
3358 /********************************************************************
3360 * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3362 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3365 struct nlmsghdr nlh;
3366 struct ifaddrmsg ifa;
3369 struct in6_addr addr;
3374 memset(&nlreq, 0, sizeof(nlreq));
3375 nlreq.nlh.nlmsg_len = sizeof(nlreq);
3376 nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3377 nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3378 nlreq.ifa.ifa_family = AF_INET6;
3379 nlreq.ifa.ifa_prefixlen = 128;
3380 nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3381 nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3382 nlreq.ifa.ifa_index = iface;
3383 nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3384 nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3385 IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3386 nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3387 nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3390 * To set only local address, older kernel expects that local address is
3391 * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3392 * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3393 * compatibility when setting only local address, set it via both IFA_LOCAL
3394 * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3395 * from iproute2 project.
3397 if (!eui64_iszero(his_eui64))
3398 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3400 IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3402 resp = rtnetlink_msg("RTM_NEWADDR/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
3405 * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3406 * addresses and error response is expected. On older kernel versions
3407 * do not show this error message. On error pppd tries to fallback to
3408 * the old IOCTL method.
3410 errno = (resp < 0) ? -resp : EINVAL;
3411 if (kernel_version >= KVERSION(3,11,0))
3412 error("sif6addr_rtnetlink: %m (line %d)", __LINE__);
3419 /********************************************************************
3421 * sif6addr - Config the interface with an IPv6 link-local address
3423 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3425 struct in6_ifreq ifr6;
3427 struct in6_rtmsg rt6;
3432 error("IPv6 socket creation failed: %m");
3435 memset(&ifr, 0, sizeof (ifr));
3436 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3437 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3438 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3442 if (kernel_version >= KVERSION(2,1,16)) {
3443 /* Set both local address and remote peer address (with route for it) via rtnetlink */
3444 ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3450 * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3451 * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3454 /* Local interface */
3455 memset(&ifr6, 0, sizeof(ifr6));
3456 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3457 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3458 ifr6.ifr6_prefixlen = 128;
3460 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3461 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3466 if (!ret && !eui64_iszero(his_eui64)) {
3468 * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3469 * setting remote peer host address, so set only route to remote host.
3472 /* Route to remote host */
3473 memset(&rt6, 0, sizeof(rt6));
3474 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3475 rt6.rtmsg_flags = RTF_UP;
3476 rt6.rtmsg_dst_len = 128;
3477 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3478 rt6.rtmsg_metric = 1;
3480 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3481 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3490 /********************************************************************
3492 * cif6addr - Remove IPv6 address from interface
3494 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3497 struct in6_ifreq ifr6;
3501 error("IPv6 socket creation failed: %m");
3504 memset(&ifr, 0, sizeof(ifr));
3505 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3506 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3507 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3511 memset(&ifr6, 0, sizeof(ifr6));
3512 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3513 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3514 ifr6.ifr6_prefixlen = 128;
3516 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3517 if (errno != EADDRNOTAVAIL) {
3518 if (! ok_error (errno))
3519 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3522 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3528 #endif /* PPP_WITH_IPV6CP */
3531 * get_pty - get a pty master/slave pair and chown the slave side
3532 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
3535 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3537 int i, mfd, ret, sfd = -1;
3539 struct termios tios;
3543 * Try the unix98 way first.
3545 mfd = open("/dev/ptmx", O_RDWR);
3548 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3549 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3550 chmod(pty_name, S_IRUSR | S_IWUSR);
3553 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3554 warn("Couldn't unlock pty slave %s: %m", pty_name);
3556 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3558 warn("Couldn't open pty slave %s: %m", pty_name);
3563 #endif /* TIOCGPTN */
3566 /* the old way - scan through the pty name space */
3567 for (i = 0; i < 64; ++i) {
3568 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3569 'p' + i / 16, i % 16);
3570 mfd = open(pty_name, O_RDWR, 0);
3573 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3575 ret = fchown(sfd, uid, -1);
3577 warn("Couldn't change ownership of %s, %m", pty_name);
3579 ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3581 warn("Couldn't change permissions of %s, %m", pty_name);
3593 strlcpy(slave_name, pty_name, 16);
3596 if (tcgetattr(sfd, &tios) == 0) {
3597 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3598 tios.c_cflag |= CS8 | CREAD | CLOCAL;
3599 tios.c_iflag = IGNPAR;
3602 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3603 warn("couldn't set attributes on pty: %m");
3605 warn("couldn't get attributes on pty: %m");
3610 /********************************************************************
3612 * open_loopback - open the device we use for getting packets
3613 * in demand mode. Under Linux, we use a pty master/slave pair.
3616 open_ppp_loopback(void)
3621 if (new_style_driver) {
3622 /* allocate ourselves a ppp unit */
3623 if (make_ppp_unit() < 0)
3625 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3626 set_kdebugflag(kdebugflag);
3631 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3632 fatal("No free pty for loopback");
3634 set_ppp_fd(slave_fd);
3636 flags = fcntl(master_fd, F_GETFL);
3638 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3639 warn("couldn't set master loopback to nonblock: %m");
3641 flags = fcntl(ppp_fd, F_GETFL);
3643 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3644 warn("couldn't set slave loopback to nonblock: %m");
3646 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3647 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3649 * Find out which interface we were given.
3651 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3652 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3654 * Enable debug in the driver if requested.
3656 set_kdebugflag (kdebugflag);
3661 /********************************************************************
3663 * sifnpmode - Set the mode for handling packets for a given NP.
3667 sifnpmode(int u, int proto, enum NPmode mode)
3671 npi.protocol = proto;
3673 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3674 if (! ok_error (errno))
3675 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3682 * Use the hostname as part of the random number seed.
3691 for (p = hostname; *p != 0; ++p)
3696 /********************************************************************
3698 * sys_check_options - check the options that the user specified
3702 sys_check_options(void)
3704 if (demand && driver_is_old) {
3705 ppp_option_error("demand dialling is not supported by kernel driver "
3706 "version %d.%d.%d", driver_version, driver_modification,
3710 if (multilink && !new_style_driver) {
3711 warn("Warning: multilink is not supported by the kernel driver");
3717 /********************************************************************
3719 * get_time - Get current time, monotonic if possible.
3722 ppp_get_time(struct timeval *tv)
3724 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3725 * Runtime checking makes it safe. */
3726 #ifndef CLOCK_MONOTONIC
3727 #define CLOCK_MONOTONIC 1
3729 static int monotonic = -1;
3734 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3738 tv->tv_sec = ts.tv_sec;
3739 tv->tv_usec = ts.tv_nsec / 1000;
3742 } else if (monotonic > 0)
3746 warn("Couldn't use monotonic clock source: %m");
3749 return gettimeofday(tv, NULL);