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