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