]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
Expand byte count statistics to 64 bits (#298)
[ppp.git] / pppd / sys-linux.c
1 /*
2  * sys-linux.c - System-dependent procedures for setting up
3  * PPP interfaces on Linux systems
4  *
5  * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
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.
17  *
18  * 3. Redistributions of any form whatsoever must retain the following
19  *    acknowledgment:
20  *    "This product includes software developed by Paul Mackerras
21  *     <paulus@samba.org>".
22  *
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.
30  *
31  * Derived from main.c and pppd.h, which are:
32  *
33  * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  *
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  *
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
45  *    distribution.
46  *
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
53  *      5000 Forbes Avenue
54  *      Pittsburgh, PA  15213-3890
55  *      (412) 268-4387, fax: (412) 268-7395
56  *      tech-transfer@andrew.cmu.edu
57  *
58  * 4. Redistributions of any form whatsoever must retain the following
59  *    acknowledgment:
60  *    "This product includes software developed by Computing Services
61  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
62  *
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.
70  */
71
72 #ifdef HAVE_CONFIG_H
73 #include "config.h"
74 #endif
75
76 #include <sys/ioctl.h>
77 #include <sys/types.h>
78 #include <sys/socket.h>
79 #include <sys/time.h>
80 #include <sys/file.h>
81 #include <sys/stat.h>
82 #include <sys/utsname.h>
83 #include <sys/sysmacros.h>
84
85 #include <errno.h>
86 #include <stddef.h>
87 #include <stdio.h>
88 #include <stdlib.h>
89 #include <syslog.h>
90 #include <string.h>
91 #include <time.h>
92 #include <memory.h>
93 #ifdef HAVE_UTMP_H
94 #include <utmp.h>
95 #endif
96 #include <mntent.h>
97 #include <signal.h>
98 #include <fcntl.h>
99 #include <ctype.h>
100 #include <unistd.h>
101 #include <limits.h>
102
103 /* This is in netdevice.h. However, this compile will fail miserably if
104    you attempt to include netdevice.h because it has so many references
105    to __memcpy functions which it should not attempt to do. So, since I
106    really don't use it, but it must be defined, define it now. */
107
108 #ifndef MAX_ADDR_LEN
109 #define MAX_ADDR_LEN 7
110 #endif
111
112 #if !defined(__GLIBC__) || __GLIBC__ >= 2
113 #include <asm/types.h>          /* glibc 2 conflicts with linux/types.h */
114 #include <net/if.h>
115 #include <net/if_arp.h>
116 #include <net/route.h>
117 #include <netinet/if_ether.h>
118 #else
119 #include <linux/types.h>
120 #include <linux/if.h>
121 #include <linux/if_arp.h>
122 #include <linux/route.h>
123 #include <linux/if_ether.h>
124 #endif
125 #include <netinet/in.h>
126 #include <arpa/inet.h>
127
128 #include <linux/ppp_defs.h>
129 #include <linux/if_ppp.h>
130
131 #include <linux/netlink.h>
132 #include <linux/rtnetlink.h>
133 #include <linux/if_link.h>
134 /* Attempt at retaining compile-support with older than 4.7 kernels, or kernels
135  * where RTM_NEWSTATS isn't defined for whatever reason.
136  */
137 #ifndef RTM_NEWSTATS
138 #define RTM_NEWSTATS 92
139 #define RTM_GETSTATS 94
140 #define IFLA_STATS_LINK_64 1
141 #endif
142
143 #ifdef INET6
144 #include <linux/if_addr.h>
145 /* glibc versions prior to 2.24 do not define SOL_NETLINK */
146 #ifndef SOL_NETLINK
147 #define SOL_NETLINK 270
148 #endif
149 /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
150 #ifndef NETLINK_CAP_ACK
151 #define NETLINK_CAP_ACK 10
152 #endif
153 #endif
154
155 #include "pppd.h"
156 #include "fsm.h"
157 #include "ipcp.h"
158
159 #ifdef IPX_CHANGE
160 #include "ipxcp.h"
161 #if __GLIBC__ >= 2 && \
162     !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
163 #include <netipx/ipx.h>
164 #else
165 #include <linux/ipx.h>
166 #endif
167 #endif /* IPX_CHANGE */
168
169 #ifdef PPP_FILTER
170 #include <pcap-bpf.h>
171 #include <linux/filter.h>
172 #endif /* PPP_FILTER */
173
174 #ifdef LOCKLIB
175 #include <sys/locks.h>
176 #endif
177
178 /*
179  * Instead of system header file <termios.h> use local "termios_linux.h" header
180  * file as it provides additional support for arbitrary baud rates via BOTHER.
181  */
182 #include "termios_linux.h"
183
184 #ifdef INET6
185 #ifndef _LINUX_IN6_H
186 /*
187  *    This is in linux/include/net/ipv6.h.
188  */
189
190 struct in6_ifreq {
191     struct in6_addr ifr6_addr;
192     __u32 ifr6_prefixlen;
193     unsigned int ifr6_ifindex;
194 };
195 #endif
196
197 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do {                 \
198         memset(&(sin6).s6_addr, 0, sizeof(struct in6_addr));    \
199         (sin6).s6_addr16[0] = htons(0xfe80);                    \
200         eui64_copy(eui64, (sin6).s6_addr32[2]);                 \
201         } while (0)
202
203 static const eui64_t nulleui64;
204 #endif /* INET6 */
205
206 /* We can get an EIO error on an ioctl if the modem has hung up */
207 #define ok_error(num) ((num)==EIO)
208
209 static int tty_disc = N_TTY;    /* The TTY discipline */
210 static int ppp_disc = N_PPP;    /* The PPP discpline */
211 static int initfdflags = -1;    /* Initial file descriptor flags for fd */
212 static int ppp_fd = -1;         /* fd which is set to PPP discipline */
213 static int sock_fd = -1;        /* socket for doing interface ioctls */
214 static int slave_fd = -1;       /* pty for old-style demand mode, slave */
215 static int master_fd = -1;      /* pty for old-style demand mode, master */
216 #ifdef INET6
217 static int sock6_fd = -1;
218 #endif /* INET6 */
219
220 /*
221  * For the old-style kernel driver, this is the same as ppp_fd.
222  * For the new-style driver, it is the fd of an instance of /dev/ppp
223  * which is attached to the ppp unit and is used for controlling it.
224  */
225 int ppp_dev_fd = -1;            /* fd for /dev/ppp (new style driver) */
226
227 static int chindex;             /* channel index (new style driver) */
228
229 static fd_set in_fds;           /* set of fds that wait_input waits for */
230 static int max_in_fd;           /* highest fd set in in_fds */
231
232 static int has_proxy_arp       = 0;
233 static int driver_version      = 0;
234 static int driver_modification = 0;
235 static int driver_patch        = 0;
236 static int driver_is_old       = 0;
237 static int restore_term        = 0;     /* 1 => we've munged the terminal */
238 static struct termios inittermios;      /* Initial TTY termios */
239
240 int new_style_driver = 0;
241
242 static char loop_name[20];
243 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
244
245 static int      if_is_up;       /* Interface has been marked up */
246 static int      if6_is_up;      /* Interface has been marked up for IPv6, to help differentiate */
247 static int      have_default_route;     /* Gateway for default route added */
248 static int      have_default_route6;    /* Gateway for default IPv6 route added */
249 static struct   rtentry old_def_rt;     /* Old default route */
250 static int      default_rt_repl_rest;   /* replace and restore old default rt */
251 static u_int32_t proxy_arp_addr;        /* Addr for proxy arp entry added */
252 static char proxy_arp_dev[16];          /* Device for proxy arp entry */
253 static u_int32_t our_old_addr;          /* for detecting address changes */
254 static int      dynaddr_set;            /* 1 if ip_dynaddr set */
255 static int      looped;                 /* 1 if using loop */
256 static int      link_mtu;               /* mtu for the link (not bundle) */
257
258 static struct utsname utsname;  /* for the kernel version */
259 static int kernel_version;
260 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
261
262 #define MAX_IFS         100
263
264 #define FLAGS_GOOD (IFF_UP          | IFF_BROADCAST)
265 #define FLAGS_MASK (IFF_UP          | IFF_BROADCAST | \
266                     IFF_POINTOPOINT | IFF_LOOPBACK  | IFF_NOARP)
267
268 #define SIN_ADDR(x)     (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
269
270 /* Prototypes for procedures local to this file. */
271 static int modify_flags(int fd, int clear_bits, int set_bits);
272 static int translate_speed (int bps);
273 static int baud_rate_of (int speed);
274 static void close_route_table (void);
275 static int open_route_table (void);
276 static int read_route_table (struct rtentry *rt);
277 static int defaultroute_exists (struct rtentry *rt, int metric);
278 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
279 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
280                            char *name, int namelen);
281 static void decode_version (char *buf, int *version, int *mod, int *patch);
282 static int set_kdebugflag(int level);
283 static int ppp_registered(void);
284 static int make_ppp_unit(void);
285 static int setifstate (int u, int state);
286
287 extern u_char   inpacket_buf[]; /* borrowed from main.c */
288
289 extern int dfl_route_metric;
290
291 /*
292  * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
293  * if it exists.
294  */
295
296 #define SET_SA_FAMILY(addr, family)                     \
297     memset ((char *) &(addr), '\0', sizeof(addr));      \
298     addr.sa_family = (family);
299
300 /*
301  * Determine if the PPP connection should still be present.
302  */
303
304 extern int hungup;
305
306 /* new_fd is the fd of a tty */
307 static void set_ppp_fd (int new_fd)
308 {
309         ppp_fd = new_fd;
310         if (!new_style_driver)
311                 ppp_dev_fd = new_fd;
312 }
313
314 static int still_ppp(void)
315 {
316         if (new_style_driver)
317                 return !hungup && ppp_fd >= 0;
318         if (!hungup || ppp_fd == slave_fd)
319                 return 1;
320         if (slave_fd >= 0) {
321                 set_ppp_fd(slave_fd);
322                 return 1;
323         }
324         return 0;
325 }
326
327 /*
328  * modify_flags - set and clear flag bits controlling the kernel
329  * PPP driver.
330  */
331 static int modify_flags(int fd, int clear_bits, int set_bits)
332 {
333         int flags;
334
335         if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
336                 goto err;
337         flags = (flags & ~clear_bits) | set_bits;
338         if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
339                 goto err;
340
341         return 0;
342
343  err:
344         if (errno != EIO)
345                 error("Failed to set PPP kernel option flags: %m");
346         return -1;
347 }
348
349 /********************************************************************
350  *
351  * sys_init - System-dependent initialization.
352  */
353
354 void sys_init(void)
355 {
356     /* Get an internet socket for doing socket ioctls. */
357     sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
358     if (sock_fd < 0)
359         fatal("Couldn't create IP socket: %m(%d)", errno);
360
361 #ifdef INET6
362     sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
363     if (sock6_fd < 0)
364         sock6_fd = -errno;      /* save errno for later */
365 #endif
366
367     FD_ZERO(&in_fds);
368     max_in_fd = 0;
369 }
370
371 /********************************************************************
372  *
373  * sys_cleanup - restore any system state we modified before exiting:
374  * mark the interface down, delete default route and/or proxy arp entry.
375  * This shouldn't call die() because it's called from die().
376  */
377
378 void sys_cleanup(void)
379 {
380 /*
381  * Take down the device
382  */
383     if (if_is_up) {
384         if_is_up = 0;
385         sifdown(0);
386     }
387     if (if6_is_up)
388         sif6down(0);
389
390 /*
391  * Delete any routes through the device.
392  */
393     if (have_default_route)
394         cifdefaultroute(0, 0, 0);
395 #ifdef INET6
396     if (have_default_route6)
397         cif6defaultroute(0, nulleui64, nulleui64);
398 #endif
399
400     if (has_proxy_arp)
401         cifproxyarp(0, proxy_arp_addr);
402 }
403
404 /********************************************************************
405  *
406  * sys_close - Clean up in a child process before execing.
407  */
408 void
409 sys_close(void)
410 {
411     if (new_style_driver && ppp_dev_fd >= 0)
412         close(ppp_dev_fd);
413     if (sock_fd >= 0)
414         close(sock_fd);
415 #ifdef INET6
416     if (sock6_fd >= 0)
417         close(sock6_fd);
418 #endif
419     if (slave_fd >= 0)
420         close(slave_fd);
421     if (master_fd >= 0)
422         close(master_fd);
423 }
424
425 /********************************************************************
426  *
427  * set_kdebugflag - Define the debugging level for the kernel
428  */
429
430 static int set_kdebugflag (int requested_level)
431 {
432     if (ppp_dev_fd < 0)
433         return 1;
434     if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
435         if ( ! ok_error (errno) )
436             error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
437         return (0);
438     }
439     return (1);
440 }
441
442 /********************************************************************
443  *
444  * tty_establish_ppp - Turn the serial port into a ppp interface.
445  */
446
447 int tty_establish_ppp (int tty_fd)
448 {
449     int ret_fd;
450
451 /*
452  * Ensure that the tty device is in exclusive mode.
453  */
454     if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
455         if ( ! ok_error ( errno ))
456             warn("Couldn't make tty exclusive: %m");
457     }
458 /*
459  * Demand mode - prime the old ppp device to relinquish the unit.
460  */
461     if (!new_style_driver && looped
462         && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
463         error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
464         return -1;
465     }
466 /*
467  * Set the current tty to the PPP discpline
468  */
469
470 #ifndef N_SYNC_PPP
471 #define N_SYNC_PPP 14
472 #endif
473     ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
474     if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
475         if ( ! ok_error (errno) ) {
476             error("Couldn't set tty to PPP discipline: %m");
477             return -1;
478         }
479     }
480
481     ret_fd = generic_establish_ppp(tty_fd);
482
483 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
484 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
485                  | SC_LOG_FLUSH)
486
487     if (ret_fd >= 0) {
488         modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
489                      (kdebugflag * SC_DEBUG) & SC_LOGB);
490     } else {
491         if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
492             warn("Couldn't reset tty to normal line discipline: %m");
493     }
494
495     return ret_fd;
496 }
497
498 /********************************************************************
499  *
500  * generic_establish_ppp - Turn the fd into a ppp interface.
501  */
502 int generic_establish_ppp (int fd)
503 {
504     int x;
505
506     if (new_style_driver) {
507         int flags;
508
509         /* If a ppp_fd is already open, close it first */
510         if (ppp_fd >= 0) {
511             close(ppp_fd);
512             remove_fd(ppp_fd);
513             ppp_fd = -1;
514         }
515
516         /* Open an instance of /dev/ppp and connect the channel to it */
517         if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
518             error("Couldn't get channel number: %m");
519             goto err;
520         }
521         dbglog("using channel %d", chindex);
522         fd = open("/dev/ppp", O_RDWR);
523         if (fd < 0) {
524             error("Couldn't reopen /dev/ppp: %m");
525             goto err;
526         }
527         (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
528         if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
529             error("Couldn't attach to channel %d: %m", chindex);
530             goto err_close;
531         }
532         flags = fcntl(fd, F_GETFL);
533         if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
534             warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
535         set_ppp_fd(fd);
536
537         if (!looped)
538             ifunit = -1;
539         if (!looped && !multilink) {
540             /*
541              * Create a new PPP unit.
542              */
543             if (make_ppp_unit() < 0)
544                 goto err_close;
545         }
546
547         if (looped)
548             modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
549
550         if (!multilink) {
551             add_fd(ppp_dev_fd);
552             if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
553                 error("Couldn't attach to PPP unit %d: %m", ifunit);
554                 goto err_close;
555             }
556         }
557
558     } else {
559         /*
560          * Old-style driver: find out which interface we were given.
561          */
562         set_ppp_fd (fd);
563         if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
564             if (ok_error (errno))
565                 goto err;
566             fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
567         }
568         /* Check that we got the same unit again. */
569         if (looped && x != ifunit)
570             fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
571         ifunit = x;
572
573         /*
574          * Fetch the initial file flags and reset blocking mode on the file.
575          */
576         initfdflags = fcntl(fd, F_GETFL);
577         if (initfdflags == -1 ||
578             fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
579             if ( ! ok_error (errno))
580                 warn("Couldn't set device to non-blocking mode: %m");
581         }
582     }
583
584     /*
585      * Enable debug in the driver if requested.
586      */
587     if (!looped)
588         set_kdebugflag (kdebugflag);
589
590     looped = 0;
591
592     return ppp_fd;
593
594  err_close:
595     close(fd);
596  err:
597     return -1;
598 }
599
600 /********************************************************************
601  *
602  * tty_disestablish_ppp - Restore the serial port to normal operation.
603  * This shouldn't call die() because it's called from die().
604  */
605
606 void tty_disestablish_ppp(int tty_fd)
607 {
608     if (!hungup) {
609 /*
610  * Flush the tty output buffer so that the TIOCSETD doesn't hang.
611  */
612         if (tcflush(tty_fd, TCIOFLUSH) < 0)
613         {
614             warn("tcflush failed: %m");
615             goto flushfailed;
616         }
617 /*
618  * Restore the previous line discipline
619  */
620         if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
621             if ( ! ok_error (errno))
622                 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
623         }
624
625         if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
626             if ( ! ok_error (errno))
627                 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
628         }
629
630         /* Reset non-blocking mode on fd. */
631         if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
632             if ( ! ok_error (errno))
633                 warn("Couldn't restore device fd flags: %m");
634         }
635     }
636 flushfailed:
637     initfdflags = -1;
638
639     generic_disestablish_ppp(tty_fd);
640 }
641
642 /********************************************************************
643  *
644  * generic_disestablish_ppp - Restore device components to normal
645  * operation, and reconnect the ppp unit to the loopback if in demand
646  * mode.  This shouldn't call die() because it's called from die().
647  */
648 void generic_disestablish_ppp(int dev_fd)
649 {
650     if (new_style_driver) {
651         close(ppp_fd);
652         ppp_fd = -1;
653         if (demand) {
654             modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
655             looped = 1;
656         } else if (!doing_multilink && ppp_dev_fd >= 0) {
657             close(ppp_dev_fd);
658             remove_fd(ppp_dev_fd);
659             ppp_dev_fd = -1;
660         }
661     } else {
662         /* old-style driver */
663         if (demand)
664             set_ppp_fd(slave_fd);
665         else
666             ppp_dev_fd = -1;
667     }
668 }
669
670 /*
671  * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
672  * Assumes new_style_driver.
673  */
674 static int make_ppp_unit(void)
675 {
676         int x, flags;
677
678         if (ppp_dev_fd >= 0) {
679                 dbglog("in make_ppp_unit, already had /dev/ppp open?");
680                 close(ppp_dev_fd);
681         }
682         ppp_dev_fd = open("/dev/ppp", O_RDWR);
683         if (ppp_dev_fd < 0)
684                 fatal("Couldn't open /dev/ppp: %m");
685         flags = fcntl(ppp_dev_fd, F_GETFL);
686         if (flags == -1
687             || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
688                 warn("Couldn't set /dev/ppp to nonblock: %m");
689
690         ifunit = req_unit;
691         x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
692         if (x < 0 && req_unit >= 0 && errno == EEXIST) {
693                 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
694                 ifunit = -1;
695                 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
696         }
697         if (x < 0)
698                 error("Couldn't create new ppp unit: %m");
699
700         if (x == 0 && req_ifname[0] != '\0') {
701                 struct ifreq ifr;
702                 char t[IFNAMSIZ];
703                 memset(&ifr, 0, sizeof(struct ifreq));
704                 slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
705                 strlcpy(ifr.ifr_name, t, IFNAMSIZ);
706                 strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
707                 x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
708                 if (x < 0)
709                     error("Couldn't rename interface %s to %s: %m", t, req_ifname);
710                 else
711                     info("Renamed interface %s to %s", t, req_ifname);
712         }
713
714         return x;
715 }
716
717 /*
718  * cfg_bundle - configure the existing bundle.
719  * Used in demand mode.
720  */
721 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
722 {
723         if (!new_style_driver)
724                 return;
725
726         /* set the mrru, mtu and flags */
727         if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
728                 error("Couldn't set MRRU: %m");
729
730         modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
731                      ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
732                       | (mrru? SC_MULTILINK: 0)));
733
734         /* connect up the channel */
735         if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
736                 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
737         add_fd(ppp_dev_fd);
738 }
739
740 /*
741  * make_new_bundle - create a new PPP unit (i.e. a bundle)
742  * and connect our channel to it.  This should only get called
743  * if `multilink' was set at the time establish_ppp was called.
744  * In demand mode this uses our existing bundle instead of making
745  * a new one.
746  */
747 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
748 {
749         if (!new_style_driver)
750                 return;
751
752         /* make us a ppp unit */
753         if (make_ppp_unit() < 0)
754                 die(1);
755
756         /* set the mrru and flags */
757         cfg_bundle(mrru, mtru, rssn, tssn);
758 }
759
760 /*
761  * bundle_attach - attach our link to a given PPP unit.
762  * We assume the unit is controlled by another pppd.
763  */
764 int bundle_attach(int ifnum)
765 {
766         int master_fd;
767
768         if (!new_style_driver)
769                 return -1;
770
771         master_fd = open("/dev/ppp", O_RDWR);
772         if (master_fd < 0)
773                 fatal("Couldn't open /dev/ppp: %m");
774         if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
775                 if (errno == ENXIO) {
776                         close(master_fd);
777                         return 0;       /* doesn't still exist */
778                 }
779                 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
780         }
781         if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
782                 fatal("Couldn't connect to interface unit %d: %m", ifnum);
783         modify_flags(master_fd, 0, SC_MULTILINK);
784         close(master_fd);
785
786         ifunit = ifnum;
787         return 1;
788 }
789
790 /*
791  * destroy_bundle - tell the driver to destroy our bundle.
792  */
793 void destroy_bundle(void)
794 {
795         if (ppp_dev_fd >= 0) {
796                 close(ppp_dev_fd);
797                 remove_fd(ppp_dev_fd);
798                 ppp_dev_fd = -1;
799         }
800 }
801
802 /********************************************************************
803  *
804  * clean_check - Fetch the flags for the device and generate
805  * appropriate error messages.
806  */
807 void clean_check(void)
808 {
809     int x;
810     char *s;
811
812     if (still_ppp()) {
813         if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
814             s = NULL;
815             switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
816             case SC_RCV_B7_0:
817                 s = "all had bit 7 set to 1";
818                 break;
819
820             case SC_RCV_B7_1:
821                 s = "all had bit 7 set to 0";
822                 break;
823
824             case SC_RCV_EVNP:
825                 s = "all had odd parity";
826                 break;
827
828             case SC_RCV_ODDP:
829                 s = "all had even parity";
830                 break;
831             }
832
833             if (s != NULL) {
834                 warn("Receive serial link is not 8-bit clean:");
835                 warn("Problem: %s", s);
836             }
837         }
838     }
839 }
840
841
842 /*
843  * List of valid speeds.
844  */
845
846 struct speed {
847     int speed_int, speed_val;
848 } speeds[] = {
849 #ifdef B50
850     { 50, B50 },
851 #endif
852 #ifdef B75
853     { 75, B75 },
854 #endif
855 #ifdef B110
856     { 110, B110 },
857 #endif
858 #ifdef B134
859     { 134, B134 },
860 #endif
861 #ifdef B150
862     { 150, B150 },
863 #endif
864 #ifdef B200
865     { 200, B200 },
866 #endif
867 #ifdef B300
868     { 300, B300 },
869 #endif
870 #ifdef B600
871     { 600, B600 },
872 #endif
873 #ifdef B1200
874     { 1200, B1200 },
875 #endif
876 #ifdef B1800
877     { 1800, B1800 },
878 #endif
879 #ifdef B2000
880     { 2000, B2000 },
881 #endif
882 #ifdef B2400
883     { 2400, B2400 },
884 #endif
885 #ifdef B3600
886     { 3600, B3600 },
887 #endif
888 #ifdef B4800
889     { 4800, B4800 },
890 #endif
891 #ifdef B7200
892     { 7200, B7200 },
893 #endif
894 #ifdef B9600
895     { 9600, B9600 },
896 #endif
897 #ifdef B19200
898     { 19200, B19200 },
899 #endif
900 #ifdef B38400
901     { 38400, B38400 },
902 #endif
903 #ifdef B57600
904     { 57600, B57600 },
905 #endif
906 #ifdef B76800
907     { 76800, B76800 },
908 #endif
909 #ifdef B115200
910     { 115200, B115200 },
911 #endif
912 #ifdef EXTA
913     { 19200, EXTA },
914 #endif
915 #ifdef EXTB
916     { 38400, EXTB },
917 #endif
918 #ifdef B230400
919     { 230400, B230400 },
920 #endif
921 #ifdef B460800
922     { 460800, B460800 },
923 #endif
924 #ifdef B500000
925     { 500000, B500000 },
926 #endif
927 #ifdef B576000
928     { 576000, B576000 },
929 #endif
930 #ifdef B921600
931     { 921600, B921600 },
932 #endif
933 #ifdef B1000000
934     { 1000000, B1000000 },
935 #endif
936 #ifdef B1152000
937     { 1152000, B1152000 },
938 #endif
939 #ifdef B1500000
940     { 1500000, B1500000 },
941 #endif
942 #ifdef B2000000
943     { 2000000, B2000000 },
944 #endif
945 #ifdef B2500000
946     { 2500000, B2500000 },
947 #endif
948 #ifdef B3000000
949     { 3000000, B3000000 },
950 #endif
951 #ifdef B3500000
952     { 3500000, B3500000 },
953 #endif
954 #ifdef B4000000
955     { 4000000, B4000000 },
956 #endif
957     { 0, 0 }
958 };
959
960 /********************************************************************
961  *
962  * Translate from bits/second to a speed_t.
963  */
964
965 static int translate_speed (int bps)
966 {
967     struct speed *speedp;
968
969     if (bps != 0) {
970         for (speedp = speeds; speedp->speed_int; speedp++) {
971             if (bps == speedp->speed_int)
972                 return speedp->speed_val;
973         }
974     }
975     return 0;
976 }
977
978 /********************************************************************
979  *
980  * Translate from a speed_t to bits/second.
981  */
982
983 static int baud_rate_of (int speed)
984 {
985     struct speed *speedp;
986
987     if (speed != 0) {
988         for (speedp = speeds; speedp->speed_int; speedp++) {
989             if (speed == speedp->speed_val)
990                 return speedp->speed_int;
991         }
992     }
993     return 0;
994 }
995
996 /********************************************************************
997  *
998  * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
999  * at the requested speed, etc.  If `local' is true, set CLOCAL
1000  * regardless of whether the modem option was specified.
1001  */
1002
1003 void set_up_tty(int tty_fd, int local)
1004 {
1005     int speed;
1006     struct termios tios;
1007
1008     setdtr(tty_fd, 1);
1009     if (tcgetattr(tty_fd, &tios) < 0) {
1010         if (!ok_error(errno))
1011             fatal("tcgetattr: %m (line %d)", __LINE__);
1012         return;
1013     }
1014
1015     if (!restore_term)
1016         inittermios = tios;
1017
1018     tios.c_cflag     &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
1019     tios.c_cflag     |= CS8 | CREAD | HUPCL;
1020
1021     tios.c_iflag      = IGNBRK | IGNPAR;
1022     tios.c_oflag      = 0;
1023     tios.c_lflag      = 0;
1024     tios.c_cc[VMIN]   = 1;
1025     tios.c_cc[VTIME]  = 0;
1026
1027     if (local || !modem)
1028         tios.c_cflag ^= (CLOCAL | HUPCL);
1029
1030     switch (crtscts) {
1031     case 1:
1032         tios.c_cflag |= CRTSCTS;
1033         break;
1034
1035     case -2:
1036         tios.c_iflag     |= IXON | IXOFF;
1037         tios.c_cc[VSTOP]  = 0x13;       /* DC3 = XOFF = ^S */
1038         tios.c_cc[VSTART] = 0x11;       /* DC1 = XON  = ^Q */
1039         break;
1040
1041     case -1:
1042         tios.c_cflag &= ~CRTSCTS;
1043         break;
1044
1045     default:
1046         break;
1047     }
1048
1049     if (stop_bits >= 2)
1050         tios.c_cflag |= CSTOPB;
1051
1052     if (inspeed) {
1053         speed = translate_speed(inspeed);
1054         if (speed) {
1055             cfsetospeed (&tios, speed);
1056             cfsetispeed (&tios, speed);
1057             speed = cfgetospeed(&tios);
1058             baud_rate = baud_rate_of(speed);
1059         } else {
1060 #ifdef BOTHER
1061             tios.c_cflag &= ~CBAUD;
1062             tios.c_cflag |= BOTHER;
1063             tios.c_ospeed = inspeed;
1064 #ifdef IBSHIFT
1065             /* B0 sets input baudrate to the output baudrate */
1066             tios.c_cflag &= ~(CBAUD << IBSHIFT);
1067             tios.c_cflag |= B0 << IBSHIFT;
1068             tios.c_ispeed = inspeed;
1069 #endif
1070             baud_rate = inspeed;
1071 #else
1072             baud_rate = 0;
1073 #endif
1074         }
1075     }
1076     else {
1077         speed = cfgetospeed(&tios);
1078         baud_rate = baud_rate_of(speed);
1079 #ifdef BOTHER
1080         if (!baud_rate)
1081             baud_rate = tios.c_ospeed;
1082 #endif
1083     }
1084
1085 /*
1086  * We can't proceed if the serial port baud rate is unknown,
1087  * since that implies that the serial port is disabled.
1088  */
1089     if (!baud_rate) {
1090         if (inspeed)
1091             fatal("speed %d not supported", inspeed);
1092         else
1093             fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1094     }
1095
1096     while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1097         if (errno != EINTR)
1098             fatal("tcsetattr: %m (line %d)", __LINE__);
1099     restore_term = 1;
1100 }
1101
1102 /********************************************************************
1103  *
1104  * setdtr - control the DTR line on the serial port.
1105  * This is called from die(), so it shouldn't call die().
1106  */
1107
1108 void setdtr (int tty_fd, int on)
1109 {
1110     int modembits = TIOCM_DTR;
1111
1112     ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1113 }
1114
1115 /********************************************************************
1116  *
1117  * restore_tty - restore the terminal to the saved settings.
1118  */
1119
1120 void restore_tty (int tty_fd)
1121 {
1122     if (restore_term) {
1123         restore_term = 0;
1124 /*
1125  * Turn off echoing, because otherwise we can get into
1126  * a loop with the tty and the modem echoing to each other.
1127  * We presume we are the sole user of this tty device, so
1128  * when we close it, it will revert to its defaults anyway.
1129  */
1130         if (!default_device)
1131             inittermios.c_lflag &= ~(ECHO | ECHONL);
1132
1133         if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1134             if (! ok_error (errno))
1135                 warn("tcsetattr: %m (line %d)", __LINE__);
1136         }
1137     }
1138 }
1139
1140 /********************************************************************
1141  *
1142  * output - Output PPP packet.
1143  */
1144
1145 void output (int unit, unsigned char *p, int len)
1146 {
1147     int fd = ppp_fd;
1148     int proto;
1149
1150     dump_packet("sent", p, len);
1151     if (snoop_send_hook) snoop_send_hook(p, len);
1152
1153     if (len < PPP_HDRLEN)
1154         return;
1155     if (new_style_driver) {
1156         p += 2;
1157         len -= 2;
1158         proto = (p[0] << 8) + p[1];
1159         if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1160             fd = ppp_dev_fd;
1161     }
1162     if (write(fd, p, len) < 0) {
1163         if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1164             || errno == ENXIO || errno == EIO || errno == EINTR)
1165             warn("write: warning: %m (%d)", errno);
1166         else
1167             error("write: %m (%d)", errno);
1168     }
1169 }
1170
1171 /********************************************************************
1172  *
1173  * wait_input - wait until there is data available,
1174  * for the length of time specified by *timo (indefinite
1175  * if timo is NULL).
1176  */
1177
1178 void wait_input(struct timeval *timo)
1179 {
1180     fd_set ready, exc;
1181     int n;
1182
1183     ready = in_fds;
1184     exc = in_fds;
1185     n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1186     if (n < 0 && errno != EINTR)
1187         fatal("select: %m");
1188 }
1189
1190 /*
1191  * add_fd - add an fd to the set that wait_input waits for.
1192  */
1193 void add_fd(int fd)
1194 {
1195     if (fd >= FD_SETSIZE)
1196         fatal("internal error: file descriptor too large (%d)", fd);
1197     FD_SET(fd, &in_fds);
1198     if (fd > max_in_fd)
1199         max_in_fd = fd;
1200 }
1201
1202 /*
1203  * remove_fd - remove an fd from the set that wait_input waits for.
1204  */
1205 void remove_fd(int fd)
1206 {
1207     FD_CLR(fd, &in_fds);
1208 }
1209
1210
1211 /********************************************************************
1212  *
1213  * read_packet - get a PPP packet from the serial device.
1214  */
1215
1216 int read_packet (unsigned char *buf)
1217 {
1218     int len, nr;
1219
1220     len = PPP_MRU + PPP_HDRLEN;
1221     if (new_style_driver) {
1222         *buf++ = PPP_ALLSTATIONS;
1223         *buf++ = PPP_UI;
1224         len -= 2;
1225     }
1226     nr = -1;
1227     if (ppp_fd >= 0) {
1228         nr = read(ppp_fd, buf, len);
1229         if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1230             && errno != EIO && errno != EINTR)
1231             error("read: %m");
1232         if (nr < 0 && errno == ENXIO)
1233             return 0;
1234     }
1235     if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1236         /* N.B. we read ppp_fd first since LCP packets come in there. */
1237         nr = read(ppp_dev_fd, buf, len);
1238         if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1239             && errno != EIO && errno != EINTR)
1240             error("read /dev/ppp: %m");
1241         if (nr < 0 && errno == ENXIO)
1242             nr = 0;
1243         if (nr == 0 && doing_multilink) {
1244             remove_fd(ppp_dev_fd);
1245             bundle_eof = 1;
1246         }
1247     }
1248     if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1249         nr = 0;
1250     return (new_style_driver && nr > 0)? nr+2: nr;
1251 }
1252
1253 /********************************************************************
1254  *
1255  * get_loop_output - get outgoing packets from the ppp device,
1256  * and detect when we want to bring the real link up.
1257  * Return value is 1 if we need to bring up the link, 0 otherwise.
1258  */
1259 int
1260 get_loop_output(void)
1261 {
1262     int rv = 0;
1263     int n;
1264
1265     if (new_style_driver) {
1266         while ((n = read_packet(inpacket_buf)) > 0)
1267             if (loop_frame(inpacket_buf, n))
1268                 rv = 1;
1269         return rv;
1270     }
1271
1272     while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1273         if (loop_chars(inbuf, n))
1274             rv = 1;
1275
1276     if (n == 0)
1277         fatal("eof on loopback");
1278
1279     if (errno != EWOULDBLOCK && errno != EAGAIN)
1280         fatal("read from loopback: %m(%d)", errno);
1281
1282     return rv;
1283 }
1284
1285 /*
1286  * netif_set_mtu - set the MTU on the PPP network interface.
1287  */
1288 void
1289 netif_set_mtu(int unit, int mtu)
1290 {
1291     struct ifreq ifr;
1292
1293     memset (&ifr, '\0', sizeof (ifr));
1294     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1295     ifr.ifr_mtu = mtu;
1296
1297     if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1298         error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1299 }
1300
1301 /*
1302  * netif_get_mtu - get the MTU on the PPP network interface.
1303  */
1304 int
1305 netif_get_mtu(int unit)
1306 {
1307     struct ifreq ifr;
1308
1309     memset (&ifr, '\0', sizeof (ifr));
1310     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1311
1312     if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1313         error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1314         return 0;
1315     }
1316     return ifr.ifr_mtu;
1317 }
1318
1319 /********************************************************************
1320  *
1321  * tty_send_config - configure the transmit characteristics of
1322  * the ppp interface.
1323  */
1324
1325 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1326 {
1327         int x;
1328
1329         if (!still_ppp())
1330                 return;
1331         link_mtu = mtu;
1332         if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1333                 if (errno != EIO && errno != ENOTTY)
1334                         error("Couldn't set transmit async character map: %m");
1335                 ++error_count;
1336                 return;
1337         }
1338
1339         x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1340             | (sync_serial? SC_SYNC: 0);
1341         modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1342 }
1343
1344 /********************************************************************
1345  *
1346  * tty_set_xaccm - set the extended transmit ACCM for the interface.
1347  */
1348
1349 void tty_set_xaccm (ext_accm accm)
1350 {
1351     if (!still_ppp())
1352         return;
1353     if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1354         if ( ! ok_error (errno))
1355             warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1356     }
1357 }
1358
1359 /********************************************************************
1360  *
1361  * tty_recv_config - configure the receive-side characteristics of
1362  * the ppp interface.
1363  */
1364
1365 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1366 {
1367 /*
1368  * If we were called because the link has gone down then there is nothing
1369  * which may be done. Just return without incident.
1370  */
1371         if (!still_ppp())
1372                 return;
1373 /*
1374  * Set the receiver parameters
1375  */
1376         if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1377                 if (errno != EIO && errno != ENOTTY)
1378                         error("Couldn't set channel receive MRU: %m");
1379         }
1380         if (new_style_driver && ppp_dev_fd >= 0
1381             && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1382                 error("Couldn't set MRU in generic PPP layer: %m");
1383
1384         if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1385                 if (errno != EIO && errno != ENOTTY)
1386                         error("Couldn't set channel receive asyncmap: %m");
1387         }
1388 }
1389
1390 /********************************************************************
1391  *
1392  * ccp_test - ask kernel whether a given compression method
1393  * is acceptable for use.
1394  */
1395
1396 int
1397 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1398 {
1399     struct ppp_option_data data;
1400
1401     memset (&data, '\0', sizeof (data));
1402     data.ptr      = opt_ptr;
1403     data.length   = opt_len;
1404     data.transmit = for_transmit;
1405
1406     if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1407         return 1;
1408
1409     return (errno == ENOBUFS)? 0: -1;
1410 }
1411
1412 /********************************************************************
1413  *
1414  * ccp_flags_set - inform kernel about the current state of CCP.
1415  */
1416
1417 void ccp_flags_set (int unit, int isopen, int isup)
1418 {
1419         int x;
1420
1421         x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1422         if (still_ppp() && ppp_dev_fd >= 0)
1423                 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1424 }
1425
1426 #ifdef PPP_FILTER
1427 /*
1428  * set_filters - set the active and pass filters in the kernel driver.
1429  */
1430 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1431 {
1432         struct sock_fprog fp;
1433
1434         fp.len = pass->bf_len;
1435         fp.filter = (struct sock_filter *) pass->bf_insns;
1436         if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1437                 if (errno == ENOTTY)
1438                         warn("kernel does not support PPP filtering");
1439                 else
1440                         error("Couldn't set pass-filter in kernel: %m");
1441                 return 0;
1442         }
1443         fp.len = active->bf_len;
1444         fp.filter = (struct sock_filter *) active->bf_insns;
1445         if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1446                 error("Couldn't set active-filter in kernel: %m");
1447                 return 0;
1448         }
1449         return 1;
1450 }
1451 #endif /* PPP_FILTER */
1452
1453 /********************************************************************
1454  *
1455  * get_idle_time - return how long the link has been idle.
1456  */
1457 int
1458 get_idle_time(int u, struct ppp_idle *ip)
1459 {
1460     return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1461 }
1462
1463 /********************************************************************
1464  *
1465  * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
1466  * this only supports 32-bit counters, so need to count the wraps.
1467  */
1468 static int
1469 get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
1470 {
1471     static u_int32_t previbytes = 0;
1472     static u_int32_t prevobytes = 0;
1473     static u_int32_t iwraps = 0;
1474     static u_int32_t owraps = 0;
1475
1476     struct ifpppstatsreq req;
1477
1478     memset (&req, 0, sizeof (req));
1479
1480     req.stats_ptr = (caddr_t) &req.stats;
1481     strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1482     if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1483         error("Couldn't get PPP statistics: %m");
1484         return 0;
1485     }
1486     stats->bytes_in = req.stats.p.ppp_ibytes;
1487     stats->bytes_out = req.stats.p.ppp_obytes;
1488     stats->pkts_in = req.stats.p.ppp_ipackets;
1489     stats->pkts_out = req.stats.p.ppp_opackets;
1490
1491     if (stats->bytes_in < previbytes)
1492         ++iwraps;
1493     if (stats->bytes_out < prevobytes)
1494         ++owraps;
1495
1496     previbytes = stats->bytes_in;
1497     prevobytes = stats->bytes_out;
1498
1499     stats->bytes_in += (uint64_t)iwraps << 32;
1500     stats->bytes_out += (uint64_t)owraps << 32;
1501
1502     return 1;
1503 }
1504
1505 /********************************************************************
1506  * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
1507  * This provides native 64-bit counters.
1508  */
1509 static int
1510 get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
1511 {
1512     static int rtnl_fd = -1;
1513
1514     struct sockaddr_nl nladdr;
1515     struct {
1516         struct nlmsghdr nlh;
1517         struct if_stats_msg ifsm;
1518     } nlreq;
1519     struct nlresp {
1520         struct nlmsghdr nlh;
1521         union {
1522             struct {
1523                 struct nlmsgerr nlerr;
1524                 char __end_err[0];
1525             };
1526             struct {
1527                 struct rtmsg rth;
1528                 struct  {
1529                     /* We only case about these first fields from rtnl_link_stats64 */
1530                     uint64_t rx_packets;
1531                     uint64_t tx_packets;
1532                     uint64_t rx_bytes;
1533                     uint64_t tx_bytes;
1534                 } stats;
1535                 char __end_stats[0];
1536             };
1537         };
1538     } nlresp;
1539     ssize_t nlresplen;
1540     struct iovec iov;
1541     struct msghdr msg;
1542
1543     memset(&nladdr, 0, sizeof(nladdr));
1544     nladdr.nl_family = AF_NETLINK;
1545
1546     if (rtnl_fd < 0) {
1547         rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1548         if (rtnl_fd < 0) {
1549             error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__);
1550             return 0;
1551         }
1552
1553         if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
1554             error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
1555             goto err;
1556         }
1557     }
1558
1559     memset(&nlreq, 0, sizeof(nlreq));
1560     nlreq.nlh.nlmsg_len = sizeof(nlreq);
1561     nlreq.nlh.nlmsg_type = RTM_GETSTATS;
1562     nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
1563
1564     nlreq.ifsm.ifindex = if_nametoindex(ifname);
1565     nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
1566
1567     memset(&iov, 0, sizeof(iov));
1568     iov.iov_base = &nlreq;
1569     iov.iov_len = sizeof(nlreq);
1570
1571     memset(&msg, 0, sizeof(msg));
1572     msg.msg_name = &nladdr;
1573     msg.msg_namelen = sizeof(nladdr);
1574     msg.msg_iov = &iov;
1575     msg.msg_iovlen = 1;
1576
1577     if (sendmsg(rtnl_fd, &msg, 0) < 0) {
1578         error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1579         goto err;
1580     }
1581
1582     /* We just need to repoint to IOV ... everything else stays the same */
1583     iov.iov_base = &nlresp;
1584     iov.iov_len = sizeof(nlresp);
1585
1586     nlresplen = recvmsg(rtnl_fd, &msg, 0);
1587
1588     if (nlresplen < 0) {
1589         error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
1590         goto err;
1591     }
1592
1593     if (nlresplen < sizeof(nlresp.nlh)) {
1594         error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__);
1595         goto err;
1596     }
1597
1598     if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) {
1599         if (nlresplen < offsetof(struct nlresp, __end_err)) {
1600             if (kernel_version >= KVERSION(4,7,0))
1601                 error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
1602         } else {
1603             error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).",
1604                     __LINE__);
1605         }
1606         goto err;
1607     }
1608
1609     if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) {
1610         error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)",
1611                 nlresp.nlh.nlmsg_type, __LINE__);
1612         goto err;
1613     }
1614
1615     if (nlresplen < offsetof(struct nlresp, __end_stats)) {
1616         error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
1617         goto err;
1618     }
1619
1620     stats->bytes_in  = nlresp.stats.rx_bytes;
1621     stats->bytes_out = nlresp.stats.tx_bytes;
1622     stats->pkts_in   = nlresp.stats.rx_packets;
1623     stats->pkts_out  = nlresp.stats.tx_packets;
1624
1625     return 1;
1626 err:
1627     close(rtnl_fd);
1628     rtnl_fd = -1;
1629     return 0;
1630 }
1631
1632 /********************************************************************
1633  * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
1634  * this provides native 64-bit counters.
1635  */
1636 static int
1637 get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
1638 {
1639     char fname[PATH_MAX+1];
1640     char buf[21], *err; /* 2^64 < 10^20 */
1641     int blen, fd, rlen;
1642     unsigned long long val;
1643
1644     struct {
1645         const char* fname;
1646         void* ptr;
1647         unsigned size;
1648     } slist[] = {
1649 #define statfield(fn, field)    { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
1650         statfield(rx_bytes, bytes_in),
1651         statfield(tx_bytes, bytes_out),
1652         statfield(rx_packets, pkts_in),
1653         statfield(tx_packets, pkts_out),
1654 #undef statfield
1655     };
1656
1657     blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
1658     if (blen >= sizeof(fname))
1659         return 0; /* ifname max 15, so this should be impossible */
1660
1661     for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
1662         if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
1663             fname[blen] = 0;
1664             error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
1665             return 0;
1666         }
1667
1668         fd = open(fname, O_RDONLY);
1669         if (fd < 0) {
1670             error("%s: %m", fname);
1671             return 0;
1672         }
1673
1674         rlen = read(fd, buf, sizeof(buf) - 1);
1675         close(fd);
1676         if (rlen < 0) {
1677             error("%s: %m", fname);
1678             return 0;
1679         }
1680         /* trim trailing \n if present */
1681         while (rlen > 0 && buf[rlen-1] == '\n')
1682             rlen--;
1683         buf[rlen] = 0;
1684
1685         errno = 0;
1686         val = strtoull(buf, &err, 10);
1687         if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
1688             error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
1689                     buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
1690             return 0;
1691         }
1692         switch (slist[i].size) {
1693 #define stattype(type)  case sizeof(type): *(type*)slist[i].ptr = (type)val; break
1694             stattype(uint64_t);
1695             stattype(uint32_t);
1696             stattype(uint16_t);
1697             stattype(uint8_t);
1698 #undef stattype
1699         default:
1700             error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
1701             return 0;
1702         }
1703     }
1704
1705     return 1;
1706 }
1707
1708 /********************************************************************
1709  * Periodic timer function to be used to keep stats up to date in case of ioctl
1710  * polling.
1711  *
1712  * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
1713  * If you do change the timer, remember to also bring the get_ppp_stats (which
1714  * sets up the initial trigger) as well.
1715  */
1716 static void
1717 ppp_stats_poller(void* u)
1718 {
1719     struct pppd_stats dummy;
1720     get_ppp_stats_ioctl((long)u, &dummy);
1721     TIMEOUT(ppp_stats_poller, u, 25);
1722 }
1723
1724 /********************************************************************
1725  * get_ppp_stats - return statistics for the link.
1726  */
1727 int get_ppp_stats(int u, struct pppd_stats *stats)
1728 {
1729     static int (*func)(int, struct pppd_stats*) = NULL;
1730
1731     if (!func) {
1732         if (get_ppp_stats_rtnetlink(u, stats)) {
1733             func = get_ppp_stats_rtnetlink;
1734             return 1;
1735         }
1736         if (get_ppp_stats_sysfs(u, stats)) {
1737             func = get_ppp_stats_sysfs;
1738             return 1;
1739         }
1740         warn("statistics falling back to ioctl which only supports 32-bit counters");
1741         func = get_ppp_stats_ioctl;
1742         TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
1743     }
1744
1745     return func(u, stats);
1746 }
1747
1748 /********************************************************************
1749  *
1750  * ccp_fatal_error - returns 1 if decompression was disabled as a
1751  * result of an error detected after decompression of a packet,
1752  * 0 otherwise.  This is necessary because of patent nonsense.
1753  */
1754
1755 int ccp_fatal_error (int unit)
1756 {
1757         int flags;
1758
1759         if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1760                 error("Couldn't read compression error flags: %m");
1761                 flags = 0;
1762         }
1763         return flags & SC_DC_FERROR;
1764 }
1765
1766 /********************************************************************
1767  *
1768  * path_to_procfs - find the path to the proc file system mount point
1769  */
1770 static char proc_path[MAXPATHLEN];
1771 static int proc_path_len;
1772
1773 static char *path_to_procfs(const char *tail)
1774 {
1775     struct mntent *mntent;
1776     FILE *fp;
1777
1778     if (proc_path_len == 0) {
1779         /* Default the mount location of /proc */
1780         strlcpy (proc_path, "/proc", sizeof(proc_path));
1781         proc_path_len = 5;
1782         fp = fopen(MOUNTED, "r");
1783         if (fp != NULL) {
1784             while ((mntent = getmntent(fp)) != NULL) {
1785                 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1786                     continue;
1787                 if (strcmp(mntent->mnt_type, "proc") == 0) {
1788                     strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1789                     proc_path_len = strlen(proc_path);
1790                     break;
1791                 }
1792             }
1793             fclose (fp);
1794         }
1795     }
1796
1797     strlcpy(proc_path + proc_path_len, tail,
1798             sizeof(proc_path) - proc_path_len);
1799     return proc_path;
1800 }
1801
1802 /*
1803  * /proc/net/route parsing stuff.
1804  */
1805 #define ROUTE_MAX_COLS  12
1806 FILE *route_fd = (FILE *) 0;
1807 static char route_buffer[512];
1808 static int route_dev_col, route_dest_col, route_gw_col;
1809 static int route_flags_col, route_metric_col, route_mask_col;
1810 static int route_num_cols;
1811
1812 static int open_route_table (void);
1813 static void close_route_table (void);
1814 static int read_route_table (struct rtentry *rt);
1815
1816 /********************************************************************
1817  *
1818  * close_route_table - close the interface to the route table
1819  */
1820
1821 static void close_route_table (void)
1822 {
1823     if (route_fd != (FILE *) 0) {
1824         fclose (route_fd);
1825         route_fd = (FILE *) 0;
1826     }
1827 }
1828
1829 /********************************************************************
1830  *
1831  * open_route_table - open the interface to the route table
1832  */
1833 static char route_delims[] = " \t\n";
1834
1835 static int open_route_table (void)
1836 {
1837     char *path;
1838
1839     close_route_table();
1840
1841     path = path_to_procfs("/net/route");
1842     route_fd = fopen (path, "r");
1843     if (route_fd == NULL) {
1844         error("can't open routing table %s: %m", path);
1845         return 0;
1846     }
1847
1848     route_dev_col = 0;          /* default to usual columns */
1849     route_dest_col = 1;
1850     route_gw_col = 2;
1851     route_flags_col = 3;
1852     route_metric_col = 6;
1853     route_mask_col = 7;
1854     route_num_cols = 8;
1855
1856     /* parse header line */
1857     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1858         char *p = route_buffer, *q;
1859         int col;
1860         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1861             int used = 1;
1862             if ((q = strtok(p, route_delims)) == 0)
1863                 break;
1864             if (strcasecmp(q, "iface") == 0)
1865                 route_dev_col = col;
1866             else if (strcasecmp(q, "destination") == 0)
1867                 route_dest_col = col;
1868             else if (strcasecmp(q, "gateway") == 0)
1869                 route_gw_col = col;
1870             else if (strcasecmp(q, "flags") == 0)
1871                 route_flags_col = col;
1872             else if (strcasecmp(q, "mask") == 0)
1873                 route_mask_col = col;
1874             else
1875                 used = 0;
1876             if (used && col >= route_num_cols)
1877                 route_num_cols = col + 1;
1878             p = NULL;
1879         }
1880     }
1881
1882     return 1;
1883 }
1884
1885 /********************************************************************
1886  *
1887  * read_route_table - read the next entry from the route table
1888  */
1889
1890 static int read_route_table(struct rtentry *rt)
1891 {
1892     char *cols[ROUTE_MAX_COLS], *p;
1893     int col;
1894
1895     memset (rt, '\0', sizeof (struct rtentry));
1896
1897     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1898         return 0;
1899
1900     p = route_buffer;
1901     for (col = 0; col < route_num_cols; ++col) {
1902         cols[col] = strtok(p, route_delims);
1903         if (cols[col] == NULL)
1904             return 0;           /* didn't get enough columns */
1905         p = NULL;
1906     }
1907
1908     SET_SA_FAMILY (rt->rt_dst,     AF_INET);
1909     SET_SA_FAMILY (rt->rt_gateway, AF_INET);
1910
1911     SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1912     SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1913     SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1914
1915     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1916     rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
1917     rt->rt_dev   = cols[route_dev_col];
1918
1919     return 1;
1920 }
1921
1922 /********************************************************************
1923  *
1924  * defaultroute_exists - determine if there is a default route
1925  * with the given metric (or negative for any)
1926  */
1927
1928 static int defaultroute_exists (struct rtentry *rt, int metric)
1929 {
1930     int result = 0;
1931
1932     if (!open_route_table())
1933         return 0;
1934
1935     while (read_route_table(rt) != 0) {
1936         if ((rt->rt_flags & RTF_UP) == 0)
1937             continue;
1938
1939         if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1940             continue;
1941         if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1942                                            || rt->rt_metric == metric)) {
1943             result = 1;
1944             break;
1945         }
1946     }
1947
1948     close_route_table();
1949     return result;
1950 }
1951
1952 /*
1953  * have_route_to - determine if the system has any route to
1954  * a given IP address.  `addr' is in network byte order.
1955  * Return value is 1 if yes, 0 if no, -1 if don't know.
1956  * For demand mode to work properly, we have to ignore routes
1957  * through our own interface.
1958  */
1959 int have_route_to(u_int32_t addr)
1960 {
1961     struct rtentry rt;
1962     int result = 0;
1963
1964     if (!open_route_table())
1965         return -1;              /* don't know */
1966
1967     while (read_route_table(&rt)) {
1968         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1969             continue;
1970         if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1971             result = 1;
1972             break;
1973         }
1974     }
1975
1976     close_route_table();
1977     return result;
1978 }
1979
1980 /********************************************************************
1981  *
1982  * sifdefaultroute - assign a default route through the address given.
1983  *
1984  * If the global default_rt_repl_rest flag is set, then this function
1985  * already replaced the original system defaultroute with some other
1986  * route and it should just replace the current defaultroute with
1987  * another one, without saving the current route. Use: demand mode,
1988  * when pppd sets first a defaultroute it it's temporary ppp0 addresses
1989  * and then changes the temporary addresses to the addresses for the real
1990  * ppp connection when it has come up.
1991  */
1992
1993 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
1994 {
1995     struct rtentry rt, tmp_rt;
1996     struct rtentry *del_rt = NULL;
1997
1998     if (default_rt_repl_rest) {
1999         /* We have already replaced the original defaultroute, if we
2000          * are called again, we will delete the current default route
2001          * and set the new default route in this function.
2002          * - this is normally only the case the doing demand: */
2003         if (defaultroute_exists(&tmp_rt, -1))
2004             del_rt = &tmp_rt;
2005     } else if (defaultroute_exists(&old_def_rt, -1           ) &&
2006                             strcmp( old_def_rt.rt_dev, ifname) != 0) {
2007         /*
2008          * We did not yet replace an existing default route, let's
2009          * check if we should save and replace a default route:
2010          */
2011         u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
2012
2013         if (old_gateway != gateway) {
2014             if (!replace) {
2015                 error("not replacing default route to %s [%I]",
2016                         old_def_rt.rt_dev, old_gateway);
2017                 return 0;
2018             } else {
2019                 /* we need to copy rt_dev because we need it permanent too: */
2020                 char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
2021                 strcpy(tmp_dev, old_def_rt.rt_dev);
2022                 old_def_rt.rt_dev = tmp_dev;
2023
2024                 notice("replacing old default route to %s [%I]",
2025                         old_def_rt.rt_dev, old_gateway);
2026                 default_rt_repl_rest = 1;
2027                 del_rt = &old_def_rt;
2028             }
2029         }
2030     }
2031
2032     memset (&rt, 0, sizeof (rt));
2033     SET_SA_FAMILY (rt.rt_dst, AF_INET);
2034
2035     rt.rt_dev = ifname;
2036     rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2037
2038     if (kernel_version > KVERSION(2,1,0)) {
2039         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2040         SIN_ADDR(rt.rt_genmask) = 0L;
2041     }
2042
2043     rt.rt_flags = RTF_UP;
2044     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2045         if ( ! ok_error ( errno ))
2046             error("default route ioctl(SIOCADDRT): %m");
2047         return 0;
2048     }
2049     if (default_rt_repl_rest && del_rt)
2050         if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
2051             if ( ! ok_error ( errno ))
2052                 error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
2053             return 0;
2054         }
2055
2056     have_default_route = 1;
2057     return 1;
2058 }
2059
2060 /********************************************************************
2061  *
2062  * cifdefaultroute - delete a default route through the address given.
2063  */
2064
2065 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
2066 {
2067     struct rtentry rt;
2068
2069     have_default_route = 0;
2070
2071     memset (&rt, '\0', sizeof (rt));
2072     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2073     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2074
2075     rt.rt_dev = ifname;
2076
2077     rt.rt_dev = ifname;
2078     rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2079
2080     if (kernel_version > KVERSION(2,1,0)) {
2081         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2082         SIN_ADDR(rt.rt_genmask) = 0L;
2083     }
2084
2085     rt.rt_flags = RTF_UP;
2086     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2087         if (still_ppp()) {
2088             if ( ! ok_error ( errno ))
2089                 error("default route ioctl(SIOCDELRT): %m");
2090             return 0;
2091         }
2092     }
2093     if (default_rt_repl_rest) {
2094         notice("restoring old default route to %s [%I]",
2095                         old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
2096         if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
2097             if ( ! ok_error ( errno ))
2098                 error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
2099             return 0;
2100         }
2101         default_rt_repl_rest = 0;
2102     }
2103
2104     return 1;
2105 }
2106
2107 #ifdef INET6
2108 /*
2109  * /proc/net/ipv6_route parsing stuff.
2110  */
2111 static int route_dest_plen_col;
2112 static int open_route6_table (void);
2113 static int read_route6_table (struct in6_rtmsg *rt);
2114
2115 /********************************************************************
2116  *
2117  * open_route6_table - open the interface to the route table
2118  */
2119 static int open_route6_table (void)
2120 {
2121     char *path;
2122
2123     close_route_table();
2124
2125     path = path_to_procfs("/net/ipv6_route");
2126     route_fd = fopen (path, "r");
2127     if (route_fd == NULL) {
2128         error("can't open routing table %s: %m", path);
2129         return 0;
2130     }
2131
2132     /* default to usual columns */
2133     route_dest_col = 0;
2134     route_dest_plen_col = 1;
2135     route_gw_col = 4;
2136     route_metric_col = 5;
2137     route_flags_col = 8;
2138     route_dev_col = 9;
2139     route_num_cols = 10;
2140
2141     return 1;
2142 }
2143
2144 /********************************************************************
2145  *
2146  * read_route6_table - read the next entry from the route table
2147  */
2148
2149 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
2150 {
2151     char hex8[9];
2152     unsigned i;
2153     uint32_t v;
2154
2155     hex8[8] = 0;
2156     for (i = 0; i < 4; i++) {
2157         memcpy(hex8, s + 8*i, 8);
2158         v = strtoul(hex8, NULL, 16);
2159         addr->s6_addr32[i] = v;
2160     }
2161 }
2162
2163 static int read_route6_table(struct in6_rtmsg *rt)
2164 {
2165     char *cols[ROUTE_MAX_COLS], *p;
2166     int col;
2167
2168     memset (rt, '\0', sizeof (struct in6_rtmsg));
2169
2170     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
2171         return 0;
2172
2173     p = route_buffer;
2174     for (col = 0; col < route_num_cols; ++col) {
2175         cols[col] = strtok(p, route_delims);
2176         if (cols[col] == NULL)
2177             return 0;           /* didn't get enough columns */
2178         p = NULL;
2179     }
2180
2181     hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
2182     rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
2183     hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
2184
2185     rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
2186     rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
2187     rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
2188
2189     return 1;
2190 }
2191
2192 /********************************************************************
2193  *
2194  * defaultroute6_exists - determine if there is a default route
2195  */
2196
2197 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
2198 {
2199     int result = 0;
2200
2201     if (!open_route6_table())
2202         return 0;
2203
2204     while (read_route6_table(rt) != 0) {
2205         if ((rt->rtmsg_flags & RTF_UP) == 0)
2206             continue;
2207
2208         if (rt->rtmsg_dst_len != 0)
2209             continue;
2210         if (rt->rtmsg_dst.s6_addr32[0] == 0L
2211          && rt->rtmsg_dst.s6_addr32[1] == 0L
2212          && rt->rtmsg_dst.s6_addr32[2] == 0L
2213          && rt->rtmsg_dst.s6_addr32[3] == 0L
2214          && (metric < 0 || rt->rtmsg_metric == metric)) {
2215             result = 1;
2216             break;
2217         }
2218     }
2219
2220     close_route_table();
2221     return result;
2222 }
2223
2224 /********************************************************************
2225  *
2226  * sif6defaultroute - assign a default route through the address given.
2227  *
2228  * If the global default_rt_repl_rest flag is set, then this function
2229  * already replaced the original system defaultroute with some other
2230  * route and it should just replace the current defaultroute with
2231  * another one, without saving the current route. Use: demand mode,
2232  * when pppd sets first a defaultroute it it's temporary ppp0 addresses
2233  * and then changes the temporary addresses to the addresses for the real
2234  * ppp connection when it has come up.
2235  */
2236
2237 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2238 {
2239     struct in6_rtmsg rt;
2240     char buf[IF_NAMESIZE];
2241
2242     if (defaultroute6_exists(&rt, dfl_route_metric) &&
2243             rt.rtmsg_ifindex != if_nametoindex(ifname)) {
2244         if (rt.rtmsg_flags & RTF_GATEWAY)
2245             error("not replacing existing default route via gateway");
2246         else
2247             error("not replacing existing default route through %s",
2248                   if_indextoname(rt.rtmsg_ifindex, buf));
2249         return 0;
2250     }
2251
2252     memset (&rt, 0, sizeof (rt));
2253
2254     rt.rtmsg_ifindex = if_nametoindex(ifname);
2255     rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2256     rt.rtmsg_dst_len = 0;
2257
2258     rt.rtmsg_flags = RTF_UP;
2259     if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
2260         if ( ! ok_error ( errno ))
2261             error("default route ioctl(SIOCADDRT): %m");
2262         return 0;
2263     }
2264
2265     have_default_route6 = 1;
2266     return 1;
2267 }
2268
2269 /********************************************************************
2270  *
2271  * cif6defaultroute - delete a default route through the address given.
2272  */
2273
2274 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
2275 {
2276     struct in6_rtmsg rt;
2277
2278     have_default_route6 = 0;
2279
2280     memset (&rt, '\0', sizeof (rt));
2281
2282     rt.rtmsg_ifindex = if_nametoindex(ifname);
2283     rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
2284     rt.rtmsg_dst_len = 0;
2285
2286     rt.rtmsg_flags = RTF_UP;
2287     if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2288         if (still_ppp()) {
2289             if ( ! ok_error ( errno ))
2290                 error("default route ioctl(SIOCDELRT): %m");
2291             return 0;
2292         }
2293     }
2294
2295     return 1;
2296 }
2297 #endif /* INET6 */
2298
2299 /********************************************************************
2300  *
2301  * sifproxyarp - Make a proxy ARP entry for the peer.
2302  */
2303
2304 int sifproxyarp (int unit, u_int32_t his_adr)
2305 {
2306     struct arpreq arpreq;
2307     char *forw_path;
2308
2309     if (has_proxy_arp == 0) {
2310         memset (&arpreq, '\0', sizeof(arpreq));
2311
2312         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2313         SIN_ADDR(arpreq.arp_pa) = his_adr;
2314         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2315 /*
2316  * Get the hardware address of an interface on the same subnet
2317  * as our local address.
2318  */
2319         if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
2320                             sizeof(proxy_arp_dev))) {
2321             error("Cannot determine ethernet address for proxy ARP");
2322             return 0;
2323         }
2324         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2325
2326         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
2327             if ( ! ok_error ( errno ))
2328                 error("ioctl(SIOCSARP): %m");
2329             return 0;
2330         }
2331         proxy_arp_addr = his_adr;
2332         has_proxy_arp = 1;
2333
2334         if (tune_kernel) {
2335             forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
2336             if (forw_path != 0) {
2337                 int fd = open(forw_path, O_WRONLY);
2338                 if (fd >= 0) {
2339                     if (write(fd, "1", 1) != 1)
2340                         error("Couldn't enable IP forwarding: %m");
2341                     close(fd);
2342                 }
2343             }
2344         }
2345     }
2346
2347     return 1;
2348 }
2349
2350 /********************************************************************
2351  *
2352  * cifproxyarp - Delete the proxy ARP entry for the peer.
2353  */
2354
2355 int cifproxyarp (int unit, u_int32_t his_adr)
2356 {
2357     struct arpreq arpreq;
2358
2359     if (has_proxy_arp) {
2360         has_proxy_arp = 0;
2361         memset (&arpreq, '\0', sizeof(arpreq));
2362         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
2363         SIN_ADDR(arpreq.arp_pa) = his_adr;
2364         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
2365         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
2366
2367         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
2368             if ( ! ok_error ( errno ))
2369                 warn("ioctl(SIOCDARP): %m");
2370             return 0;
2371         }
2372     }
2373     return 1;
2374 }
2375
2376 /********************************************************************
2377  *
2378  * get_ether_addr - get the hardware address of an interface on the
2379  * the same subnet as ipaddr.
2380  */
2381
2382 static int get_ether_addr (u_int32_t ipaddr,
2383                            struct sockaddr *hwaddr,
2384                            char *name, int namelen)
2385 {
2386     struct ifreq *ifr, *ifend;
2387     u_int32_t ina, mask;
2388     char *aliasp;
2389     struct ifreq ifreq, bestifreq;
2390     struct ifconf ifc;
2391     struct ifreq ifs[MAX_IFS];
2392
2393     u_int32_t bestmask=0;
2394     int found_interface = 0;
2395
2396     ifc.ifc_len = sizeof(ifs);
2397     ifc.ifc_req = ifs;
2398     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2399         if ( ! ok_error ( errno ))
2400             error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2401         return 0;
2402     }
2403
2404 /*
2405  * Scan through looking for an interface with an Internet
2406  * address on the same subnet as `ipaddr'.
2407  */
2408     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2409     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2410         if (ifr->ifr_addr.sa_family == AF_INET) {
2411             ina = SIN_ADDR(ifr->ifr_addr);
2412             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2413 /*
2414  * Check that the interface is up, and not point-to-point
2415  * nor loopback.
2416  */
2417             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2418                 continue;
2419
2420             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2421                 continue;
2422 /*
2423  * Get its netmask and check that it's on the right subnet.
2424  */
2425             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2426                 continue;
2427
2428             mask = SIN_ADDR(ifreq.ifr_addr);
2429
2430             if (((ipaddr ^ ina) & mask) != 0)
2431                 continue; /* no match */
2432             /* matched */
2433             if (mask >= bestmask) {
2434                 /* Compare using >= instead of > -- it is possible for
2435                    an interface to have a netmask of 0.0.0.0 */
2436                 found_interface = 1;
2437                 bestifreq = ifreq;
2438                 bestmask = mask;
2439             }
2440         }
2441     }
2442
2443     if (!found_interface) return 0;
2444
2445     strlcpy(name, bestifreq.ifr_name, namelen);
2446
2447     /* trim off the :1 in eth0:1 */
2448     aliasp = strchr(name, ':');
2449     if (aliasp != 0)
2450         *aliasp = 0;
2451
2452     info("found interface %s for proxy arp", name);
2453 /*
2454  * Now get the hardware address.
2455  */
2456     memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2457     if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2458         error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2459         return 0;
2460     }
2461
2462     memcpy (hwaddr,
2463             &bestifreq.ifr_hwaddr,
2464             sizeof (struct sockaddr));
2465
2466     return 1;
2467 }
2468
2469 /*
2470  * get_if_hwaddr - get the hardware address for the specified
2471  * network interface device.
2472  */
2473 int
2474 get_if_hwaddr(u_char *addr, char *name)
2475 {
2476         struct ifreq ifreq;
2477         int ret, sock_fd;
2478
2479         sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2480         if (sock_fd < 0)
2481                 return -1;
2482         memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2483         strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2484         ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2485         close(sock_fd);
2486         if (ret >= 0)
2487                 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2488         return ret;
2489 }
2490
2491 /*
2492  * get_first_ether_hwaddr - get the hardware address for the first
2493  * ethernet-style interface on this system.
2494  */
2495 int
2496 get_first_ether_hwaddr(u_char *addr)
2497 {
2498         struct if_nameindex *if_ni, *i;
2499         struct ifreq ifreq;
2500         int ret, sock_fd;
2501
2502         sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2503         if (sock_fd < 0)
2504                 return -1;
2505
2506         if_ni = if_nameindex();
2507         if (!if_ni) {
2508                 close(sock_fd);
2509                 return -1;
2510         }
2511
2512         ret = -1;
2513
2514         for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
2515                 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2516                 strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
2517                 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2518                 if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
2519                         memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2520                         break;
2521                 }
2522                 ret = -1;
2523         }
2524
2525         if_freenameindex(if_ni);
2526         close(sock_fd);
2527
2528         return ret;
2529 }
2530
2531 /********************************************************************
2532  *
2533  * Return user specified netmask, modified by any mask we might determine
2534  * for address `addr' (in network byte order).
2535  * Here we scan through the system's list of interfaces, looking for
2536  * any non-point-to-point interfaces which might appear to be on the same
2537  * network as `addr'.  If we find any, we OR in their netmask to the
2538  * user-specified netmask.
2539  */
2540
2541 u_int32_t GetMask (u_int32_t addr)
2542 {
2543     u_int32_t mask, nmask, ina;
2544     struct ifreq *ifr, *ifend, ifreq;
2545     struct ifconf ifc;
2546     struct ifreq ifs[MAX_IFS];
2547
2548     addr = ntohl(addr);
2549
2550     if (IN_CLASSA(addr))        /* determine network mask for address class */
2551         nmask = IN_CLASSA_NET;
2552     else if (IN_CLASSB(addr))
2553             nmask = IN_CLASSB_NET;
2554     else
2555             nmask = IN_CLASSC_NET;
2556
2557     /* class D nets are disallowed by bad_ip_adrs */
2558     mask = netmask | htonl(nmask);
2559 /*
2560  * Scan through the system's network interfaces.
2561  */
2562     ifc.ifc_len = sizeof(ifs);
2563     ifc.ifc_req = ifs;
2564     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2565         if ( ! ok_error ( errno ))
2566             warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2567         return mask;
2568     }
2569
2570     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2571     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2572 /*
2573  * Check the interface's internet address.
2574  */
2575         if (ifr->ifr_addr.sa_family != AF_INET)
2576             continue;
2577         ina = SIN_ADDR(ifr->ifr_addr);
2578         if (((ntohl(ina) ^ addr) & nmask) != 0)
2579             continue;
2580 /*
2581  * Check that the interface is up, and not point-to-point nor loopback.
2582  */
2583         strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2584         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2585             continue;
2586
2587         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2588             continue;
2589 /*
2590  * Get its netmask and OR it into our mask.
2591  */
2592         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2593             continue;
2594         mask |= SIN_ADDR(ifreq.ifr_addr);
2595         break;
2596     }
2597     return mask;
2598 }
2599
2600 /********************************************************************
2601  *
2602  * Internal routine to decode the version.modification.patch level
2603  */
2604
2605 static void decode_version (char *buf, int *version,
2606                             int *modification, int *patch)
2607 {
2608     char *endp;
2609
2610     *version      = (int) strtoul (buf, &endp, 10);
2611     *modification = 0;
2612     *patch        = 0;
2613
2614     if (endp != buf && *endp == '.') {
2615         buf = endp + 1;
2616         *modification = (int) strtoul (buf, &endp, 10);
2617         if (endp != buf && *endp == '.') {
2618             buf = endp + 1;
2619             *patch = (int) strtoul (buf, &buf, 10);
2620         }
2621     }
2622 }
2623
2624 /********************************************************************
2625  *
2626  * Procedure to determine if the PPP line discipline is registered.
2627  */
2628
2629 static int
2630 ppp_registered(void)
2631 {
2632     int local_fd;
2633     int mfd = -1;
2634     int ret = 0;
2635     char slave[16];
2636
2637     /*
2638      * We used to open the serial device and set it to the ppp line
2639      * discipline here, in order to create a ppp unit.  But that is
2640      * not a good idea - the user might have specified a device that
2641      * they can't open (permission, or maybe it doesn't really exist).
2642      * So we grab a pty master/slave pair and use that.
2643      */
2644     if (!get_pty(&mfd, &local_fd, slave, 0)) {
2645         no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2646         return 0;
2647     }
2648
2649     /*
2650      * Try to put the device into the PPP discipline.
2651      */
2652     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2653         error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2654     } else
2655         ret = 1;
2656
2657     close(local_fd);
2658     close(mfd);
2659     return ret;
2660 }
2661
2662 /********************************************************************
2663  *
2664  * ppp_available - check whether the system has any ppp interfaces
2665  * (in fact we check whether we can do an ioctl on ppp0).
2666  */
2667
2668 int ppp_available(void)
2669 {
2670     int s, ok, fd;
2671     struct ifreq ifr;
2672     int    size;
2673     int    my_version, my_modification, my_patch;
2674     int osmaj, osmin, ospatch;
2675
2676     /* get the kernel version now, since we are called before sys_init */
2677     uname(&utsname);
2678     osmaj = osmin = ospatch = 0;
2679     sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2680     kernel_version = KVERSION(osmaj, osmin, ospatch);
2681
2682     fd = open("/dev/ppp", O_RDWR);
2683     if (fd >= 0) {
2684         new_style_driver = 1;
2685
2686         /* XXX should get from driver */
2687         driver_version = 2;
2688         driver_modification = 4;
2689         driver_patch = 0;
2690         close(fd);
2691         return 1;
2692     }
2693
2694     if (kernel_version >= KVERSION(2,3,13)) {
2695         error("Couldn't open the /dev/ppp device: %m");
2696         if (errno == ENOENT)
2697             no_ppp_msg =
2698                 "You need to create the /dev/ppp device node by\n"
2699                 "executing the following command as root:\n"
2700                 "       mknod /dev/ppp c 108 0\n";
2701         else if (errno == ENODEV || errno == ENXIO)
2702             no_ppp_msg =
2703                 "Please load the ppp_generic kernel module.\n";
2704         return 0;
2705     }
2706
2707     /* we are running on a really really old kernel */
2708     no_ppp_msg =
2709         "This system lacks kernel support for PPP.  This could be because\n"
2710         "the PPP kernel module could not be loaded, or because PPP was not\n"
2711         "included in the kernel configuration.  If PPP was included as a\n"
2712         "module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
2713         "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2714         "See README.linux file in the ppp distribution for more details.\n";
2715
2716 /*
2717  * Open a socket for doing the ioctl operations.
2718  */
2719     s = socket(AF_INET, SOCK_DGRAM, 0);
2720     if (s < 0)
2721         return 0;
2722
2723     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2724     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2725 /*
2726  * If the device did not exist then attempt to create one by putting the
2727  * current tty into the PPP discipline. If this works then obtain the
2728  * flags for the device again.
2729  */
2730     if (!ok) {
2731         if (ppp_registered()) {
2732             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2733             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2734         }
2735     }
2736 /*
2737  * Ensure that the hardware address is for PPP and not something else
2738  */
2739     if (ok)
2740         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2741
2742     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2743         ok = 0;
2744
2745 /*
2746  *  This is the PPP device. Validate the version of the driver at this
2747  *  point to ensure that this program will work with the driver.
2748  */
2749     if (ok) {
2750         char   abBuffer [1024];
2751
2752         ifr.ifr_data = abBuffer;
2753         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2754         if (size < 0) {
2755             error("Couldn't read driver version: %m");
2756             ok = 0;
2757             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2758
2759         } else {
2760             decode_version(abBuffer,
2761                            &driver_version,
2762                            &driver_modification,
2763                            &driver_patch);
2764 /*
2765  * Validate the version of the driver against the version that we used.
2766  */
2767             decode_version(VERSION,
2768                            &my_version,
2769                            &my_modification,
2770                            &my_patch);
2771
2772             /* The version numbers must match */
2773             if (driver_version != my_version)
2774                 ok = 0;
2775
2776             /* The modification levels must be legal */
2777             if (driver_modification < 3) {
2778                 if (driver_modification >= 2) {
2779                     /* we can cope with 2.2.0 and above */
2780                     driver_is_old = 1;
2781                 } else {
2782                     ok = 0;
2783                 }
2784             }
2785
2786             if (!ok) {
2787                 slprintf(route_buffer, sizeof(route_buffer),
2788                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
2789                          driver_version, driver_modification, driver_patch);
2790
2791                 no_ppp_msg = route_buffer;
2792             }
2793         }
2794     }
2795     close(s);
2796     return ok;
2797 }
2798
2799 #ifndef HAVE_LOGWTMP
2800 /********************************************************************
2801  *
2802  * Update the wtmp file with the appropriate user name and tty device.
2803  */
2804
2805 void logwtmp (const char *line, const char *name, const char *host)
2806 {
2807     struct utmp ut, *utp;
2808     pid_t  mypid = getpid();
2809 #if __GLIBC__ < 2
2810     int    wtmp;
2811 #endif
2812
2813 /*
2814  * Update the signon database for users.
2815  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2816  */
2817     utmpname(_PATH_UTMP);
2818     setutent();
2819     while ((utp = getutent()) && (utp->ut_pid != mypid))
2820         /* nothing */;
2821
2822     if (utp)
2823         memcpy(&ut, utp, sizeof(ut));
2824     else
2825         /* some gettys/telnetds don't initialize utmp... */
2826         memset(&ut, 0, sizeof(ut));
2827
2828     if (ut.ut_id[0] == 0)
2829         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2830
2831     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2832     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2833
2834     time(&ut.ut_time);
2835
2836     ut.ut_type = USER_PROCESS;
2837     ut.ut_pid  = mypid;
2838
2839     /* Insert the host name if one is supplied */
2840     if (*host)
2841         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2842
2843     /* Insert the IP address of the remote system if IP is enabled */
2844     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2845         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2846                  sizeof(ut.ut_addr));
2847
2848     /* CL: Makes sure that the logout works */
2849     if (*host == 0 && *name==0)
2850         ut.ut_host[0]=0;
2851
2852     pututline(&ut);
2853     endutent();
2854 /*
2855  * Update the wtmp file.
2856  */
2857 #if __GLIBC__ >= 2
2858     updwtmp(_PATH_WTMP, &ut);
2859 #else
2860     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2861     if (wtmp >= 0) {
2862         flock(wtmp, LOCK_EX);
2863
2864         if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2865             warn("error writing %s: %m", _PATH_WTMP);
2866
2867         flock(wtmp, LOCK_UN);
2868
2869         close (wtmp);
2870     }
2871 #endif
2872 }
2873 #endif /* HAVE_LOGWTMP */
2874
2875 /********************************************************************
2876  *
2877  * sifvjcomp - config tcp header compression
2878  */
2879
2880 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2881 {
2882         u_int x;
2883
2884         if (vjcomp) {
2885                 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2886                         error("Couldn't set up TCP header compression: %m");
2887                         vjcomp = 0;
2888                 }
2889         }
2890
2891         x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2892         modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2893
2894         return 1;
2895 }
2896
2897 /********************************************************************
2898  *
2899  * sifup - Config the interface up and enable IP packets to pass.
2900  */
2901
2902 int sifup(int u)
2903 {
2904     int ret;
2905
2906     if ((ret = setifstate(u, 1)))
2907         if_is_up++;
2908
2909     return ret;
2910 }
2911
2912 /********************************************************************
2913  *
2914  * sifdown - Disable the indicated protocol and config the interface
2915  *           down if there are no remaining protocols.
2916  */
2917
2918 int sifdown (int u)
2919 {
2920     if (if_is_up && --if_is_up > 0)
2921         return 1;
2922
2923 #ifdef INET6
2924     if (if6_is_up)
2925         return 1;
2926 #endif /* INET6 */
2927
2928     return setifstate(u, 0);
2929 }
2930
2931 #ifdef INET6
2932 /********************************************************************
2933  *
2934  * sif6up - Config the interface up for IPv6
2935  */
2936
2937 int sif6up(int u)
2938 {
2939     int ret;
2940
2941     if ((ret = setifstate(u, 1)))
2942         if6_is_up = 1;
2943
2944     return ret;
2945 }
2946
2947 /********************************************************************
2948  *
2949  * sif6down - Disable the IPv6CP protocol and config the interface
2950  *            down if there are no remaining protocols.
2951  */
2952
2953 int sif6down (int u)
2954 {
2955     if6_is_up = 0;
2956
2957     if (if_is_up)
2958         return 1;
2959
2960     return setifstate(u, 0);
2961 }
2962 #endif /* INET6 */
2963
2964 /********************************************************************
2965  *
2966  * setifstate - Config the interface up or down
2967  */
2968
2969 static int setifstate (int u, int state)
2970 {
2971     struct ifreq ifr;
2972
2973     memset (&ifr, '\0', sizeof (ifr));
2974     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2975     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2976         if (! ok_error (errno))
2977             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2978         return 0;
2979     }
2980
2981     if (state)
2982         ifr.ifr_flags |= IFF_UP;
2983     else
2984         ifr.ifr_flags &= ~IFF_UP;
2985     ifr.ifr_flags |= IFF_POINTOPOINT;
2986     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2987         if (! ok_error (errno))
2988             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2989         return 0;
2990     }
2991     return 1;
2992 }
2993
2994 /********************************************************************
2995  *
2996  * sifaddr - Config the interface IP addresses and netmask.
2997  */
2998
2999 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
3000              u_int32_t net_mask)
3001 {
3002     struct ifreq   ifr;
3003     struct rtentry rt;
3004
3005     memset (&ifr, '\0', sizeof (ifr));
3006     memset (&rt,  '\0', sizeof (rt));
3007
3008     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET);
3009     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
3010     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
3011
3012     strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
3013 /*
3014  *  Set our IP address
3015  */
3016     SIN_ADDR(ifr.ifr_addr) = our_adr;
3017     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3018         if (errno != EEXIST) {
3019             if (! ok_error (errno))
3020                 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3021         }
3022         else {
3023             warn("ioctl(SIOCSIFADDR): Address already exists");
3024         }
3025         return (0);
3026     }
3027 /*
3028  *  Set the gateway address
3029  */
3030     if (his_adr != 0) {
3031         SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
3032         if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
3033             if (! ok_error (errno))
3034                 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
3035             return (0);
3036         }
3037     }
3038 /*
3039  *  Set the netmask.
3040  *  For recent kernels, force the netmask to 255.255.255.255.
3041  */
3042     if (kernel_version >= KVERSION(2,1,16))
3043         net_mask = ~0L;
3044     if (net_mask != 0) {
3045         SIN_ADDR(ifr.ifr_netmask) = net_mask;
3046         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
3047             if (! ok_error (errno))
3048                 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
3049             return (0);
3050         }
3051     }
3052 /*
3053  *  Add the device route
3054  */
3055     if (kernel_version < KVERSION(2,1,16)) {
3056         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
3057         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3058         rt.rt_dev = ifname;
3059
3060         SIN_ADDR(rt.rt_gateway) = 0L;
3061         SIN_ADDR(rt.rt_dst)     = his_adr;
3062         rt.rt_flags = RTF_UP | RTF_HOST;
3063
3064         if (kernel_version > KVERSION(2,1,0)) {
3065             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3066             SIN_ADDR(rt.rt_genmask) = -1L;
3067         }
3068
3069         if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
3070             if (! ok_error (errno))
3071                 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
3072             return (0);
3073         }
3074     }
3075
3076     /* set ip_dynaddr in demand mode if address changes */
3077     if (demand && tune_kernel && !dynaddr_set
3078         && our_old_addr && our_old_addr != our_adr) {
3079         /* set ip_dynaddr if possible */
3080         char *path;
3081         int fd;
3082
3083         path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
3084         if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
3085             if (write(fd, "1", 1) != 1)
3086                 error("Couldn't enable dynamic IP addressing: %m");
3087             close(fd);
3088         }
3089         dynaddr_set = 1;        /* only 1 attempt */
3090     }
3091     our_old_addr = 0;
3092
3093     return 1;
3094 }
3095
3096 /********************************************************************
3097  *
3098  * cifaddr - Clear the interface IP addresses, and delete routes
3099  * through the interface if possible.
3100  */
3101
3102 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
3103 {
3104     struct ifreq ifr;
3105
3106     if (kernel_version < KVERSION(2,1,16)) {
3107 /*
3108  *  Delete the route through the device
3109  */
3110         struct rtentry rt;
3111         memset (&rt, '\0', sizeof (rt));
3112
3113         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
3114         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
3115         rt.rt_dev = ifname;
3116
3117         SIN_ADDR(rt.rt_gateway) = 0;
3118         SIN_ADDR(rt.rt_dst)     = his_adr;
3119         rt.rt_flags = RTF_UP | RTF_HOST;
3120
3121         if (kernel_version > KVERSION(2,1,0)) {
3122             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
3123             SIN_ADDR(rt.rt_genmask) = -1L;
3124         }
3125
3126         if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
3127             if (still_ppp() && ! ok_error (errno))
3128                 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
3129             return (0);
3130         }
3131     }
3132
3133     /* This way it is possible to have an IPX-only or IPv6-only interface */
3134     memset(&ifr, 0, sizeof(ifr));
3135     SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
3136     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3137
3138     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3139         if (! ok_error (errno)) {
3140             error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3141             return 0;
3142         }
3143     }
3144
3145     our_old_addr = our_adr;
3146
3147     return 1;
3148 }
3149
3150 #ifdef INET6
3151 /********************************************************************
3152  *
3153  * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
3154  */
3155 static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
3156 {
3157     struct {
3158         struct nlmsghdr nlh;
3159         struct ifaddrmsg ifa;
3160         struct {
3161             struct rtattr rta;
3162             struct in6_addr addr;
3163         } addrs[2];
3164     } nlreq;
3165     struct {
3166         struct nlmsghdr nlh;
3167         struct nlmsgerr nlerr;
3168     } nlresp;
3169     struct sockaddr_nl nladdr;
3170     struct iovec iov;
3171     struct msghdr msg;
3172     ssize_t nlresplen;
3173     int one;
3174     int fd;
3175
3176     fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
3177     if (fd < 0) {
3178         error("sif6addr_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
3179         return 0;
3180     }
3181
3182     /*
3183      * Tell kernel to not send to us payload of acknowledgment error message.
3184      * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
3185      * older kernel versions always send full payload in acknowledgment netlink
3186      * message. We ignore payload of this message as we need only error code,
3187      * to check if our set remote peer address request succeeded or failed.
3188      * So ignore return value from the following setsockopt() call as setting
3189      * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
3190      */
3191     one = 1;
3192     setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
3193
3194     memset(&nladdr, 0, sizeof(nladdr));
3195     nladdr.nl_family = AF_NETLINK;
3196
3197     if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
3198         error("sif6addr_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
3199         close(fd);
3200         return 0;
3201     }
3202
3203     memset(&nlreq, 0, sizeof(nlreq));
3204     nlreq.nlh.nlmsg_len = sizeof(nlreq);
3205     nlreq.nlh.nlmsg_type = RTM_NEWADDR;
3206     nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
3207     nlreq.ifa.ifa_family = AF_INET6;
3208     nlreq.ifa.ifa_prefixlen = 128;
3209     nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
3210     nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
3211     nlreq.ifa.ifa_index = iface;
3212     nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
3213     nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
3214     IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
3215     nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
3216     nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
3217
3218     /*
3219      * To set only local address, older kernel expects that local address is
3220      * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer
3221      * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward
3222      * compatibility when setting only local address, set it via both IFA_LOCAL
3223      * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command
3224      * from iproute2 project.
3225      */
3226     if (!eui64_iszero(his_eui64))
3227         IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
3228     else
3229         IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64);
3230
3231     memset(&nladdr, 0, sizeof(nladdr));
3232     nladdr.nl_family = AF_NETLINK;
3233
3234     memset(&iov, 0, sizeof(iov));
3235     iov.iov_base = &nlreq;
3236     iov.iov_len = sizeof(nlreq);
3237
3238     memset(&msg, 0, sizeof(msg));
3239     msg.msg_name = &nladdr;
3240     msg.msg_namelen = sizeof(nladdr);
3241     msg.msg_iov = &iov;
3242     msg.msg_iovlen = 1;
3243
3244     if (sendmsg(fd, &msg, 0) < 0) {
3245         error("sif6addr_rtnetlink: sendmsg(RTM_NEWADDR/NLM_F_CREATE): %m (line %d)", __LINE__);
3246         close(fd);
3247         return 0;
3248     }
3249
3250     memset(&iov, 0, sizeof(iov));
3251     iov.iov_base = &nlresp;
3252     iov.iov_len = sizeof(nlresp);
3253
3254     memset(&msg, 0, sizeof(msg));
3255     msg.msg_name = &nladdr;
3256     msg.msg_namelen = sizeof(nladdr);
3257     msg.msg_iov = &iov;
3258     msg.msg_iovlen = 1;
3259
3260     nlresplen = recvmsg(fd, &msg, 0);
3261
3262     if (nlresplen < 0) {
3263         error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
3264         close(fd);
3265         return 0;
3266     }
3267
3268     close(fd);
3269
3270     if (nladdr.nl_family != AF_NETLINK) {
3271         error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
3272         return 0;
3273     }
3274
3275     if ((size_t)nlresplen != sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
3276         error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
3277         return 0;
3278     }
3279
3280     /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
3281     if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
3282         error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
3283         return 0;
3284     }
3285
3286     /* error == 0 indicates success, negative value is errno code */
3287     if (nlresp.nlerr.error != 0) {
3288         /*
3289          * Linux kernel versions prior 3.11 do not support setting IPv6 peer
3290          * addresses and error response is expected. On older kernel versions
3291          * do not show this error message. On error pppd tries to fallback to
3292          * the old IOCTL method.
3293          */
3294         if (kernel_version >= KVERSION(3,11,0))
3295             error("sif6addr_rtnetlink: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
3296         return 0;
3297     }
3298
3299     return 1;
3300 }
3301
3302 /********************************************************************
3303  *
3304  * sif6addr - Config the interface with an IPv6 link-local address
3305  */
3306 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3307 {
3308     struct in6_ifreq ifr6;
3309     struct ifreq ifr;
3310     struct in6_rtmsg rt6;
3311     int ret;
3312
3313     if (sock6_fd < 0) {
3314         errno = -sock6_fd;
3315         error("IPv6 socket creation failed: %m");
3316         return 0;
3317     }
3318     memset(&ifr, 0, sizeof (ifr));
3319     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3320     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3321         error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3322         return 0;
3323     }
3324
3325     if (kernel_version >= KVERSION(2,1,16)) {
3326         /* Set both local address and remote peer address (with route for it) via rtnetlink */
3327         ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
3328     } else {
3329         ret = 0;
3330     }
3331
3332     /*
3333      * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
3334      * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
3335      */
3336     if (!ret) {
3337         /* Local interface */
3338         memset(&ifr6, 0, sizeof(ifr6));
3339         IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3340         ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3341         ifr6.ifr6_prefixlen = 128;
3342
3343         if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
3344             error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
3345             return 0;
3346         }
3347     }
3348
3349     if (!ret && !eui64_iszero(his_eui64)) {
3350         /*
3351          * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
3352          * setting remote peer host address, so set only route to remote host.
3353          */
3354
3355         /* Route to remote host */
3356         memset(&rt6, 0, sizeof(rt6));
3357         IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
3358         rt6.rtmsg_flags = RTF_UP;
3359         rt6.rtmsg_dst_len = 128;
3360         rt6.rtmsg_ifindex = ifr.ifr_ifindex;
3361         rt6.rtmsg_metric = 1;
3362
3363         if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
3364             error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
3365             return 0;
3366         }
3367     }
3368
3369     return 1;
3370 }
3371
3372
3373 /********************************************************************
3374  *
3375  * cif6addr - Remove IPv6 address from interface
3376  */
3377 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
3378 {
3379     struct ifreq ifr;
3380     struct in6_ifreq ifr6;
3381
3382     if (sock6_fd < 0) {
3383         errno = -sock6_fd;
3384         error("IPv6 socket creation failed: %m");
3385         return 0;
3386     }
3387     memset(&ifr, 0, sizeof(ifr));
3388     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3389     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
3390         error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
3391         return 0;
3392     }
3393
3394     memset(&ifr6, 0, sizeof(ifr6));
3395     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
3396     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
3397     ifr6.ifr6_prefixlen = 128;
3398
3399     if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
3400         if (errno != EADDRNOTAVAIL) {
3401             if (! ok_error (errno))
3402                 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
3403         }
3404         else {
3405             warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
3406         }
3407         return (0);
3408     }
3409     return 1;
3410 }
3411 #endif /* INET6 */
3412
3413 /*
3414  * get_pty - get a pty master/slave pair and chown the slave side
3415  * to the uid given.  Assumes slave_name points to >= 16 bytes of space.
3416  */
3417 int
3418 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
3419 {
3420     int i, mfd, ret, sfd = -1;
3421     char pty_name[16];
3422     struct termios tios;
3423
3424 #ifdef TIOCGPTN
3425     /*
3426      * Try the unix98 way first.
3427      */
3428     mfd = open("/dev/ptmx", O_RDWR);
3429     if (mfd >= 0) {
3430         int ptn;
3431         if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
3432             slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
3433             chmod(pty_name, S_IRUSR | S_IWUSR);
3434 #ifdef TIOCSPTLCK
3435             ptn = 0;
3436             if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
3437                 warn("Couldn't unlock pty slave %s: %m", pty_name);
3438 #endif
3439             if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
3440             {
3441                 warn("Couldn't open pty slave %s: %m", pty_name);
3442                 close(mfd);
3443             }
3444         }
3445     }
3446 #endif /* TIOCGPTN */
3447
3448     if (sfd < 0) {
3449         /* the old way - scan through the pty name space */
3450         for (i = 0; i < 64; ++i) {
3451             slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
3452                      'p' + i / 16, i % 16);
3453             mfd = open(pty_name, O_RDWR, 0);
3454             if (mfd >= 0) {
3455                 pty_name[5] = 't';
3456                 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
3457                 if (sfd >= 0) {
3458                     ret = fchown(sfd, uid, -1);
3459                     if (ret != 0) {
3460                         warn("Couldn't change ownership of %s, %m", pty_name);
3461                     }
3462                     ret = fchmod(sfd, S_IRUSR | S_IWUSR);
3463                     if (ret != 0) {
3464                         warn("Couldn't change permissions of %s, %m", pty_name);
3465                     }
3466                     break;
3467                 }
3468                 close(mfd);
3469             }
3470         }
3471     }
3472
3473     if (sfd < 0)
3474         return 0;
3475
3476     strlcpy(slave_name, pty_name, 16);
3477     *master_fdp = mfd;
3478     *slave_fdp = sfd;
3479     if (tcgetattr(sfd, &tios) == 0) {
3480         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
3481         tios.c_cflag |= CS8 | CREAD | CLOCAL;
3482         tios.c_iflag  = IGNPAR;
3483         tios.c_oflag  = 0;
3484         tios.c_lflag  = 0;
3485         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
3486             warn("couldn't set attributes on pty: %m");
3487     } else
3488         warn("couldn't get attributes on pty: %m");
3489
3490     return 1;
3491 }
3492
3493 /********************************************************************
3494  *
3495  * open_loopback - open the device we use for getting packets
3496  * in demand mode.  Under Linux, we use a pty master/slave pair.
3497  */
3498 int
3499 open_ppp_loopback(void)
3500 {
3501     int flags;
3502
3503     looped = 1;
3504     if (new_style_driver) {
3505         /* allocate ourselves a ppp unit */
3506         if (make_ppp_unit() < 0)
3507             die(1);
3508         modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
3509         set_kdebugflag(kdebugflag);
3510         ppp_fd = -1;
3511         return ppp_dev_fd;
3512     }
3513
3514     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
3515         fatal("No free pty for loopback");
3516
3517     set_ppp_fd(slave_fd);
3518
3519     flags = fcntl(master_fd, F_GETFL);
3520     if (flags == -1 ||
3521         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3522         warn("couldn't set master loopback to nonblock: %m");
3523
3524     flags = fcntl(ppp_fd, F_GETFL);
3525     if (flags == -1 ||
3526         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
3527         warn("couldn't set slave loopback to nonblock: %m");
3528
3529     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
3530         fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
3531 /*
3532  * Find out which interface we were given.
3533  */
3534     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
3535         fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
3536 /*
3537  * Enable debug in the driver if requested.
3538  */
3539     set_kdebugflag (kdebugflag);
3540
3541     return master_fd;
3542 }
3543
3544 /********************************************************************
3545  *
3546  * sifnpmode - Set the mode for handling packets for a given NP.
3547  */
3548
3549 int
3550 sifnpmode(int u, int proto, enum NPmode mode)
3551 {
3552     struct npioctl npi;
3553
3554     npi.protocol = proto;
3555     npi.mode     = mode;
3556     if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
3557         if (! ok_error (errno))
3558             error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
3559         return 0;
3560     }
3561     return 1;
3562 }
3563
3564 \f
3565 /********************************************************************
3566  *
3567  * sipxfaddr - Config the interface IPX networknumber
3568  */
3569
3570 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
3571 {
3572     int    result = 1;
3573
3574 #ifdef IPX_CHANGE
3575     int    skfd;
3576     struct ifreq         ifr;
3577     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3578
3579     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3580     if (skfd < 0) {
3581         if (! ok_error (errno))
3582             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3583         result = 0;
3584     }
3585     else {
3586         memset (&ifr, '\0', sizeof (ifr));
3587         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3588
3589         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
3590         sipx->sipx_family  = AF_IPX;
3591         sipx->sipx_port    = 0;
3592         sipx->sipx_network = htonl (network);
3593         sipx->sipx_type    = IPX_FRAME_ETHERII;
3594         sipx->sipx_action  = IPX_CRTITF;
3595 /*
3596  *  Set the IPX device
3597  */
3598         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3599             result = 0;
3600             if (errno != EEXIST) {
3601                 if (! ok_error (errno))
3602                     dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
3603             }
3604             else {
3605                 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
3606             }
3607         }
3608         close (skfd);
3609     }
3610 #endif
3611     return result;
3612 }
3613
3614 /********************************************************************
3615  *
3616  * cipxfaddr - Clear the information for the IPX network. The IPX routes
3617  *             are removed and the device is no longer able to pass IPX
3618  *             frames.
3619  */
3620
3621 int cipxfaddr (int unit)
3622 {
3623     int    result = 1;
3624
3625 #ifdef IPX_CHANGE
3626     int    skfd;
3627     struct ifreq         ifr;
3628     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3629
3630     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3631     if (skfd < 0) {
3632         if (! ok_error (errno))
3633             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3634         result = 0;
3635     }
3636     else {
3637         memset (&ifr, '\0', sizeof (ifr));
3638         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3639
3640         sipx->sipx_type    = IPX_FRAME_ETHERII;
3641         sipx->sipx_action  = IPX_DLTITF;
3642         sipx->sipx_family  = AF_IPX;
3643 /*
3644  *  Set the IPX device
3645  */
3646         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3647             if (! ok_error (errno))
3648                 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
3649             result = 0;
3650         }
3651         close (skfd);
3652     }
3653 #endif
3654     return result;
3655 }
3656
3657 /*
3658  * Use the hostname as part of the random number seed.
3659  */
3660 int
3661 get_host_seed(void)
3662 {
3663     int h;
3664     char *p = hostname;
3665
3666     h = 407;
3667     for (p = hostname; *p != 0; ++p)
3668         h = h * 37 + *p;
3669     return h;
3670 }
3671
3672 /********************************************************************
3673  *
3674  * sys_check_options - check the options that the user specified
3675  */
3676
3677 int
3678 sys_check_options(void)
3679 {
3680 #ifdef IPX_CHANGE
3681 /*
3682  * Disable the IPX protocol if the support is not present in the kernel.
3683  */
3684     char *path;
3685
3686     if (ipxcp_protent.enabled_flag) {
3687         struct stat stat_buf;
3688         if (  ((path = path_to_procfs("/net/ipx/interface")) == NULL
3689             && (path = path_to_procfs("/net/ipx_interface")) == NULL)
3690             || lstat(path, &stat_buf) < 0) {
3691             error("IPX support is not present in the kernel\n");
3692             ipxcp_protent.enabled_flag = 0;
3693         }
3694     }
3695 #endif
3696     if (demand && driver_is_old) {
3697         option_error("demand dialling is not supported by kernel driver "
3698                      "version %d.%d.%d", driver_version, driver_modification,
3699                      driver_patch);
3700         return 0;
3701     }
3702     if (multilink && !new_style_driver) {
3703         warn("Warning: multilink is not supported by the kernel driver");
3704         multilink = 0;
3705     }
3706     return 1;
3707 }
3708
3709 /********************************************************************
3710  *
3711  * get_time - Get current time, monotonic if possible.
3712  */
3713 int
3714 get_time(struct timeval *tv)
3715 {
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
3720 #endif
3721     static int monotonic = -1;
3722     struct timespec ts;
3723     int ret;
3724
3725     if (monotonic) {
3726         ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3727         if (ret == 0) {
3728             monotonic = 1;
3729             if (tv) {
3730                 tv->tv_sec = ts.tv_sec;
3731                 tv->tv_usec = ts.tv_nsec / 1000;
3732             }
3733             return ret;
3734         } else if (monotonic > 0)
3735             return ret;
3736
3737         monotonic = 0;
3738         warn("Couldn't use monotonic clock source: %m");
3739     }
3740
3741     return gettimeofday(tv, NULL);
3742 }