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