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