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