OSDN Git Service

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