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