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