]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
Make sure we don't do FD_SET(fd, set) with fd >= FD_SETSIZE since
[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 int ppp_dev_fd = -1;    /* fd for /dev/ppp (new style driver) */
187 static int chindex;             /* channel index (new style driver) */
188
189 static fd_set in_fds;           /* set of fds that wait_input waits for */
190 static int max_in_fd;           /* highest fd set in in_fds */
191
192 static int has_proxy_arp       = 0;
193 static int driver_version      = 0;
194 static int driver_modification = 0;
195 static int driver_patch        = 0;
196 static int driver_is_old       = 0;
197 static int restore_term        = 0;     /* 1 => we've munged the terminal */
198 static struct termios inittermios;      /* Initial TTY termios */
199
200 int new_style_driver = 0;
201
202 static char loop_name[20];
203 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
204
205 static int      if_is_up;       /* Interface has been marked up */
206 static u_int32_t default_route_gateway; /* Gateway for default route added */
207 static u_int32_t proxy_arp_addr;        /* Addr for proxy arp entry added */
208 static char proxy_arp_dev[16];          /* Device for proxy arp entry */
209 static u_int32_t our_old_addr;          /* for detecting address changes */
210 static int      dynaddr_set;            /* 1 if ip_dynaddr set */
211 static int      looped;                 /* 1 if using loop */
212 static int      link_mtu;               /* mtu for the link (not bundle) */
213
214 static struct utsname utsname;  /* for the kernel version */
215 static int kernel_version;
216 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
217
218 #define MAX_IFS         100
219
220 #define FLAGS_GOOD (IFF_UP          | IFF_BROADCAST)
221 #define FLAGS_MASK (IFF_UP          | IFF_BROADCAST | \
222                     IFF_POINTOPOINT | IFF_LOOPBACK  | IFF_NOARP)
223
224 #define SIN_ADDR(x)     (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
225
226 /* Prototypes for procedures local to this file. */
227 static int get_flags (int fd);
228 static void set_flags (int fd, int flags);
229 static int translate_speed (int bps);
230 static int baud_rate_of (int speed);
231 static void close_route_table (void);
232 static int open_route_table (void);
233 static int read_route_table (struct rtentry *rt);
234 static int defaultroute_exists (struct rtentry *rt);
235 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
236                            char *name, int namelen);
237 static void decode_version (char *buf, int *version, int *mod, int *patch);
238 static int set_kdebugflag(int level);
239 static int ppp_registered(void);
240 static int make_ppp_unit(void);
241
242 extern u_char   inpacket_buf[]; /* borrowed from main.c */
243
244 /*
245  * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
246  * if it exists.
247  */
248
249 #define SET_SA_FAMILY(addr, family)                     \
250     memset ((char *) &(addr), '\0', sizeof(addr));      \
251     addr.sa_family = (family);
252
253 /*
254  * Determine if the PPP connection should still be present.
255  */
256
257 extern int hungup;
258
259 /* new_fd is the fd of a tty */
260 static void set_ppp_fd (int new_fd)
261 {
262         SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
263         ppp_fd = new_fd;
264         if (!new_style_driver)
265                 ppp_dev_fd = new_fd;
266 }
267
268 static int still_ppp(void)
269 {
270         if (new_style_driver)
271                 return !hungup && ppp_fd >= 0;
272         if (!hungup || ppp_fd == slave_fd)
273                 return 1;
274         if (slave_fd >= 0) {
275                 set_ppp_fd(slave_fd);
276                 return 1;
277         }
278         return 0;
279 }
280
281 /********************************************************************
282  *
283  * Functions to read and set the flags value in the device driver
284  */
285
286 static int get_flags (int fd)
287 {
288     int flags;
289
290     if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) {
291         if ( ok_error (errno) )
292             flags = 0;
293         else
294             fatal("ioctl(PPPIOCGFLAGS): %m (line %d)", __LINE__);
295     }
296
297     SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags));
298     return flags;
299 }
300
301 /********************************************************************/
302
303 static void set_flags (int fd, int flags)
304 {
305     SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
306
307     if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
308         if (! ok_error (errno) )
309             fatal("ioctl(PPPIOCSFLAGS, %x): %m (line %d)", flags, errno, __LINE__);
310     }
311 }
312
313 /********************************************************************
314  *
315  * sys_init - System-dependent initialization.
316  */
317
318 void sys_init(void)
319 {
320     int flags;
321
322     if (new_style_driver) {
323         ppp_dev_fd = open("/dev/ppp", O_RDWR);
324         if (ppp_dev_fd < 0)
325             fatal("Couldn't open /dev/ppp: %m");
326         flags = fcntl(ppp_dev_fd, F_GETFL);
327         if (flags == -1
328             || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
329             warn("Couldn't set /dev/ppp to nonblock: %m");
330     }
331
332     /* Get an internet socket for doing socket ioctls. */
333     sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
334     if (sock_fd < 0)
335         fatal("Couldn't create IP socket: %m(%d)", errno);
336
337 #ifdef INET6
338     sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
339     if (sock6_fd < 0)
340         sock6_fd = -errno;      /* save errno for later */
341 #endif
342
343     FD_ZERO(&in_fds);
344     max_in_fd = 0;
345 }
346
347 /********************************************************************
348  *
349  * sys_cleanup - restore any system state we modified before exiting:
350  * mark the interface down, delete default route and/or proxy arp entry.
351  * This shouldn't call die() because it's called from die().
352  */
353
354 void sys_cleanup(void)
355 {
356 /*
357  * Take down the device
358  */
359     if (if_is_up) {
360         if_is_up = 0;
361         sifdown(0);
362     }
363 /*
364  * Delete any routes through the device.
365  */
366     if (default_route_gateway != 0)
367         cifdefaultroute(0, 0, default_route_gateway);
368
369     if (has_proxy_arp)
370         cifproxyarp(0, proxy_arp_addr);
371 }
372
373 /********************************************************************
374  *
375  * sys_close - Clean up in a child process before execing.
376  */
377 void
378 sys_close(void)
379 {
380     if (new_style_driver)
381         close(ppp_dev_fd);
382     if (sock_fd >= 0)
383         close(sock_fd);
384     if (slave_fd >= 0)
385         close(slave_fd);
386     if (master_fd >= 0)
387         close(master_fd);
388     closelog();
389 }
390
391 /********************************************************************
392  *
393  * set_kdebugflag - Define the debugging level for the kernel
394  */
395
396 static int set_kdebugflag (int requested_level)
397 {
398     if (new_style_driver && ifunit < 0)
399         return 1;
400     if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
401         if ( ! ok_error (errno) )
402             error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
403         return (0);
404     }
405     SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
406                 requested_level));
407     return (1);
408 }
409
410 /********************************************************************
411  *
412  * tty_establish_ppp - Turn the serial port into a ppp interface.
413  */
414
415 int tty_establish_ppp (int tty_fd)
416 {
417     int ret_fd;
418
419 /*
420  * Ensure that the tty device is in exclusive mode.
421  */
422     if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
423         if ( ! ok_error ( errno ))
424             warn("Couldn't make tty exclusive: %m");
425     }
426 /*
427  * Demand mode - prime the old ppp device to relinquish the unit.
428  */
429     if (!new_style_driver && looped
430         && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
431         error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
432         return -1;
433     }
434 /*
435  * Set the current tty to the PPP discpline
436  */
437
438 #ifndef N_SYNC_PPP
439 #define N_SYNC_PPP 14
440 #endif
441     ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
442     if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
443         if ( ! ok_error (errno) ) {
444             error("Couldn't set tty to PPP discipline: %m");
445             return -1;
446         }
447     }
448
449     ret_fd = generic_establish_ppp(tty_fd);
450
451 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
452 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
453                  | SC_LOG_FLUSH)
454
455     if (ret_fd >= 0) {
456         set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB))
457                            | ((kdebugflag * SC_DEBUG) & SC_LOGB)));
458     } else {
459         if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
460             warn("Couldn't reset tty to normal line discipline: %m");
461     }
462
463     return ret_fd;
464 }
465
466 /********************************************************************
467  *
468  * generic_establish_ppp - Turn the fd into a ppp interface.
469  */
470 int generic_establish_ppp (int fd)
471 {
472     int x;
473
474     if (new_style_driver) {
475         /* Open another instance of /dev/ppp and connect the channel to it */
476         int flags;
477
478         if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
479             error("Couldn't get channel number: %m");
480             goto err;
481         }
482         dbglog("using channel %d", chindex);
483         fd = open("/dev/ppp", O_RDWR);
484         if (fd < 0) {
485             error("Couldn't reopen /dev/ppp: %m");
486             goto err;
487         }
488         if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
489             error("Couldn't attach to channel %d: %m", chindex);
490             goto err_close;
491         }
492         flags = fcntl(fd, F_GETFL);
493         if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
494             warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
495         set_ppp_fd(fd);
496
497         if (!looped)
498             ifunit = -1;
499         if (!looped && !multilink) {
500             /*
501              * Create a new PPP unit.
502              */
503             if (make_ppp_unit() < 0)
504                 goto err_close;
505         }
506
507         if (looped)
508             set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC);
509
510         if (!multilink) {
511             add_fd(ppp_dev_fd);
512             if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
513                 error("Couldn't attach to PPP unit %d: %m", ifunit);
514                 goto err_close;
515             }
516         }
517
518     } else {
519         /*
520          * Old-style driver: find out which interface we were given.
521          */
522         set_ppp_fd (fd);
523         if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
524             if (ok_error (errno))
525                 goto err;
526             fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
527         }
528         /* Check that we got the same unit again. */
529         if (looped && x != ifunit)
530             fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
531         ifunit = x;
532
533         /*
534          * Fetch the initial file flags and reset blocking mode on the file.
535          */
536         initfdflags = fcntl(fd, F_GETFL);
537         if (initfdflags == -1 ||
538             fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
539             if ( ! ok_error (errno))
540                 warn("Couldn't set device to non-blocking mode: %m");
541         }
542     }
543
544     looped = 0;
545
546     /*
547      * Enable debug in the driver if requested.
548      */
549     if (!looped)
550         set_kdebugflag (kdebugflag);
551
552     SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
553             driver_version, driver_modification, driver_patch));
554
555     return ppp_fd;
556
557  err_close:
558     close(fd);
559  err:
560     return -1;
561 }
562
563 /********************************************************************
564  *
565  * tty_disestablish_ppp - Restore the serial port to normal operation.
566  * This shouldn't call die() because it's called from die().
567  */
568
569 void tty_disestablish_ppp(int tty_fd)
570 {
571     if (!hungup) {
572 /*
573  * Flush the tty output buffer so that the TIOCSETD doesn't hang.
574  */
575         if (tcflush(tty_fd, TCIOFLUSH) < 0)
576         {
577             warn("tcflush failed: %m");
578             goto flushfailed;
579         }
580 /*
581  * Restore the previous line discipline
582  */
583         if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
584             if ( ! ok_error (errno))
585                 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
586         }
587
588         if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
589             if ( ! ok_error (errno))
590                 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
591         }
592
593         /* Reset non-blocking mode on fd. */
594         if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
595             if ( ! ok_error (errno))
596                 warn("Couldn't restore device fd flags: %m");
597         }
598     }
599 flushfailed:
600     initfdflags = -1;
601
602     generic_disestablish_ppp(tty_fd);
603 }
604
605 /********************************************************************
606  *
607  * generic_disestablish_ppp - Restore device components to normal
608  * operation, and reconnect the ppp unit to the loopback if in demand
609  * mode.  This shouldn't call die() because it's called from die().
610  */
611 void generic_disestablish_ppp(int dev_fd)
612 {
613     if (new_style_driver) {
614         close(ppp_fd);
615         ppp_fd = -1;
616         if (demand) {
617             set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC);
618             looped = 1;
619         } else if (ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
620             error("Couldn't release PPP unit: %m");
621         if (!multilink)
622             remove_fd(ppp_dev_fd);
623     } else {
624         /* old-style driver */
625         if (demand)
626             set_ppp_fd(slave_fd);
627     }
628 }
629
630 /*
631  * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
632  * Assumes new_style_driver.
633  */
634 static int make_ppp_unit()
635 {
636         int x;
637
638         ifunit = req_unit;
639         x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
640         if (x < 0 && req_unit >= 0 && errno == EEXIST) {
641                 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
642                 ifunit = -1;
643                 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
644         }
645         if (x < 0)
646                 error("Couldn't create new ppp unit: %m");
647         return x;
648 }
649
650 /*
651  * cfg_bundle - configure the existing bundle.
652  * Used in demand mode.
653  */
654 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
655 {
656         int flags;
657
658         if (!new_style_driver)
659                 return;
660
661         /* set the mrru, mtu and flags */
662         if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
663                 error("Couldn't set MRRU: %m");
664         flags = get_flags(ppp_dev_fd);
665         flags &= ~(SC_MP_SHORTSEQ | SC_MP_XSHORTSEQ);
666         flags |= (rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
667                 | (mrru? SC_MULTILINK: 0);
668
669         set_flags(ppp_dev_fd, flags);
670
671         /* connect up the channel */
672         if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
673                 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
674         add_fd(ppp_dev_fd);
675 }
676
677 /*
678  * make_new_bundle - create a new PPP unit (i.e. a bundle)
679  * and connect our channel to it.  This should only get called
680  * if `multilink' was set at the time establish_ppp was called.
681  * In demand mode this uses our existing bundle instead of making
682  * a new one.
683  */
684 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
685 {
686         if (!new_style_driver)
687                 return;
688
689         /* make us a ppp unit */
690         if (make_ppp_unit() < 0)
691                 die(1);
692
693         /* set the mrru and flags */
694         cfg_bundle(mrru, mtru, rssn, tssn);
695 }
696
697 /*
698  * bundle_attach - attach our link to a given PPP unit.
699  * We assume the unit is controlled by another pppd.
700  */
701 int bundle_attach(int ifnum)
702 {
703         if (!new_style_driver)
704                 return -1;
705
706         if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) {
707                 if (errno == ENXIO)
708                         return 0;       /* doesn't still exist */
709                 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
710         }
711         if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
712                 fatal("Couldn't connect to interface unit %d: %m", ifnum);
713         set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK);
714
715         ifunit = ifnum;
716         return 1;
717 }
718
719 /********************************************************************
720  *
721  * clean_check - Fetch the flags for the device and generate
722  * appropriate error messages.
723  */
724 void clean_check(void)
725 {
726     int x;
727     char *s;
728
729     if (still_ppp()) {
730         if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
731             s = NULL;
732             switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
733             case SC_RCV_B7_0:
734                 s = "all had bit 7 set to 1";
735                 break;
736
737             case SC_RCV_B7_1:
738                 s = "all had bit 7 set to 0";
739                 break;
740
741             case SC_RCV_EVNP:
742                 s = "all had odd parity";
743                 break;
744
745             case SC_RCV_ODDP:
746                 s = "all had even parity";
747                 break;
748             }
749
750             if (s != NULL) {
751                 warn("Receive serial link is not 8-bit clean:");
752                 warn("Problem: %s", s);
753             }
754         }
755     }
756 }
757
758
759 /*
760  * List of valid speeds.
761  */
762
763 struct speed {
764     int speed_int, speed_val;
765 } speeds[] = {
766 #ifdef B50
767     { 50, B50 },
768 #endif
769 #ifdef B75
770     { 75, B75 },
771 #endif
772 #ifdef B110
773     { 110, B110 },
774 #endif
775 #ifdef B134
776     { 134, B134 },
777 #endif
778 #ifdef B150
779     { 150, B150 },
780 #endif
781 #ifdef B200
782     { 200, B200 },
783 #endif
784 #ifdef B300
785     { 300, B300 },
786 #endif
787 #ifdef B600
788     { 600, B600 },
789 #endif
790 #ifdef B1200
791     { 1200, B1200 },
792 #endif
793 #ifdef B1800
794     { 1800, B1800 },
795 #endif
796 #ifdef B2000
797     { 2000, B2000 },
798 #endif
799 #ifdef B2400
800     { 2400, B2400 },
801 #endif
802 #ifdef B3600
803     { 3600, B3600 },
804 #endif
805 #ifdef B4800
806     { 4800, B4800 },
807 #endif
808 #ifdef B7200
809     { 7200, B7200 },
810 #endif
811 #ifdef B9600
812     { 9600, B9600 },
813 #endif
814 #ifdef B19200
815     { 19200, B19200 },
816 #endif
817 #ifdef B38400
818     { 38400, B38400 },
819 #endif
820 #ifdef B57600
821     { 57600, B57600 },
822 #endif
823 #ifdef B76800
824     { 76800, B76800 },
825 #endif
826 #ifdef B115200
827     { 115200, B115200 },
828 #endif
829 #ifdef EXTA
830     { 19200, EXTA },
831 #endif
832 #ifdef EXTB
833     { 38400, EXTB },
834 #endif
835 #ifdef B230400
836     { 230400, B230400 },
837 #endif
838 #ifdef B460800
839     { 460800, B460800 },
840 #endif
841 #ifdef B921600
842     { 921600, B921600 },
843 #endif
844     { 0, 0 }
845 };
846
847 /********************************************************************
848  *
849  * Translate from bits/second to a speed_t.
850  */
851
852 static int translate_speed (int bps)
853 {
854     struct speed *speedp;
855
856     if (bps != 0) {
857         for (speedp = speeds; speedp->speed_int; speedp++) {
858             if (bps == speedp->speed_int)
859                 return speedp->speed_val;
860         }
861         warn("speed %d not supported", bps);
862     }
863     return 0;
864 }
865
866 /********************************************************************
867  *
868  * Translate from a speed_t to bits/second.
869  */
870
871 static int baud_rate_of (int speed)
872 {
873     struct speed *speedp;
874
875     if (speed != 0) {
876         for (speedp = speeds; speedp->speed_int; speedp++) {
877             if (speed == speedp->speed_val)
878                 return speedp->speed_int;
879         }
880     }
881     return 0;
882 }
883
884 /********************************************************************
885  *
886  * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
887  * at the requested speed, etc.  If `local' is true, set CLOCAL
888  * regardless of whether the modem option was specified.
889  */
890
891 void set_up_tty(int tty_fd, int local)
892 {
893     int speed;
894     struct termios tios;
895
896     setdtr(tty_fd, 1);
897     if (tcgetattr(tty_fd, &tios) < 0) {
898         if (!ok_error(errno))
899             fatal("tcgetattr: %m (line %d)", __LINE__);
900         return;
901     }
902
903     if (!restore_term)
904         inittermios = tios;
905
906     tios.c_cflag     &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
907     tios.c_cflag     |= CS8 | CREAD | HUPCL;
908
909     tios.c_iflag      = IGNBRK | IGNPAR;
910     tios.c_oflag      = 0;
911     tios.c_lflag      = 0;
912     tios.c_cc[VMIN]   = 1;
913     tios.c_cc[VTIME]  = 0;
914
915     if (local || !modem)
916         tios.c_cflag ^= (CLOCAL | HUPCL);
917
918     switch (crtscts) {
919     case 1:
920         tios.c_cflag |= CRTSCTS;
921         break;
922
923     case -2:
924         tios.c_iflag     |= IXON | IXOFF;
925         tios.c_cc[VSTOP]  = 0x13;       /* DC3 = XOFF = ^S */
926         tios.c_cc[VSTART] = 0x11;       /* DC1 = XON  = ^Q */
927         break;
928
929     case -1:
930         tios.c_cflag &= ~CRTSCTS;
931         break;
932
933     default:
934         break;
935     }
936
937     speed = translate_speed(inspeed);
938     if (speed) {
939         cfsetospeed (&tios, speed);
940         cfsetispeed (&tios, speed);
941     }
942 /*
943  * We can't proceed if the serial port speed is B0,
944  * since that implies that the serial port is disabled.
945  */
946     else {
947         speed = cfgetospeed(&tios);
948         if (speed == B0)
949             fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
950     }
951
952     if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0)
953         if (!ok_error(errno))
954             fatal("tcsetattr: %m (line %d)", __LINE__);
955
956     baud_rate    = baud_rate_of(speed);
957     restore_term = 1;
958 }
959
960 /********************************************************************
961  *
962  * setdtr - control the DTR line on the serial port.
963  * This is called from die(), so it shouldn't call die().
964  */
965
966 void setdtr (int tty_fd, int on)
967 {
968     int modembits = TIOCM_DTR;
969
970     ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
971 }
972
973 /********************************************************************
974  *
975  * restore_tty - restore the terminal to the saved settings.
976  */
977
978 void restore_tty (int tty_fd)
979 {
980     if (restore_term) {
981         restore_term = 0;
982 /*
983  * Turn off echoing, because otherwise we can get into
984  * a loop with the tty and the modem echoing to each other.
985  * We presume we are the sole user of this tty device, so
986  * when we close it, it will revert to its defaults anyway.
987  */
988         if (!default_device)
989             inittermios.c_lflag &= ~(ECHO | ECHONL);
990
991         if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
992             if (! ok_error (errno))
993                 warn("tcsetattr: %m (line %d)", __LINE__);
994         }
995     }
996 }
997
998 /********************************************************************
999  *
1000  * output - Output PPP packet.
1001  */
1002
1003 void output (int unit, unsigned char *p, int len)
1004 {
1005     int fd = ppp_fd;
1006     int proto;
1007
1008     dump_packet("sent", p, len);
1009     if (snoop_send_hook) snoop_send_hook(p, len);
1010
1011     if (len < PPP_HDRLEN)
1012         return;
1013     if (new_style_driver) {
1014         p += 2;
1015         len -= 2;
1016         proto = (p[0] << 8) + p[1];
1017         if (ifunit >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1018             fd = ppp_dev_fd;
1019     }
1020     if (write(fd, p, len) < 0) {
1021         if (errno == EWOULDBLOCK || errno == ENOBUFS
1022             || errno == ENXIO || errno == EIO || errno == EINTR)
1023             warn("write: warning: %m (%d)", errno);
1024         else
1025             error("write: %m (%d)", errno);
1026     }
1027 }
1028
1029 /********************************************************************
1030  *
1031  * wait_input - wait until there is data available,
1032  * for the length of time specified by *timo (indefinite
1033  * if timo is NULL).
1034  */
1035
1036 void wait_input(struct timeval *timo)
1037 {
1038     fd_set ready, exc;
1039     int n;
1040
1041     ready = in_fds;
1042     exc = in_fds;
1043     n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1044     if (n < 0 && errno != EINTR)
1045         fatal("select: %m");
1046 }
1047
1048 /*
1049  * add_fd - add an fd to the set that wait_input waits for.
1050  */
1051 void add_fd(int fd)
1052 {
1053     if (fd >= FD_SETSIZE)
1054         fatal("internal error: file descriptor too large (%d)", fd);
1055     FD_SET(fd, &in_fds);
1056     if (fd > max_in_fd)
1057         max_in_fd = fd;
1058 }
1059
1060 /*
1061  * remove_fd - remove an fd from the set that wait_input waits for.
1062  */
1063 void remove_fd(int fd)
1064 {
1065     FD_CLR(fd, &in_fds);
1066 }
1067
1068
1069 /********************************************************************
1070  *
1071  * read_packet - get a PPP packet from the serial device.
1072  */
1073
1074 int read_packet (unsigned char *buf)
1075 {
1076     int len, nr;
1077
1078     len = PPP_MRU + PPP_HDRLEN;
1079     if (new_style_driver) {
1080         *buf++ = PPP_ALLSTATIONS;
1081         *buf++ = PPP_UI;
1082         len -= 2;
1083     }
1084     nr = -1;
1085     if (ppp_fd >= 0) {
1086         nr = read(ppp_fd, buf, len);
1087         if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
1088             error("read: %m");
1089         if (nr < 0 && errno == ENXIO)
1090             return 0;
1091     }
1092     if (nr < 0 && new_style_driver && ifunit >= 0) {
1093         /* N.B. we read ppp_fd first since LCP packets come in there. */
1094         nr = read(ppp_dev_fd, buf, len);
1095         if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
1096             error("read /dev/ppp: %m");
1097         if (nr < 0 && errno == ENXIO)
1098             return 0;
1099     }
1100     return (new_style_driver && nr > 0)? nr+2: nr;
1101 }
1102
1103 /********************************************************************
1104  *
1105  * get_loop_output - get outgoing packets from the ppp device,
1106  * and detect when we want to bring the real link up.
1107  * Return value is 1 if we need to bring up the link, 0 otherwise.
1108  */
1109 int
1110 get_loop_output(void)
1111 {
1112     int rv = 0;
1113     int n;
1114
1115     if (new_style_driver) {
1116         while ((n = read_packet(inpacket_buf)) > 0)
1117             if (loop_frame(inpacket_buf, n))
1118                 rv = 1;
1119         return rv;
1120     }
1121
1122     while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1123         if (loop_chars(inbuf, n))
1124             rv = 1;
1125
1126     if (n == 0)
1127         fatal("eof on loopback");
1128
1129     if (errno != EWOULDBLOCK)
1130         fatal("read from loopback: %m(%d)", errno);
1131
1132     return rv;
1133 }
1134
1135 /*
1136  * netif_set_mtu - set the MTU on the PPP network interface.
1137  */
1138 void
1139 netif_set_mtu(int unit, int mtu)
1140 {
1141     struct ifreq ifr;
1142
1143     SYSDEBUG ((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu));
1144
1145     memset (&ifr, '\0', sizeof (ifr));
1146     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1147     ifr.ifr_mtu = mtu;
1148
1149     if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1150         error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1151 }
1152
1153 /*
1154  * netif_get_mtu - get the MTU on the PPP network interface.
1155  */
1156 int
1157 netif_get_mtu(int unit)
1158 {
1159     struct ifreq ifr;
1160
1161     memset (&ifr, '\0', sizeof (ifr));
1162     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1163
1164     if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1165         error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1166         return 0;
1167     }
1168     return ifr.ifr_mtu;
1169 }
1170
1171 /********************************************************************
1172  *
1173  * tty_send_config - configure the transmit characteristics of
1174  * the ppp interface.
1175  */
1176
1177 void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
1178 {
1179     u_int x;
1180
1181 /*
1182  * Set the asyncmap and other parameters for the ppp device
1183  */
1184     if (!still_ppp())
1185         return;
1186     link_mtu = mtu;
1187     SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
1188     if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1189         if (!ok_error(errno))
1190             fatal("ioctl(PPPIOCSASYNCMAP): %m (line %d)", __LINE__);
1191         return;
1192     }
1193
1194     x = get_flags(ppp_fd);
1195     x = pcomp  ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
1196     x = accomp ? x | SC_COMP_AC   : x & ~SC_COMP_AC;
1197     x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
1198     set_flags(ppp_fd, x);
1199 }
1200
1201 /********************************************************************
1202  *
1203  * tty_set_xaccm - set the extended transmit ACCM for the interface.
1204  */
1205
1206 void tty_set_xaccm (ext_accm accm)
1207 {
1208     SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
1209                 accm[0], accm[1], accm[2], accm[3]));
1210
1211     if (!still_ppp())
1212         return;
1213     if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1214         if ( ! ok_error (errno))
1215             warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1216     }
1217 }
1218
1219 /********************************************************************
1220  *
1221  * tty_recv_config - configure the receive-side characteristics of
1222  * the ppp interface.
1223  */
1224
1225 void tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp)
1226 {
1227     SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
1228 /*
1229  * If we were called because the link has gone down then there is nothing
1230  * which may be done. Just return without incident.
1231  */
1232     if (!still_ppp())
1233         return;
1234 /*
1235  * Set the receiver parameters
1236  */
1237     if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1238         if ( ! ok_error (errno))
1239             error("ioctl(PPPIOCSMRU): %m (line %d)", __LINE__);
1240     }
1241     if (new_style_driver && ifunit >= 0
1242         && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1243         error("Couldn't set MRU in generic PPP layer: %m");
1244
1245     SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
1246     if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1247         if (!ok_error(errno))
1248             error("ioctl(PPPIOCSRASYNCMAP): %m (line %d)", __LINE__);
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     if (still_ppp() && ifunit >= 0) {
1282         int x = get_flags(ppp_dev_fd);
1283         x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;
1284         x = isup?   x | SC_CCP_UP   : x &~ SC_CCP_UP;
1285         set_flags (ppp_dev_fd, x);
1286     }
1287 }
1288
1289 #ifdef PPP_FILTER
1290 /*
1291  * set_filters - set the active and pass filters in the kernel driver.
1292  */
1293 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1294 {
1295         struct sock_fprog fp;
1296
1297         fp.len = pass->bf_len;
1298         fp.filter = (struct sock_filter *) pass->bf_insns;
1299         if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1300                 if (errno == ENOTTY)
1301                         warn("kernel does not support PPP filtering");
1302                 else
1303                         error("Couldn't set pass-filter in kernel: %m");
1304                 return 0;
1305         }
1306         fp.len = active->bf_len;
1307         fp.filter = (struct sock_filter *) active->bf_insns;
1308         if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1309                 error("Couldn't set active-filter in kernel: %m");
1310                 return 0;
1311         }
1312         return 1;
1313 }
1314 #endif /* PPP_FILTER */
1315
1316 /********************************************************************
1317  *
1318  * get_idle_time - return how long the link has been idle.
1319  */
1320 int
1321 get_idle_time(u, ip)
1322     int u;
1323     struct ppp_idle *ip;
1324 {
1325     return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1326 }
1327
1328 /********************************************************************
1329  *
1330  * get_ppp_stats - return statistics for the link.
1331  */
1332 int
1333 get_ppp_stats(u, stats)
1334     int u;
1335     struct pppd_stats *stats;
1336 {
1337     struct ifpppstatsreq req;
1338
1339     memset (&req, 0, sizeof (req));
1340
1341     req.stats_ptr = (caddr_t) &req.stats;
1342     strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1343     if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1344         error("Couldn't get PPP statistics: %m");
1345         return 0;
1346     }
1347     stats->bytes_in = req.stats.p.ppp_ibytes;
1348     stats->bytes_out = req.stats.p.ppp_obytes;
1349     stats->pkts_in = req.stats.p.ppp_ipackets;
1350     stats->pkts_out = req.stats.p.ppp_opackets;
1351     return 1;
1352 }
1353
1354 /********************************************************************
1355  *
1356  * ccp_fatal_error - returns 1 if decompression was disabled as a
1357  * result of an error detected after decompression of a packet,
1358  * 0 otherwise.  This is necessary because of patent nonsense.
1359  */
1360
1361 int ccp_fatal_error (int unit)
1362 {
1363     int x = get_flags(ppp_dev_fd);
1364
1365     return x & SC_DC_FERROR;
1366 }
1367
1368 /********************************************************************
1369  *
1370  * path_to_procfs - find the path to the proc file system mount point
1371  */
1372 static char proc_path[MAXPATHLEN];
1373 static int proc_path_len;
1374
1375 static char *path_to_procfs(const char *tail)
1376 {
1377     struct mntent *mntent;
1378     FILE *fp;
1379
1380     if (proc_path_len == 0) {
1381         /* Default the mount location of /proc */
1382         strlcpy (proc_path, "/proc", sizeof(proc_path));
1383         proc_path_len = 5;
1384         fp = fopen(MOUNTED, "r");
1385         if (fp != NULL) {
1386             while ((mntent = getmntent(fp)) != NULL) {
1387                 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1388                     continue;
1389                 if (strcmp(mntent->mnt_type, "proc") == 0) {
1390                     strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1391                     proc_path_len = strlen(proc_path);
1392                     break;
1393                 }
1394             }
1395             fclose (fp);
1396         }
1397     }
1398
1399     strlcpy(proc_path + proc_path_len, tail,
1400             sizeof(proc_path) - proc_path_len);
1401     return proc_path;
1402 }
1403
1404 /*
1405  * /proc/net/route parsing stuff.
1406  */
1407 #define ROUTE_MAX_COLS  12
1408 FILE *route_fd = (FILE *) 0;
1409 static char route_buffer[512];
1410 static int route_dev_col, route_dest_col, route_gw_col;
1411 static int route_flags_col, route_mask_col;
1412 static int route_num_cols;
1413
1414 static int open_route_table (void);
1415 static void close_route_table (void);
1416 static int read_route_table (struct rtentry *rt);
1417
1418 /********************************************************************
1419  *
1420  * close_route_table - close the interface to the route table
1421  */
1422
1423 static void close_route_table (void)
1424 {
1425     if (route_fd != (FILE *) 0) {
1426         fclose (route_fd);
1427         route_fd = (FILE *) 0;
1428     }
1429 }
1430
1431 /********************************************************************
1432  *
1433  * open_route_table - open the interface to the route table
1434  */
1435 static char route_delims[] = " \t\n";
1436
1437 static int open_route_table (void)
1438 {
1439     char *path;
1440
1441     close_route_table();
1442
1443     path = path_to_procfs("/net/route");
1444     route_fd = fopen (path, "r");
1445     if (route_fd == NULL) {
1446         error("can't open routing table %s: %m", path);
1447         return 0;
1448     }
1449
1450     route_dev_col = 0;          /* default to usual columns */
1451     route_dest_col = 1;
1452     route_gw_col = 2;
1453     route_flags_col = 3;
1454     route_mask_col = 7;
1455     route_num_cols = 8;
1456
1457     /* parse header line */
1458     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1459         char *p = route_buffer, *q;
1460         int col;
1461         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1462             int used = 1;
1463             if ((q = strtok(p, route_delims)) == 0)
1464                 break;
1465             if (strcasecmp(q, "iface") == 0)
1466                 route_dev_col = col;
1467             else if (strcasecmp(q, "destination") == 0)
1468                 route_dest_col = col;
1469             else if (strcasecmp(q, "gateway") == 0)
1470                 route_gw_col = col;
1471             else if (strcasecmp(q, "flags") == 0)
1472                 route_flags_col = col;
1473             else if (strcasecmp(q, "mask") == 0)
1474                 route_mask_col = col;
1475             else
1476                 used = 0;
1477             if (used && col >= route_num_cols)
1478                 route_num_cols = col + 1;
1479             p = NULL;
1480         }
1481     }
1482
1483     return 1;
1484 }
1485
1486 /********************************************************************
1487  *
1488  * read_route_table - read the next entry from the route table
1489  */
1490
1491 static int read_route_table(struct rtentry *rt)
1492 {
1493     char *cols[ROUTE_MAX_COLS], *p;
1494     int col;
1495
1496     memset (rt, '\0', sizeof (struct rtentry));
1497
1498     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1499         return 0;
1500
1501     p = route_buffer;
1502     for (col = 0; col < route_num_cols; ++col) {
1503         cols[col] = strtok(p, route_delims);
1504         if (cols[col] == NULL)
1505             return 0;           /* didn't get enough columns */
1506         p = NULL;
1507     }
1508
1509     SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1510     SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1511     SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1512
1513     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1514     rt->rt_dev   = cols[route_dev_col];
1515
1516     return 1;
1517 }
1518
1519 /********************************************************************
1520  *
1521  * defaultroute_exists - determine if there is a default route
1522  */
1523
1524 static int defaultroute_exists (struct rtentry *rt)
1525 {
1526     int result = 0;
1527
1528     if (!open_route_table())
1529         return 0;
1530
1531     while (read_route_table(rt) != 0) {
1532         if ((rt->rt_flags & RTF_UP) == 0)
1533             continue;
1534
1535         if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1536             continue;
1537         if (SIN_ADDR(rt->rt_dst) == 0L) {
1538             result = 1;
1539             break;
1540         }
1541     }
1542
1543     close_route_table();
1544     return result;
1545 }
1546
1547 /*
1548  * have_route_to - determine if the system has any route to
1549  * a given IP address.  `addr' is in network byte order.
1550  * Return value is 1 if yes, 0 if no, -1 if don't know.
1551  * For demand mode to work properly, we have to ignore routes
1552  * through our own interface.
1553  */
1554 int have_route_to(u_int32_t addr)
1555 {
1556     struct rtentry rt;
1557     int result = 0;
1558
1559     if (!open_route_table())
1560         return -1;              /* don't know */
1561
1562     while (read_route_table(&rt)) {
1563         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1564             continue;
1565         if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1566             result = 1;
1567             break;
1568         }
1569     }
1570
1571     close_route_table();
1572     return result;
1573 }
1574
1575 /********************************************************************
1576  *
1577  * sifdefaultroute - assign a default route through the address given.
1578  */
1579
1580 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1581 {
1582     struct rtentry rt;
1583
1584     if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1585         u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1586
1587         if (old_gateway != gateway)
1588             error("not replacing existing default route to %s [%I]",
1589                   rt.rt_dev, old_gateway);
1590         return 0;
1591     }
1592
1593     memset (&rt, '\0', sizeof (rt));
1594     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1595     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1596
1597     rt.rt_dev = ifname;
1598
1599     if (kernel_version > KVERSION(2,1,0)) {
1600         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1601         SIN_ADDR(rt.rt_genmask) = 0L;
1602     }
1603
1604     SIN_ADDR(rt.rt_gateway) = gateway;
1605
1606     rt.rt_flags = RTF_UP | RTF_GATEWAY;
1607     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1608         if ( ! ok_error ( errno ))
1609             error("default route ioctl(SIOCADDRT): %m");
1610         return 0;
1611     }
1612
1613     default_route_gateway = gateway;
1614     return 1;
1615 }
1616
1617 /********************************************************************
1618  *
1619  * cifdefaultroute - delete a default route through the address given.
1620  */
1621
1622 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1623 {
1624     struct rtentry rt;
1625
1626     default_route_gateway = 0;
1627
1628     memset (&rt, '\0', sizeof (rt));
1629     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1630     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1631
1632     if (kernel_version > KVERSION(2,1,0)) {
1633         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1634         SIN_ADDR(rt.rt_genmask) = 0L;
1635     }
1636
1637     SIN_ADDR(rt.rt_gateway) = gateway;
1638
1639     rt.rt_flags = RTF_UP | RTF_GATEWAY;
1640     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1641         if (still_ppp()) {
1642             if ( ! ok_error ( errno ))
1643                 error("default route ioctl(SIOCDELRT): %m");
1644             return 0;
1645         }
1646     }
1647
1648     return 1;
1649 }
1650
1651 /********************************************************************
1652  *
1653  * sifproxyarp - Make a proxy ARP entry for the peer.
1654  */
1655
1656 int sifproxyarp (int unit, u_int32_t his_adr)
1657 {
1658     struct arpreq arpreq;
1659     char *forw_path;
1660
1661     if (has_proxy_arp == 0) {
1662         memset (&arpreq, '\0', sizeof(arpreq));
1663
1664         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1665         SIN_ADDR(arpreq.arp_pa) = his_adr;
1666         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1667 /*
1668  * Get the hardware address of an interface on the same subnet
1669  * as our local address.
1670  */
1671         if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1672                             sizeof(proxy_arp_dev))) {
1673             error("Cannot determine ethernet address for proxy ARP");
1674             return 0;
1675         }
1676         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1677
1678         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1679             if ( ! ok_error ( errno ))
1680                 error("ioctl(SIOCSARP): %m");
1681             return 0;
1682         }
1683         proxy_arp_addr = his_adr;
1684         has_proxy_arp = 1;
1685
1686         if (tune_kernel) {
1687             forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1688             if (forw_path != 0) {
1689                 int fd = open(forw_path, O_WRONLY);
1690                 if (fd >= 0) {
1691                     if (write(fd, "1", 1) != 1)
1692                         error("Couldn't enable IP forwarding: %m");
1693                     close(fd);
1694                 }
1695             }
1696         }
1697     }
1698
1699     return 1;
1700 }
1701
1702 /********************************************************************
1703  *
1704  * cifproxyarp - Delete the proxy ARP entry for the peer.
1705  */
1706
1707 int cifproxyarp (int unit, u_int32_t his_adr)
1708 {
1709     struct arpreq arpreq;
1710
1711     if (has_proxy_arp) {
1712         has_proxy_arp = 0;
1713         memset (&arpreq, '\0', sizeof(arpreq));
1714         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1715         SIN_ADDR(arpreq.arp_pa) = his_adr;
1716         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1717         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1718
1719         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1720             if ( ! ok_error ( errno ))
1721                 warn("ioctl(SIOCDARP): %m");
1722             return 0;
1723         }
1724     }
1725     return 1;
1726 }
1727
1728 /********************************************************************
1729  *
1730  * get_ether_addr - get the hardware address of an interface on the
1731  * the same subnet as ipaddr.
1732  */
1733
1734 static int get_ether_addr (u_int32_t ipaddr,
1735                            struct sockaddr *hwaddr,
1736                            char *name, int namelen)
1737 {
1738     struct ifreq *ifr, *ifend;
1739     u_int32_t ina, mask;
1740     char *aliasp;
1741     struct ifreq ifreq, bestifreq;
1742     struct ifconf ifc;
1743     struct ifreq ifs[MAX_IFS];
1744
1745     u_int32_t bestmask=0;
1746     int found_interface = 0;
1747
1748     ifc.ifc_len = sizeof(ifs);
1749     ifc.ifc_req = ifs;
1750     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1751         if ( ! ok_error ( errno ))
1752             error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1753         return 0;
1754     }
1755
1756     SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1757                 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1758 /*
1759  * Scan through looking for an interface with an Internet
1760  * address on the same subnet as `ipaddr'.
1761  */
1762     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1763     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1764         if (ifr->ifr_addr.sa_family == AF_INET) {
1765             ina = SIN_ADDR(ifr->ifr_addr);
1766             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1767             SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1768                         ifreq.ifr_name));
1769 /*
1770  * Check that the interface is up, and not point-to-point
1771  * nor loopback.
1772  */
1773             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1774                 continue;
1775
1776             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1777                 continue;
1778 /*
1779  * Get its netmask and check that it's on the right subnet.
1780  */
1781             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1782                 continue;
1783
1784             mask = SIN_ADDR(ifreq.ifr_addr);
1785             SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1786                        ip_ntoa(ina), ntohl(mask)));
1787
1788             if (((ipaddr ^ ina) & mask) != 0)
1789                 continue; /* no match */
1790             /* matched */
1791             if (mask >= bestmask) {
1792                 /* Compare using >= instead of > -- it is possible for
1793                    an interface to have a netmask of 0.0.0.0 */
1794                 found_interface = 1;
1795                 bestifreq = ifreq;
1796                 bestmask = mask;
1797             }
1798         }
1799     }
1800
1801     if (!found_interface) return 0;
1802
1803     strlcpy(name, bestifreq.ifr_name, namelen);
1804
1805     /* trim off the :1 in eth0:1 */
1806     aliasp = strchr(name, ':');
1807     if (aliasp != 0)
1808         *aliasp = 0;
1809
1810     info("found interface %s for proxy arp", name);
1811 /*
1812  * Now get the hardware address.
1813  */
1814     memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1815     if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1816         error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1817         return 0;
1818     }
1819
1820     memcpy (hwaddr,
1821             &bestifreq.ifr_hwaddr,
1822             sizeof (struct sockaddr));
1823
1824     SYSDEBUG ((LOG_DEBUG,
1825            "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1826                 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1827                 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1828                 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1829                 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1830                 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1831                 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1832                 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1833                 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1834     return 1;
1835 }
1836
1837 /*
1838  * get_if_hwaddr - get the hardware address for the specified
1839  * network interface device.
1840  */
1841 int
1842 get_if_hwaddr(u_char *addr, char *name)
1843 {
1844         struct ifreq ifreq;
1845         int ret, sock_fd;
1846
1847         sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1848         if (sock_fd < 0)
1849                 return 0;
1850         memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1851         strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1852         ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1853         close(sock_fd);
1854         if (ret >= 0)
1855                 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1856         return ret;
1857 }
1858
1859 /*
1860  * get_first_ethernet - return the name of the first ethernet-style
1861  * interface on this system.
1862  */
1863 char *
1864 get_first_ethernet()
1865 {
1866         return "eth0";
1867 }
1868
1869 /********************************************************************
1870  *
1871  * Return user specified netmask, modified by any mask we might determine
1872  * for address `addr' (in network byte order).
1873  * Here we scan through the system's list of interfaces, looking for
1874  * any non-point-to-point interfaces which might appear to be on the same
1875  * network as `addr'.  If we find any, we OR in their netmask to the
1876  * user-specified netmask.
1877  */
1878
1879 u_int32_t GetMask (u_int32_t addr)
1880 {
1881     u_int32_t mask, nmask, ina;
1882     struct ifreq *ifr, *ifend, ifreq;
1883     struct ifconf ifc;
1884     struct ifreq ifs[MAX_IFS];
1885
1886     addr = ntohl(addr);
1887
1888     if (IN_CLASSA(addr))        /* determine network mask for address class */
1889         nmask = IN_CLASSA_NET;
1890     else if (IN_CLASSB(addr))
1891             nmask = IN_CLASSB_NET;
1892     else
1893             nmask = IN_CLASSC_NET;
1894
1895     /* class D nets are disallowed by bad_ip_adrs */
1896     mask = netmask | htonl(nmask);
1897 /*
1898  * Scan through the system's network interfaces.
1899  */
1900     ifc.ifc_len = sizeof(ifs);
1901     ifc.ifc_req = ifs;
1902     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1903         if ( ! ok_error ( errno ))
1904             warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1905         return mask;
1906     }
1907
1908     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1909     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1910 /*
1911  * Check the interface's internet address.
1912  */
1913         if (ifr->ifr_addr.sa_family != AF_INET)
1914             continue;
1915         ina = SIN_ADDR(ifr->ifr_addr);
1916         if (((ntohl(ina) ^ addr) & nmask) != 0)
1917             continue;
1918 /*
1919  * Check that the interface is up, and not point-to-point nor loopback.
1920  */
1921         strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1922         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1923             continue;
1924
1925         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1926             continue;
1927 /*
1928  * Get its netmask and OR it into our mask.
1929  */
1930         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1931             continue;
1932         mask |= SIN_ADDR(ifreq.ifr_addr);
1933         break;
1934     }
1935     return mask;
1936 }
1937
1938 /********************************************************************
1939  *
1940  * Internal routine to decode the version.modification.patch level
1941  */
1942
1943 static void decode_version (char *buf, int *version,
1944                             int *modification, int *patch)
1945 {
1946     char *endp;
1947
1948     *version      = (int) strtoul (buf, &endp, 10);
1949     *modification = 0;
1950     *patch        = 0;
1951
1952     if (endp != buf && *endp == '.') {
1953         buf = endp + 1;
1954         *modification = (int) strtoul (buf, &endp, 10);
1955         if (endp != buf && *endp == '.') {
1956             buf = endp + 1;
1957             *patch = (int) strtoul (buf, &buf, 10);
1958         }
1959     }
1960 }
1961
1962 /********************************************************************
1963  *
1964  * Procedure to determine if the PPP line discipline is registered.
1965  */
1966
1967 static int
1968 ppp_registered(void)
1969 {
1970     int local_fd;
1971     int mfd = -1;
1972     int ret = 0;
1973     char slave[16];
1974
1975     /*
1976      * We used to open the serial device and set it to the ppp line
1977      * discipline here, in order to create a ppp unit.  But that is
1978      * not a good idea - the user might have specified a device that
1979      * they can't open (permission, or maybe it doesn't really exist).
1980      * So we grab a pty master/slave pair and use that.
1981      */
1982     if (!get_pty(&mfd, &local_fd, slave, 0)) {
1983         no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1984         return 0;
1985     }
1986
1987     /*
1988      * Try to put the device into the PPP discipline.
1989      */
1990     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1991         error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
1992     } else
1993         ret = 1;
1994
1995     close(local_fd);
1996     close(mfd);
1997     return ret;
1998 }
1999
2000 /********************************************************************
2001  *
2002  * ppp_available - check whether the system has any ppp interfaces
2003  * (in fact we check whether we can do an ioctl on ppp0).
2004  */
2005
2006 int ppp_available(void)
2007 {
2008     int s, ok, fd;
2009     struct ifreq ifr;
2010     int    size;
2011     int    my_version, my_modification, my_patch;
2012     int osmaj, osmin, ospatch;
2013
2014     no_ppp_msg =
2015         "This system lacks kernel support for PPP.  This could be because\n"
2016         "the PPP kernel module could not be loaded, or because PPP was not\n"
2017         "included in the kernel configuration.  If PPP was included as a\n"
2018         "module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
2019         "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2020         "See README.linux file in the ppp distribution for more details.\n";
2021
2022     /* get the kernel version now, since we are called before sys_init */
2023     uname(&utsname);
2024     osmaj = osmin = ospatch = 0;
2025     sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2026     kernel_version = KVERSION(osmaj, osmin, ospatch);
2027
2028     fd = open("/dev/ppp", O_RDWR);
2029 #if 0
2030     if (fd < 0 && errno == ENOENT) {
2031         /* try making it and see if that helps. */
2032         if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR,
2033                   makedev(108, 0)) >= 0) {
2034             fd = open("/dev/ppp", O_RDWR);
2035             if (fd >= 0)
2036                 info("Created /dev/ppp device node");
2037             else
2038                 unlink("/dev/ppp");     /* didn't work, undo the mknod */
2039         } else if (errno == EEXIST) {
2040             fd = open("/dev/ppp", O_RDWR);
2041         }
2042     }
2043 #endif /* 0 */
2044     if (fd >= 0) {
2045         new_style_driver = 1;
2046
2047         /* XXX should get from driver */
2048         driver_version = 2;
2049         driver_modification = 4;
2050         driver_patch = 0;
2051         close(fd);
2052         return 1;
2053     }
2054     if (kernel_version >= KVERSION(2,3,13)) {
2055         if (errno == ENOENT)
2056             no_ppp_msg =
2057                 "pppd is unable to open the /dev/ppp device.\n"
2058                 "You need to create the /dev/ppp device node by\n"
2059                 "executing the following command as root:\n"
2060                 "       mknod /dev/ppp c 108 0\n";
2061         return 0;
2062     }
2063
2064 /*
2065  * Open a socket for doing the ioctl operations.
2066  */
2067     s = socket(AF_INET, SOCK_DGRAM, 0);
2068     if (s < 0)
2069         return 0;
2070
2071     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2072     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2073 /*
2074  * If the device did not exist then attempt to create one by putting the
2075  * current tty into the PPP discipline. If this works then obtain the
2076  * flags for the device again.
2077  */
2078     if (!ok) {
2079         if (ppp_registered()) {
2080             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2081             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2082         }
2083     }
2084 /*
2085  * Ensure that the hardware address is for PPP and not something else
2086  */
2087     if (ok)
2088         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2089
2090     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2091         ok = 0;
2092
2093 /*
2094  *  This is the PPP device. Validate the version of the driver at this
2095  *  point to ensure that this program will work with the driver.
2096  */
2097     if (ok) {
2098         char   abBuffer [1024];
2099
2100         ifr.ifr_data = abBuffer;
2101         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2102         if (size < 0) {
2103             error("Couldn't read driver version: %m");
2104             ok = 0;
2105             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2106
2107         } else {
2108             decode_version(abBuffer,
2109                            &driver_version,
2110                            &driver_modification,
2111                            &driver_patch);
2112 /*
2113  * Validate the version of the driver against the version that we used.
2114  */
2115             decode_version(VERSION,
2116                            &my_version,
2117                            &my_modification,
2118                            &my_patch);
2119
2120             /* The version numbers must match */
2121             if (driver_version != my_version)
2122                 ok = 0;
2123
2124             /* The modification levels must be legal */
2125             if (driver_modification < 3) {
2126                 if (driver_modification >= 2) {
2127                     /* we can cope with 2.2.0 and above */
2128                     driver_is_old = 1;
2129                 } else {
2130                     ok = 0;
2131                 }
2132             }
2133
2134             close (s);
2135             if (!ok) {
2136                 slprintf(route_buffer, sizeof(route_buffer),
2137                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
2138                          driver_version, driver_modification, driver_patch);
2139
2140                 no_ppp_msg = route_buffer;
2141             }
2142         }
2143     }
2144     return ok;
2145 }
2146
2147 /********************************************************************
2148  *
2149  * Update the wtmp file with the appropriate user name and tty device.
2150  */
2151
2152 void logwtmp (const char *line, const char *name, const char *host)
2153 {
2154     struct utmp ut, *utp;
2155     pid_t  mypid = getpid();
2156 #if __GLIBC__ < 2
2157     int    wtmp;
2158 #endif
2159
2160 /*
2161  * Update the signon database for users.
2162  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2163  */
2164     utmpname(_PATH_UTMP);
2165     setutent();
2166     while ((utp = getutent()) && (utp->ut_pid != mypid))
2167         /* nothing */;
2168
2169     if (utp)
2170         memcpy(&ut, utp, sizeof(ut));
2171     else
2172         /* some gettys/telnetds don't initialize utmp... */
2173         memset(&ut, 0, sizeof(ut));
2174
2175     if (ut.ut_id[0] == 0)
2176         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2177
2178     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2179     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2180
2181     time(&ut.ut_time);
2182
2183     ut.ut_type = USER_PROCESS;
2184     ut.ut_pid  = mypid;
2185
2186     /* Insert the host name if one is supplied */
2187     if (*host)
2188         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2189
2190     /* Insert the IP address of the remote system if IP is enabled */
2191     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2192         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2193                  sizeof(ut.ut_addr));
2194
2195     /* CL: Makes sure that the logout works */
2196     if (*host == 0 && *name==0)
2197         ut.ut_host[0]=0;
2198
2199     pututline(&ut);
2200     endutent();
2201 /*
2202  * Update the wtmp file.
2203  */
2204 #if __GLIBC__ >= 2
2205     updwtmp(_PATH_WTMP, &ut);
2206 #else
2207     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2208     if (wtmp >= 0) {
2209         flock(wtmp, LOCK_EX);
2210
2211         if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2212             warn("error writing %s: %m", _PATH_WTMP);
2213
2214         flock(wtmp, LOCK_UN);
2215
2216         close (wtmp);
2217     }
2218 #endif
2219 }
2220
2221
2222 /********************************************************************
2223  *
2224  * sifvjcomp - config tcp header compression
2225  */
2226
2227 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2228 {
2229     u_int x = get_flags(ppp_dev_fd);
2230
2231     if (vjcomp) {
2232         if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2233             if (! ok_error (errno))
2234                 error("ioctl(PPPIOCSMAXCID): %m (line %d)", __LINE__);
2235             vjcomp = 0;
2236         }
2237     }
2238
2239     x = vjcomp  ? x | SC_COMP_TCP     : x &~ SC_COMP_TCP;
2240     x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
2241     set_flags (ppp_dev_fd, 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         set_flags(ppp_dev_fd, 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