2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
5 * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
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.
18 * 3. Redistributions of any form whatsoever must retain the following
20 * "This product includes software developed by Paul Mackerras
21 * <paulus@samba.org>".
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.
31 * Derived from main.c and pppd.h, which are:
33 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
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
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
54 * Pittsburgh, PA 15213-3890
55 * (412) 268-4387, fax: (412) 268-7395
56 * tech-transfer@andrew.cmu.edu
58 * 4. Redistributions of any form whatsoever must retain the following
60 * "This product includes software developed by Computing Services
61 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
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.
72 #include <sys/ioctl.h>
73 #include <sys/types.h>
74 #include <sys/socket.h>
78 #include <sys/utsname.h>
79 #include <sys/sysmacros.h>
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. */
102 #define MAX_ADDR_LEN 7
105 #if !defined(__GLIBC__) || __GLIBC__ >= 2
106 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
108 #include <net/if_arp.h>
109 #include <net/route.h>
110 #include <netinet/if_ether.h>
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>
118 #include <netinet/in.h>
119 #include <arpa/inet.h>
121 #include <linux/ppp_defs.h>
122 #include <linux/if_ppp.h>
130 #if __GLIBC__ >= 2 && \
131 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
132 #include <netipx/ipx.h>
134 #include <linux/ipx.h>
136 #endif /* IPX_CHANGE */
139 #include <pcap-bpf.h>
140 #include <linux/filter.h>
141 #endif /* PPP_FILTER */
144 #include <sys/locks.h>
150 * This is in linux/include/net/ipv6.h.
154 struct in6_addr ifr6_addr;
155 __u32 ifr6_prefixlen;
156 unsigned int ifr6_ifindex;
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]); \
166 static const eui64_t nulleui64;
169 /* We can get an EIO error on an ioctl if the modem has hung up */
170 #define ok_error(num) ((num)==EIO)
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 */
180 static int sock6_fd = -1;
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.
188 int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
190 static int chindex; /* channel index (new style driver) */
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 */
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 */
203 int new_style_driver = 0;
205 static char loop_name[20];
206 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
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) */
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))
225 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
226 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
227 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
229 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
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);
248 extern u_char inpacket_buf[]; /* borrowed from main.c */
250 extern int dfl_route_metric;
253 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
257 #define SET_SA_FAMILY(addr, family) \
258 memset ((char *) &(addr), '\0', sizeof(addr)); \
259 addr.sa_family = (family);
262 * Determine if the PPP connection should still be present.
267 /* new_fd is the fd of a tty */
268 static void set_ppp_fd (int new_fd)
271 if (!new_style_driver)
275 static int still_ppp(void)
277 if (new_style_driver)
278 return !hungup && ppp_fd >= 0;
279 if (!hungup || ppp_fd == slave_fd)
282 set_ppp_fd(slave_fd);
289 * modify_flags - set and clear flag bits controlling the kernel
292 static int modify_flags(int fd, int clear_bits, int set_bits)
296 if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
298 flags = (flags & ~clear_bits) | set_bits;
299 if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
306 error("Failed to set PPP kernel option flags: %m");
310 /********************************************************************
312 * sys_init - System-dependent initialization.
317 /* Get an internet socket for doing socket ioctls. */
318 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
320 fatal("Couldn't create IP socket: %m(%d)", errno);
323 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
325 sock6_fd = -errno; /* save errno for later */
332 /********************************************************************
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().
339 void sys_cleanup(void)
342 * Take down the device
352 * Delete any routes through the device.
354 if (have_default_route)
355 cifdefaultroute(0, 0, 0);
357 if (have_default_route6)
358 cif6defaultroute(0, nulleui64, nulleui64);
362 cifproxyarp(0, proxy_arp_addr);
365 /********************************************************************
367 * sys_close - Clean up in a child process before execing.
372 if (new_style_driver && ppp_dev_fd >= 0)
386 /********************************************************************
388 * set_kdebugflag - Define the debugging level for the kernel
391 static int set_kdebugflag (int requested_level)
395 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
396 if ( ! ok_error (errno) )
397 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
403 /********************************************************************
405 * tty_establish_ppp - Turn the serial port into a ppp interface.
408 int tty_establish_ppp (int tty_fd)
413 * Ensure that the tty device is in exclusive mode.
415 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
416 if ( ! ok_error ( errno ))
417 warn("Couldn't make tty exclusive: %m");
420 * Demand mode - prime the old ppp device to relinquish the unit.
422 if (!new_style_driver && looped
423 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
424 error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
428 * Set the current tty to the PPP discpline
432 #define N_SYNC_PPP 14
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");
442 ret_fd = generic_establish_ppp(tty_fd);
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 \
449 modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
450 (kdebugflag * SC_DEBUG) & SC_LOGB);
452 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
453 warn("Couldn't reset tty to normal line discipline: %m");
459 /********************************************************************
461 * generic_establish_ppp - Turn the fd into a ppp interface.
463 int generic_establish_ppp (int fd)
467 if (new_style_driver) {
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");
475 dbglog("using channel %d", chindex);
476 fd = open("/dev/ppp", O_RDWR);
478 error("Couldn't reopen /dev/ppp: %m");
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);
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");
493 if (!looped && !multilink) {
495 * Create a new PPP unit.
497 if (make_ppp_unit() < 0)
502 modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
506 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
507 error("Couldn't attach to PPP unit %d: %m", ifunit);
514 * Old-style driver: find out which interface we were given.
517 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
518 if (ok_error (errno))
520 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
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);
528 * Fetch the initial file flags and reset blocking mode on the file.
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");
539 * Enable debug in the driver if requested.
542 set_kdebugflag (kdebugflag);
554 /********************************************************************
556 * tty_disestablish_ppp - Restore the serial port to normal operation.
557 * This shouldn't call die() because it's called from die().
560 void tty_disestablish_ppp(int tty_fd)
564 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
566 if (tcflush(tty_fd, TCIOFLUSH) < 0)
568 warn("tcflush failed: %m");
572 * Restore the previous line discipline
574 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
575 if ( ! ok_error (errno))
576 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
579 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
580 if ( ! ok_error (errno))
581 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
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");
593 generic_disestablish_ppp(tty_fd);
596 /********************************************************************
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().
602 void generic_disestablish_ppp(int dev_fd)
604 if (new_style_driver) {
608 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
610 } else if (!doing_multilink && ppp_dev_fd >= 0) {
612 remove_fd(ppp_dev_fd);
616 /* old-style driver */
618 set_ppp_fd(slave_fd);
625 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
626 * Assumes new_style_driver.
628 static int make_ppp_unit(void)
632 if (ppp_dev_fd >= 0) {
633 dbglog("in make_ppp_unit, already had /dev/ppp open?");
636 ppp_dev_fd = open("/dev/ppp", O_RDWR);
638 fatal("Couldn't open /dev/ppp: %m");
639 flags = fcntl(ppp_dev_fd, F_GETFL);
641 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
642 warn("Couldn't set /dev/ppp to nonblock: %m");
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);
649 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
652 error("Couldn't create new ppp unit: %m");
654 if (x == 0 && req_ifname[0] != '\0') {
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);
663 error("Couldn't rename interface %s to %s: %m", t, req_ifname);
665 info("Renamed interface %s to %s", t, req_ifname);
672 * cfg_bundle - configure the existing bundle.
673 * Used in demand mode.
675 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
677 if (!new_style_driver)
680 /* set the mrru, mtu and flags */
681 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
682 error("Couldn't set MRRU: %m");
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)));
688 /* connect up the channel */
689 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
690 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
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
701 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
703 if (!new_style_driver)
706 /* make us a ppp unit */
707 if (make_ppp_unit() < 0)
710 /* set the mrru and flags */
711 cfg_bundle(mrru, mtru, rssn, tssn);
715 * bundle_attach - attach our link to a given PPP unit.
716 * We assume the unit is controlled by another pppd.
718 int bundle_attach(int ifnum)
722 if (!new_style_driver)
725 master_fd = open("/dev/ppp", O_RDWR);
727 fatal("Couldn't open /dev/ppp: %m");
728 if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
729 if (errno == ENXIO) {
731 return 0; /* doesn't still exist */
733 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
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);
745 * destroy_bundle - tell the driver to destroy our bundle.
747 void destroy_bundle(void)
749 if (ppp_dev_fd >= 0) {
751 remove_fd(ppp_dev_fd);
756 /********************************************************************
758 * clean_check - Fetch the flags for the device and generate
759 * appropriate error messages.
761 void clean_check(void)
767 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
769 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
771 s = "all had bit 7 set to 1";
775 s = "all had bit 7 set to 0";
779 s = "all had odd parity";
783 s = "all had even parity";
788 warn("Receive serial link is not 8-bit clean:");
789 warn("Problem: %s", s);
797 * List of valid speeds.
801 int speed_int, speed_val;
882 { 1000000, B1000000 },
885 { 1152000, B1152000 },
888 { 1500000, B1500000 },
891 { 2000000, B2000000 },
894 { 2500000, B2500000 },
897 { 3000000, B3000000 },
900 { 3500000, B3500000 },
903 { 4000000, B4000000 },
908 /********************************************************************
910 * Translate from bits/second to a speed_t.
913 static int translate_speed (int bps)
915 struct speed *speedp;
918 for (speedp = speeds; speedp->speed_int; speedp++) {
919 if (bps == speedp->speed_int)
920 return speedp->speed_val;
922 warn("speed %d not supported", bps);
927 /********************************************************************
929 * Translate from a speed_t to bits/second.
932 static int baud_rate_of (int speed)
934 struct speed *speedp;
937 for (speedp = speeds; speedp->speed_int; speedp++) {
938 if (speed == speedp->speed_val)
939 return speedp->speed_int;
945 /********************************************************************
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.
952 void set_up_tty(int tty_fd, int local)
958 if (tcgetattr(tty_fd, &tios) < 0) {
959 if (!ok_error(errno))
960 fatal("tcgetattr: %m (line %d)", __LINE__);
967 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
968 tios.c_cflag |= CS8 | CREAD | HUPCL;
970 tios.c_iflag = IGNBRK | IGNPAR;
974 tios.c_cc[VTIME] = 0;
977 tios.c_cflag ^= (CLOCAL | HUPCL);
981 tios.c_cflag |= CRTSCTS;
985 tios.c_iflag |= IXON | IXOFF;
986 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
987 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
991 tios.c_cflag &= ~CRTSCTS;
999 tios.c_cflag |= CSTOPB;
1001 speed = translate_speed(inspeed);
1003 cfsetospeed (&tios, speed);
1004 cfsetispeed (&tios, speed);
1007 * We can't proceed if the serial port speed is B0,
1008 * since that implies that the serial port is disabled.
1011 speed = cfgetospeed(&tios);
1013 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
1016 while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
1018 fatal("tcsetattr: %m (line %d)", __LINE__);
1020 baud_rate = baud_rate_of(speed);
1024 /********************************************************************
1026 * setdtr - control the DTR line on the serial port.
1027 * This is called from die(), so it shouldn't call die().
1030 void setdtr (int tty_fd, int on)
1032 int modembits = TIOCM_DTR;
1034 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1037 /********************************************************************
1039 * restore_tty - restore the terminal to the saved settings.
1042 void restore_tty (int tty_fd)
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.
1052 if (!default_device)
1053 inittermios.c_lflag &= ~(ECHO | ECHONL);
1055 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1056 if (! ok_error (errno))
1057 warn("tcsetattr: %m (line %d)", __LINE__);
1062 /********************************************************************
1064 * output - Output PPP packet.
1067 void output (int unit, unsigned char *p, int len)
1072 dump_packet("sent", p, len);
1073 if (snoop_send_hook) snoop_send_hook(p, len);
1075 if (len < PPP_HDRLEN)
1077 if (new_style_driver) {
1080 proto = (p[0] << 8) + p[1];
1081 if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
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);
1089 error("write: %m (%d)", errno);
1093 /********************************************************************
1095 * wait_input - wait until there is data available,
1096 * for the length of time specified by *timo (indefinite
1100 void wait_input(struct timeval *timo)
1107 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1108 if (n < 0 && errno != EINTR)
1109 fatal("select: %m");
1113 * add_fd - add an fd to the set that wait_input waits for.
1117 if (fd >= FD_SETSIZE)
1118 fatal("internal error: file descriptor too large (%d)", fd);
1119 FD_SET(fd, &in_fds);
1125 * remove_fd - remove an fd from the set that wait_input waits for.
1127 void remove_fd(int fd)
1129 FD_CLR(fd, &in_fds);
1133 /********************************************************************
1135 * read_packet - get a PPP packet from the serial device.
1138 int read_packet (unsigned char *buf)
1142 len = PPP_MRU + PPP_HDRLEN;
1143 if (new_style_driver) {
1144 *buf++ = PPP_ALLSTATIONS;
1150 nr = read(ppp_fd, buf, len);
1151 if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1152 && errno != EIO && errno != EINTR)
1154 if (nr < 0 && errno == ENXIO)
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)
1165 if (nr == 0 && doing_multilink) {
1166 remove_fd(ppp_dev_fd);
1170 if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1172 return (new_style_driver && nr > 0)? nr+2: nr;
1175 /********************************************************************
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.
1182 get_loop_output(void)
1187 if (new_style_driver) {
1188 while ((n = read_packet(inpacket_buf)) > 0)
1189 if (loop_frame(inpacket_buf, n))
1194 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1195 if (loop_chars(inbuf, n))
1199 fatal("eof on loopback");
1201 if (errno != EWOULDBLOCK && errno != EAGAIN)
1202 fatal("read from loopback: %m(%d)", errno);
1208 * netif_set_mtu - set the MTU on the PPP network interface.
1211 netif_set_mtu(int unit, int mtu)
1215 memset (&ifr, '\0', sizeof (ifr));
1216 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1219 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1220 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1224 * netif_get_mtu - get the MTU on the PPP network interface.
1227 netif_get_mtu(int unit)
1231 memset (&ifr, '\0', sizeof (ifr));
1232 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1234 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1235 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1241 /********************************************************************
1243 * tty_send_config - configure the transmit characteristics of
1244 * the ppp interface.
1247 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
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");
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);
1266 /********************************************************************
1268 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1271 void tty_set_xaccm (ext_accm accm)
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__);
1281 /********************************************************************
1283 * tty_recv_config - configure the receive-side characteristics of
1284 * the ppp interface.
1287 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1290 * If we were called because the link has gone down then there is nothing
1291 * which may be done. Just return without incident.
1296 * Set the receiver parameters
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");
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");
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");
1312 /********************************************************************
1314 * ccp_test - ask kernel whether a given compression method
1315 * is acceptable for use.
1319 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1321 struct ppp_option_data data;
1323 memset (&data, '\0', sizeof (data));
1325 data.length = opt_len;
1326 data.transmit = for_transmit;
1328 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1331 return (errno == ENOBUFS)? 0: -1;
1334 /********************************************************************
1336 * ccp_flags_set - inform kernel about the current state of CCP.
1339 void ccp_flags_set (int unit, int isopen, int isup)
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);
1350 * set_filters - set the active and pass filters in the kernel driver.
1352 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1354 struct sock_fprog fp;
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");
1362 error("Couldn't set pass-filter in kernel: %m");
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");
1373 #endif /* PPP_FILTER */
1375 /********************************************************************
1377 * get_idle_time - return how long the link has been idle.
1380 get_idle_time(int u, struct ppp_idle *ip)
1382 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1385 /********************************************************************
1387 * get_ppp_stats - return statistics for the link.
1390 get_ppp_stats(int u, struct pppd_stats *stats)
1392 struct ifpppstatsreq req;
1394 memset (&req, 0, sizeof (req));
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");
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;
1409 /********************************************************************
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.
1416 int ccp_fatal_error (int unit)
1420 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1421 error("Couldn't read compression error flags: %m");
1424 return flags & SC_DC_FERROR;
1427 /********************************************************************
1429 * path_to_procfs - find the path to the proc file system mount point
1431 static char proc_path[MAXPATHLEN];
1432 static int proc_path_len;
1434 static char *path_to_procfs(const char *tail)
1436 struct mntent *mntent;
1439 if (proc_path_len == 0) {
1440 /* Default the mount location of /proc */
1441 strlcpy (proc_path, "/proc", sizeof(proc_path));
1443 fp = fopen(MOUNTED, "r");
1445 while ((mntent = getmntent(fp)) != NULL) {
1446 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
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);
1458 strlcpy(proc_path + proc_path_len, tail,
1459 sizeof(proc_path) - proc_path_len);
1464 * /proc/net/route parsing stuff.
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;
1473 static int open_route_table (void);
1474 static void close_route_table (void);
1475 static int read_route_table (struct rtentry *rt);
1477 /********************************************************************
1479 * close_route_table - close the interface to the route table
1482 static void close_route_table (void)
1484 if (route_fd != (FILE *) 0) {
1486 route_fd = (FILE *) 0;
1490 /********************************************************************
1492 * open_route_table - open the interface to the route table
1494 static char route_delims[] = " \t\n";
1496 static int open_route_table (void)
1500 close_route_table();
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);
1509 route_dev_col = 0; /* default to usual columns */
1512 route_flags_col = 3;
1513 route_metric_col = 6;
1517 /* parse header line */
1518 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1519 char *p = route_buffer, *q;
1521 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1523 if ((q = strtok(p, route_delims)) == 0)
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)
1531 else if (strcasecmp(q, "flags") == 0)
1532 route_flags_col = col;
1533 else if (strcasecmp(q, "mask") == 0)
1534 route_mask_col = col;
1537 if (used && col >= route_num_cols)
1538 route_num_cols = col + 1;
1546 /********************************************************************
1548 * read_route_table - read the next entry from the route table
1551 static int read_route_table(struct rtentry *rt)
1553 char *cols[ROUTE_MAX_COLS], *p;
1556 memset (rt, '\0', sizeof (struct rtentry));
1558 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
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 */
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);
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];
1580 /********************************************************************
1582 * defaultroute_exists - determine if there is a default route
1583 * with the given metric (or negative for any)
1586 static int defaultroute_exists (struct rtentry *rt, int metric)
1590 if (!open_route_table())
1593 while (read_route_table(rt) != 0) {
1594 if ((rt->rt_flags & RTF_UP) == 0)
1597 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1599 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1600 || rt->rt_metric == metric)) {
1606 close_route_table();
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.
1617 int have_route_to(u_int32_t addr)
1622 if (!open_route_table())
1623 return -1; /* don't know */
1625 while (read_route_table(&rt)) {
1626 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1628 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1634 close_route_table();
1638 /********************************************************************
1640 * sifdefaultroute - assign a default route through the address given.
1643 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
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);
1652 error("not replacing existing default route through %s with metric %d",
1653 rt.rt_dev, dfl_route_metric);
1657 memset (&rt, 0, sizeof (rt));
1658 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1661 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1663 if (kernel_version > KVERSION(2,1,0)) {
1664 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1665 SIN_ADDR(rt.rt_genmask) = 0L;
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");
1675 have_default_route = 1;
1679 /********************************************************************
1681 * cifdefaultroute - delete a default route through the address given.
1684 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1688 have_default_route = 0;
1690 memset (&rt, '\0', sizeof (rt));
1691 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1692 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1697 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1699 if (kernel_version > KVERSION(2,1,0)) {
1700 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1701 SIN_ADDR(rt.rt_genmask) = 0L;
1704 rt.rt_flags = RTF_UP;
1705 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1707 if ( ! ok_error ( errno ))
1708 error("default route ioctl(SIOCDELRT): %m");
1718 * /proc/net/ipv6_route parsing stuff.
1720 static int route_dest_plen_col;
1721 static int open_route6_table (void);
1722 static int read_route6_table (struct in6_rtmsg *rt);
1724 /********************************************************************
1726 * open_route6_table - open the interface to the route table
1728 static int open_route6_table (void)
1732 close_route_table();
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);
1741 /* default to usual columns */
1743 route_dest_plen_col = 1;
1745 route_metric_col = 5;
1746 route_flags_col = 8;
1748 route_num_cols = 10;
1753 /********************************************************************
1755 * read_route6_table - read the next entry from the route table
1758 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
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;
1772 static int read_route6_table(struct in6_rtmsg *rt)
1774 char *cols[ROUTE_MAX_COLS], *p;
1777 memset (rt, '\0', sizeof (struct in6_rtmsg));
1779 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
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 */
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]);
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]);
1801 /********************************************************************
1803 * defaultroute6_exists - determine if there is a default route
1806 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
1810 if (!open_route6_table())
1813 while (read_route6_table(rt) != 0) {
1814 if ((rt->rtmsg_flags & RTF_UP) == 0)
1817 if (rt->rtmsg_dst_len != 0)
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)) {
1829 close_route_table();
1833 /********************************************************************
1835 * sif6defaultroute - assign a default route through the address given.
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.
1846 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
1848 struct in6_rtmsg rt;
1849 char buf[IF_NAMESIZE];
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");
1856 error("not replacing existing default route through %s",
1857 if_indextoname(rt.rtmsg_ifindex, buf));
1861 memset (&rt, 0, sizeof (rt));
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;
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");
1874 have_default_route6 = 1;
1878 /********************************************************************
1880 * cif6defaultroute - delete a default route through the address given.
1883 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
1885 struct in6_rtmsg rt;
1887 have_default_route6 = 0;
1889 memset (&rt, '\0', sizeof (rt));
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;
1895 rt.rtmsg_flags = RTF_UP;
1896 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1898 if ( ! ok_error ( errno ))
1899 error("default route ioctl(SIOCDELRT): %m");
1908 /********************************************************************
1910 * sifproxyarp - Make a proxy ARP entry for the peer.
1913 int sifproxyarp (int unit, u_int32_t his_adr)
1915 struct arpreq arpreq;
1918 if (has_proxy_arp == 0) {
1919 memset (&arpreq, '\0', sizeof(arpreq));
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;
1925 * Get the hardware address of an interface on the same subnet
1926 * as our local address.
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");
1933 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1935 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1936 if ( ! ok_error ( errno ))
1937 error("ioctl(SIOCSARP): %m");
1940 proxy_arp_addr = his_adr;
1944 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1945 if (forw_path != 0) {
1946 int fd = open(forw_path, O_WRONLY);
1948 if (write(fd, "1", 1) != 1)
1949 error("Couldn't enable IP forwarding: %m");
1959 /********************************************************************
1961 * cifproxyarp - Delete the proxy ARP entry for the peer.
1964 int cifproxyarp (int unit, u_int32_t his_adr)
1966 struct arpreq arpreq;
1968 if (has_proxy_arp) {
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));
1976 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1977 if ( ! ok_error ( errno ))
1978 warn("ioctl(SIOCDARP): %m");
1985 /********************************************************************
1987 * get_ether_addr - get the hardware address of an interface on the
1988 * the same subnet as ipaddr.
1991 static int get_ether_addr (u_int32_t ipaddr,
1992 struct sockaddr *hwaddr,
1993 char *name, int namelen)
1995 struct ifreq *ifr, *ifend;
1996 u_int32_t ina, mask;
1998 struct ifreq ifreq, bestifreq;
2000 struct ifreq ifs[MAX_IFS];
2002 u_int32_t bestmask=0;
2003 int found_interface = 0;
2005 ifc.ifc_len = sizeof(ifs);
2007 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2008 if ( ! ok_error ( errno ))
2009 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2014 * Scan through looking for an interface with an Internet
2015 * address on the same subnet as `ipaddr'.
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));
2023 * Check that the interface is up, and not point-to-point
2026 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2029 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2032 * Get its netmask and check that it's on the right subnet.
2034 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2037 mask = SIN_ADDR(ifreq.ifr_addr);
2039 if (((ipaddr ^ ina) & mask) != 0)
2040 continue; /* no match */
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;
2052 if (!found_interface) return 0;
2054 strlcpy(name, bestifreq.ifr_name, namelen);
2056 /* trim off the :1 in eth0:1 */
2057 aliasp = strchr(name, ':');
2061 info("found interface %s for proxy arp", name);
2063 * Now get the hardware address.
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);
2072 &bestifreq.ifr_hwaddr,
2073 sizeof (struct sockaddr));
2079 * get_if_hwaddr - get the hardware address for the specified
2080 * network interface device.
2083 get_if_hwaddr(u_char *addr, char *name)
2088 sock_fd = socket(AF_INET, SOCK_DGRAM, 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);
2096 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2101 * get_first_ethernet - return the name of the first ethernet-style
2102 * interface on this system.
2105 get_first_ethernet(void)
2110 /********************************************************************
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.
2120 u_int32_t GetMask (u_int32_t addr)
2122 u_int32_t mask, nmask, ina;
2123 struct ifreq *ifr, *ifend, ifreq;
2125 struct ifreq ifs[MAX_IFS];
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;
2134 nmask = IN_CLASSC_NET;
2136 /* class D nets are disallowed by bad_ip_adrs */
2137 mask = netmask | htonl(nmask);
2139 * Scan through the system's network interfaces.
2141 ifc.ifc_len = sizeof(ifs);
2143 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2144 if ( ! ok_error ( errno ))
2145 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2149 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2150 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2152 * Check the interface's internet address.
2154 if (ifr->ifr_addr.sa_family != AF_INET)
2156 ina = SIN_ADDR(ifr->ifr_addr);
2157 if (((ntohl(ina) ^ addr) & nmask) != 0)
2160 * Check that the interface is up, and not point-to-point nor loopback.
2162 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2163 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2166 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2169 * Get its netmask and OR it into our mask.
2171 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2173 mask |= SIN_ADDR(ifreq.ifr_addr);
2179 /********************************************************************
2181 * Internal routine to decode the version.modification.patch level
2184 static void decode_version (char *buf, int *version,
2185 int *modification, int *patch)
2189 *version = (int) strtoul (buf, &endp, 10);
2193 if (endp != buf && *endp == '.') {
2195 *modification = (int) strtoul (buf, &endp, 10);
2196 if (endp != buf && *endp == '.') {
2198 *patch = (int) strtoul (buf, &buf, 10);
2203 /********************************************************************
2205 * Procedure to determine if the PPP line discipline is registered.
2209 ppp_registered(void)
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.
2223 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2224 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2229 * Try to put the device into the PPP discipline.
2231 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2232 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2241 /********************************************************************
2243 * ppp_available - check whether the system has any ppp interfaces
2244 * (in fact we check whether we can do an ioctl on ppp0).
2247 int ppp_available(void)
2252 int my_version, my_modification, my_patch;
2253 int osmaj, osmin, ospatch;
2255 /* get the kernel version now, since we are called before sys_init */
2257 osmaj = osmin = ospatch = 0;
2258 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2259 kernel_version = KVERSION(osmaj, osmin, ospatch);
2261 fd = open("/dev/ppp", O_RDWR);
2263 new_style_driver = 1;
2265 /* XXX should get from driver */
2267 driver_modification = 4;
2273 if (kernel_version >= KVERSION(2,3,13)) {
2274 error("Couldn't open the /dev/ppp device: %m");
2275 if (errno == ENOENT)
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)
2282 "Please load the ppp_generic kernel module.\n";
2286 /* we are running on a really really old kernel */
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";
2296 * Open a socket for doing the ioctl operations.
2298 s = socket(AF_INET, SOCK_DGRAM, 0);
2302 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2303 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
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.
2310 if (ppp_registered()) {
2311 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2312 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2316 * Ensure that the hardware address is for PPP and not something else
2319 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2321 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
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.
2329 char abBuffer [1024];
2331 ifr.ifr_data = abBuffer;
2332 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2334 error("Couldn't read driver version: %m");
2336 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2339 decode_version(abBuffer,
2341 &driver_modification,
2344 * Validate the version of the driver against the version that we used.
2346 decode_version(VERSION,
2351 /* The version numbers must match */
2352 if (driver_version != my_version)
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 */
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);
2370 no_ppp_msg = route_buffer;
2378 #ifndef HAVE_LOGWTMP
2379 /********************************************************************
2381 * Update the wtmp file with the appropriate user name and tty device.
2384 void logwtmp (const char *line, const char *name, const char *host)
2386 struct utmp ut, *utp;
2387 pid_t mypid = getpid();
2393 * Update the signon database for users.
2394 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2396 utmpname(_PATH_UTMP);
2398 while ((utp = getutent()) && (utp->ut_pid != mypid))
2402 memcpy(&ut, utp, sizeof(ut));
2404 /* some gettys/telnetds don't initialize utmp... */
2405 memset(&ut, 0, sizeof(ut));
2407 if (ut.ut_id[0] == 0)
2408 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2410 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2411 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2415 ut.ut_type = USER_PROCESS;
2418 /* Insert the host name if one is supplied */
2420 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
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));
2427 /* CL: Makes sure that the logout works */
2428 if (*host == 0 && *name==0)
2434 * Update the wtmp file.
2437 updwtmp(_PATH_WTMP, &ut);
2439 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2441 flock(wtmp, LOCK_EX);
2443 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2444 warn("error writing %s: %m", _PATH_WTMP);
2446 flock(wtmp, LOCK_UN);
2452 #endif /* HAVE_LOGWTMP */
2454 /********************************************************************
2456 * sifvjcomp - config tcp header compression
2459 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2464 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2465 error("Couldn't set up TCP header compression: %m");
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);
2476 /********************************************************************
2478 * sifup - Config the interface up and enable IP packets to pass.
2485 if ((ret = setifstate(u, 1)))
2491 /********************************************************************
2493 * sifdown - Disable the indicated protocol and config the interface
2494 * down if there are no remaining protocols.
2499 if (if_is_up && --if_is_up > 0)
2507 return setifstate(u, 0);
2511 /********************************************************************
2513 * sif6up - Config the interface up for IPv6
2520 if ((ret = setifstate(u, 1)))
2526 /********************************************************************
2528 * sif6down - Disable the IPv6CP protocol and config the interface
2529 * down if there are no remaining protocols.
2532 int sif6down (int u)
2539 return setifstate(u, 0);
2543 /********************************************************************
2545 * setifstate - Config the interface up or down
2548 static int setifstate (int u, int state)
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__);
2561 ifr.ifr_flags |= IFF_UP;
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__);
2573 /********************************************************************
2575 * sifaddr - Config the interface IP addresses and netmask.
2578 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2584 memset (&ifr, '\0', sizeof (ifr));
2585 memset (&rt, '\0', sizeof (rt));
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);
2591 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2593 * Set our IP address
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__);
2602 warn("ioctl(SIOCSIFADDR): Address already exists");
2607 * Set the gateway address
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__);
2619 * For recent kernels, force the netmask to 255.255.255.255.
2621 if (kernel_version >= KVERSION(2,1,16))
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__);
2632 * Add the device route
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);
2639 SIN_ADDR(rt.rt_gateway) = 0L;
2640 SIN_ADDR(rt.rt_dst) = his_adr;
2641 rt.rt_flags = RTF_UP | RTF_HOST;
2643 if (kernel_version > KVERSION(2,1,0)) {
2644 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2645 SIN_ADDR(rt.rt_genmask) = -1L;
2648 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2649 if (! ok_error (errno))
2650 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
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 */
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");
2668 dynaddr_set = 1; /* only 1 attempt */
2675 /********************************************************************
2677 * cifaddr - Clear the interface IP addresses, and delete routes
2678 * through the interface if possible.
2681 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2685 if (kernel_version < KVERSION(2,1,16)) {
2687 * Delete the route through the device
2690 memset (&rt, '\0', sizeof (rt));
2692 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2693 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2696 SIN_ADDR(rt.rt_gateway) = 0;
2697 SIN_ADDR(rt.rt_dst) = his_adr;
2698 rt.rt_flags = RTF_UP | RTF_HOST;
2700 if (kernel_version > KVERSION(2,1,0)) {
2701 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2702 SIN_ADDR(rt.rt_genmask) = -1L;
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__);
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));
2717 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2718 if (! ok_error (errno)) {
2719 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2724 our_old_addr = our_adr;
2730 /********************************************************************
2732 * sif6addr - Config the interface with an IPv6 link-local address
2734 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2736 struct in6_ifreq ifr6;
2738 struct in6_rtmsg rt6;
2742 error("IPv6 socket creation failed: %m");
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__);
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;
2758 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2759 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
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;
2771 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2772 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2780 /********************************************************************
2782 * cif6addr - Remove IPv6 address from interface
2784 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2787 struct in6_ifreq ifr6;
2791 error("IPv6 socket creation failed: %m");
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__);
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;
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__);
2812 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
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.
2825 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
2827 int i, mfd, sfd = -1;
2829 struct termios tios;
2833 * Try the unix98 way first.
2835 mfd = open("/dev/ptmx", O_RDWR);
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);
2843 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2844 warn("Couldn't unlock pty slave %s: %m", pty_name);
2846 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2848 warn("Couldn't open pty slave %s: %m", pty_name);
2853 #endif /* TIOCGPTN */
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);
2863 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2865 fchown(sfd, uid, -1);
2866 fchmod(sfd, S_IRUSR | S_IWUSR);
2877 strlcpy(slave_name, pty_name, 16);
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;
2886 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2887 warn("couldn't set attributes on pty: %m");
2889 warn("couldn't get attributes on pty: %m");
2894 /********************************************************************
2896 * open_loopback - open the device we use for getting packets
2897 * in demand mode. Under Linux, we use a pty master/slave pair.
2900 open_ppp_loopback(void)
2905 if (new_style_driver) {
2906 /* allocate ourselves a ppp unit */
2907 if (make_ppp_unit() < 0)
2909 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2910 set_kdebugflag(kdebugflag);
2915 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2916 fatal("No free pty for loopback");
2918 set_ppp_fd(slave_fd);
2920 flags = fcntl(master_fd, F_GETFL);
2922 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2923 warn("couldn't set master loopback to nonblock: %m");
2925 flags = fcntl(ppp_fd, F_GETFL);
2927 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2928 warn("couldn't set slave loopback to nonblock: %m");
2930 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2931 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2933 * Find out which interface we were given.
2935 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2936 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2938 * Enable debug in the driver if requested.
2940 set_kdebugflag (kdebugflag);
2945 /********************************************************************
2947 * sifnpmode - Set the mode for handling packets for a given NP.
2951 sifnpmode(int u, int proto, enum NPmode mode)
2955 npi.protocol = proto;
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);
2966 /********************************************************************
2968 * sipxfaddr - Config the interface IPX networknumber
2971 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2978 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2980 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2982 if (! ok_error (errno))
2983 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2987 memset (&ifr, '\0', sizeof (ifr));
2988 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
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;
2997 * Set the IPX device
2999 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3001 if (errno != EEXIST) {
3002 if (! ok_error (errno))
3003 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
3006 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
3015 /********************************************************************
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
3022 int cipxfaddr (int unit)
3029 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3031 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3033 if (! ok_error (errno))
3034 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3038 memset (&ifr, '\0', sizeof (ifr));
3039 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3041 sipx->sipx_type = IPX_FRAME_ETHERII;
3042 sipx->sipx_action = IPX_DLTITF;
3043 sipx->sipx_family = AF_IPX;
3045 * Set the IPX device
3047 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3048 if (! ok_error (errno))
3049 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
3059 * Use the hostname as part of the random number seed.
3068 for (p = hostname; *p != 0; ++p)
3073 /********************************************************************
3075 * sys_check_options - check the options that the user specified
3079 sys_check_options(void)
3083 * Disable the IPX protocol if the support is not present in the kernel.
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;
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,
3103 if (multilink && !new_style_driver) {
3104 warn("Warning: multilink is not supported by the kernel driver");
3112 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
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.
3119 ether_to_eui64(eui64_t *p_eui64)
3123 const unsigned char *ptr;
3125 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
3128 warn("could not open IPv6 socket");
3132 strcpy(ifr.ifr_name, "eth0");
3133 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
3136 warn("could not obtain hardware address for eth0");
3142 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
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];
3158 /********************************************************************
3160 * get_time - Get current time, monotonic if possible.
3163 get_time(struct timeval *tv)
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
3170 static int monotonic = -1;
3175 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3179 tv->tv_sec = ts.tv_sec;
3180 tv->tv_usec = ts.tv_nsec / 1000;
3183 } else if (monotonic > 0)
3187 warn("Couldn't use monotonic clock source: %m");
3190 return gettimeofday(tv, NULL);