]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
Update copyrights. The new CMU copyright notice is from CMU and now
[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     FD_SET(fd, &in_fds);
1054     if (fd > max_in_fd)
1055         max_in_fd = fd;
1056 }
1057
1058 /*
1059  * remove_fd - remove an fd from the set that wait_input waits for.
1060  */
1061 void remove_fd(int fd)
1062 {
1063     FD_CLR(fd, &in_fds);
1064 }
1065
1066
1067 /********************************************************************
1068  *
1069  * read_packet - get a PPP packet from the serial device.
1070  */
1071
1072 int read_packet (unsigned char *buf)
1073 {
1074     int len, nr;
1075
1076     len = PPP_MRU + PPP_HDRLEN;
1077     if (new_style_driver) {
1078         *buf++ = PPP_ALLSTATIONS;
1079         *buf++ = PPP_UI;
1080         len -= 2;
1081     }
1082     nr = -1;
1083     if (ppp_fd >= 0) {
1084         nr = read(ppp_fd, buf, len);
1085         if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
1086             error("read: %m");
1087         if (nr < 0 && errno == ENXIO)
1088             return 0;
1089     }
1090     if (nr < 0 && new_style_driver && ifunit >= 0) {
1091         /* N.B. we read ppp_fd first since LCP packets come in there. */
1092         nr = read(ppp_dev_fd, buf, len);
1093         if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
1094             error("read /dev/ppp: %m");
1095         if (nr < 0 && errno == ENXIO)
1096             return 0;
1097     }
1098     return (new_style_driver && nr > 0)? nr+2: nr;
1099 }
1100
1101 /********************************************************************
1102  *
1103  * get_loop_output - get outgoing packets from the ppp device,
1104  * and detect when we want to bring the real link up.
1105  * Return value is 1 if we need to bring up the link, 0 otherwise.
1106  */
1107 int
1108 get_loop_output(void)
1109 {
1110     int rv = 0;
1111     int n;
1112
1113     if (new_style_driver) {
1114         while ((n = read_packet(inpacket_buf)) > 0)
1115             if (loop_frame(inpacket_buf, n))
1116                 rv = 1;
1117         return rv;
1118     }
1119
1120     while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1121         if (loop_chars(inbuf, n))
1122             rv = 1;
1123
1124     if (n == 0)
1125         fatal("eof on loopback");
1126
1127     if (errno != EWOULDBLOCK)
1128         fatal("read from loopback: %m(%d)", errno);
1129
1130     return rv;
1131 }
1132
1133 /*
1134  * netif_set_mtu - set the MTU on the PPP network interface.
1135  */
1136 void
1137 netif_set_mtu(int unit, int mtu)
1138 {
1139     struct ifreq ifr;
1140
1141     SYSDEBUG ((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu));
1142
1143     memset (&ifr, '\0', sizeof (ifr));
1144     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1145     ifr.ifr_mtu = mtu;
1146
1147     if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1148         error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1149 }
1150
1151 /*
1152  * netif_get_mtu - get the MTU on the PPP network interface.
1153  */
1154 int
1155 netif_get_mtu(int unit)
1156 {
1157     struct ifreq ifr;
1158
1159     memset (&ifr, '\0', sizeof (ifr));
1160     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1161
1162     if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1163         error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1164         return 0;
1165     }
1166     return ifr.ifr_mtu;
1167 }
1168
1169 /********************************************************************
1170  *
1171  * tty_send_config - configure the transmit characteristics of
1172  * the ppp interface.
1173  */
1174
1175 void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
1176 {
1177     u_int x;
1178
1179 /*
1180  * Set the asyncmap and other parameters for the ppp device
1181  */
1182     if (!still_ppp())
1183         return;
1184     link_mtu = mtu;
1185     SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
1186     if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1187         if (!ok_error(errno))
1188             fatal("ioctl(PPPIOCSASYNCMAP): %m (line %d)", __LINE__);
1189         return;
1190     }
1191
1192     x = get_flags(ppp_fd);
1193     x = pcomp  ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
1194     x = accomp ? x | SC_COMP_AC   : x & ~SC_COMP_AC;
1195     x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
1196     set_flags(ppp_fd, x);
1197 }
1198
1199 /********************************************************************
1200  *
1201  * tty_set_xaccm - set the extended transmit ACCM for the interface.
1202  */
1203
1204 void tty_set_xaccm (ext_accm accm)
1205 {
1206     SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
1207                 accm[0], accm[1], accm[2], accm[3]));
1208
1209     if (!still_ppp())
1210         return;
1211     if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1212         if ( ! ok_error (errno))
1213             warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1214     }
1215 }
1216
1217 /********************************************************************
1218  *
1219  * tty_recv_config - configure the receive-side characteristics of
1220  * the ppp interface.
1221  */
1222
1223 void tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp)
1224 {
1225     SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
1226 /*
1227  * If we were called because the link has gone down then there is nothing
1228  * which may be done. Just return without incident.
1229  */
1230     if (!still_ppp())
1231         return;
1232 /*
1233  * Set the receiver parameters
1234  */
1235     if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1236         if ( ! ok_error (errno))
1237             error("ioctl(PPPIOCSMRU): %m (line %d)", __LINE__);
1238     }
1239     if (new_style_driver && ifunit >= 0
1240         && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1241         error("Couldn't set MRU in generic PPP layer: %m");
1242
1243     SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
1244     if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1245         if (!ok_error(errno))
1246             error("ioctl(PPPIOCSRASYNCMAP): %m (line %d)", __LINE__);
1247     }
1248 }
1249
1250 /********************************************************************
1251  *
1252  * ccp_test - ask kernel whether a given compression method
1253  * is acceptable for use.
1254  */
1255
1256 int
1257 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1258 {
1259     struct ppp_option_data data;
1260
1261     memset (&data, '\0', sizeof (data));
1262     data.ptr      = opt_ptr;
1263     data.length   = opt_len;
1264     data.transmit = for_transmit;
1265
1266     if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1267         return 1;
1268
1269     return (errno == ENOBUFS)? 0: -1;
1270 }
1271
1272 /********************************************************************
1273  *
1274  * ccp_flags_set - inform kernel about the current state of CCP.
1275  */
1276
1277 void ccp_flags_set (int unit, int isopen, int isup)
1278 {
1279     if (still_ppp() && ifunit >= 0) {
1280         int x = get_flags(ppp_dev_fd);
1281         x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;
1282         x = isup?   x | SC_CCP_UP   : x &~ SC_CCP_UP;
1283         set_flags (ppp_dev_fd, x);
1284     }
1285 }
1286
1287 #ifdef PPP_FILTER
1288 /*
1289  * set_filters - set the active and pass filters in the kernel driver.
1290  */
1291 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1292 {
1293         struct sock_fprog fp;
1294
1295         fp.len = pass->bf_len;
1296         fp.filter = (struct sock_filter *) pass->bf_insns;
1297         if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1298                 if (errno == ENOTTY)
1299                         warn("kernel does not support PPP filtering");
1300                 else
1301                         error("Couldn't set pass-filter in kernel: %m");
1302                 return 0;
1303         }
1304         fp.len = active->bf_len;
1305         fp.filter = (struct sock_filter *) active->bf_insns;
1306         if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1307                 error("Couldn't set active-filter in kernel: %m");
1308                 return 0;
1309         }
1310         return 1;
1311 }
1312 #endif /* PPP_FILTER */
1313
1314 /********************************************************************
1315  *
1316  * get_idle_time - return how long the link has been idle.
1317  */
1318 int
1319 get_idle_time(u, ip)
1320     int u;
1321     struct ppp_idle *ip;
1322 {
1323     return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1324 }
1325
1326 /********************************************************************
1327  *
1328  * get_ppp_stats - return statistics for the link.
1329  */
1330 int
1331 get_ppp_stats(u, stats)
1332     int u;
1333     struct pppd_stats *stats;
1334 {
1335     struct ifpppstatsreq req;
1336
1337     memset (&req, 0, sizeof (req));
1338
1339     req.stats_ptr = (caddr_t) &req.stats;
1340     strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1341     if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1342         error("Couldn't get PPP statistics: %m");
1343         return 0;
1344     }
1345     stats->bytes_in = req.stats.p.ppp_ibytes;
1346     stats->bytes_out = req.stats.p.ppp_obytes;
1347     stats->pkts_in = req.stats.p.ppp_ipackets;
1348     stats->pkts_out = req.stats.p.ppp_opackets;
1349     return 1;
1350 }
1351
1352 /********************************************************************
1353  *
1354  * ccp_fatal_error - returns 1 if decompression was disabled as a
1355  * result of an error detected after decompression of a packet,
1356  * 0 otherwise.  This is necessary because of patent nonsense.
1357  */
1358
1359 int ccp_fatal_error (int unit)
1360 {
1361     int x = get_flags(ppp_dev_fd);
1362
1363     return x & SC_DC_FERROR;
1364 }
1365
1366 /********************************************************************
1367  *
1368  * path_to_procfs - find the path to the proc file system mount point
1369  */
1370 static char proc_path[MAXPATHLEN];
1371 static int proc_path_len;
1372
1373 static char *path_to_procfs(const char *tail)
1374 {
1375     struct mntent *mntent;
1376     FILE *fp;
1377
1378     if (proc_path_len == 0) {
1379         /* Default the mount location of /proc */
1380         strlcpy (proc_path, "/proc", sizeof(proc_path));
1381         proc_path_len = 5;
1382         fp = fopen(MOUNTED, "r");
1383         if (fp != NULL) {
1384             while ((mntent = getmntent(fp)) != NULL) {
1385                 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1386                     continue;
1387                 if (strcmp(mntent->mnt_type, "proc") == 0) {
1388                     strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1389                     proc_path_len = strlen(proc_path);
1390                     break;
1391                 }
1392             }
1393             fclose (fp);
1394         }
1395     }
1396
1397     strlcpy(proc_path + proc_path_len, tail,
1398             sizeof(proc_path) - proc_path_len);
1399     return proc_path;
1400 }
1401
1402 /*
1403  * /proc/net/route parsing stuff.
1404  */
1405 #define ROUTE_MAX_COLS  12
1406 FILE *route_fd = (FILE *) 0;
1407 static char route_buffer[512];
1408 static int route_dev_col, route_dest_col, route_gw_col;
1409 static int route_flags_col, route_mask_col;
1410 static int route_num_cols;
1411
1412 static int open_route_table (void);
1413 static void close_route_table (void);
1414 static int read_route_table (struct rtentry *rt);
1415
1416 /********************************************************************
1417  *
1418  * close_route_table - close the interface to the route table
1419  */
1420
1421 static void close_route_table (void)
1422 {
1423     if (route_fd != (FILE *) 0) {
1424         fclose (route_fd);
1425         route_fd = (FILE *) 0;
1426     }
1427 }
1428
1429 /********************************************************************
1430  *
1431  * open_route_table - open the interface to the route table
1432  */
1433 static char route_delims[] = " \t\n";
1434
1435 static int open_route_table (void)
1436 {
1437     char *path;
1438
1439     close_route_table();
1440
1441     path = path_to_procfs("/net/route");
1442     route_fd = fopen (path, "r");
1443     if (route_fd == NULL) {
1444         error("can't open routing table %s: %m", path);
1445         return 0;
1446     }
1447
1448     route_dev_col = 0;          /* default to usual columns */
1449     route_dest_col = 1;
1450     route_gw_col = 2;
1451     route_flags_col = 3;
1452     route_mask_col = 7;
1453     route_num_cols = 8;
1454
1455     /* parse header line */
1456     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1457         char *p = route_buffer, *q;
1458         int col;
1459         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1460             int used = 1;
1461             if ((q = strtok(p, route_delims)) == 0)
1462                 break;
1463             if (strcasecmp(q, "iface") == 0)
1464                 route_dev_col = col;
1465             else if (strcasecmp(q, "destination") == 0)
1466                 route_dest_col = col;
1467             else if (strcasecmp(q, "gateway") == 0)
1468                 route_gw_col = col;
1469             else if (strcasecmp(q, "flags") == 0)
1470                 route_flags_col = col;
1471             else if (strcasecmp(q, "mask") == 0)
1472                 route_mask_col = col;
1473             else
1474                 used = 0;
1475             if (used && col >= route_num_cols)
1476                 route_num_cols = col + 1;
1477             p = NULL;
1478         }
1479     }
1480
1481     return 1;
1482 }
1483
1484 /********************************************************************
1485  *
1486  * read_route_table - read the next entry from the route table
1487  */
1488
1489 static int read_route_table(struct rtentry *rt)
1490 {
1491     char *cols[ROUTE_MAX_COLS], *p;
1492     int col;
1493
1494     memset (rt, '\0', sizeof (struct rtentry));
1495
1496     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1497         return 0;
1498
1499     p = route_buffer;
1500     for (col = 0; col < route_num_cols; ++col) {
1501         cols[col] = strtok(p, route_delims);
1502         if (cols[col] == NULL)
1503             return 0;           /* didn't get enough columns */
1504         p = NULL;
1505     }
1506
1507     SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1508     SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1509     SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1510
1511     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1512     rt->rt_dev   = cols[route_dev_col];
1513
1514     return 1;
1515 }
1516
1517 /********************************************************************
1518  *
1519  * defaultroute_exists - determine if there is a default route
1520  */
1521
1522 static int defaultroute_exists (struct rtentry *rt)
1523 {
1524     int result = 0;
1525
1526     if (!open_route_table())
1527         return 0;
1528
1529     while (read_route_table(rt) != 0) {
1530         if ((rt->rt_flags & RTF_UP) == 0)
1531             continue;
1532
1533         if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1534             continue;
1535         if (SIN_ADDR(rt->rt_dst) == 0L) {
1536             result = 1;
1537             break;
1538         }
1539     }
1540
1541     close_route_table();
1542     return result;
1543 }
1544
1545 /*
1546  * have_route_to - determine if the system has any route to
1547  * a given IP address.  `addr' is in network byte order.
1548  * Return value is 1 if yes, 0 if no, -1 if don't know.
1549  * For demand mode to work properly, we have to ignore routes
1550  * through our own interface.
1551  */
1552 int have_route_to(u_int32_t addr)
1553 {
1554     struct rtentry rt;
1555     int result = 0;
1556
1557     if (!open_route_table())
1558         return -1;              /* don't know */
1559
1560     while (read_route_table(&rt)) {
1561         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1562             continue;
1563         if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1564             result = 1;
1565             break;
1566         }
1567     }
1568
1569     close_route_table();
1570     return result;
1571 }
1572
1573 /********************************************************************
1574  *
1575  * sifdefaultroute - assign a default route through the address given.
1576  */
1577
1578 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1579 {
1580     struct rtentry rt;
1581
1582     if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1583         u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1584
1585         if (old_gateway != gateway)
1586             error("not replacing existing default route to %s [%I]",
1587                   rt.rt_dev, old_gateway);
1588         return 0;
1589     }
1590
1591     memset (&rt, '\0', sizeof (rt));
1592     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1593     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1594
1595     rt.rt_dev = ifname;
1596
1597     if (kernel_version > KVERSION(2,1,0)) {
1598         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1599         SIN_ADDR(rt.rt_genmask) = 0L;
1600     }
1601
1602     SIN_ADDR(rt.rt_gateway) = gateway;
1603
1604     rt.rt_flags = RTF_UP | RTF_GATEWAY;
1605     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1606         if ( ! ok_error ( errno ))
1607             error("default route ioctl(SIOCADDRT): %m");
1608         return 0;
1609     }
1610
1611     default_route_gateway = gateway;
1612     return 1;
1613 }
1614
1615 /********************************************************************
1616  *
1617  * cifdefaultroute - delete a default route through the address given.
1618  */
1619
1620 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1621 {
1622     struct rtentry rt;
1623
1624     default_route_gateway = 0;
1625
1626     memset (&rt, '\0', sizeof (rt));
1627     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1628     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1629
1630     if (kernel_version > KVERSION(2,1,0)) {
1631         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1632         SIN_ADDR(rt.rt_genmask) = 0L;
1633     }
1634
1635     SIN_ADDR(rt.rt_gateway) = gateway;
1636
1637     rt.rt_flags = RTF_UP | RTF_GATEWAY;
1638     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1639         if (still_ppp()) {
1640             if ( ! ok_error ( errno ))
1641                 error("default route ioctl(SIOCDELRT): %m");
1642             return 0;
1643         }
1644     }
1645
1646     return 1;
1647 }
1648
1649 /********************************************************************
1650  *
1651  * sifproxyarp - Make a proxy ARP entry for the peer.
1652  */
1653
1654 int sifproxyarp (int unit, u_int32_t his_adr)
1655 {
1656     struct arpreq arpreq;
1657     char *forw_path;
1658
1659     if (has_proxy_arp == 0) {
1660         memset (&arpreq, '\0', sizeof(arpreq));
1661
1662         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1663         SIN_ADDR(arpreq.arp_pa) = his_adr;
1664         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1665 /*
1666  * Get the hardware address of an interface on the same subnet
1667  * as our local address.
1668  */
1669         if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1670                             sizeof(proxy_arp_dev))) {
1671             error("Cannot determine ethernet address for proxy ARP");
1672             return 0;
1673         }
1674         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1675
1676         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1677             if ( ! ok_error ( errno ))
1678                 error("ioctl(SIOCSARP): %m");
1679             return 0;
1680         }
1681         proxy_arp_addr = his_adr;
1682         has_proxy_arp = 1;
1683
1684         if (tune_kernel) {
1685             forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1686             if (forw_path != 0) {
1687                 int fd = open(forw_path, O_WRONLY);
1688                 if (fd >= 0) {
1689                     if (write(fd, "1", 1) != 1)
1690                         error("Couldn't enable IP forwarding: %m");
1691                     close(fd);
1692                 }
1693             }
1694         }
1695     }
1696
1697     return 1;
1698 }
1699
1700 /********************************************************************
1701  *
1702  * cifproxyarp - Delete the proxy ARP entry for the peer.
1703  */
1704
1705 int cifproxyarp (int unit, u_int32_t his_adr)
1706 {
1707     struct arpreq arpreq;
1708
1709     if (has_proxy_arp) {
1710         has_proxy_arp = 0;
1711         memset (&arpreq, '\0', sizeof(arpreq));
1712         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1713         SIN_ADDR(arpreq.arp_pa) = his_adr;
1714         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1715         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1716
1717         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1718             if ( ! ok_error ( errno ))
1719                 warn("ioctl(SIOCDARP): %m");
1720             return 0;
1721         }
1722     }
1723     return 1;
1724 }
1725
1726 /********************************************************************
1727  *
1728  * get_ether_addr - get the hardware address of an interface on the
1729  * the same subnet as ipaddr.
1730  */
1731
1732 static int get_ether_addr (u_int32_t ipaddr,
1733                            struct sockaddr *hwaddr,
1734                            char *name, int namelen)
1735 {
1736     struct ifreq *ifr, *ifend;
1737     u_int32_t ina, mask;
1738     char *aliasp;
1739     struct ifreq ifreq, bestifreq;
1740     struct ifconf ifc;
1741     struct ifreq ifs[MAX_IFS];
1742
1743     u_int32_t bestmask=0;
1744     int found_interface = 0;
1745
1746     ifc.ifc_len = sizeof(ifs);
1747     ifc.ifc_req = ifs;
1748     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1749         if ( ! ok_error ( errno ))
1750             error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1751         return 0;
1752     }
1753
1754     SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1755                 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1756 /*
1757  * Scan through looking for an interface with an Internet
1758  * address on the same subnet as `ipaddr'.
1759  */
1760     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1761     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1762         if (ifr->ifr_addr.sa_family == AF_INET) {
1763             ina = SIN_ADDR(ifr->ifr_addr);
1764             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1765             SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1766                         ifreq.ifr_name));
1767 /*
1768  * Check that the interface is up, and not point-to-point
1769  * nor loopback.
1770  */
1771             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1772                 continue;
1773
1774             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1775                 continue;
1776 /*
1777  * Get its netmask and check that it's on the right subnet.
1778  */
1779             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1780                 continue;
1781
1782             mask = SIN_ADDR(ifreq.ifr_addr);
1783             SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1784                        ip_ntoa(ina), ntohl(mask)));
1785
1786             if (((ipaddr ^ ina) & mask) != 0)
1787                 continue; /* no match */
1788             /* matched */
1789             if (mask >= bestmask) {
1790                 /* Compare using >= instead of > -- it is possible for
1791                    an interface to have a netmask of 0.0.0.0 */
1792                 found_interface = 1;
1793                 bestifreq = ifreq;
1794                 bestmask = mask;
1795             }
1796         }
1797     }
1798
1799     if (!found_interface) return 0;
1800
1801     strlcpy(name, bestifreq.ifr_name, namelen);
1802
1803     /* trim off the :1 in eth0:1 */
1804     aliasp = strchr(name, ':');
1805     if (aliasp != 0)
1806         *aliasp = 0;
1807
1808     info("found interface %s for proxy arp", name);
1809 /*
1810  * Now get the hardware address.
1811  */
1812     memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1813     if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1814         error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1815         return 0;
1816     }
1817
1818     memcpy (hwaddr,
1819             &bestifreq.ifr_hwaddr,
1820             sizeof (struct sockaddr));
1821
1822     SYSDEBUG ((LOG_DEBUG,
1823            "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1824                 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1825                 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1826                 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1827                 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1828                 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1829                 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1830                 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1831                 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1832     return 1;
1833 }
1834
1835 /*
1836  * get_if_hwaddr - get the hardware address for the specified
1837  * network interface device.
1838  */
1839 int
1840 get_if_hwaddr(u_char *addr, char *name)
1841 {
1842         struct ifreq ifreq;
1843         int ret, sock_fd;
1844
1845         sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1846         if (sock_fd < 0)
1847                 return 0;
1848         memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1849         strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1850         ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1851         close(sock_fd);
1852         if (ret >= 0)
1853                 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1854         return ret;
1855 }
1856
1857 /*
1858  * get_first_ethernet - return the name of the first ethernet-style
1859  * interface on this system.
1860  */
1861 char *
1862 get_first_ethernet()
1863 {
1864         return "eth0";
1865 }
1866
1867 /********************************************************************
1868  *
1869  * Return user specified netmask, modified by any mask we might determine
1870  * for address `addr' (in network byte order).
1871  * Here we scan through the system's list of interfaces, looking for
1872  * any non-point-to-point interfaces which might appear to be on the same
1873  * network as `addr'.  If we find any, we OR in their netmask to the
1874  * user-specified netmask.
1875  */
1876
1877 u_int32_t GetMask (u_int32_t addr)
1878 {
1879     u_int32_t mask, nmask, ina;
1880     struct ifreq *ifr, *ifend, ifreq;
1881     struct ifconf ifc;
1882     struct ifreq ifs[MAX_IFS];
1883
1884     addr = ntohl(addr);
1885
1886     if (IN_CLASSA(addr))        /* determine network mask for address class */
1887         nmask = IN_CLASSA_NET;
1888     else if (IN_CLASSB(addr))
1889             nmask = IN_CLASSB_NET;
1890     else
1891             nmask = IN_CLASSC_NET;
1892
1893     /* class D nets are disallowed by bad_ip_adrs */
1894     mask = netmask | htonl(nmask);
1895 /*
1896  * Scan through the system's network interfaces.
1897  */
1898     ifc.ifc_len = sizeof(ifs);
1899     ifc.ifc_req = ifs;
1900     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1901         if ( ! ok_error ( errno ))
1902             warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1903         return mask;
1904     }
1905
1906     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1907     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1908 /*
1909  * Check the interface's internet address.
1910  */
1911         if (ifr->ifr_addr.sa_family != AF_INET)
1912             continue;
1913         ina = SIN_ADDR(ifr->ifr_addr);
1914         if (((ntohl(ina) ^ addr) & nmask) != 0)
1915             continue;
1916 /*
1917  * Check that the interface is up, and not point-to-point nor loopback.
1918  */
1919         strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1920         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1921             continue;
1922
1923         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1924             continue;
1925 /*
1926  * Get its netmask and OR it into our mask.
1927  */
1928         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1929             continue;
1930         mask |= SIN_ADDR(ifreq.ifr_addr);
1931         break;
1932     }
1933     return mask;
1934 }
1935
1936 /********************************************************************
1937  *
1938  * Internal routine to decode the version.modification.patch level
1939  */
1940
1941 static void decode_version (char *buf, int *version,
1942                             int *modification, int *patch)
1943 {
1944     char *endp;
1945
1946     *version      = (int) strtoul (buf, &endp, 10);
1947     *modification = 0;
1948     *patch        = 0;
1949
1950     if (endp != buf && *endp == '.') {
1951         buf = endp + 1;
1952         *modification = (int) strtoul (buf, &endp, 10);
1953         if (endp != buf && *endp == '.') {
1954             buf = endp + 1;
1955             *patch = (int) strtoul (buf, &buf, 10);
1956         }
1957     }
1958 }
1959
1960 /********************************************************************
1961  *
1962  * Procedure to determine if the PPP line discipline is registered.
1963  */
1964
1965 static int
1966 ppp_registered(void)
1967 {
1968     int local_fd;
1969     int mfd = -1;
1970     int ret = 0;
1971     char slave[16];
1972
1973     /*
1974      * We used to open the serial device and set it to the ppp line
1975      * discipline here, in order to create a ppp unit.  But that is
1976      * not a good idea - the user might have specified a device that
1977      * they can't open (permission, or maybe it doesn't really exist).
1978      * So we grab a pty master/slave pair and use that.
1979      */
1980     if (!get_pty(&mfd, &local_fd, slave, 0)) {
1981         no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1982         return 0;
1983     }
1984
1985     /*
1986      * Try to put the device into the PPP discipline.
1987      */
1988     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1989         error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
1990     } else
1991         ret = 1;
1992
1993     close(local_fd);
1994     close(mfd);
1995     return ret;
1996 }
1997
1998 /********************************************************************
1999  *
2000  * ppp_available - check whether the system has any ppp interfaces
2001  * (in fact we check whether we can do an ioctl on ppp0).
2002  */
2003
2004 int ppp_available(void)
2005 {
2006     int s, ok, fd;
2007     struct ifreq ifr;
2008     int    size;
2009     int    my_version, my_modification, my_patch;
2010     int osmaj, osmin, ospatch;
2011
2012     no_ppp_msg =
2013         "This system lacks kernel support for PPP.  This could be because\n"
2014         "the PPP kernel module could not be loaded, or because PPP was not\n"
2015         "included in the kernel configuration.  If PPP was included as a\n"
2016         "module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
2017         "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2018         "See README.linux file in the ppp distribution for more details.\n";
2019
2020     /* get the kernel version now, since we are called before sys_init */
2021     uname(&utsname);
2022     osmaj = osmin = ospatch = 0;
2023     sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2024     kernel_version = KVERSION(osmaj, osmin, ospatch);
2025
2026     fd = open("/dev/ppp", O_RDWR);
2027 #if 0
2028     if (fd < 0 && errno == ENOENT) {
2029         /* try making it and see if that helps. */
2030         if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR,
2031                   makedev(108, 0)) >= 0) {
2032             fd = open("/dev/ppp", O_RDWR);
2033             if (fd >= 0)
2034                 info("Created /dev/ppp device node");
2035             else
2036                 unlink("/dev/ppp");     /* didn't work, undo the mknod */
2037         } else if (errno == EEXIST) {
2038             fd = open("/dev/ppp", O_RDWR);
2039         }
2040     }
2041 #endif /* 0 */
2042     if (fd >= 0) {
2043         new_style_driver = 1;
2044
2045         /* XXX should get from driver */
2046         driver_version = 2;
2047         driver_modification = 4;
2048         driver_patch = 0;
2049         close(fd);
2050         return 1;
2051     }
2052     if (kernel_version >= KVERSION(2,3,13)) {
2053         if (errno == ENOENT)
2054             no_ppp_msg =
2055                 "pppd is unable to open the /dev/ppp device.\n"
2056                 "You need to create the /dev/ppp device node by\n"
2057                 "executing the following command as root:\n"
2058                 "       mknod /dev/ppp c 108 0\n";
2059         return 0;
2060     }
2061
2062 /*
2063  * Open a socket for doing the ioctl operations.
2064  */
2065     s = socket(AF_INET, SOCK_DGRAM, 0);
2066     if (s < 0)
2067         return 0;
2068
2069     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2070     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2071 /*
2072  * If the device did not exist then attempt to create one by putting the
2073  * current tty into the PPP discipline. If this works then obtain the
2074  * flags for the device again.
2075  */
2076     if (!ok) {
2077         if (ppp_registered()) {
2078             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2079             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2080         }
2081     }
2082 /*
2083  * Ensure that the hardware address is for PPP and not something else
2084  */
2085     if (ok)
2086         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2087
2088     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2089         ok = 0;
2090
2091 /*
2092  *  This is the PPP device. Validate the version of the driver at this
2093  *  point to ensure that this program will work with the driver.
2094  */
2095     if (ok) {
2096         char   abBuffer [1024];
2097
2098         ifr.ifr_data = abBuffer;
2099         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2100         if (size < 0) {
2101             error("Couldn't read driver version: %m");
2102             ok = 0;
2103             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2104
2105         } else {
2106             decode_version(abBuffer,
2107                            &driver_version,
2108                            &driver_modification,
2109                            &driver_patch);
2110 /*
2111  * Validate the version of the driver against the version that we used.
2112  */
2113             decode_version(VERSION,
2114                            &my_version,
2115                            &my_modification,
2116                            &my_patch);
2117
2118             /* The version numbers must match */
2119             if (driver_version != my_version)
2120                 ok = 0;
2121
2122             /* The modification levels must be legal */
2123             if (driver_modification < 3) {
2124                 if (driver_modification >= 2) {
2125                     /* we can cope with 2.2.0 and above */
2126                     driver_is_old = 1;
2127                 } else {
2128                     ok = 0;
2129                 }
2130             }
2131
2132             close (s);
2133             if (!ok) {
2134                 slprintf(route_buffer, sizeof(route_buffer),
2135                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
2136                          driver_version, driver_modification, driver_patch);
2137
2138                 no_ppp_msg = route_buffer;
2139             }
2140         }
2141     }
2142     return ok;
2143 }
2144
2145 /********************************************************************
2146  *
2147  * Update the wtmp file with the appropriate user name and tty device.
2148  */
2149
2150 void logwtmp (const char *line, const char *name, const char *host)
2151 {
2152     struct utmp ut, *utp;
2153     pid_t  mypid = getpid();
2154 #if __GLIBC__ < 2
2155     int    wtmp;
2156 #endif
2157
2158 /*
2159  * Update the signon database for users.
2160  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2161  */
2162     utmpname(_PATH_UTMP);
2163     setutent();
2164     while ((utp = getutent()) && (utp->ut_pid != mypid))
2165         /* nothing */;
2166
2167     if (utp)
2168         memcpy(&ut, utp, sizeof(ut));
2169     else
2170         /* some gettys/telnetds don't initialize utmp... */
2171         memset(&ut, 0, sizeof(ut));
2172
2173     if (ut.ut_id[0] == 0)
2174         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2175
2176     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2177     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2178
2179     time(&ut.ut_time);
2180
2181     ut.ut_type = USER_PROCESS;
2182     ut.ut_pid  = mypid;
2183
2184     /* Insert the host name if one is supplied */
2185     if (*host)
2186         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2187
2188     /* Insert the IP address of the remote system if IP is enabled */
2189     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2190         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2191                  sizeof(ut.ut_addr));
2192
2193     /* CL: Makes sure that the logout works */
2194     if (*host == 0 && *name==0)
2195         ut.ut_host[0]=0;
2196
2197     pututline(&ut);
2198     endutent();
2199 /*
2200  * Update the wtmp file.
2201  */
2202 #if __GLIBC__ >= 2
2203     updwtmp(_PATH_WTMP, &ut);
2204 #else
2205     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2206     if (wtmp >= 0) {
2207         flock(wtmp, LOCK_EX);
2208
2209         if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2210             warn("error writing %s: %m", _PATH_WTMP);
2211
2212         flock(wtmp, LOCK_UN);
2213
2214         close (wtmp);
2215     }
2216 #endif
2217 }
2218
2219
2220 /********************************************************************
2221  *
2222  * sifvjcomp - config tcp header compression
2223  */
2224
2225 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2226 {
2227     u_int x = get_flags(ppp_dev_fd);
2228
2229     if (vjcomp) {
2230         if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2231             if (! ok_error (errno))
2232                 error("ioctl(PPPIOCSMAXCID): %m (line %d)", __LINE__);
2233             vjcomp = 0;
2234         }
2235     }
2236
2237     x = vjcomp  ? x | SC_COMP_TCP     : x &~ SC_COMP_TCP;
2238     x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
2239     set_flags (ppp_dev_fd, x);
2240
2241     return 1;
2242 }
2243
2244 /********************************************************************
2245  *
2246  * sifup - Config the interface up and enable IP packets to pass.
2247  */
2248
2249 int sifup(int u)
2250 {
2251     struct ifreq ifr;
2252
2253     memset (&ifr, '\0', sizeof (ifr));
2254     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2255     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2256         if (! ok_error (errno))
2257             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2258         return 0;
2259     }
2260
2261     ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2262     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2263         if (! ok_error (errno))
2264             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2265         return 0;
2266     }
2267     if_is_up++;
2268
2269     return 1;
2270 }
2271
2272 /********************************************************************
2273  *
2274  * sifdown - Disable the indicated protocol and config the interface
2275  *           down if there are no remaining protocols.
2276  */
2277
2278 int sifdown (int u)
2279 {
2280     struct ifreq ifr;
2281
2282     if (if_is_up && --if_is_up > 0)
2283         return 1;
2284
2285     memset (&ifr, '\0', sizeof (ifr));
2286     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2287     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2288         if (! ok_error (errno))
2289             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2290         return 0;
2291     }
2292
2293     ifr.ifr_flags &= ~IFF_UP;
2294     ifr.ifr_flags |= IFF_POINTOPOINT;
2295     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2296         if (! ok_error (errno))
2297             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2298         return 0;
2299     }
2300     return 1;
2301 }
2302
2303 /********************************************************************
2304  *
2305  * sifaddr - Config the interface IP addresses and netmask.
2306  */
2307
2308 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2309              u_int32_t net_mask)
2310 {
2311     struct ifreq   ifr;
2312     struct rtentry rt;
2313
2314     memset (&ifr, '\0', sizeof (ifr));
2315     memset (&rt,  '\0', sizeof (rt));
2316
2317     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET);
2318     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2319     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2320
2321     strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2322 /*
2323  *  Set our IP address
2324  */
2325     SIN_ADDR(ifr.ifr_addr) = our_adr;
2326     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2327         if (errno != EEXIST) {
2328             if (! ok_error (errno))
2329                 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2330         }
2331         else {
2332             warn("ioctl(SIOCSIFADDR): Address already exists");
2333         }
2334         return (0);
2335     }
2336 /*
2337  *  Set the gateway address
2338  */
2339     SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2340     if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2341         if (! ok_error (errno))
2342             error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2343         return (0);
2344     }
2345 /*
2346  *  Set the netmask.
2347  *  For recent kernels, force the netmask to 255.255.255.255.
2348  */
2349     if (kernel_version >= KVERSION(2,1,16))
2350         net_mask = ~0L;
2351     if (net_mask != 0) {
2352         SIN_ADDR(ifr.ifr_netmask) = net_mask;
2353         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2354             if (! ok_error (errno))
2355                 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2356             return (0);
2357         }
2358     }
2359 /*
2360  *  Add the device route
2361  */
2362     if (kernel_version < KVERSION(2,1,16)) {
2363         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2364         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2365         rt.rt_dev = ifname;
2366
2367         SIN_ADDR(rt.rt_gateway) = 0L;
2368         SIN_ADDR(rt.rt_dst)     = his_adr;
2369         rt.rt_flags = RTF_UP | RTF_HOST;
2370
2371         if (kernel_version > KVERSION(2,1,0)) {
2372             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2373             SIN_ADDR(rt.rt_genmask) = -1L;
2374         }
2375
2376         if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2377             if (! ok_error (errno))
2378                 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2379             return (0);
2380         }
2381     }
2382
2383     /* set ip_dynaddr in demand mode if address changes */
2384     if (demand && tune_kernel && !dynaddr_set
2385         && our_old_addr && our_old_addr != our_adr) {
2386         /* set ip_dynaddr if possible */
2387         char *path;
2388         int fd;
2389
2390         path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2391         if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2392             if (write(fd, "1", 1) != 1)
2393                 error("Couldn't enable dynamic IP addressing: %m");
2394             close(fd);
2395         }
2396         dynaddr_set = 1;        /* only 1 attempt */
2397     }
2398     our_old_addr = 0;
2399
2400     return 1;
2401 }
2402
2403 /********************************************************************
2404  *
2405  * cifaddr - Clear the interface IP addresses, and delete routes
2406  * through the interface if possible.
2407  */
2408
2409 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2410 {
2411     struct ifreq ifr;
2412
2413     if (kernel_version < KVERSION(2,1,16)) {
2414 /*
2415  *  Delete the route through the device
2416  */
2417         struct rtentry rt;
2418         memset (&rt, '\0', sizeof (rt));
2419
2420         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2421         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2422         rt.rt_dev = ifname;
2423
2424         SIN_ADDR(rt.rt_gateway) = 0;
2425         SIN_ADDR(rt.rt_dst)     = his_adr;
2426         rt.rt_flags = RTF_UP | RTF_HOST;
2427
2428         if (kernel_version > KVERSION(2,1,0)) {
2429             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2430             SIN_ADDR(rt.rt_genmask) = -1L;
2431         }
2432
2433         if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2434             if (still_ppp() && ! ok_error (errno))
2435                 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2436             return (0);
2437         }
2438     }
2439
2440     /* This way it is possible to have an IPX-only or IPv6-only interface */
2441     memset(&ifr, 0, sizeof(ifr));
2442     SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2443     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2444
2445     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2446         if (! ok_error (errno)) {
2447             error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2448             return 0;
2449         }
2450     }
2451
2452     our_old_addr = our_adr;
2453
2454     return 1;
2455 }
2456
2457 #ifdef INET6
2458 /********************************************************************
2459  *
2460  * sif6addr - Config the interface with an IPv6 link-local address
2461  */
2462 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2463 {
2464     struct in6_ifreq ifr6;
2465     struct ifreq ifr;
2466     struct in6_rtmsg rt6;
2467
2468     if (sock6_fd < 0) {
2469         errno = -sock6_fd;
2470         error("IPv6 socket creation failed: %m");
2471         return 0;
2472     }
2473     memset(&ifr, 0, sizeof (ifr));
2474     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2475     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2476         error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2477         return 0;
2478     }
2479
2480     /* Local interface */
2481     memset(&ifr6, 0, sizeof(ifr6));
2482     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2483     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2484     ifr6.ifr6_prefixlen = 10;
2485
2486     if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2487         error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2488         return 0;
2489     }
2490
2491     /* Route to remote host */
2492     memset(&rt6, 0, sizeof(rt6));
2493     IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2494     rt6.rtmsg_flags = RTF_UP;
2495     rt6.rtmsg_dst_len = 10;
2496     rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2497     rt6.rtmsg_metric = 1;
2498
2499     if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2500         error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2501         return 0;
2502     }
2503
2504     return 1;
2505 }
2506
2507
2508 /********************************************************************
2509  *
2510  * cif6addr - Remove IPv6 address from interface
2511  */
2512 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2513 {
2514     struct ifreq ifr;
2515     struct in6_ifreq ifr6;
2516
2517     if (sock6_fd < 0) {
2518         errno = -sock6_fd;
2519         error("IPv6 socket creation failed: %m");
2520         return 0;
2521     }
2522     memset(&ifr, 0, sizeof(ifr));
2523     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2524     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2525         error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2526         return 0;
2527     }
2528
2529     memset(&ifr6, 0, sizeof(ifr6));
2530     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2531     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2532     ifr6.ifr6_prefixlen = 10;
2533
2534     if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2535         if (errno != EADDRNOTAVAIL) {
2536             if (! ok_error (errno))
2537                 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2538         }
2539         else {
2540             warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2541         }
2542         return (0);
2543     }
2544     return 1;
2545 }
2546 #endif /* INET6 */
2547
2548 /*
2549  * get_pty - get a pty master/slave pair and chown the slave side
2550  * to the uid given.  Assumes slave_name points to >= 16 bytes of space.
2551  */
2552 int
2553 get_pty(master_fdp, slave_fdp, slave_name, uid)
2554     int *master_fdp;
2555     int *slave_fdp;
2556     char *slave_name;
2557     int uid;
2558 {
2559     int i, mfd, sfd = -1;
2560     char pty_name[16];
2561     struct termios tios;
2562
2563 #ifdef TIOCGPTN
2564     /*
2565      * Try the unix98 way first.
2566      */
2567     mfd = open("/dev/ptmx", O_RDWR);
2568     if (mfd >= 0) {
2569         int ptn;
2570         if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2571             slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2572             chmod(pty_name, S_IRUSR | S_IWUSR);
2573 #ifdef TIOCSPTLCK
2574             ptn = 0;
2575             if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2576                 warn("Couldn't unlock pty slave %s: %m", pty_name);
2577 #endif
2578             if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2579                 warn("Couldn't open pty slave %s: %m", pty_name);
2580         }
2581     }
2582 #endif /* TIOCGPTN */
2583
2584     if (sfd < 0) {
2585         /* the old way - scan through the pty name space */
2586         for (i = 0; i < 64; ++i) {
2587             slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2588                      'p' + i / 16, i % 16);
2589             mfd = open(pty_name, O_RDWR, 0);
2590             if (mfd >= 0) {
2591                 pty_name[5] = 't';
2592                 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2593                 if (sfd >= 0) {
2594                     fchown(sfd, uid, -1);
2595                     fchmod(sfd, S_IRUSR | S_IWUSR);
2596                     break;
2597                 }
2598                 close(mfd);
2599             }
2600         }
2601     }
2602
2603     if (sfd < 0)
2604         return 0;
2605
2606     strlcpy(slave_name, pty_name, 16);
2607     *master_fdp = mfd;
2608     *slave_fdp = sfd;
2609     if (tcgetattr(sfd, &tios) == 0) {
2610         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2611         tios.c_cflag |= CS8 | CREAD | CLOCAL;
2612         tios.c_iflag  = IGNPAR;
2613         tios.c_oflag  = 0;
2614         tios.c_lflag  = 0;
2615         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2616             warn("couldn't set attributes on pty: %m");
2617     } else
2618         warn("couldn't get attributes on pty: %m");
2619
2620     return 1;
2621 }
2622
2623 /********************************************************************
2624  *
2625  * open_loopback - open the device we use for getting packets
2626  * in demand mode.  Under Linux, we use a pty master/slave pair.
2627  */
2628 int
2629 open_ppp_loopback(void)
2630 {
2631     int flags;
2632
2633     looped = 1;
2634     if (new_style_driver) {
2635         /* allocate ourselves a ppp unit */
2636         if (make_ppp_unit() < 0)
2637             die(1);
2638         set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC);
2639         set_kdebugflag(kdebugflag);
2640         ppp_fd = -1;
2641         return ppp_dev_fd;
2642     }
2643
2644     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2645         fatal("No free pty for loopback");
2646     SYSDEBUG(("using %s for loopback", loop_name));
2647
2648     set_ppp_fd(slave_fd);
2649
2650     flags = fcntl(master_fd, F_GETFL);
2651     if (flags == -1 ||
2652         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2653         warn("couldn't set master loopback to nonblock: %m");
2654
2655     flags = fcntl(ppp_fd, F_GETFL);
2656     if (flags == -1 ||
2657         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2658         warn("couldn't set slave loopback to nonblock: %m");
2659
2660     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2661         fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2662 /*
2663  * Find out which interface we were given.
2664  */
2665     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2666         fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2667 /*
2668  * Enable debug in the driver if requested.
2669  */
2670     set_kdebugflag (kdebugflag);
2671
2672     return master_fd;
2673 }
2674
2675 /********************************************************************
2676  *
2677  * sifnpmode - Set the mode for handling packets for a given NP.
2678  */
2679
2680 int
2681 sifnpmode(u, proto, mode)
2682     int u;
2683     int proto;
2684     enum NPmode mode;
2685 {
2686     struct npioctl npi;
2687
2688     npi.protocol = proto;
2689     npi.mode     = mode;
2690     if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2691         if (! ok_error (errno))
2692             error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2693         return 0;
2694     }
2695     return 1;
2696 }
2697
2698 \f
2699 /********************************************************************
2700  *
2701  * sipxfaddr - Config the interface IPX networknumber
2702  */
2703
2704 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2705 {
2706     int    result = 1;
2707
2708 #ifdef IPX_CHANGE
2709     int    skfd;
2710     struct ifreq         ifr;
2711     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2712
2713     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2714     if (skfd < 0) {
2715         if (! ok_error (errno))
2716             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2717         result = 0;
2718     }
2719     else {
2720         memset (&ifr, '\0', sizeof (ifr));
2721         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2722
2723         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2724         sipx->sipx_family  = AF_IPX;
2725         sipx->sipx_port    = 0;
2726         sipx->sipx_network = htonl (network);
2727         sipx->sipx_type    = IPX_FRAME_ETHERII;
2728         sipx->sipx_action  = IPX_CRTITF;
2729 /*
2730  *  Set the IPX device
2731  */
2732         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2733             result = 0;
2734             if (errno != EEXIST) {
2735                 if (! ok_error (errno))
2736                     dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2737             }
2738             else {
2739                 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2740             }
2741         }
2742         close (skfd);
2743     }
2744 #endif
2745     return result;
2746 }
2747
2748 /********************************************************************
2749  *
2750  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2751  *             are removed and the device is no longer able to pass IPX
2752  *             frames.
2753  */
2754
2755 int cipxfaddr (int unit)
2756 {
2757     int    result = 1;
2758
2759 #ifdef IPX_CHANGE
2760     int    skfd;
2761     struct ifreq         ifr;
2762     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2763
2764     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2765     if (skfd < 0) {
2766         if (! ok_error (errno))
2767             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2768         result = 0;
2769     }
2770     else {
2771         memset (&ifr, '\0', sizeof (ifr));
2772         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2773
2774         sipx->sipx_type    = IPX_FRAME_ETHERII;
2775         sipx->sipx_action  = IPX_DLTITF;
2776         sipx->sipx_family  = AF_IPX;
2777 /*
2778  *  Set the IPX device
2779  */
2780         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2781             if (! ok_error (errno))
2782                 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2783             result = 0;
2784         }
2785         close (skfd);
2786     }
2787 #endif
2788     return result;
2789 }
2790
2791 /*
2792  * Use the hostname as part of the random number seed.
2793  */
2794 int
2795 get_host_seed()
2796 {
2797     int h;
2798     char *p = hostname;
2799
2800     h = 407;
2801     for (p = hostname; *p != 0; ++p)
2802         h = h * 37 + *p;
2803     return h;
2804 }
2805
2806 /********************************************************************
2807  *
2808  * sys_check_options - check the options that the user specified
2809  */
2810
2811 int
2812 sys_check_options(void)
2813 {
2814 #ifdef IPX_CHANGE
2815 /*
2816  * Disable the IPX protocol if the support is not present in the kernel.
2817  */
2818     char *path;
2819
2820     if (ipxcp_protent.enabled_flag) {
2821         struct stat stat_buf;
2822         if ((path = path_to_procfs("/net/ipx_interface")) == 0
2823             || lstat(path, &stat_buf) < 0) {
2824             error("IPX support is not present in the kernel\n");
2825             ipxcp_protent.enabled_flag = 0;
2826         }
2827     }
2828 #endif
2829     if (demand && driver_is_old) {
2830         option_error("demand dialling is not supported by kernel driver "
2831                      "version %d.%d.%d", driver_version, driver_modification,
2832                      driver_patch);
2833         return 0;
2834     }
2835     if (multilink && !new_style_driver) {
2836         warn("Warning: multilink is not supported by the kernel driver");
2837         multilink = 0;
2838     }
2839     return 1;
2840 }
2841
2842 #ifdef INET6
2843 /*
2844  * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2845  *
2846  * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2847  * that the system has a properly configured Ethernet interface for this
2848  * function to return non-zero.
2849  */
2850 int
2851 ether_to_eui64(eui64_t *p_eui64)
2852 {
2853     struct ifreq ifr;
2854     int skfd;
2855     const unsigned char *ptr;
2856
2857     skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2858     if(skfd == -1)
2859     {
2860         warn("could not open IPv6 socket");
2861         return 0;
2862     }
2863
2864     strcpy(ifr.ifr_name, "eth0");
2865     if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2866     {
2867         close(skfd);
2868         warn("could not obtain hardware address for eth0");
2869         return 0;
2870     }
2871     close(skfd);
2872
2873     /*
2874      * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2875      */
2876     ptr = ifr.ifr_hwaddr.sa_data;
2877     p_eui64->e8[0] = ptr[0] | 0x02;
2878     p_eui64->e8[1] = ptr[1];
2879     p_eui64->e8[2] = ptr[2];
2880     p_eui64->e8[3] = 0xFF;
2881     p_eui64->e8[4] = 0xFE;
2882     p_eui64->e8[5] = ptr[3];
2883     p_eui64->e8[6] = ptr[4];
2884     p_eui64->e8[7] = ptr[5];
2885
2886     return 1;
2887 }
2888 #endif