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