]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
2540c4fba29e38ce72120c4d316f369916e421c6
[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 #ifdef B1000000
853     { 1000000, B1000000 },
854 #endif
855 #ifdef B1152000
856     { 1152000, B1152000 },
857 #endif
858 #ifdef B1500000
859     { 1500000, B1500000 },
860 #endif
861 #ifdef B2000000
862     { 2000000, B2000000 },
863 #endif
864 #ifdef B2500000
865     { 2500000, B2500000 },
866 #endif
867 #ifdef B3000000
868     { 3000000, B3000000 },
869 #endif
870 #ifdef B3500000
871     { 3500000, B3500000 },
872 #endif
873 #ifdef B4000000
874     { 4000000, B4000000 },
875 #endif
876     { 0, 0 }
877 };
878
879 /********************************************************************
880  *
881  * Translate from bits/second to a speed_t.
882  */
883
884 static int translate_speed (int bps)
885 {
886     struct speed *speedp;
887
888     if (bps != 0) {
889         for (speedp = speeds; speedp->speed_int; speedp++) {
890             if (bps == speedp->speed_int)
891                 return speedp->speed_val;
892         }
893         warn("speed %d not supported", bps);
894     }
895     return 0;
896 }
897
898 /********************************************************************
899  *
900  * Translate from a speed_t to bits/second.
901  */
902
903 static int baud_rate_of (int speed)
904 {
905     struct speed *speedp;
906
907     if (speed != 0) {
908         for (speedp = speeds; speedp->speed_int; speedp++) {
909             if (speed == speedp->speed_val)
910                 return speedp->speed_int;
911         }
912     }
913     return 0;
914 }
915
916 /********************************************************************
917  *
918  * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
919  * at the requested speed, etc.  If `local' is true, set CLOCAL
920  * regardless of whether the modem option was specified.
921  */
922
923 void set_up_tty(int tty_fd, int local)
924 {
925     int speed;
926     struct termios tios;
927
928     setdtr(tty_fd, 1);
929     if (tcgetattr(tty_fd, &tios) < 0) {
930         if (!ok_error(errno))
931             fatal("tcgetattr: %m (line %d)", __LINE__);
932         return;
933     }
934
935     if (!restore_term)
936         inittermios = tios;
937
938     tios.c_cflag     &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
939     tios.c_cflag     |= CS8 | CREAD | HUPCL;
940
941     tios.c_iflag      = IGNBRK | IGNPAR;
942     tios.c_oflag      = 0;
943     tios.c_lflag      = 0;
944     tios.c_cc[VMIN]   = 1;
945     tios.c_cc[VTIME]  = 0;
946
947     if (local || !modem)
948         tios.c_cflag ^= (CLOCAL | HUPCL);
949
950     switch (crtscts) {
951     case 1:
952         tios.c_cflag |= CRTSCTS;
953         break;
954
955     case -2:
956         tios.c_iflag     |= IXON | IXOFF;
957         tios.c_cc[VSTOP]  = 0x13;       /* DC3 = XOFF = ^S */
958         tios.c_cc[VSTART] = 0x11;       /* DC1 = XON  = ^Q */
959         break;
960
961     case -1:
962         tios.c_cflag &= ~CRTSCTS;
963         break;
964
965     default:
966         break;
967     }
968
969     speed = translate_speed(inspeed);
970     if (speed) {
971         cfsetospeed (&tios, speed);
972         cfsetispeed (&tios, speed);
973     }
974 /*
975  * We can't proceed if the serial port speed is B0,
976  * since that implies that the serial port is disabled.
977  */
978     else {
979         speed = cfgetospeed(&tios);
980         if (speed == B0)
981             fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
982     }
983
984     while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
985         if (errno != EINTR)
986             fatal("tcsetattr: %m (line %d)", __LINE__);
987
988     baud_rate    = baud_rate_of(speed);
989     restore_term = 1;
990 }
991
992 /********************************************************************
993  *
994  * setdtr - control the DTR line on the serial port.
995  * This is called from die(), so it shouldn't call die().
996  */
997
998 void setdtr (int tty_fd, int on)
999 {
1000     int modembits = TIOCM_DTR;
1001
1002     ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1003 }
1004
1005 /********************************************************************
1006  *
1007  * restore_tty - restore the terminal to the saved settings.
1008  */
1009
1010 void restore_tty (int tty_fd)
1011 {
1012     if (restore_term) {
1013         restore_term = 0;
1014 /*
1015  * Turn off echoing, because otherwise we can get into
1016  * a loop with the tty and the modem echoing to each other.
1017  * We presume we are the sole user of this tty device, so
1018  * when we close it, it will revert to its defaults anyway.
1019  */
1020         if (!default_device)
1021             inittermios.c_lflag &= ~(ECHO | ECHONL);
1022
1023         if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1024             if (! ok_error (errno))
1025                 warn("tcsetattr: %m (line %d)", __LINE__);
1026         }
1027     }
1028 }
1029
1030 /********************************************************************
1031  *
1032  * output - Output PPP packet.
1033  */
1034
1035 void output (int unit, unsigned char *p, int len)
1036 {
1037     int fd = ppp_fd;
1038     int proto;
1039
1040     dump_packet("sent", p, len);
1041     if (snoop_send_hook) snoop_send_hook(p, len);
1042
1043     if (len < PPP_HDRLEN)
1044         return;
1045     if (new_style_driver) {
1046         p += 2;
1047         len -= 2;
1048         proto = (p[0] << 8) + p[1];
1049         if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1050             fd = ppp_dev_fd;
1051     }
1052     if (write(fd, p, len) < 0) {
1053         if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1054             || errno == ENXIO || errno == EIO || errno == EINTR)
1055             warn("write: warning: %m (%d)", errno);
1056         else
1057             error("write: %m (%d)", errno);
1058     }
1059 }
1060
1061 /********************************************************************
1062  *
1063  * wait_input - wait until there is data available,
1064  * for the length of time specified by *timo (indefinite
1065  * if timo is NULL).
1066  */
1067
1068 void wait_input(struct timeval *timo)
1069 {
1070     fd_set ready, exc;
1071     int n;
1072
1073     ready = in_fds;
1074     exc = in_fds;
1075     n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1076     if (n < 0 && errno != EINTR)
1077         fatal("select: %m");
1078 }
1079
1080 /*
1081  * add_fd - add an fd to the set that wait_input waits for.
1082  */
1083 void add_fd(int fd)
1084 {
1085     if (fd >= FD_SETSIZE)
1086         fatal("internal error: file descriptor too large (%d)", fd);
1087     FD_SET(fd, &in_fds);
1088     if (fd > max_in_fd)
1089         max_in_fd = fd;
1090 }
1091
1092 /*
1093  * remove_fd - remove an fd from the set that wait_input waits for.
1094  */
1095 void remove_fd(int fd)
1096 {
1097     FD_CLR(fd, &in_fds);
1098 }
1099
1100
1101 /********************************************************************
1102  *
1103  * read_packet - get a PPP packet from the serial device.
1104  */
1105
1106 int read_packet (unsigned char *buf)
1107 {
1108     int len, nr;
1109
1110     len = PPP_MRU + PPP_HDRLEN;
1111     if (new_style_driver) {
1112         *buf++ = PPP_ALLSTATIONS;
1113         *buf++ = PPP_UI;
1114         len -= 2;
1115     }
1116     nr = -1;
1117     if (ppp_fd >= 0) {
1118         nr = read(ppp_fd, buf, len);
1119         if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1120             && errno != EIO && errno != EINTR)
1121             error("read: %m");
1122         if (nr < 0 && errno == ENXIO)
1123             return 0;
1124     }
1125     if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1126         /* N.B. we read ppp_fd first since LCP packets come in there. */
1127         nr = read(ppp_dev_fd, buf, len);
1128         if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1129             && errno != EIO && errno != EINTR)
1130             error("read /dev/ppp: %m");
1131         if (nr < 0 && errno == ENXIO)
1132             nr = 0;
1133         if (nr == 0 && doing_multilink) {
1134             remove_fd(ppp_dev_fd);
1135             bundle_eof = 1;
1136         }
1137     }
1138     if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1139         nr = 0;
1140     return (new_style_driver && nr > 0)? nr+2: nr;
1141 }
1142
1143 /********************************************************************
1144  *
1145  * get_loop_output - get outgoing packets from the ppp device,
1146  * and detect when we want to bring the real link up.
1147  * Return value is 1 if we need to bring up the link, 0 otherwise.
1148  */
1149 int
1150 get_loop_output(void)
1151 {
1152     int rv = 0;
1153     int n;
1154
1155     if (new_style_driver) {
1156         while ((n = read_packet(inpacket_buf)) > 0)
1157             if (loop_frame(inpacket_buf, n))
1158                 rv = 1;
1159         return rv;
1160     }
1161
1162     while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1163         if (loop_chars(inbuf, n))
1164             rv = 1;
1165
1166     if (n == 0)
1167         fatal("eof on loopback");
1168
1169     if (errno != EWOULDBLOCK && errno != EAGAIN)
1170         fatal("read from loopback: %m(%d)", errno);
1171
1172     return rv;
1173 }
1174
1175 /*
1176  * netif_set_mtu - set the MTU on the PPP network interface.
1177  */
1178 void
1179 netif_set_mtu(int unit, int mtu)
1180 {
1181     struct ifreq ifr;
1182
1183     memset (&ifr, '\0', sizeof (ifr));
1184     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1185     ifr.ifr_mtu = mtu;
1186
1187     if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1188         error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1189 }
1190
1191 /*
1192  * netif_get_mtu - get the MTU on the PPP network interface.
1193  */
1194 int
1195 netif_get_mtu(int unit)
1196 {
1197     struct ifreq ifr;
1198
1199     memset (&ifr, '\0', sizeof (ifr));
1200     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1201
1202     if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1203         error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1204         return 0;
1205     }
1206     return ifr.ifr_mtu;
1207 }
1208
1209 /********************************************************************
1210  *
1211  * tty_send_config - configure the transmit characteristics of
1212  * the ppp interface.
1213  */
1214
1215 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1216 {
1217         int x;
1218
1219         if (!still_ppp())
1220                 return;
1221         link_mtu = mtu;
1222         if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1223                 if (errno != EIO && errno != ENOTTY)
1224                         error("Couldn't set transmit async character map: %m");
1225                 ++error_count;
1226                 return;
1227         }
1228
1229         x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1230             | (sync_serial? SC_SYNC: 0);
1231         modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1232 }
1233
1234 /********************************************************************
1235  *
1236  * tty_set_xaccm - set the extended transmit ACCM for the interface.
1237  */
1238
1239 void tty_set_xaccm (ext_accm accm)
1240 {
1241     if (!still_ppp())
1242         return;
1243     if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1244         if ( ! ok_error (errno))
1245             warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1246     }
1247 }
1248
1249 /********************************************************************
1250  *
1251  * tty_recv_config - configure the receive-side characteristics of
1252  * the ppp interface.
1253  */
1254
1255 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1256 {
1257 /*
1258  * If we were called because the link has gone down then there is nothing
1259  * which may be done. Just return without incident.
1260  */
1261         if (!still_ppp())
1262                 return;
1263 /*
1264  * Set the receiver parameters
1265  */
1266         if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1267                 if (errno != EIO && errno != ENOTTY)
1268                         error("Couldn't set channel receive MRU: %m");
1269         }
1270         if (new_style_driver && ppp_dev_fd >= 0
1271             && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1272                 error("Couldn't set MRU in generic PPP layer: %m");
1273
1274         if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1275                 if (errno != EIO && errno != ENOTTY)
1276                         error("Couldn't set channel receive asyncmap: %m");
1277         }
1278 }
1279
1280 /********************************************************************
1281  *
1282  * ccp_test - ask kernel whether a given compression method
1283  * is acceptable for use.
1284  */
1285
1286 int
1287 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1288 {
1289     struct ppp_option_data data;
1290
1291     memset (&data, '\0', sizeof (data));
1292     data.ptr      = opt_ptr;
1293     data.length   = opt_len;
1294     data.transmit = for_transmit;
1295
1296     if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1297         return 1;
1298
1299     return (errno == ENOBUFS)? 0: -1;
1300 }
1301
1302 /********************************************************************
1303  *
1304  * ccp_flags_set - inform kernel about the current state of CCP.
1305  */
1306
1307 void ccp_flags_set (int unit, int isopen, int isup)
1308 {
1309         int x;
1310
1311         x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1312         if (still_ppp() && ppp_dev_fd >= 0)
1313                 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1314 }
1315
1316 #ifdef PPP_FILTER
1317 /*
1318  * set_filters - set the active and pass filters in the kernel driver.
1319  */
1320 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1321 {
1322         struct sock_fprog fp;
1323
1324         fp.len = pass->bf_len;
1325         fp.filter = (struct sock_filter *) pass->bf_insns;
1326         if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1327                 if (errno == ENOTTY)
1328                         warn("kernel does not support PPP filtering");
1329                 else
1330                         error("Couldn't set pass-filter in kernel: %m");
1331                 return 0;
1332         }
1333         fp.len = active->bf_len;
1334         fp.filter = (struct sock_filter *) active->bf_insns;
1335         if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1336                 error("Couldn't set active-filter in kernel: %m");
1337                 return 0;
1338         }
1339         return 1;
1340 }
1341 #endif /* PPP_FILTER */
1342
1343 /********************************************************************
1344  *
1345  * get_idle_time - return how long the link has been idle.
1346  */
1347 int
1348 get_idle_time(u, ip)
1349     int u;
1350     struct ppp_idle *ip;
1351 {
1352     return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1353 }
1354
1355 /********************************************************************
1356  *
1357  * get_ppp_stats - return statistics for the link.
1358  */
1359 int
1360 get_ppp_stats(u, stats)
1361     int u;
1362     struct pppd_stats *stats;
1363 {
1364     struct ifpppstatsreq req;
1365
1366     memset (&req, 0, sizeof (req));
1367
1368     req.stats_ptr = (caddr_t) &req.stats;
1369     strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1370     if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1371         error("Couldn't get PPP statistics: %m");
1372         return 0;
1373     }
1374     stats->bytes_in = req.stats.p.ppp_ibytes;
1375     stats->bytes_out = req.stats.p.ppp_obytes;
1376     stats->pkts_in = req.stats.p.ppp_ipackets;
1377     stats->pkts_out = req.stats.p.ppp_opackets;
1378     return 1;
1379 }
1380
1381 /********************************************************************
1382  *
1383  * ccp_fatal_error - returns 1 if decompression was disabled as a
1384  * result of an error detected after decompression of a packet,
1385  * 0 otherwise.  This is necessary because of patent nonsense.
1386  */
1387
1388 int ccp_fatal_error (int unit)
1389 {
1390         int flags;
1391
1392         if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1393                 error("Couldn't read compression error flags: %m");
1394                 flags = 0;
1395         }
1396         return flags & SC_DC_FERROR;
1397 }
1398
1399 /********************************************************************
1400  *
1401  * path_to_procfs - find the path to the proc file system mount point
1402  */
1403 static char proc_path[MAXPATHLEN];
1404 static int proc_path_len;
1405
1406 static char *path_to_procfs(const char *tail)
1407 {
1408     struct mntent *mntent;
1409     FILE *fp;
1410
1411     if (proc_path_len == 0) {
1412         /* Default the mount location of /proc */
1413         strlcpy (proc_path, "/proc", sizeof(proc_path));
1414         proc_path_len = 5;
1415         fp = fopen(MOUNTED, "r");
1416         if (fp != NULL) {
1417             while ((mntent = getmntent(fp)) != NULL) {
1418                 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1419                     continue;
1420                 if (strcmp(mntent->mnt_type, "proc") == 0) {
1421                     strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1422                     proc_path_len = strlen(proc_path);
1423                     break;
1424                 }
1425             }
1426             fclose (fp);
1427         }
1428     }
1429
1430     strlcpy(proc_path + proc_path_len, tail,
1431             sizeof(proc_path) - proc_path_len);
1432     return proc_path;
1433 }
1434
1435 /*
1436  * /proc/net/route parsing stuff.
1437  */
1438 #define ROUTE_MAX_COLS  12
1439 FILE *route_fd = (FILE *) 0;
1440 static char route_buffer[512];
1441 static int route_dev_col, route_dest_col, route_gw_col;
1442 static int route_flags_col, route_mask_col;
1443 static int route_num_cols;
1444
1445 static int open_route_table (void);
1446 static void close_route_table (void);
1447 static int read_route_table (struct rtentry *rt);
1448
1449 /********************************************************************
1450  *
1451  * close_route_table - close the interface to the route table
1452  */
1453
1454 static void close_route_table (void)
1455 {
1456     if (route_fd != (FILE *) 0) {
1457         fclose (route_fd);
1458         route_fd = (FILE *) 0;
1459     }
1460 }
1461
1462 /********************************************************************
1463  *
1464  * open_route_table - open the interface to the route table
1465  */
1466 static char route_delims[] = " \t\n";
1467
1468 static int open_route_table (void)
1469 {
1470     char *path;
1471
1472     close_route_table();
1473
1474     path = path_to_procfs("/net/route");
1475     route_fd = fopen (path, "r");
1476     if (route_fd == NULL) {
1477         error("can't open routing table %s: %m", path);
1478         return 0;
1479     }
1480
1481     route_dev_col = 0;          /* default to usual columns */
1482     route_dest_col = 1;
1483     route_gw_col = 2;
1484     route_flags_col = 3;
1485     route_mask_col = 7;
1486     route_num_cols = 8;
1487
1488     /* parse header line */
1489     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1490         char *p = route_buffer, *q;
1491         int col;
1492         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1493             int used = 1;
1494             if ((q = strtok(p, route_delims)) == 0)
1495                 break;
1496             if (strcasecmp(q, "iface") == 0)
1497                 route_dev_col = col;
1498             else if (strcasecmp(q, "destination") == 0)
1499                 route_dest_col = col;
1500             else if (strcasecmp(q, "gateway") == 0)
1501                 route_gw_col = col;
1502             else if (strcasecmp(q, "flags") == 0)
1503                 route_flags_col = col;
1504             else if (strcasecmp(q, "mask") == 0)
1505                 route_mask_col = col;
1506             else
1507                 used = 0;
1508             if (used && col >= route_num_cols)
1509                 route_num_cols = col + 1;
1510             p = NULL;
1511         }
1512     }
1513
1514     return 1;
1515 }
1516
1517 /********************************************************************
1518  *
1519  * read_route_table - read the next entry from the route table
1520  */
1521
1522 static int read_route_table(struct rtentry *rt)
1523 {
1524     char *cols[ROUTE_MAX_COLS], *p;
1525     int col;
1526
1527     memset (rt, '\0', sizeof (struct rtentry));
1528
1529     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1530         return 0;
1531
1532     p = route_buffer;
1533     for (col = 0; col < route_num_cols; ++col) {
1534         cols[col] = strtok(p, route_delims);
1535         if (cols[col] == NULL)
1536             return 0;           /* didn't get enough columns */
1537         p = NULL;
1538     }
1539
1540     SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1541     SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1542     SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1543
1544     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1545     rt->rt_dev   = cols[route_dev_col];
1546
1547     return 1;
1548 }
1549
1550 /********************************************************************
1551  *
1552  * defaultroute_exists - determine if there is a default route
1553  */
1554
1555 static int defaultroute_exists (struct rtentry *rt)
1556 {
1557     int result = 0;
1558
1559     if (!open_route_table())
1560         return 0;
1561
1562     while (read_route_table(rt) != 0) {
1563         if ((rt->rt_flags & RTF_UP) == 0)
1564             continue;
1565
1566         if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1567             continue;
1568         if (SIN_ADDR(rt->rt_dst) == 0L) {
1569             result = 1;
1570             break;
1571         }
1572     }
1573
1574     close_route_table();
1575     return result;
1576 }
1577
1578 /*
1579  * have_route_to - determine if the system has any route to
1580  * a given IP address.  `addr' is in network byte order.
1581  * Return value is 1 if yes, 0 if no, -1 if don't know.
1582  * For demand mode to work properly, we have to ignore routes
1583  * through our own interface.
1584  */
1585 int have_route_to(u_int32_t addr)
1586 {
1587     struct rtentry rt;
1588     int result = 0;
1589
1590     if (!open_route_table())
1591         return -1;              /* don't know */
1592
1593     while (read_route_table(&rt)) {
1594         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1595             continue;
1596         if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1597             result = 1;
1598             break;
1599         }
1600     }
1601
1602     close_route_table();
1603     return result;
1604 }
1605
1606 /********************************************************************
1607  *
1608  * sifdefaultroute - assign a default route through the address given.
1609  */
1610
1611 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1612 {
1613     struct rtentry rt;
1614
1615     if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1616         if (rt.rt_flags & RTF_GATEWAY)
1617             error("not replacing existing default route via %I",
1618                   SIN_ADDR(rt.rt_gateway));
1619         else
1620             error("not replacing existing default route through %s",
1621                   rt.rt_dev);
1622         return 0;
1623     }
1624
1625     memset (&rt, 0, sizeof (rt));
1626     SET_SA_FAMILY (rt.rt_dst, AF_INET);
1627
1628     rt.rt_dev = ifname;
1629
1630     if (kernel_version > KVERSION(2,1,0)) {
1631         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1632         SIN_ADDR(rt.rt_genmask) = 0L;
1633     }
1634
1635     rt.rt_flags = RTF_UP;
1636     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1637         if ( ! ok_error ( errno ))
1638             error("default route ioctl(SIOCADDRT): %m");
1639         return 0;
1640     }
1641
1642     have_default_route = 1;
1643     return 1;
1644 }
1645
1646 /********************************************************************
1647  *
1648  * cifdefaultroute - delete a default route through the address given.
1649  */
1650
1651 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1652 {
1653     struct rtentry rt;
1654
1655     have_default_route = 0;
1656
1657     memset (&rt, '\0', sizeof (rt));
1658     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1659     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1660
1661     rt.rt_dev = ifname;
1662
1663     if (kernel_version > KVERSION(2,1,0)) {
1664         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1665         SIN_ADDR(rt.rt_genmask) = 0L;
1666     }
1667
1668     rt.rt_flags = RTF_UP;
1669     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1670         if (still_ppp()) {
1671             if ( ! ok_error ( errno ))
1672                 error("default route ioctl(SIOCDELRT): %m");
1673             return 0;
1674         }
1675     }
1676
1677     return 1;
1678 }
1679
1680 /********************************************************************
1681  *
1682  * sifproxyarp - Make a proxy ARP entry for the peer.
1683  */
1684
1685 int sifproxyarp (int unit, u_int32_t his_adr)
1686 {
1687     struct arpreq arpreq;
1688     char *forw_path;
1689
1690     if (has_proxy_arp == 0) {
1691         memset (&arpreq, '\0', sizeof(arpreq));
1692
1693         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1694         SIN_ADDR(arpreq.arp_pa) = his_adr;
1695         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1696 /*
1697  * Get the hardware address of an interface on the same subnet
1698  * as our local address.
1699  */
1700         if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1701                             sizeof(proxy_arp_dev))) {
1702             error("Cannot determine ethernet address for proxy ARP");
1703             return 0;
1704         }
1705         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1706
1707         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1708             if ( ! ok_error ( errno ))
1709                 error("ioctl(SIOCSARP): %m");
1710             return 0;
1711         }
1712         proxy_arp_addr = his_adr;
1713         has_proxy_arp = 1;
1714
1715         if (tune_kernel) {
1716             forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1717             if (forw_path != 0) {
1718                 int fd = open(forw_path, O_WRONLY);
1719                 if (fd >= 0) {
1720                     if (write(fd, "1", 1) != 1)
1721                         error("Couldn't enable IP forwarding: %m");
1722                     close(fd);
1723                 }
1724             }
1725         }
1726     }
1727
1728     return 1;
1729 }
1730
1731 /********************************************************************
1732  *
1733  * cifproxyarp - Delete the proxy ARP entry for the peer.
1734  */
1735
1736 int cifproxyarp (int unit, u_int32_t his_adr)
1737 {
1738     struct arpreq arpreq;
1739
1740     if (has_proxy_arp) {
1741         has_proxy_arp = 0;
1742         memset (&arpreq, '\0', sizeof(arpreq));
1743         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1744         SIN_ADDR(arpreq.arp_pa) = his_adr;
1745         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1746         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1747
1748         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1749             if ( ! ok_error ( errno ))
1750                 warn("ioctl(SIOCDARP): %m");
1751             return 0;
1752         }
1753     }
1754     return 1;
1755 }
1756
1757 /********************************************************************
1758  *
1759  * get_ether_addr - get the hardware address of an interface on the
1760  * the same subnet as ipaddr.
1761  */
1762
1763 static int get_ether_addr (u_int32_t ipaddr,
1764                            struct sockaddr *hwaddr,
1765                            char *name, int namelen)
1766 {
1767     struct ifreq *ifr, *ifend;
1768     u_int32_t ina, mask;
1769     char *aliasp;
1770     struct ifreq ifreq, bestifreq;
1771     struct ifconf ifc;
1772     struct ifreq ifs[MAX_IFS];
1773
1774     u_int32_t bestmask=0;
1775     int found_interface = 0;
1776
1777     ifc.ifc_len = sizeof(ifs);
1778     ifc.ifc_req = ifs;
1779     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1780         if ( ! ok_error ( errno ))
1781             error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1782         return 0;
1783     }
1784
1785 /*
1786  * Scan through looking for an interface with an Internet
1787  * address on the same subnet as `ipaddr'.
1788  */
1789     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1790     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1791         if (ifr->ifr_addr.sa_family == AF_INET) {
1792             ina = SIN_ADDR(ifr->ifr_addr);
1793             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1794 /*
1795  * Check that the interface is up, and not point-to-point
1796  * nor loopback.
1797  */
1798             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1799                 continue;
1800
1801             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1802                 continue;
1803 /*
1804  * Get its netmask and check that it's on the right subnet.
1805  */
1806             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1807                 continue;
1808
1809             mask = SIN_ADDR(ifreq.ifr_addr);
1810
1811             if (((ipaddr ^ ina) & mask) != 0)
1812                 continue; /* no match */
1813             /* matched */
1814             if (mask >= bestmask) {
1815                 /* Compare using >= instead of > -- it is possible for
1816                    an interface to have a netmask of 0.0.0.0 */
1817                 found_interface = 1;
1818                 bestifreq = ifreq;
1819                 bestmask = mask;
1820             }
1821         }
1822     }
1823
1824     if (!found_interface) return 0;
1825
1826     strlcpy(name, bestifreq.ifr_name, namelen);
1827
1828     /* trim off the :1 in eth0:1 */
1829     aliasp = strchr(name, ':');
1830     if (aliasp != 0)
1831         *aliasp = 0;
1832
1833     info("found interface %s for proxy arp", name);
1834 /*
1835  * Now get the hardware address.
1836  */
1837     memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1838     if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1839         error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1840         return 0;
1841     }
1842
1843     memcpy (hwaddr,
1844             &bestifreq.ifr_hwaddr,
1845             sizeof (struct sockaddr));
1846
1847     return 1;
1848 }
1849
1850 /*
1851  * get_if_hwaddr - get the hardware address for the specified
1852  * network interface device.
1853  */
1854 int
1855 get_if_hwaddr(u_char *addr, char *name)
1856 {
1857         struct ifreq ifreq;
1858         int ret, sock_fd;
1859
1860         sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1861         if (sock_fd < 0)
1862                 return 0;
1863         memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1864         strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1865         ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1866         close(sock_fd);
1867         if (ret >= 0)
1868                 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1869         return ret;
1870 }
1871
1872 /*
1873  * get_first_ethernet - return the name of the first ethernet-style
1874  * interface on this system.
1875  */
1876 char *
1877 get_first_ethernet()
1878 {
1879         return "eth0";
1880 }
1881
1882 /********************************************************************
1883  *
1884  * Return user specified netmask, modified by any mask we might determine
1885  * for address `addr' (in network byte order).
1886  * Here we scan through the system's list of interfaces, looking for
1887  * any non-point-to-point interfaces which might appear to be on the same
1888  * network as `addr'.  If we find any, we OR in their netmask to the
1889  * user-specified netmask.
1890  */
1891
1892 u_int32_t GetMask (u_int32_t addr)
1893 {
1894     u_int32_t mask, nmask, ina;
1895     struct ifreq *ifr, *ifend, ifreq;
1896     struct ifconf ifc;
1897     struct ifreq ifs[MAX_IFS];
1898
1899     addr = ntohl(addr);
1900
1901     if (IN_CLASSA(addr))        /* determine network mask for address class */
1902         nmask = IN_CLASSA_NET;
1903     else if (IN_CLASSB(addr))
1904             nmask = IN_CLASSB_NET;
1905     else
1906             nmask = IN_CLASSC_NET;
1907
1908     /* class D nets are disallowed by bad_ip_adrs */
1909     mask = netmask | htonl(nmask);
1910 /*
1911  * Scan through the system's network interfaces.
1912  */
1913     ifc.ifc_len = sizeof(ifs);
1914     ifc.ifc_req = ifs;
1915     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1916         if ( ! ok_error ( errno ))
1917             warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1918         return mask;
1919     }
1920
1921     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1922     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1923 /*
1924  * Check the interface's internet address.
1925  */
1926         if (ifr->ifr_addr.sa_family != AF_INET)
1927             continue;
1928         ina = SIN_ADDR(ifr->ifr_addr);
1929         if (((ntohl(ina) ^ addr) & nmask) != 0)
1930             continue;
1931 /*
1932  * Check that the interface is up, and not point-to-point nor loopback.
1933  */
1934         strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1935         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1936             continue;
1937
1938         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1939             continue;
1940 /*
1941  * Get its netmask and OR it into our mask.
1942  */
1943         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1944             continue;
1945         mask |= SIN_ADDR(ifreq.ifr_addr);
1946         break;
1947     }
1948     return mask;
1949 }
1950
1951 /********************************************************************
1952  *
1953  * Internal routine to decode the version.modification.patch level
1954  */
1955
1956 static void decode_version (char *buf, int *version,
1957                             int *modification, int *patch)
1958 {
1959     char *endp;
1960
1961     *version      = (int) strtoul (buf, &endp, 10);
1962     *modification = 0;
1963     *patch        = 0;
1964
1965     if (endp != buf && *endp == '.') {
1966         buf = endp + 1;
1967         *modification = (int) strtoul (buf, &endp, 10);
1968         if (endp != buf && *endp == '.') {
1969             buf = endp + 1;
1970             *patch = (int) strtoul (buf, &buf, 10);
1971         }
1972     }
1973 }
1974
1975 /********************************************************************
1976  *
1977  * Procedure to determine if the PPP line discipline is registered.
1978  */
1979
1980 static int
1981 ppp_registered(void)
1982 {
1983     int local_fd;
1984     int mfd = -1;
1985     int ret = 0;
1986     char slave[16];
1987
1988     /*
1989      * We used to open the serial device and set it to the ppp line
1990      * discipline here, in order to create a ppp unit.  But that is
1991      * not a good idea - the user might have specified a device that
1992      * they can't open (permission, or maybe it doesn't really exist).
1993      * So we grab a pty master/slave pair and use that.
1994      */
1995     if (!get_pty(&mfd, &local_fd, slave, 0)) {
1996         no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1997         return 0;
1998     }
1999
2000     /*
2001      * Try to put the device into the PPP discipline.
2002      */
2003     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2004         error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2005     } else
2006         ret = 1;
2007
2008     close(local_fd);
2009     close(mfd);
2010     return ret;
2011 }
2012
2013 /********************************************************************
2014  *
2015  * ppp_available - check whether the system has any ppp interfaces
2016  * (in fact we check whether we can do an ioctl on ppp0).
2017  */
2018
2019 int ppp_available(void)
2020 {
2021     int s, ok, fd;
2022     struct ifreq ifr;
2023     int    size;
2024     int    my_version, my_modification, my_patch;
2025     int osmaj, osmin, ospatch;
2026
2027     /* get the kernel version now, since we are called before sys_init */
2028     uname(&utsname);
2029     osmaj = osmin = ospatch = 0;
2030     sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2031     kernel_version = KVERSION(osmaj, osmin, ospatch);
2032
2033     fd = open("/dev/ppp", O_RDWR);
2034     if (fd >= 0) {
2035         new_style_driver = 1;
2036
2037         /* XXX should get from driver */
2038         driver_version = 2;
2039         driver_modification = 4;
2040         driver_patch = 0;
2041         close(fd);
2042         return 1;
2043     }
2044
2045     if (kernel_version >= KVERSION(2,3,13)) {
2046         error("Couldn't open the /dev/ppp device: %m");
2047         if (errno == ENOENT)
2048             no_ppp_msg =
2049                 "You need to create the /dev/ppp device node by\n"
2050                 "executing the following command as root:\n"
2051                 "       mknod /dev/ppp c 108 0\n";
2052         else if (errno == ENODEV || errno == ENXIO)
2053             no_ppp_msg =
2054                 "Please load the ppp_generic kernel module.\n";
2055         return 0;
2056     }
2057
2058     /* we are running on a really really old kernel */
2059     no_ppp_msg =
2060         "This system lacks kernel support for PPP.  This could be because\n"
2061         "the PPP kernel module could not be loaded, or because PPP was not\n"
2062         "included in the kernel configuration.  If PPP was included as a\n"
2063         "module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
2064         "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2065         "See README.linux file in the ppp distribution for more details.\n";
2066
2067 /*
2068  * Open a socket for doing the ioctl operations.
2069  */
2070     s = socket(AF_INET, SOCK_DGRAM, 0);
2071     if (s < 0)
2072         return 0;
2073
2074     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2075     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2076 /*
2077  * If the device did not exist then attempt to create one by putting the
2078  * current tty into the PPP discipline. If this works then obtain the
2079  * flags for the device again.
2080  */
2081     if (!ok) {
2082         if (ppp_registered()) {
2083             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2084             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2085         }
2086     }
2087 /*
2088  * Ensure that the hardware address is for PPP and not something else
2089  */
2090     if (ok)
2091         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2092
2093     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2094         ok = 0;
2095
2096 /*
2097  *  This is the PPP device. Validate the version of the driver at this
2098  *  point to ensure that this program will work with the driver.
2099  */
2100     if (ok) {
2101         char   abBuffer [1024];
2102
2103         ifr.ifr_data = abBuffer;
2104         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2105         if (size < 0) {
2106             error("Couldn't read driver version: %m");
2107             ok = 0;
2108             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2109
2110         } else {
2111             decode_version(abBuffer,
2112                            &driver_version,
2113                            &driver_modification,
2114                            &driver_patch);
2115 /*
2116  * Validate the version of the driver against the version that we used.
2117  */
2118             decode_version(VERSION,
2119                            &my_version,
2120                            &my_modification,
2121                            &my_patch);
2122
2123             /* The version numbers must match */
2124             if (driver_version != my_version)
2125                 ok = 0;
2126
2127             /* The modification levels must be legal */
2128             if (driver_modification < 3) {
2129                 if (driver_modification >= 2) {
2130                     /* we can cope with 2.2.0 and above */
2131                     driver_is_old = 1;
2132                 } else {
2133                     ok = 0;
2134                 }
2135             }
2136
2137             close (s);
2138             if (!ok) {
2139                 slprintf(route_buffer, sizeof(route_buffer),
2140                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
2141                          driver_version, driver_modification, driver_patch);
2142
2143                 no_ppp_msg = route_buffer;
2144             }
2145         }
2146     }
2147     return ok;
2148 }
2149
2150 /********************************************************************
2151  *
2152  * Update the wtmp file with the appropriate user name and tty device.
2153  */
2154
2155 void logwtmp (const char *line, const char *name, const char *host)
2156 {
2157     struct utmp ut, *utp;
2158     pid_t  mypid = getpid();
2159 #if __GLIBC__ < 2
2160     int    wtmp;
2161 #endif
2162
2163 /*
2164  * Update the signon database for users.
2165  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2166  */
2167     utmpname(_PATH_UTMP);
2168     setutent();
2169     while ((utp = getutent()) && (utp->ut_pid != mypid))
2170         /* nothing */;
2171
2172     if (utp)
2173         memcpy(&ut, utp, sizeof(ut));
2174     else
2175         /* some gettys/telnetds don't initialize utmp... */
2176         memset(&ut, 0, sizeof(ut));
2177
2178     if (ut.ut_id[0] == 0)
2179         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2180
2181     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2182     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2183
2184     time(&ut.ut_time);
2185
2186     ut.ut_type = USER_PROCESS;
2187     ut.ut_pid  = mypid;
2188
2189     /* Insert the host name if one is supplied */
2190     if (*host)
2191         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2192
2193     /* Insert the IP address of the remote system if IP is enabled */
2194     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2195         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2196                  sizeof(ut.ut_addr));
2197
2198     /* CL: Makes sure that the logout works */
2199     if (*host == 0 && *name==0)
2200         ut.ut_host[0]=0;
2201
2202     pututline(&ut);
2203     endutent();
2204 /*
2205  * Update the wtmp file.
2206  */
2207 #if __GLIBC__ >= 2
2208     updwtmp(_PATH_WTMP, &ut);
2209 #else
2210     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2211     if (wtmp >= 0) {
2212         flock(wtmp, LOCK_EX);
2213
2214         if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2215             warn("error writing %s: %m", _PATH_WTMP);
2216
2217         flock(wtmp, LOCK_UN);
2218
2219         close (wtmp);
2220     }
2221 #endif
2222 }
2223
2224
2225 /********************************************************************
2226  *
2227  * sifvjcomp - config tcp header compression
2228  */
2229
2230 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2231 {
2232         u_int x;
2233
2234         if (vjcomp) {
2235                 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2236                         error("Couldn't set up TCP header compression: %m");
2237                         vjcomp = 0;
2238                 }
2239         }
2240
2241         x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2242         modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2243
2244         return 1;
2245 }
2246
2247 /********************************************************************
2248  *
2249  * sifup - Config the interface up and enable IP packets to pass.
2250  */
2251
2252 int sifup(int u)
2253 {
2254     struct ifreq ifr;
2255
2256     memset (&ifr, '\0', sizeof (ifr));
2257     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2258     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2259         if (! ok_error (errno))
2260             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2261         return 0;
2262     }
2263
2264     ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2265     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2266         if (! ok_error (errno))
2267             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2268         return 0;
2269     }
2270     if_is_up++;
2271
2272     return 1;
2273 }
2274
2275 /********************************************************************
2276  *
2277  * sifdown - Disable the indicated protocol and config the interface
2278  *           down if there are no remaining protocols.
2279  */
2280
2281 int sifdown (int u)
2282 {
2283     struct ifreq ifr;
2284
2285     if (if_is_up && --if_is_up > 0)
2286         return 1;
2287
2288     memset (&ifr, '\0', sizeof (ifr));
2289     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2290     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2291         if (! ok_error (errno))
2292             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2293         return 0;
2294     }
2295
2296     ifr.ifr_flags &= ~IFF_UP;
2297     ifr.ifr_flags |= IFF_POINTOPOINT;
2298     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2299         if (! ok_error (errno))
2300             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2301         return 0;
2302     }
2303     return 1;
2304 }
2305
2306 /********************************************************************
2307  *
2308  * sifaddr - Config the interface IP addresses and netmask.
2309  */
2310
2311 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2312              u_int32_t net_mask)
2313 {
2314     struct ifreq   ifr;
2315     struct rtentry rt;
2316
2317     memset (&ifr, '\0', sizeof (ifr));
2318     memset (&rt,  '\0', sizeof (rt));
2319
2320     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET);
2321     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2322     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2323
2324     strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2325 /*
2326  *  Set our IP address
2327  */
2328     SIN_ADDR(ifr.ifr_addr) = our_adr;
2329     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2330         if (errno != EEXIST) {
2331             if (! ok_error (errno))
2332                 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2333         }
2334         else {
2335             warn("ioctl(SIOCSIFADDR): Address already exists");
2336         }
2337         return (0);
2338     }
2339 /*
2340  *  Set the gateway address
2341  */
2342     if (his_adr != 0) {
2343         SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2344         if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2345             if (! ok_error (errno))
2346                 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2347             return (0);
2348         }
2349     }
2350 /*
2351  *  Set the netmask.
2352  *  For recent kernels, force the netmask to 255.255.255.255.
2353  */
2354     if (kernel_version >= KVERSION(2,1,16))
2355         net_mask = ~0L;
2356     if (net_mask != 0) {
2357         SIN_ADDR(ifr.ifr_netmask) = net_mask;
2358         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2359             if (! ok_error (errno))
2360                 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2361             return (0);
2362         }
2363     }
2364 /*
2365  *  Add the device route
2366  */
2367     if (kernel_version < KVERSION(2,1,16)) {
2368         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2369         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2370         rt.rt_dev = ifname;
2371
2372         SIN_ADDR(rt.rt_gateway) = 0L;
2373         SIN_ADDR(rt.rt_dst)     = his_adr;
2374         rt.rt_flags = RTF_UP | RTF_HOST;
2375
2376         if (kernel_version > KVERSION(2,1,0)) {
2377             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2378             SIN_ADDR(rt.rt_genmask) = -1L;
2379         }
2380
2381         if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2382             if (! ok_error (errno))
2383                 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2384             return (0);
2385         }
2386     }
2387
2388     /* set ip_dynaddr in demand mode if address changes */
2389     if (demand && tune_kernel && !dynaddr_set
2390         && our_old_addr && our_old_addr != our_adr) {
2391         /* set ip_dynaddr if possible */
2392         char *path;
2393         int fd;
2394
2395         path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2396         if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2397             if (write(fd, "1", 1) != 1)
2398                 error("Couldn't enable dynamic IP addressing: %m");
2399             close(fd);
2400         }
2401         dynaddr_set = 1;        /* only 1 attempt */
2402     }
2403     our_old_addr = 0;
2404
2405     return 1;
2406 }
2407
2408 /********************************************************************
2409  *
2410  * cifaddr - Clear the interface IP addresses, and delete routes
2411  * through the interface if possible.
2412  */
2413
2414 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2415 {
2416     struct ifreq ifr;
2417
2418     if (kernel_version < KVERSION(2,1,16)) {
2419 /*
2420  *  Delete the route through the device
2421  */
2422         struct rtentry rt;
2423         memset (&rt, '\0', sizeof (rt));
2424
2425         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2426         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2427         rt.rt_dev = ifname;
2428
2429         SIN_ADDR(rt.rt_gateway) = 0;
2430         SIN_ADDR(rt.rt_dst)     = his_adr;
2431         rt.rt_flags = RTF_UP | RTF_HOST;
2432
2433         if (kernel_version > KVERSION(2,1,0)) {
2434             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2435             SIN_ADDR(rt.rt_genmask) = -1L;
2436         }
2437
2438         if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2439             if (still_ppp() && ! ok_error (errno))
2440                 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2441             return (0);
2442         }
2443     }
2444
2445     /* This way it is possible to have an IPX-only or IPv6-only interface */
2446     memset(&ifr, 0, sizeof(ifr));
2447     SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2448     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2449
2450     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2451         if (! ok_error (errno)) {
2452             error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2453             return 0;
2454         }
2455     }
2456
2457     our_old_addr = our_adr;
2458
2459     return 1;
2460 }
2461
2462 #ifdef INET6
2463 /********************************************************************
2464  *
2465  * sif6addr - Config the interface with an IPv6 link-local address
2466  */
2467 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2468 {
2469     struct in6_ifreq ifr6;
2470     struct ifreq ifr;
2471     struct in6_rtmsg rt6;
2472
2473     if (sock6_fd < 0) {
2474         errno = -sock6_fd;
2475         error("IPv6 socket creation failed: %m");
2476         return 0;
2477     }
2478     memset(&ifr, 0, sizeof (ifr));
2479     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2480     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2481         error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2482         return 0;
2483     }
2484
2485     /* Local interface */
2486     memset(&ifr6, 0, sizeof(ifr6));
2487     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2488     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2489     ifr6.ifr6_prefixlen = 10;
2490
2491     if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2492         error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2493         return 0;
2494     }
2495
2496     /* Route to remote host */
2497     memset(&rt6, 0, sizeof(rt6));
2498     IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2499     rt6.rtmsg_flags = RTF_UP;
2500     rt6.rtmsg_dst_len = 10;
2501     rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2502     rt6.rtmsg_metric = 1;
2503
2504     if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2505         error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2506         return 0;
2507     }
2508
2509     return 1;
2510 }
2511
2512
2513 /********************************************************************
2514  *
2515  * cif6addr - Remove IPv6 address from interface
2516  */
2517 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2518 {
2519     struct ifreq ifr;
2520     struct in6_ifreq ifr6;
2521
2522     if (sock6_fd < 0) {
2523         errno = -sock6_fd;
2524         error("IPv6 socket creation failed: %m");
2525         return 0;
2526     }
2527     memset(&ifr, 0, sizeof(ifr));
2528     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2529     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2530         error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2531         return 0;
2532     }
2533
2534     memset(&ifr6, 0, sizeof(ifr6));
2535     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2536     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2537     ifr6.ifr6_prefixlen = 10;
2538
2539     if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2540         if (errno != EADDRNOTAVAIL) {
2541             if (! ok_error (errno))
2542                 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2543         }
2544         else {
2545             warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2546         }
2547         return (0);
2548     }
2549     return 1;
2550 }
2551 #endif /* INET6 */
2552
2553 /*
2554  * get_pty - get a pty master/slave pair and chown the slave side
2555  * to the uid given.  Assumes slave_name points to >= 16 bytes of space.
2556  */
2557 int
2558 get_pty(master_fdp, slave_fdp, slave_name, uid)
2559     int *master_fdp;
2560     int *slave_fdp;
2561     char *slave_name;
2562     int uid;
2563 {
2564     int i, mfd, sfd = -1;
2565     char pty_name[16];
2566     struct termios tios;
2567
2568 #ifdef TIOCGPTN
2569     /*
2570      * Try the unix98 way first.
2571      */
2572     mfd = open("/dev/ptmx", O_RDWR);
2573     if (mfd >= 0) {
2574         int ptn;
2575         if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2576             slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2577             chmod(pty_name, S_IRUSR | S_IWUSR);
2578 #ifdef TIOCSPTLCK
2579             ptn = 0;
2580             if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2581                 warn("Couldn't unlock pty slave %s: %m", pty_name);
2582 #endif
2583             if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2584                 warn("Couldn't open pty slave %s: %m", pty_name);
2585         }
2586     }
2587 #endif /* TIOCGPTN */
2588
2589     if (sfd < 0) {
2590         /* the old way - scan through the pty name space */
2591         for (i = 0; i < 64; ++i) {
2592             slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2593                      'p' + i / 16, i % 16);
2594             mfd = open(pty_name, O_RDWR, 0);
2595             if (mfd >= 0) {
2596                 pty_name[5] = 't';
2597                 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2598                 if (sfd >= 0) {
2599                     fchown(sfd, uid, -1);
2600                     fchmod(sfd, S_IRUSR | S_IWUSR);
2601                     break;
2602                 }
2603                 close(mfd);
2604             }
2605         }
2606     }
2607
2608     if (sfd < 0)
2609         return 0;
2610
2611     strlcpy(slave_name, pty_name, 16);
2612     *master_fdp = mfd;
2613     *slave_fdp = sfd;
2614     if (tcgetattr(sfd, &tios) == 0) {
2615         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2616         tios.c_cflag |= CS8 | CREAD | CLOCAL;
2617         tios.c_iflag  = IGNPAR;
2618         tios.c_oflag  = 0;
2619         tios.c_lflag  = 0;
2620         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2621             warn("couldn't set attributes on pty: %m");
2622     } else
2623         warn("couldn't get attributes on pty: %m");
2624
2625     return 1;
2626 }
2627
2628 /********************************************************************
2629  *
2630  * open_loopback - open the device we use for getting packets
2631  * in demand mode.  Under Linux, we use a pty master/slave pair.
2632  */
2633 int
2634 open_ppp_loopback(void)
2635 {
2636     int flags;
2637
2638     looped = 1;
2639     if (new_style_driver) {
2640         /* allocate ourselves a ppp unit */
2641         if (make_ppp_unit() < 0)
2642             die(1);
2643         modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2644         set_kdebugflag(kdebugflag);
2645         ppp_fd = -1;
2646         return ppp_dev_fd;
2647     }
2648
2649     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2650         fatal("No free pty for loopback");
2651
2652     set_ppp_fd(slave_fd);
2653
2654     flags = fcntl(master_fd, F_GETFL);
2655     if (flags == -1 ||
2656         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2657         warn("couldn't set master loopback to nonblock: %m");
2658
2659     flags = fcntl(ppp_fd, F_GETFL);
2660     if (flags == -1 ||
2661         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2662         warn("couldn't set slave loopback to nonblock: %m");
2663
2664     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2665         fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2666 /*
2667  * Find out which interface we were given.
2668  */
2669     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2670         fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2671 /*
2672  * Enable debug in the driver if requested.
2673  */
2674     set_kdebugflag (kdebugflag);
2675
2676     return master_fd;
2677 }
2678
2679 /********************************************************************
2680  *
2681  * sifnpmode - Set the mode for handling packets for a given NP.
2682  */
2683
2684 int
2685 sifnpmode(u, proto, mode)
2686     int u;
2687     int proto;
2688     enum NPmode mode;
2689 {
2690     struct npioctl npi;
2691
2692     npi.protocol = proto;
2693     npi.mode     = mode;
2694     if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2695         if (! ok_error (errno))
2696             error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2697         return 0;
2698     }
2699     return 1;
2700 }
2701
2702 \f
2703 /********************************************************************
2704  *
2705  * sipxfaddr - Config the interface IPX networknumber
2706  */
2707
2708 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2709 {
2710     int    result = 1;
2711
2712 #ifdef IPX_CHANGE
2713     int    skfd;
2714     struct ifreq         ifr;
2715     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2716
2717     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2718     if (skfd < 0) {
2719         if (! ok_error (errno))
2720             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2721         result = 0;
2722     }
2723     else {
2724         memset (&ifr, '\0', sizeof (ifr));
2725         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2726
2727         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2728         sipx->sipx_family  = AF_IPX;
2729         sipx->sipx_port    = 0;
2730         sipx->sipx_network = htonl (network);
2731         sipx->sipx_type    = IPX_FRAME_ETHERII;
2732         sipx->sipx_action  = IPX_CRTITF;
2733 /*
2734  *  Set the IPX device
2735  */
2736         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2737             result = 0;
2738             if (errno != EEXIST) {
2739                 if (! ok_error (errno))
2740                     dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2741             }
2742             else {
2743                 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2744             }
2745         }
2746         close (skfd);
2747     }
2748 #endif
2749     return result;
2750 }
2751
2752 /********************************************************************
2753  *
2754  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2755  *             are removed and the device is no longer able to pass IPX
2756  *             frames.
2757  */
2758
2759 int cipxfaddr (int unit)
2760 {
2761     int    result = 1;
2762
2763 #ifdef IPX_CHANGE
2764     int    skfd;
2765     struct ifreq         ifr;
2766     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2767
2768     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2769     if (skfd < 0) {
2770         if (! ok_error (errno))
2771             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2772         result = 0;
2773     }
2774     else {
2775         memset (&ifr, '\0', sizeof (ifr));
2776         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2777
2778         sipx->sipx_type    = IPX_FRAME_ETHERII;
2779         sipx->sipx_action  = IPX_DLTITF;
2780         sipx->sipx_family  = AF_IPX;
2781 /*
2782  *  Set the IPX device
2783  */
2784         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2785             if (! ok_error (errno))
2786                 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2787             result = 0;
2788         }
2789         close (skfd);
2790     }
2791 #endif
2792     return result;
2793 }
2794
2795 /*
2796  * Use the hostname as part of the random number seed.
2797  */
2798 int
2799 get_host_seed()
2800 {
2801     int h;
2802     char *p = hostname;
2803
2804     h = 407;
2805     for (p = hostname; *p != 0; ++p)
2806         h = h * 37 + *p;
2807     return h;
2808 }
2809
2810 /********************************************************************
2811  *
2812  * sys_check_options - check the options that the user specified
2813  */
2814
2815 int
2816 sys_check_options(void)
2817 {
2818 #ifdef IPX_CHANGE
2819 /*
2820  * Disable the IPX protocol if the support is not present in the kernel.
2821  */
2822     char *path;
2823
2824     if (ipxcp_protent.enabled_flag) {
2825         struct stat stat_buf;
2826         if (  ((path = path_to_procfs("/net/ipx/interface")) == NULL
2827             && (path = path_to_procfs("/net/ipx_interface")) == NULL)
2828             || lstat(path, &stat_buf) < 0) {
2829             error("IPX support is not present in the kernel\n");
2830             ipxcp_protent.enabled_flag = 0;
2831         }
2832     }
2833 #endif
2834     if (demand && driver_is_old) {
2835         option_error("demand dialling is not supported by kernel driver "
2836                      "version %d.%d.%d", driver_version, driver_modification,
2837                      driver_patch);
2838         return 0;
2839     }
2840     if (multilink && !new_style_driver) {
2841         warn("Warning: multilink is not supported by the kernel driver");
2842         multilink = 0;
2843     }
2844     return 1;
2845 }
2846
2847 #ifdef INET6
2848 /*
2849  * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2850  *
2851  * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2852  * that the system has a properly configured Ethernet interface for this
2853  * function to return non-zero.
2854  */
2855 int
2856 ether_to_eui64(eui64_t *p_eui64)
2857 {
2858     struct ifreq ifr;
2859     int skfd;
2860     const unsigned char *ptr;
2861
2862     skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2863     if(skfd == -1)
2864     {
2865         warn("could not open IPv6 socket");
2866         return 0;
2867     }
2868
2869     strcpy(ifr.ifr_name, "eth0");
2870     if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2871     {
2872         close(skfd);
2873         warn("could not obtain hardware address for eth0");
2874         return 0;
2875     }
2876     close(skfd);
2877
2878     /*
2879      * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2880      */
2881     ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data;
2882     p_eui64->e8[0] = ptr[0] | 0x02;
2883     p_eui64->e8[1] = ptr[1];
2884     p_eui64->e8[2] = ptr[2];
2885     p_eui64->e8[3] = 0xFF;
2886     p_eui64->e8[4] = 0xFE;
2887     p_eui64->e8[5] = ptr[3];
2888     p_eui64->e8[6] = ptr[4];
2889     p_eui64->e8[7] = ptr[5];
2890
2891     return 1;
2892 }
2893 #endif