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