OSDN Git Service

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