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