fix the bug in non-demand mode that I inadvertently introduced
[mpls-ppp.git] / pppd / sys-linux.c
blob676839bf359ad52d6b2d8715fa60cdfa0cb27dc8
1 /*
2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
5 * Copyright (c) 1989 Carnegie Mellon University.
6 * All rights reserved.
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by Carnegie Mellon University. The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 #include <sys/ioctl.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/time.h>
25 #include <sys/errno.h>
26 #include <sys/file.h>
27 #include <sys/stat.h>
28 #include <sys/utsname.h>
29 #include <sys/sysmacros.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <syslog.h>
34 #include <string.h>
35 #include <time.h>
36 #include <memory.h>
37 #include <utmp.h>
38 #include <mntent.h>
39 #include <signal.h>
40 #include <fcntl.h>
41 #include <ctype.h>
42 #include <termios.h>
43 #include <unistd.h>
45 /* This is in netdevice.h. However, this compile will fail miserably if
46 you attempt to include netdevice.h because it has so many references
47 to __memcpy functions which it should not attempt to do. So, since I
48 really don't use it, but it must be defined, define it now. */
50 #ifndef MAX_ADDR_LEN
51 #define MAX_ADDR_LEN 7
52 #endif
54 #if __GLIBC__ >= 2
55 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
56 #include <net/if.h>
57 #include <net/if_arp.h>
58 #include <net/route.h>
59 #include <netinet/if_ether.h>
60 #else
61 #include <linux/types.h>
62 #include <linux/if.h>
63 #include <linux/if_arp.h>
64 #include <linux/route.h>
65 #include <linux/if_ether.h>
66 #endif
67 #include <netinet/in.h>
68 #include <arpa/inet.h>
70 #include <linux/ppp_defs.h>
71 #include <linux/if_ppp.h>
73 #include "pppd.h"
74 #include "fsm.h"
75 #include "ipcp.h"
76 #include "patchlevel.h"
78 #ifdef IPX_CHANGE
79 #include "ipxcp.h"
80 #if __GLIBC__ >= 2 && \
81 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
82 #include <netipx/ipx.h>
83 #else
84 #include <linux/ipx.h>
85 #endif
86 #endif /* IPX_CHANGE */
88 #ifdef LOCKLIB
89 #include <sys/locks.h>
90 #endif
92 #ifdef INET6
93 #ifndef _LINUX_IN6_H
95 * This is in linux/include/net/ipv6.h.
98 struct in6_ifreq {
99 struct in6_addr ifr6_addr;
100 __u32 ifr6_prefixlen;
101 unsigned int ifr6_ifindex;
103 #endif
105 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
106 memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \
107 sin6.s6_addr16[0] = htons(0xfe80); \
108 eui64_copy(eui64, sin6.s6_addr32[2]); \
109 } while (0)
111 #endif /* INET6 */
113 /* We can get an EIO error on an ioctl if the modem has hung up */
114 #define ok_error(num) ((num)==EIO)
116 static int tty_disc = N_TTY; /* The TTY discipline */
117 static int ppp_disc = N_PPP; /* The PPP discpline */
118 static int initfdflags = -1; /* Initial file descriptor flags for fd */
119 static int ppp_fd = -1; /* fd which is set to PPP discipline */
120 static int sock_fd = -1; /* socket for doing interface ioctls */
121 static int slave_fd = -1;
122 static int master_fd = -1;
123 #ifdef INET6
124 static int sock6_fd = -1;
125 #endif /* INET6 */
126 static int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
127 static int chindex; /* channel index (new style driver) */
129 static fd_set in_fds; /* set of fds that wait_input waits for */
130 static int max_in_fd; /* highest fd set in in_fds */
132 static int has_proxy_arp = 0;
133 static int driver_version = 0;
134 static int driver_modification = 0;
135 static int driver_patch = 0;
136 static int driver_is_old = 0;
137 static int restore_term = 0; /* 1 => we've munged the terminal */
138 static struct termios inittermios; /* Initial TTY termios */
140 static int new_style_driver = 0;
142 static char loop_name[20];
143 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
145 static int if_is_up; /* Interface has been marked up */
146 static u_int32_t default_route_gateway; /* Gateway for default route added */
147 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
148 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
149 static u_int32_t our_old_addr; /* for detecting address changes */
150 static int dynaddr_set; /* 1 if ip_dynaddr set */
151 static int looped; /* 1 if using loop */
152 static int link_mtu; /* mtu for the link (not bundle) */
154 static struct utsname utsname; /* for the kernel version */
155 static int kernel_version;
156 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
158 #define MAX_IFS 100
160 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
161 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
162 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
164 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
166 /* Prototypes for procedures local to this file. */
167 static int get_flags (int fd);
168 static void set_flags (int fd, int flags);
169 static int translate_speed (int bps);
170 static int baud_rate_of (int speed);
171 static void close_route_table (void);
172 static int open_route_table (void);
173 static int read_route_table (struct rtentry *rt);
174 static int defaultroute_exists (struct rtentry *rt);
175 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
176 char *name, int namelen);
177 static void decode_version (char *buf, int *version, int *mod, int *patch);
178 static int set_kdebugflag(int level);
179 static int ppp_registered(void);
180 static int make_ppp_unit(void);
182 extern u_char inpacket_buf[]; /* borrowed from main.c */
185 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
186 * if it exists.
189 #define SET_SA_FAMILY(addr, family) \
190 memset ((char *) &(addr), '\0', sizeof(addr)); \
191 addr.sa_family = (family);
194 * Determine if the PPP connection should still be present.
197 extern int hungup;
199 /* new_fd is the fd of a tty */
200 static void set_ppp_fd (int new_fd)
202 SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
203 ppp_fd = new_fd;
204 if (!new_style_driver)
205 ppp_dev_fd = new_fd;
208 static int still_ppp(void)
210 if (new_style_driver)
211 return !hungup && ppp_fd >= 0;
212 if (!hungup || ppp_fd == slave_fd)
213 return 1;
214 if (slave_fd >= 0) {
215 set_ppp_fd(slave_fd);
216 return 1;
218 return 0;
221 /********************************************************************
223 * Functions to read and set the flags value in the device driver
226 static int get_flags (int fd)
228 int flags;
230 if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) {
231 if ( ok_error (errno) )
232 flags = 0;
233 else
234 fatal("ioctl(PPPIOCGFLAGS): %m");
237 SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags));
238 return flags;
241 /********************************************************************/
243 static void set_flags (int fd, int flags)
245 SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
247 if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
248 if (! ok_error (errno) )
249 fatal("ioctl(PPPIOCSFLAGS, %x): %m", flags, errno);
253 /********************************************************************
255 * sys_init - System-dependent initialization.
258 void sys_init(void)
260 int flags;
262 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
263 setlogmask(LOG_UPTO(LOG_INFO));
264 if (debug)
265 setlogmask(LOG_UPTO(LOG_DEBUG));
267 if (new_style_driver) {
268 ppp_dev_fd = open("/dev/ppp", O_RDWR);
269 if (ppp_dev_fd < 0)
270 fatal("Couldn't open /dev/ppp: %m");
271 flags = fcntl(ppp_dev_fd, F_GETFL);
272 if (flags == -1
273 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
274 warn("Couldn't set /dev/ppp to nonblock: %m");
277 /* Get an internet socket for doing socket ioctls. */
278 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
279 if (sock_fd < 0)
280 fatal("Couldn't create IP socket: %m(%d)", errno);
282 #ifdef INET6
283 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
284 if (sock6_fd < 0)
285 fatal("Couldn't create IPv6 socket: %m(%d)", errno);
286 #endif
288 FD_ZERO(&in_fds);
289 max_in_fd = 0;
292 /********************************************************************
294 * sys_cleanup - restore any system state we modified before exiting:
295 * mark the interface down, delete default route and/or proxy arp entry.
296 * This shouldn't call die() because it's called from die().
299 void sys_cleanup(void)
302 * Take down the device
304 if (if_is_up) {
305 if_is_up = 0;
306 sifdown(0);
309 * Delete any routes through the device.
311 if (default_route_gateway != 0)
312 cifdefaultroute(0, 0, default_route_gateway);
314 if (has_proxy_arp)
315 cifproxyarp(0, proxy_arp_addr);
318 /********************************************************************
320 * sys_close - Clean up in a child process before execing.
322 void
323 sys_close(void)
325 if (new_style_driver)
326 close(ppp_dev_fd);
327 if (sock_fd >= 0)
328 close(sock_fd);
329 if (slave_fd >= 0)
330 close(slave_fd);
331 if (master_fd >= 0)
332 close(master_fd);
333 closelog();
336 /********************************************************************
338 * set_kdebugflag - Define the debugging level for the kernel
341 static int set_kdebugflag (int requested_level)
343 if (new_style_driver && ifunit < 0)
344 return 1;
345 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
346 if ( ! ok_error (errno) )
347 error("ioctl(PPPIOCSDEBUG): %m");
348 return (0);
350 SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
351 requested_level));
352 return (1);
355 /********************************************************************
357 * establish_ppp - Turn the serial port into a ppp interface.
360 int establish_ppp (int tty_fd)
362 int x;
363 int fd = -1;
366 * Ensure that the tty device is in exclusive mode.
368 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
369 if ( ! ok_error ( errno ))
370 warn("Couldn't make tty exclusive: %m");
373 * Demand mode - prime the old ppp device to relinquish the unit.
375 if (!new_style_driver && looped
376 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
377 error("ioctl(transfer ppp unit): %m");
378 return -1;
381 * Set the current tty to the PPP discpline
384 #ifndef N_SYNC_PPP
385 #define N_SYNC_PPP 14
386 #endif
387 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
388 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
389 if ( ! ok_error (errno) ) {
390 error("Couldn't set tty to PPP discipline: %m");
391 return -1;
395 if (new_style_driver) {
396 /* Open another instance of /dev/ppp and connect the channel to it */
397 int flags;
399 if (ioctl(tty_fd, PPPIOCGCHAN, &chindex) == -1) {
400 error("Couldn't get channel number: %m");
401 goto err;
403 dbglog("using channel %d", chindex);
404 fd = open("/dev/ppp", O_RDWR);
405 if (fd < 0) {
406 error("Couldn't reopen /dev/ppp: %m");
407 goto err;
409 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
410 error("Couldn't attach to channel %d: %m", chindex);
411 goto err_close;
413 flags = fcntl(fd, F_GETFL);
414 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
415 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
416 set_ppp_fd(fd);
418 if (!looped)
419 ifunit = -1;
420 if (!looped && !multilink) {
422 * Create a new PPP unit.
424 if (make_ppp_unit() < 0)
425 goto err_close;
428 if (looped)
429 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC);
431 if (!multilink) {
432 add_fd(ppp_dev_fd);
433 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
434 error("Couldn't attach to PPP unit %d: %m", ifunit);
435 goto err_close;
439 } else {
441 * Old-style driver: find out which interface we were given.
443 set_ppp_fd (tty_fd);
444 if (ioctl(tty_fd, PPPIOCGUNIT, &x) < 0) {
445 if ( ! ok_error (errno))
446 fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
448 /* Check that we got the same unit again. */
449 if (looped && x != ifunit)
450 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
451 ifunit = x;
454 * Fetch the initial file flags and reset blocking mode on the file.
456 initfdflags = fcntl(tty_fd, F_GETFL);
457 if (initfdflags == -1 ||
458 fcntl(tty_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
459 if ( ! ok_error (errno))
460 warn("Couldn't set device to non-blocking mode: %m");
464 looped = 0;
467 * Enable debug in the driver if requested.
469 if (!looped)
470 set_kdebugflag (kdebugflag);
472 set_flags(ppp_fd, get_flags(ppp_fd) & ~(SC_RCV_B7_0 | SC_RCV_B7_1 |
473 SC_RCV_EVNP | SC_RCV_ODDP));
475 SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
476 driver_version, driver_modification, driver_patch));
478 return ppp_fd;
480 err_close:
481 close(fd);
482 err:
483 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
484 warn("Couldn't reset tty to normal line discipline: %m");
485 return -1;
488 /********************************************************************
490 * disestablish_ppp - Restore the serial port to normal operation.
491 * This shouldn't call die() because it's called from die().
494 void disestablish_ppp(int tty_fd)
496 if (!hungup) {
498 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
500 if (tcflush(tty_fd, TCIOFLUSH) < 0)
501 warn("tcflush failed: %m");
503 * Restore the previous line discipline
505 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
506 if ( ! ok_error (errno))
507 error("ioctl(TIOCSETD, N_TTY): %m");
510 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
511 if ( ! ok_error (errno))
512 warn("ioctl(TIOCNXCL): %m(%d)", errno);
515 /* Reset non-blocking mode on fd. */
516 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
517 if ( ! ok_error (errno))
518 warn("Couldn't restore device fd flags: %m");
521 initfdflags = -1;
523 if (new_style_driver) {
524 close(ppp_fd);
525 ppp_fd = -1;
526 if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
527 error("Couldn't release PPP unit: %m");
528 if (!multilink)
529 remove_fd(ppp_dev_fd);
534 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
535 * Assumes new_style_driver.
537 static int make_ppp_unit()
539 int x;
541 ifunit = req_unit;
542 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
543 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
544 warn("Couldn't allocate PPP unit %d as it is already in use");
545 ifunit = -1;
546 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
548 if (x < 0)
549 error("Couldn't create new ppp unit: %m");
550 return x;
554 * cfg_bundle - configure the existing bundle.
555 * Used in demand mode.
557 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
559 int flags;
560 struct ifreq ifr;
562 if (!new_style_driver)
563 return;
565 /* set the mrru, mtu and flags */
566 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
567 error("Couldn't set MRRU: %m");
568 flags = get_flags(ppp_dev_fd);
569 flags &= ~(SC_MP_SHORTSEQ | SC_MP_XSHORTSEQ);
570 flags |= (rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0);
572 if (mtru > 0 && mtru != link_mtu) {
573 memset(&ifr, 0, sizeof(ifr));
574 slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "ppp%d", ifunit);
575 ifr.ifr_mtu = mtru;
576 if (ioctl(sock_fd, SIOCSIFMTU, &ifr) < 0)
577 error("Couldn't set interface MTU: %m");
578 flags |= SC_MULTILINK;
581 set_flags(ppp_dev_fd, flags);
583 /* connect up the channel */
584 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
585 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
586 add_fd(ppp_dev_fd);
590 * make_new_bundle - create a new PPP unit (i.e. a bundle)
591 * and connect our channel to it. This should only get called
592 * if `multilink' was set at the time establish_ppp was called.
593 * In demand mode this uses our existing bundle instead of making
594 * a new one.
596 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
598 if (!new_style_driver)
599 return;
601 /* make us a ppp unit */
602 if (make_ppp_unit() < 0)
603 die(1);
605 /* set the mrru, mtu and flags */
606 cfg_bundle(mrru, mtru, rssn, tssn);
610 * bundle_attach - attach our link to a given PPP unit.
611 * We assume the unit is controlled by another pppd.
613 int bundle_attach(int ifnum)
615 if (!new_style_driver)
616 return -1;
618 if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) {
619 if (errno == ENXIO)
620 return 0; /* doesn't still exist */
621 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
623 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
624 fatal("Couldn't connect to interface unit %d: %m", ifnum);
625 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK);
627 ifunit = ifnum;
628 return 1;
631 /********************************************************************
633 * clean_check - Fetch the flags for the device and generate
634 * appropriate error messages.
636 void clean_check(void)
638 int x;
639 char *s;
641 if (still_ppp()) {
642 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
643 s = NULL;
644 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
645 case SC_RCV_B7_0:
646 s = "all had bit 7 set to 1";
647 break;
649 case SC_RCV_B7_1:
650 s = "all had bit 7 set to 0";
651 break;
653 case SC_RCV_EVNP:
654 s = "all had odd parity";
655 break;
657 case SC_RCV_ODDP:
658 s = "all had even parity";
659 break;
662 if (s != NULL) {
663 warn("Receive serial link is not 8-bit clean:");
664 warn("Problem: %s", s);
672 * List of valid speeds.
675 struct speed {
676 int speed_int, speed_val;
677 } speeds[] = {
678 #ifdef B50
679 { 50, B50 },
680 #endif
681 #ifdef B75
682 { 75, B75 },
683 #endif
684 #ifdef B110
685 { 110, B110 },
686 #endif
687 #ifdef B134
688 { 134, B134 },
689 #endif
690 #ifdef B150
691 { 150, B150 },
692 #endif
693 #ifdef B200
694 { 200, B200 },
695 #endif
696 #ifdef B300
697 { 300, B300 },
698 #endif
699 #ifdef B600
700 { 600, B600 },
701 #endif
702 #ifdef B1200
703 { 1200, B1200 },
704 #endif
705 #ifdef B1800
706 { 1800, B1800 },
707 #endif
708 #ifdef B2000
709 { 2000, B2000 },
710 #endif
711 #ifdef B2400
712 { 2400, B2400 },
713 #endif
714 #ifdef B3600
715 { 3600, B3600 },
716 #endif
717 #ifdef B4800
718 { 4800, B4800 },
719 #endif
720 #ifdef B7200
721 { 7200, B7200 },
722 #endif
723 #ifdef B9600
724 { 9600, B9600 },
725 #endif
726 #ifdef B19200
727 { 19200, B19200 },
728 #endif
729 #ifdef B38400
730 { 38400, B38400 },
731 #endif
732 #ifdef B57600
733 { 57600, B57600 },
734 #endif
735 #ifdef B115200
736 { 115200, B115200 },
737 #endif
738 #ifdef EXTA
739 { 19200, EXTA },
740 #endif
741 #ifdef EXTB
742 { 38400, EXTB },
743 #endif
744 #ifdef B230400
745 { 230400, B230400 },
746 #endif
747 #ifdef B460800
748 { 460800, B460800 },
749 #endif
750 { 0, 0 }
753 /********************************************************************
755 * Translate from bits/second to a speed_t.
758 static int translate_speed (int bps)
760 struct speed *speedp;
762 if (bps != 0) {
763 for (speedp = speeds; speedp->speed_int; speedp++) {
764 if (bps == speedp->speed_int)
765 return speedp->speed_val;
767 warn("speed %d not supported", bps);
769 return 0;
772 /********************************************************************
774 * Translate from a speed_t to bits/second.
777 static int baud_rate_of (int speed)
779 struct speed *speedp;
781 if (speed != 0) {
782 for (speedp = speeds; speedp->speed_int; speedp++) {
783 if (speed == speedp->speed_val)
784 return speedp->speed_int;
787 return 0;
790 /********************************************************************
792 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
793 * at the requested speed, etc. If `local' is true, set CLOCAL
794 * regardless of whether the modem option was specified.
797 void set_up_tty(int tty_fd, int local)
799 int speed;
800 struct termios tios;
802 setdtr(tty_fd, 1);
803 if (tcgetattr(tty_fd, &tios) < 0) {
804 if (!ok_error(errno))
805 fatal("tcgetattr: %m(%d)", errno);
806 return;
809 if (!restore_term)
810 inittermios = tios;
812 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
813 tios.c_cflag |= CS8 | CREAD | HUPCL;
815 tios.c_iflag = IGNBRK | IGNPAR;
816 tios.c_oflag = 0;
817 tios.c_lflag = 0;
818 tios.c_cc[VMIN] = 1;
819 tios.c_cc[VTIME] = 0;
821 if (local || !modem)
822 tios.c_cflag ^= (CLOCAL | HUPCL);
824 switch (crtscts) {
825 case 1:
826 tios.c_cflag |= CRTSCTS;
827 break;
829 case -2:
830 tios.c_iflag |= IXON | IXOFF;
831 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
832 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
833 break;
835 case -1:
836 tios.c_cflag &= ~CRTSCTS;
837 break;
839 default:
840 break;
843 speed = translate_speed(inspeed);
844 if (speed) {
845 cfsetospeed (&tios, speed);
846 cfsetispeed (&tios, speed);
849 * We can't proceed if the serial port speed is B0,
850 * since that implies that the serial port is disabled.
852 else {
853 speed = cfgetospeed(&tios);
854 if (speed == B0)
855 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
858 if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0)
859 if (!ok_error(errno))
860 fatal("tcsetattr: %m");
862 baud_rate = baud_rate_of(speed);
863 restore_term = 1;
866 /********************************************************************
868 * setdtr - control the DTR line on the serial port.
869 * This is called from die(), so it shouldn't call die().
872 void setdtr (int tty_fd, int on)
874 int modembits = TIOCM_DTR;
876 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
879 /********************************************************************
881 * restore_tty - restore the terminal to the saved settings.
884 void restore_tty (int tty_fd)
886 if (restore_term) {
887 restore_term = 0;
889 * Turn off echoing, because otherwise we can get into
890 * a loop with the tty and the modem echoing to each other.
891 * We presume we are the sole user of this tty device, so
892 * when we close it, it will revert to its defaults anyway.
894 if (!default_device)
895 inittermios.c_lflag &= ~(ECHO | ECHONL);
897 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
898 if (! ok_error (errno))
899 warn("tcsetattr: %m");
904 /********************************************************************
906 * output - Output PPP packet.
909 void output (int unit, unsigned char *p, int len)
911 int fd = ppp_fd;
912 int proto;
914 if (debug)
915 dbglog("sent %P", p, len);
917 if (len < PPP_HDRLEN)
918 return;
919 if (new_style_driver) {
920 p += 2;
921 len -= 2;
922 proto = (p[0] << 8) + p[1];
923 if (ifunit >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
924 fd = ppp_dev_fd;
926 if (write(fd, p, len) < 0) {
927 if (errno == EWOULDBLOCK || errno == ENOBUFS
928 || errno == ENXIO || errno == EIO || errno == EINTR)
929 warn("write: warning: %m (%d)", errno);
930 else
931 error("write: %m (%d)", errno);
935 /********************************************************************
937 * wait_input - wait until there is data available,
938 * for the length of time specified by *timo (indefinite
939 * if timo is NULL).
942 void wait_input(struct timeval *timo)
944 fd_set ready, exc;
945 int n;
947 ready = in_fds;
948 exc = in_fds;
949 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
950 if (n < 0 && errno != EINTR)
951 fatal("select: %m(%d)", errno);
955 * add_fd - add an fd to the set that wait_input waits for.
957 void add_fd(int fd)
959 FD_SET(fd, &in_fds);
960 if (fd > max_in_fd)
961 max_in_fd = fd;
965 * remove_fd - remove an fd from the set that wait_input waits for.
967 void remove_fd(int fd)
969 FD_CLR(fd, &in_fds);
973 /********************************************************************
975 * read_packet - get a PPP packet from the serial device.
978 int read_packet (unsigned char *buf)
980 int len, nr;
982 len = PPP_MRU + PPP_HDRLEN;
983 if (new_style_driver) {
984 *buf++ = PPP_ALLSTATIONS;
985 *buf++ = PPP_UI;
986 len -= 2;
988 nr = -1;
989 if (ppp_fd >= 0) {
990 nr = read(ppp_fd, buf, len);
991 if (nr < 0 && errno != EWOULDBLOCK && errno != EIO)
992 error("read: %m");
994 if (nr < 0 && new_style_driver && ifunit >= 0) {
995 /* N.B. we read ppp_fd first since LCP packets come in there. */
996 nr = read(ppp_dev_fd, buf, len);
997 if (nr < 0 && errno != EWOULDBLOCK && errno != EIO)
998 error("read /dev/ppp: %m");
1000 return (new_style_driver && nr > 0)? nr+2: nr;
1003 /********************************************************************
1005 * get_loop_output - get outgoing packets from the ppp device,
1006 * and detect when we want to bring the real link up.
1007 * Return value is 1 if we need to bring up the link, 0 otherwise.
1010 get_loop_output(void)
1012 int rv = 0;
1013 int n;
1015 if (new_style_driver) {
1016 while ((n = read_packet(inpacket_buf)) > 0)
1017 if (loop_frame(inpacket_buf, n))
1018 rv = 1;
1019 return rv;
1022 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1023 if (loop_chars(inbuf, n))
1024 rv = 1;
1026 if (n == 0)
1027 fatal("eof on loopback");
1029 if (errno != EWOULDBLOCK)
1030 fatal("read from loopback: %m(%d)", errno);
1032 return rv;
1035 /********************************************************************
1037 * ppp_send_config - configure the transmit characteristics of
1038 * the ppp interface.
1041 void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp)
1043 u_int x;
1044 struct ifreq ifr;
1046 SYSDEBUG ((LOG_DEBUG, "send_config: mtu = %d\n", mtu));
1048 * Set the MTU and other parameters for the ppp device
1050 memset (&ifr, '\0', sizeof (ifr));
1051 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1052 ifr.ifr_mtu = mtu;
1054 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1055 fatal("ioctl(SIOCSIFMTU): %m(%d)", errno);
1056 link_mtu = mtu;
1058 if (!still_ppp())
1059 return;
1060 SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
1061 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1062 if (!ok_error(errno))
1063 fatal("ioctl(PPPIOCSASYNCMAP): %m(%d)", errno);
1064 return;
1067 x = get_flags(ppp_fd);
1068 x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
1069 x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
1070 x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
1071 set_flags(ppp_fd, x);
1074 /********************************************************************
1076 * ppp_set_xaccm - set the extended transmit ACCM for the interface.
1079 void ppp_set_xaccm (int unit, ext_accm accm)
1081 SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
1082 accm[0], accm[1], accm[2], accm[3]));
1084 if (!still_ppp())
1085 return;
1086 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1087 if ( ! ok_error (errno))
1088 warn("ioctl(set extended ACCM): %m(%d)", errno);
1092 /********************************************************************
1094 * ppp_recv_config - configure the receive-side characteristics of
1095 * the ppp interface.
1098 void ppp_recv_config (int unit,int mru,u_int32_t asyncmap,int pcomp,int accomp)
1100 SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
1102 * If we were called because the link has gone down then there is nothing
1103 * which may be done. Just return without incident.
1105 if (!still_ppp())
1106 return;
1108 * Set the receiver parameters
1110 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1111 if ( ! ok_error (errno))
1112 error("ioctl(PPPIOCSMRU): %m(%d)", errno);
1114 if (new_style_driver && ifunit >= 0
1115 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1116 error("Couldn't set MRU in generic PPP layer: %m");
1118 SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
1119 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1120 if (!ok_error(errno))
1121 error("ioctl(PPPIOCSRASYNCMAP): %m(%d)", errno);
1125 /********************************************************************
1127 * ccp_test - ask kernel whether a given compression method
1128 * is acceptable for use.
1131 int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1133 struct ppp_option_data data;
1135 memset (&data, '\0', sizeof (data));
1136 data.ptr = opt_ptr;
1137 data.length = opt_len;
1138 data.transmit = for_transmit;
1140 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1141 return 1;
1143 return (errno == ENOBUFS)? 0: -1;
1146 /********************************************************************
1148 * ccp_flags_set - inform kernel about the current state of CCP.
1151 void ccp_flags_set (int unit, int isopen, int isup)
1153 if (still_ppp()) {
1154 int x = get_flags(ppp_dev_fd);
1155 x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;
1156 x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP;
1157 set_flags (ppp_dev_fd, x);
1161 /********************************************************************
1163 * get_idle_time - return how long the link has been idle.
1166 get_idle_time(u, ip)
1167 int u;
1168 struct ppp_idle *ip;
1170 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1173 /********************************************************************
1175 * get_ppp_stats - return statistics for the link.
1178 get_ppp_stats(u, stats)
1179 int u;
1180 struct pppd_stats *stats;
1182 struct ifpppstatsreq req;
1184 memset (&req, 0, sizeof (req));
1186 req.stats_ptr = (caddr_t) &req.stats;
1187 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1188 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1189 error("Couldn't get PPP statistics: %m");
1190 return 0;
1192 stats->bytes_in = req.stats.p.ppp_ibytes;
1193 stats->bytes_out = req.stats.p.ppp_obytes;
1194 return 1;
1197 /********************************************************************
1199 * ccp_fatal_error - returns 1 if decompression was disabled as a
1200 * result of an error detected after decompression of a packet,
1201 * 0 otherwise. This is necessary because of patent nonsense.
1204 int ccp_fatal_error (int unit)
1206 int x = get_flags(ppp_dev_fd);
1208 return x & SC_DC_FERROR;
1211 /********************************************************************
1213 * path_to_procfs - find the path to the proc file system mount point
1215 static char proc_path[MAXPATHLEN];
1216 static int proc_path_len;
1218 static char *path_to_procfs(const char *tail)
1220 struct mntent *mntent;
1221 FILE *fp;
1223 if (proc_path_len == 0) {
1224 /* Default the mount location of /proc */
1225 strlcpy (proc_path, "/proc", sizeof(proc_path));
1226 proc_path_len = 5;
1227 fp = fopen(MOUNTED, "r");
1228 if (fp != NULL) {
1229 while ((mntent = getmntent(fp)) != NULL) {
1230 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1231 continue;
1232 if (strcmp(mntent->mnt_type, "proc") == 0) {
1233 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1234 proc_path_len = strlen(proc_path);
1235 break;
1238 fclose (fp);
1242 strlcpy(proc_path + proc_path_len, tail,
1243 sizeof(proc_path) - proc_path_len);
1244 return proc_path;
1248 * /proc/net/route parsing stuff.
1250 #define ROUTE_MAX_COLS 12
1251 FILE *route_fd = (FILE *) 0;
1252 static char route_buffer[512];
1253 static int route_dev_col, route_dest_col, route_gw_col;
1254 static int route_flags_col, route_mask_col;
1255 static int route_num_cols;
1257 static int open_route_table (void);
1258 static void close_route_table (void);
1259 static int read_route_table (struct rtentry *rt);
1261 /********************************************************************
1263 * close_route_table - close the interface to the route table
1266 static void close_route_table (void)
1268 if (route_fd != (FILE *) 0) {
1269 fclose (route_fd);
1270 route_fd = (FILE *) 0;
1274 /********************************************************************
1276 * open_route_table - open the interface to the route table
1278 static char route_delims[] = " \t\n";
1280 static int open_route_table (void)
1282 char *path;
1284 close_route_table();
1286 path = path_to_procfs("/net/route");
1287 route_fd = fopen (path, "r");
1288 if (route_fd == NULL) {
1289 error("can't open routing table %s: %m", path);
1290 return 0;
1293 route_dev_col = 0; /* default to usual columns */
1294 route_dest_col = 1;
1295 route_gw_col = 2;
1296 route_flags_col = 3;
1297 route_mask_col = 7;
1298 route_num_cols = 8;
1300 /* parse header line */
1301 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1302 char *p = route_buffer, *q;
1303 int col;
1304 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1305 int used = 1;
1306 if ((q = strtok(p, route_delims)) == 0)
1307 break;
1308 if (strcasecmp(q, "iface") == 0)
1309 route_dev_col = col;
1310 else if (strcasecmp(q, "destination") == 0)
1311 route_dest_col = col;
1312 else if (strcasecmp(q, "gateway") == 0)
1313 route_gw_col = col;
1314 else if (strcasecmp(q, "flags") == 0)
1315 route_flags_col = col;
1316 else if (strcasecmp(q, "mask") == 0)
1317 route_mask_col = col;
1318 else
1319 used = 0;
1320 if (used && col >= route_num_cols)
1321 route_num_cols = col + 1;
1322 p = NULL;
1326 return 1;
1329 /********************************************************************
1331 * read_route_table - read the next entry from the route table
1334 static int read_route_table(struct rtentry *rt)
1336 char *cols[ROUTE_MAX_COLS], *p;
1337 int col;
1339 memset (rt, '\0', sizeof (struct rtentry));
1341 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1342 return 0;
1344 p = route_buffer;
1345 for (col = 0; col < route_num_cols; ++col) {
1346 cols[col] = strtok(p, route_delims);
1347 if (cols[col] == NULL)
1348 return 0; /* didn't get enough columns */
1349 p = NULL;
1352 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1353 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1354 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1356 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1357 rt->rt_dev = cols[route_dev_col];
1359 return 1;
1362 /********************************************************************
1364 * defaultroute_exists - determine if there is a default route
1367 static int defaultroute_exists (struct rtentry *rt)
1369 int result = 0;
1371 if (!open_route_table())
1372 return 0;
1374 while (read_route_table(rt) != 0) {
1375 if ((rt->rt_flags & RTF_UP) == 0)
1376 continue;
1378 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1379 continue;
1380 if (SIN_ADDR(rt->rt_dst) == 0L) {
1381 result = 1;
1382 break;
1386 close_route_table();
1387 return result;
1391 * have_route_to - determine if the system has any route to
1392 * a given IP address. `addr' is in network byte order.
1393 * Return value is 1 if yes, 0 if no, -1 if don't know.
1394 * For demand mode to work properly, we have to ignore routes
1395 * through our own interface.
1397 int have_route_to(u_int32_t addr)
1399 struct rtentry rt;
1400 int result = 0;
1402 if (!open_route_table())
1403 return -1; /* don't know */
1405 while (read_route_table(&rt)) {
1406 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1407 continue;
1408 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1409 result = 1;
1410 break;
1414 close_route_table();
1415 return result;
1418 /********************************************************************
1420 * sifdefaultroute - assign a default route through the address given.
1423 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1425 struct rtentry rt;
1427 if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1428 u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1430 if (old_gateway != gateway)
1431 error("not replacing existing default route to %s [%I]",
1432 rt.rt_dev, old_gateway);
1433 return 0;
1436 memset (&rt, '\0', sizeof (rt));
1437 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1438 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1440 if (kernel_version > KVERSION(2,1,0)) {
1441 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1442 SIN_ADDR(rt.rt_genmask) = 0L;
1445 SIN_ADDR(rt.rt_gateway) = gateway;
1447 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1448 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1449 if ( ! ok_error ( errno ))
1450 error("default route ioctl(SIOCADDRT): %m(%d)", errno);
1451 return 0;
1454 default_route_gateway = gateway;
1455 return 1;
1458 /********************************************************************
1460 * cifdefaultroute - delete a default route through the address given.
1463 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1465 struct rtentry rt;
1467 default_route_gateway = 0;
1469 memset (&rt, '\0', sizeof (rt));
1470 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1471 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1473 if (kernel_version > KVERSION(2,1,0)) {
1474 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1475 SIN_ADDR(rt.rt_genmask) = 0L;
1478 SIN_ADDR(rt.rt_gateway) = gateway;
1480 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1481 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1482 if (still_ppp()) {
1483 if ( ! ok_error ( errno ))
1484 error("default route ioctl(SIOCDELRT): %m (%d)", errno);
1485 return 0;
1489 return 1;
1492 /********************************************************************
1494 * sifproxyarp - Make a proxy ARP entry for the peer.
1497 int sifproxyarp (int unit, u_int32_t his_adr)
1499 struct arpreq arpreq;
1500 char *forw_path;
1502 if (has_proxy_arp == 0) {
1503 memset (&arpreq, '\0', sizeof(arpreq));
1505 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1506 SIN_ADDR(arpreq.arp_pa) = his_adr;
1507 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1509 * Get the hardware address of an interface on the same subnet
1510 * as our local address.
1512 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1513 sizeof(proxy_arp_dev))) {
1514 error("Cannot determine ethernet address for proxy ARP");
1515 return 0;
1517 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1519 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1520 if ( ! ok_error ( errno ))
1521 error("ioctl(SIOCSARP): %m(%d)", errno);
1522 return 0;
1524 proxy_arp_addr = his_adr;
1525 has_proxy_arp = 1;
1527 if (tune_kernel) {
1528 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1529 if (forw_path != 0) {
1530 int fd = open(forw_path, O_WRONLY);
1531 if (fd >= 0) {
1532 if (write(fd, "1", 1) != 1)
1533 error("Couldn't enable IP forwarding: %m");
1534 close(fd);
1540 return 1;
1543 /********************************************************************
1545 * cifproxyarp - Delete the proxy ARP entry for the peer.
1548 int cifproxyarp (int unit, u_int32_t his_adr)
1550 struct arpreq arpreq;
1552 if (has_proxy_arp) {
1553 has_proxy_arp = 0;
1554 memset (&arpreq, '\0', sizeof(arpreq));
1555 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1556 SIN_ADDR(arpreq.arp_pa) = his_adr;
1557 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1558 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1560 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1561 if ( ! ok_error ( errno ))
1562 warn("ioctl(SIOCDARP): %m(%d)", errno);
1563 return 0;
1566 return 1;
1569 /********************************************************************
1571 * get_ether_addr - get the hardware address of an interface on the
1572 * the same subnet as ipaddr.
1575 static int get_ether_addr (u_int32_t ipaddr,
1576 struct sockaddr *hwaddr,
1577 char *name, int namelen)
1579 struct ifreq *ifr, *ifend;
1580 u_int32_t ina, mask;
1581 char *aliasp;
1582 struct ifreq ifreq;
1583 struct ifconf ifc;
1584 struct ifreq ifs[MAX_IFS];
1586 ifc.ifc_len = sizeof(ifs);
1587 ifc.ifc_req = ifs;
1588 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1589 if ( ! ok_error ( errno ))
1590 error("ioctl(SIOCGIFCONF): %m(%d)", errno);
1591 return 0;
1594 SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1595 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1597 * Scan through looking for an interface with an Internet
1598 * address on the same subnet as `ipaddr'.
1600 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1601 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1602 if (ifr->ifr_addr.sa_family == AF_INET) {
1603 ina = SIN_ADDR(ifr->ifr_addr);
1604 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1605 SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1606 ifreq.ifr_name));
1608 * Check that the interface is up, and not point-to-point
1609 * nor loopback.
1611 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1612 continue;
1614 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1615 continue;
1617 * Get its netmask and check that it's on the right subnet.
1619 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1620 continue;
1622 mask = SIN_ADDR(ifreq.ifr_addr);
1623 SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1624 ip_ntoa(ina), ntohl(mask)));
1626 if (((ipaddr ^ ina) & mask) != 0)
1627 continue;
1628 break;
1632 if (ifr >= ifend)
1633 return 0;
1635 strlcpy(name, ifreq.ifr_name, namelen);
1637 /* trim off the :1 in eth0:1 */
1638 aliasp = strchr(name, ':');
1639 if (aliasp != 0)
1640 *aliasp = 0;
1642 info("found interface %s for proxy arp", name);
1644 * Now get the hardware address.
1646 memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1647 if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0) {
1648 error("SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno);
1649 return 0;
1652 memcpy (hwaddr,
1653 &ifreq.ifr_hwaddr,
1654 sizeof (struct sockaddr));
1656 SYSDEBUG ((LOG_DEBUG,
1657 "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1658 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1659 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1660 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1661 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1662 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1663 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1664 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1665 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1666 return 1;
1670 * get_if_hwaddr - get the hardware address for the specified
1671 * network interface device.
1674 get_if_hwaddr(u_char *addr, char *name)
1676 struct ifreq ifreq;
1677 int ret, sock_fd;
1679 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1680 if (sock_fd < 0)
1681 return 0;
1682 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1683 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1684 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1685 close(sock_fd);
1686 if (ret >= 0)
1687 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1688 return ret;
1692 * get_first_ethernet - return the name of the first ethernet-style
1693 * interface on this system.
1695 char *
1696 get_first_ethernet()
1698 return "eth0";
1701 /********************************************************************
1703 * Return user specified netmask, modified by any mask we might determine
1704 * for address `addr' (in network byte order).
1705 * Here we scan through the system's list of interfaces, looking for
1706 * any non-point-to-point interfaces which might appear to be on the same
1707 * network as `addr'. If we find any, we OR in their netmask to the
1708 * user-specified netmask.
1711 u_int32_t GetMask (u_int32_t addr)
1713 u_int32_t mask, nmask, ina;
1714 struct ifreq *ifr, *ifend, ifreq;
1715 struct ifconf ifc;
1716 struct ifreq ifs[MAX_IFS];
1718 addr = ntohl(addr);
1720 if (IN_CLASSA(addr)) /* determine network mask for address class */
1721 nmask = IN_CLASSA_NET;
1722 else if (IN_CLASSB(addr))
1723 nmask = IN_CLASSB_NET;
1724 else
1725 nmask = IN_CLASSC_NET;
1727 /* class D nets are disallowed by bad_ip_adrs */
1728 mask = netmask | htonl(nmask);
1730 * Scan through the system's network interfaces.
1732 ifc.ifc_len = sizeof(ifs);
1733 ifc.ifc_req = ifs;
1734 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1735 if ( ! ok_error ( errno ))
1736 warn("ioctl(SIOCGIFCONF): %m(%d)", errno);
1737 return mask;
1740 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1741 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1743 * Check the interface's internet address.
1745 if (ifr->ifr_addr.sa_family != AF_INET)
1746 continue;
1747 ina = SIN_ADDR(ifr->ifr_addr);
1748 if (((ntohl(ina) ^ addr) & nmask) != 0)
1749 continue;
1751 * Check that the interface is up, and not point-to-point nor loopback.
1753 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1754 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1755 continue;
1757 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1758 continue;
1760 * Get its netmask and OR it into our mask.
1762 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1763 continue;
1764 mask |= SIN_ADDR(ifreq.ifr_addr);
1765 break;
1767 return mask;
1770 /********************************************************************
1772 * Internal routine to decode the version.modification.patch level
1775 static void decode_version (char *buf, int *version,
1776 int *modification, int *patch)
1778 *version = (int) strtoul (buf, &buf, 10);
1779 *modification = 0;
1780 *patch = 0;
1782 if (*buf == '.') {
1783 ++buf;
1784 *modification = (int) strtoul (buf, &buf, 10);
1785 if (*buf == '.') {
1786 ++buf;
1787 *patch = (int) strtoul (buf, &buf, 10);
1791 if (*buf != '\0') {
1792 *version =
1793 *modification =
1794 *patch = 0;
1798 /********************************************************************
1800 * Procedure to determine if the PPP line discipline is registered.
1803 static int
1804 ppp_registered(void)
1806 int local_fd;
1807 int mfd = -1;
1808 int ret = 0;
1809 char slave[16];
1812 * We used to open the serial device and set it to the ppp line
1813 * discipline here, in order to create a ppp unit. But that is
1814 * not a good idea - the user might have specified a device that
1815 * they can't open (permission, or maybe it doesn't really exist).
1816 * So we grab a pty master/slave pair and use that.
1818 if (!get_pty(&mfd, &local_fd, slave, 0)) {
1819 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1820 return 0;
1824 * Try to put the device into the PPP discipline.
1826 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1827 error("ioctl(TIOCSETD(PPP)): %m(%d)", errno);
1828 } else
1829 ret = 1;
1831 close(local_fd);
1832 close(mfd);
1833 return ret;
1836 /********************************************************************
1838 * ppp_available - check whether the system has any ppp interfaces
1839 * (in fact we check whether we can do an ioctl on ppp0).
1842 int ppp_available(void)
1844 int s, ok, fd;
1845 struct ifreq ifr;
1846 int size;
1847 int my_version, my_modification, my_patch;
1848 int osmaj, osmin, ospatch;
1850 no_ppp_msg =
1851 "This system lacks kernel support for PPP. This could be because\n"
1852 "the PPP kernel module could not be loaded, or because PPP was not\n"
1853 "included in the kernel configuration. If PPP was included as a\n"
1854 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
1855 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
1856 "See README.linux file in the ppp distribution for more details.\n";
1858 /* get the kernel version now, since we are called before sys_init */
1859 uname(&utsname);
1860 osmaj = osmin = ospatch = 0;
1861 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
1862 kernel_version = KVERSION(osmaj, osmin, ospatch);
1864 fd = open("/dev/ppp", O_RDWR);
1865 #if 0
1866 if (fd < 0 && errno == ENOENT) {
1867 /* try making it and see if that helps. */
1868 if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR,
1869 makedev(108, 0)) >= 0) {
1870 fd = open("/dev/ppp", O_RDWR);
1871 if (fd >= 0)
1872 info("Created /dev/ppp device node");
1873 else
1874 unlink("/dev/ppp"); /* didn't work, undo the mknod */
1875 } else if (errno == EEXIST) {
1876 fd = open("/dev/ppp", O_RDWR);
1879 #endif /* 0 */
1880 if (fd >= 0) {
1881 new_style_driver = 1;
1883 /* XXX should get from driver */
1884 driver_version = 2;
1885 driver_modification = 4;
1886 driver_patch = 0;
1887 close(fd);
1888 return 1;
1890 if (kernel_version >= KVERSION(2,3,13))
1891 return 0;
1894 * Open a socket for doing the ioctl operations.
1896 s = socket(AF_INET, SOCK_DGRAM, 0);
1897 if (s < 0)
1898 return 0;
1900 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1901 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1903 * If the device did not exist then attempt to create one by putting the
1904 * current tty into the PPP discipline. If this works then obtain the
1905 * flags for the device again.
1907 if (!ok) {
1908 if (ppp_registered()) {
1909 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1910 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1914 * Ensure that the hardware address is for PPP and not something else
1916 if (ok)
1917 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
1919 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
1920 ok = 0;
1923 * This is the PPP device. Validate the version of the driver at this
1924 * point to ensure that this program will work with the driver.
1926 if (ok) {
1927 char abBuffer [1024];
1929 ifr.ifr_data = abBuffer;
1930 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
1931 if (size < 0) {
1932 error("Couldn't read driver version: %m");
1933 ok = 0;
1934 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
1936 } else {
1937 decode_version(abBuffer,
1938 &driver_version,
1939 &driver_modification,
1940 &driver_patch);
1942 * Validate the version of the driver against the version that we used.
1944 decode_version(VERSION,
1945 &my_version,
1946 &my_modification,
1947 &my_patch);
1949 /* The version numbers must match */
1950 if (driver_version != my_version)
1951 ok = 0;
1953 /* The modification levels must be legal */
1954 if (driver_modification < 3) {
1955 if (driver_modification >= 2) {
1956 /* we can cope with 2.2.0 and above */
1957 driver_is_old = 1;
1958 } else {
1959 ok = 0;
1963 close (s);
1964 if (!ok) {
1965 slprintf(route_buffer, sizeof(route_buffer),
1966 "Sorry - PPP driver version %d.%d.%d is out of date\n",
1967 driver_version, driver_modification, driver_patch);
1969 no_ppp_msg = route_buffer;
1973 return ok;
1976 /********************************************************************
1978 * Update the wtmp file with the appropriate user name and tty device.
1981 void logwtmp (const char *line, const char *name, const char *host)
1983 struct utmp ut, *utp;
1984 pid_t mypid = getpid();
1985 #if __GLIBC__ < 2
1986 int wtmp;
1987 #endif
1990 * Update the signon database for users.
1991 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
1993 utmpname(_PATH_UTMP);
1994 setutent();
1995 while ((utp = getutent()) && (utp->ut_pid != mypid))
1996 /* nothing */;
1998 /* Is this call really necessary? There is another one after the 'put' */
1999 endutent();
2001 if (utp)
2002 memcpy(&ut, utp, sizeof(ut));
2003 else
2004 /* some gettys/telnetds don't initialize utmp... */
2005 memset(&ut, 0, sizeof(ut));
2007 if (ut.ut_id[0] == 0)
2008 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2010 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2011 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2013 time(&ut.ut_time);
2015 ut.ut_type = USER_PROCESS;
2016 ut.ut_pid = mypid;
2018 /* Insert the host name if one is supplied */
2019 if (*host)
2020 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2022 /* Insert the IP address of the remote system if IP is enabled */
2023 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2024 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2025 sizeof(ut.ut_addr));
2027 /* CL: Makes sure that the logout works */
2028 if (*host == 0 && *name==0)
2029 ut.ut_host[0]=0;
2031 pututline(&ut);
2032 endutent();
2034 * Update the wtmp file.
2036 #if __GLIBC__ >= 2
2037 updwtmp(_PATH_WTMP, &ut);
2038 #else
2039 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2040 if (wtmp >= 0) {
2041 flock(wtmp, LOCK_EX);
2043 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2044 warn("error writing %s: %m", _PATH_WTMP);
2046 flock(wtmp, LOCK_UN);
2048 close (wtmp);
2050 #endif
2054 /********************************************************************
2056 * sifvjcomp - config tcp header compression
2059 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2061 u_int x = get_flags(ppp_dev_fd);
2063 if (vjcomp) {
2064 if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2065 if (! ok_error (errno))
2066 error("ioctl(PPPIOCSMAXCID): %m(%d)", errno);
2067 vjcomp = 0;
2071 x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP;
2072 x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
2073 set_flags (ppp_dev_fd, x);
2075 return 1;
2078 /********************************************************************
2080 * sifup - Config the interface up and enable IP packets to pass.
2083 int sifup(int u)
2085 struct ifreq ifr;
2087 memset (&ifr, '\0', sizeof (ifr));
2088 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2089 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2090 if (! ok_error (errno))
2091 error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
2092 return 0;
2095 ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2096 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2097 if (! ok_error (errno))
2098 error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
2099 return 0;
2101 if_is_up++;
2103 return 1;
2106 /********************************************************************
2108 * sifdown - Disable the indicated protocol and config the interface
2109 * down if there are no remaining protocols.
2112 int sifdown (int u)
2114 struct ifreq ifr;
2116 if (if_is_up && --if_is_up > 0)
2117 return 1;
2119 memset (&ifr, '\0', sizeof (ifr));
2120 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2121 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2122 if (! ok_error (errno))
2123 error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
2124 return 0;
2127 ifr.ifr_flags &= ~IFF_UP;
2128 ifr.ifr_flags |= IFF_POINTOPOINT;
2129 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2130 if (! ok_error (errno))
2131 error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
2132 return 0;
2134 return 1;
2137 /********************************************************************
2139 * sifaddr - Config the interface IP addresses and netmask.
2142 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2143 u_int32_t net_mask)
2145 struct ifreq ifr;
2146 struct rtentry rt;
2148 memset (&ifr, '\0', sizeof (ifr));
2149 memset (&rt, '\0', sizeof (rt));
2151 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2152 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2153 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2155 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2157 * Set our IP address
2159 SIN_ADDR(ifr.ifr_addr) = our_adr;
2160 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2161 if (errno != EEXIST) {
2162 if (! ok_error (errno))
2163 error("ioctl(SIOCSIFADDR): %m(%d)", errno);
2165 else {
2166 warn("ioctl(SIOCSIFADDR): Address already exists");
2168 return (0);
2171 * Set the gateway address
2173 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2174 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2175 if (! ok_error (errno))
2176 error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno);
2177 return (0);
2180 * Set the netmask.
2181 * For recent kernels, force the netmask to 255.255.255.255.
2183 if (kernel_version >= KVERSION(2,1,16))
2184 net_mask = ~0L;
2185 if (net_mask != 0) {
2186 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2187 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2188 if (! ok_error (errno))
2189 error("ioctl(SIOCSIFNETMASK): %m(%d)", errno);
2190 return (0);
2194 * Add the device route
2196 if (kernel_version < KVERSION(2,1,16)) {
2197 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2198 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2199 rt.rt_dev = ifname;
2201 SIN_ADDR(rt.rt_gateway) = 0L;
2202 SIN_ADDR(rt.rt_dst) = his_adr;
2203 rt.rt_flags = RTF_UP | RTF_HOST;
2205 if (kernel_version > KVERSION(2,1,0)) {
2206 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2207 SIN_ADDR(rt.rt_genmask) = -1L;
2210 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2211 if (! ok_error (errno))
2212 error("ioctl(SIOCADDRT) device route: %m(%d)", errno);
2213 return (0);
2217 /* set ip_dynaddr in demand mode if address changes */
2218 if (demand && tune_kernel && !dynaddr_set
2219 && our_old_addr && our_old_addr != our_adr) {
2220 /* set ip_dynaddr if possible */
2221 char *path;
2222 int fd;
2224 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2225 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2226 if (write(fd, "1", 1) != 1)
2227 error("Couldn't enable dynamic IP addressing: %m");
2228 close(fd);
2230 dynaddr_set = 1; /* only 1 attempt */
2232 our_old_addr = 0;
2234 return 1;
2237 /********************************************************************
2239 * cifaddr - Clear the interface IP addresses, and delete routes
2240 * through the interface if possible.
2243 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2245 struct ifreq ifr;
2247 if (kernel_version < KVERSION(2,1,16)) {
2249 * Delete the route through the device
2251 struct rtentry rt;
2252 memset (&rt, '\0', sizeof (rt));
2254 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2255 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2256 rt.rt_dev = ifname;
2258 SIN_ADDR(rt.rt_gateway) = 0;
2259 SIN_ADDR(rt.rt_dst) = his_adr;
2260 rt.rt_flags = RTF_UP | RTF_HOST;
2262 if (kernel_version > KVERSION(2,1,0)) {
2263 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2264 SIN_ADDR(rt.rt_genmask) = -1L;
2267 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2268 if (still_ppp() && ! ok_error (errno))
2269 error("ioctl(SIOCDELRT) device route: %m(%d)", errno);
2270 return (0);
2274 /* This way it is possible to have an IPX-only or IPv6-only interface */
2275 memset(&ifr, 0, sizeof(ifr));
2276 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2277 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2279 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2280 if (! ok_error (errno)) {
2281 error("ioctl(SIOCSIFADDR): %m(%d)", errno);
2282 return 0;
2286 our_old_addr = our_adr;
2288 return 1;
2291 #ifdef INET6
2292 /********************************************************************
2294 * sif6addr - Config the interface with an IPv6 link-local address
2296 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2298 struct in6_ifreq ifr6;
2299 struct ifreq ifr;
2300 struct in6_rtmsg rt6;
2302 memset(&ifr, 0, sizeof (ifr));
2303 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2304 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2305 error("sif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno);
2306 return 0;
2309 /* Local interface */
2310 memset(&ifr6, 0, sizeof(ifr6));
2311 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2312 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2313 ifr6.ifr6_prefixlen = 10;
2315 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2316 error("sif6addr: ioctl(SIOCSIFADDR): %m (%d)", errno);
2317 return 0;
2320 /* Route to remote host */
2321 memset(&rt6, 0, sizeof(rt6));
2322 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2323 rt6.rtmsg_flags = RTF_UP;
2324 rt6.rtmsg_dst_len = 10;
2325 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2326 rt6.rtmsg_metric = 1;
2328 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2329 error("sif6addr: ioctl(SIOCADDRT): %m (%d)", errno);
2330 return 0;
2333 return 1;
2337 /********************************************************************
2339 * cif6addr - Remove IPv6 address from interface
2341 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2343 struct ifreq ifr;
2344 struct in6_ifreq ifr6;
2346 memset(&ifr, 0, sizeof(ifr));
2347 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2348 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2349 error("cif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno);
2350 return 0;
2353 memset(&ifr6, 0, sizeof(ifr6));
2354 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2355 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2356 ifr6.ifr6_prefixlen = 10;
2358 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2359 if (errno != EADDRNOTAVAIL) {
2360 if (! ok_error (errno))
2361 error("cif6addr: ioctl(SIOCDIFADDR): %m (%d)", errno);
2363 else {
2364 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2366 return (0);
2368 return 1;
2370 #endif /* INET6 */
2373 * get_pty - get a pty master/slave pair and chown the slave side
2374 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2377 get_pty(master_fdp, slave_fdp, slave_name, uid)
2378 int *master_fdp;
2379 int *slave_fdp;
2380 char *slave_name;
2381 int uid;
2383 int i, mfd, sfd = -1;
2384 char pty_name[16];
2385 struct termios tios;
2387 #ifdef TIOCGPTN
2389 * Try the unix98 way first.
2391 mfd = open("/dev/ptmx", O_RDWR);
2392 if (mfd >= 0) {
2393 int ptn;
2394 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2395 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2396 chmod(pty_name, S_IRUSR | S_IWUSR);
2397 #ifdef TIOCSPTLCK
2398 ptn = 0;
2399 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2400 warn("Couldn't unlock pty slave %s: %m", pty_name);
2401 #endif
2402 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2403 warn("Couldn't open pty slave %s: %m", pty_name);
2406 #endif /* TIOCGPTN */
2408 if (sfd < 0) {
2409 /* the old way - scan through the pty name space */
2410 for (i = 0; i < 64; ++i) {
2411 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2412 'p' + i / 16, i % 16);
2413 mfd = open(pty_name, O_RDWR, 0);
2414 if (mfd >= 0) {
2415 pty_name[5] = 't';
2416 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2417 if (sfd >= 0) {
2418 fchown(sfd, uid, -1);
2419 fchmod(sfd, S_IRUSR | S_IWUSR);
2420 break;
2422 close(mfd);
2427 if (sfd < 0)
2428 return 0;
2430 strlcpy(slave_name, pty_name, 16);
2431 *master_fdp = mfd;
2432 *slave_fdp = sfd;
2433 if (tcgetattr(sfd, &tios) == 0) {
2434 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2435 tios.c_cflag |= CS8 | CREAD;
2436 tios.c_iflag = IGNPAR | CLOCAL;
2437 tios.c_oflag = 0;
2438 tios.c_lflag = 0;
2439 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2440 warn("couldn't set attributes on pty: %m");
2441 } else
2442 warn("couldn't get attributes on pty: %m");
2444 return 1;
2447 /********************************************************************
2449 * open_loopback - open the device we use for getting packets
2450 * in demand mode. Under Linux, we use a pty master/slave pair.
2453 open_ppp_loopback(void)
2455 int flags;
2457 looped = 1;
2458 if (new_style_driver) {
2459 /* allocate ourselves a ppp unit */
2460 if (make_ppp_unit() < 0)
2461 die(1);
2462 set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC);
2463 set_kdebugflag(kdebugflag);
2464 ppp_fd = -1;
2465 return ppp_dev_fd;
2468 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2469 fatal("No free pty for loopback");
2470 SYSDEBUG(("using %s for loopback", loop_name));
2472 set_ppp_fd(slave_fd);
2474 flags = fcntl(master_fd, F_GETFL);
2475 if (flags == -1 ||
2476 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2477 warn("couldn't set master loopback to nonblock: %m(%d)", errno);
2479 flags = fcntl(ppp_fd, F_GETFL);
2480 if (flags == -1 ||
2481 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2482 warn("couldn't set slave loopback to nonblock: %m(%d)", errno);
2484 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2485 fatal("ioctl(TIOCSETD): %m(%d)", errno);
2487 * Find out which interface we were given.
2489 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2490 fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
2492 * Enable debug in the driver if requested.
2494 set_kdebugflag (kdebugflag);
2496 return master_fd;
2499 /********************************************************************
2501 * restore_loop - reattach the ppp unit to the loopback.
2503 * The kernel ppp driver automatically reattaches the ppp unit to
2504 * the loopback if the serial port is set to a line discipline other
2505 * than ppp, or if it detects a modem hangup. The former will happen
2506 * in disestablish_ppp if the latter hasn't already happened, so we
2507 * shouldn't need to do anything.
2509 * Just to be sure, set the real serial port to the normal discipline.
2512 void
2513 restore_loop(void)
2515 looped = 1;
2516 if (new_style_driver) {
2517 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC);
2518 return;
2520 if (ppp_fd != slave_fd) {
2521 (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
2522 set_ppp_fd(slave_fd);
2526 /********************************************************************
2528 * sifnpmode - Set the mode for handling packets for a given NP.
2532 sifnpmode(u, proto, mode)
2533 int u;
2534 int proto;
2535 enum NPmode mode;
2537 struct npioctl npi;
2539 npi.protocol = proto;
2540 npi.mode = mode;
2541 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2542 if (! ok_error (errno))
2543 error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)",
2544 proto, mode, errno);
2545 return 0;
2547 return 1;
2551 /********************************************************************
2553 * sipxfaddr - Config the interface IPX networknumber
2556 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2558 int result = 1;
2560 #ifdef IPX_CHANGE
2561 int skfd;
2562 struct ifreq ifr;
2563 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2565 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2566 if (skfd < 0) {
2567 if (! ok_error (errno))
2568 dbglog("socket(AF_IPX): %m (%d)", errno);
2569 result = 0;
2571 else {
2572 memset (&ifr, '\0', sizeof (ifr));
2573 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2575 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2576 sipx->sipx_family = AF_IPX;
2577 sipx->sipx_port = 0;
2578 sipx->sipx_network = htonl (network);
2579 sipx->sipx_type = IPX_FRAME_ETHERII;
2580 sipx->sipx_action = IPX_CRTITF;
2582 * Set the IPX device
2584 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2585 result = 0;
2586 if (errno != EEXIST) {
2587 if (! ok_error (errno))
2588 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno);
2590 else {
2591 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2594 close (skfd);
2596 #endif
2597 return result;
2600 /********************************************************************
2602 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2603 * are removed and the device is no longer able to pass IPX
2604 * frames.
2607 int cipxfaddr (int unit)
2609 int result = 1;
2611 #ifdef IPX_CHANGE
2612 int skfd;
2613 struct ifreq ifr;
2614 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2616 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2617 if (skfd < 0) {
2618 if (! ok_error (errno))
2619 dbglog("socket(AF_IPX): %m (%d)", errno);
2620 result = 0;
2622 else {
2623 memset (&ifr, '\0', sizeof (ifr));
2624 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2626 sipx->sipx_type = IPX_FRAME_ETHERII;
2627 sipx->sipx_action = IPX_DLTITF;
2628 sipx->sipx_family = AF_IPX;
2630 * Set the IPX device
2632 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2633 if (! ok_error (errno))
2634 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno);
2635 result = 0;
2637 close (skfd);
2639 #endif
2640 return result;
2644 * Use the hostname as part of the random number seed.
2647 get_host_seed()
2649 int h;
2650 char *p = hostname;
2652 h = 407;
2653 for (p = hostname; *p != 0; ++p)
2654 h = h * 37 + *p;
2655 return h;
2658 /********************************************************************
2660 * sys_check_options - check the options that the user specified
2664 sys_check_options(void)
2666 #ifdef IPX_CHANGE
2668 * Disable the IPX protocol if the support is not present in the kernel.
2670 char *path;
2672 if (ipxcp_protent.enabled_flag) {
2673 struct stat stat_buf;
2674 if ((path = path_to_procfs("/net/ipx_interface")) == 0
2675 || lstat(path, &stat_buf) < 0) {
2676 error("IPX support is not present in the kernel\n");
2677 ipxcp_protent.enabled_flag = 0;
2680 #endif
2681 if (demand && driver_is_old) {
2682 option_error("demand dialling is not supported by kernel driver "
2683 "version %d.%d.%d", driver_version, driver_modification,
2684 driver_patch);
2685 return 0;
2687 if (multilink && !new_style_driver) {
2688 warn("Warning: multilink is not supported by the kernel driver");
2689 multilink = 0;
2691 return 1;