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