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