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