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