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()
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(u, ip)
1382 struct ppp_idle *ip;
1384 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1387 /********************************************************************
1389 * get_ppp_stats - return statistics for the link.
1392 get_ppp_stats(u, stats)
1394 struct pppd_stats *stats;
1396 struct ifpppstatsreq req;
1398 memset (&req, 0, sizeof (req));
1400 req.stats_ptr = (caddr_t) &req.stats;
1401 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1402 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1403 error("Couldn't get PPP statistics: %m");
1406 stats->bytes_in = req.stats.p.ppp_ibytes;
1407 stats->bytes_out = req.stats.p.ppp_obytes;
1408 stats->pkts_in = req.stats.p.ppp_ipackets;
1409 stats->pkts_out = req.stats.p.ppp_opackets;
1413 /********************************************************************
1415 * ccp_fatal_error - returns 1 if decompression was disabled as a
1416 * result of an error detected after decompression of a packet,
1417 * 0 otherwise. This is necessary because of patent nonsense.
1420 int ccp_fatal_error (int unit)
1424 if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1425 error("Couldn't read compression error flags: %m");
1428 return flags & SC_DC_FERROR;
1431 /********************************************************************
1433 * path_to_procfs - find the path to the proc file system mount point
1435 static char proc_path[MAXPATHLEN];
1436 static int proc_path_len;
1438 static char *path_to_procfs(const char *tail)
1440 struct mntent *mntent;
1443 if (proc_path_len == 0) {
1444 /* Default the mount location of /proc */
1445 strlcpy (proc_path, "/proc", sizeof(proc_path));
1447 fp = fopen(MOUNTED, "r");
1449 while ((mntent = getmntent(fp)) != NULL) {
1450 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1452 if (strcmp(mntent->mnt_type, "proc") == 0) {
1453 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1454 proc_path_len = strlen(proc_path);
1462 strlcpy(proc_path + proc_path_len, tail,
1463 sizeof(proc_path) - proc_path_len);
1468 * /proc/net/route parsing stuff.
1470 #define ROUTE_MAX_COLS 12
1471 FILE *route_fd = (FILE *) 0;
1472 static char route_buffer[512];
1473 static int route_dev_col, route_dest_col, route_gw_col;
1474 static int route_flags_col, route_metric_col, route_mask_col;
1475 static int route_num_cols;
1477 static int open_route_table (void);
1478 static void close_route_table (void);
1479 static int read_route_table (struct rtentry *rt);
1481 /********************************************************************
1483 * close_route_table - close the interface to the route table
1486 static void close_route_table (void)
1488 if (route_fd != (FILE *) 0) {
1490 route_fd = (FILE *) 0;
1494 /********************************************************************
1496 * open_route_table - open the interface to the route table
1498 static char route_delims[] = " \t\n";
1500 static int open_route_table (void)
1504 close_route_table();
1506 path = path_to_procfs("/net/route");
1507 route_fd = fopen (path, "r");
1508 if (route_fd == NULL) {
1509 error("can't open routing table %s: %m", path);
1513 route_dev_col = 0; /* default to usual columns */
1516 route_flags_col = 3;
1517 route_metric_col = 6;
1521 /* parse header line */
1522 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1523 char *p = route_buffer, *q;
1525 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1527 if ((q = strtok(p, route_delims)) == 0)
1529 if (strcasecmp(q, "iface") == 0)
1530 route_dev_col = col;
1531 else if (strcasecmp(q, "destination") == 0)
1532 route_dest_col = col;
1533 else if (strcasecmp(q, "gateway") == 0)
1535 else if (strcasecmp(q, "flags") == 0)
1536 route_flags_col = col;
1537 else if (strcasecmp(q, "mask") == 0)
1538 route_mask_col = col;
1541 if (used && col >= route_num_cols)
1542 route_num_cols = col + 1;
1550 /********************************************************************
1552 * read_route_table - read the next entry from the route table
1555 static int read_route_table(struct rtentry *rt)
1557 char *cols[ROUTE_MAX_COLS], *p;
1560 memset (rt, '\0', sizeof (struct rtentry));
1562 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1566 for (col = 0; col < route_num_cols; ++col) {
1567 cols[col] = strtok(p, route_delims);
1568 if (cols[col] == NULL)
1569 return 0; /* didn't get enough columns */
1573 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1574 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1575 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1577 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1578 rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10);
1579 rt->rt_dev = cols[route_dev_col];
1584 /********************************************************************
1586 * defaultroute_exists - determine if there is a default route
1587 * with the given metric (or negative for any)
1590 static int defaultroute_exists (struct rtentry *rt, int metric)
1594 if (!open_route_table())
1597 while (read_route_table(rt) != 0) {
1598 if ((rt->rt_flags & RTF_UP) == 0)
1601 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1603 if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0
1604 || rt->rt_metric == metric)) {
1610 close_route_table();
1615 * have_route_to - determine if the system has any route to
1616 * a given IP address. `addr' is in network byte order.
1617 * Return value is 1 if yes, 0 if no, -1 if don't know.
1618 * For demand mode to work properly, we have to ignore routes
1619 * through our own interface.
1621 int have_route_to(u_int32_t addr)
1626 if (!open_route_table())
1627 return -1; /* don't know */
1629 while (read_route_table(&rt)) {
1630 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1632 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1638 close_route_table();
1642 /********************************************************************
1644 * sifdefaultroute - assign a default route through the address given.
1647 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1651 if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) {
1652 if (rt.rt_flags & RTF_GATEWAY)
1653 error("not replacing existing default route via %I with metric %d",
1654 SIN_ADDR(rt.rt_gateway), dfl_route_metric);
1656 error("not replacing existing default route through %s with metric %d",
1657 rt.rt_dev, dfl_route_metric);
1661 memset (&rt, 0, sizeof (rt));
1662 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1665 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1667 if (kernel_version > KVERSION(2,1,0)) {
1668 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1669 SIN_ADDR(rt.rt_genmask) = 0L;
1672 rt.rt_flags = RTF_UP;
1673 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1674 if ( ! ok_error ( errno ))
1675 error("default route ioctl(SIOCADDRT): %m");
1679 have_default_route = 1;
1683 /********************************************************************
1685 * cifdefaultroute - delete a default route through the address given.
1688 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1692 have_default_route = 0;
1694 memset (&rt, '\0', sizeof (rt));
1695 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1696 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1701 rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1703 if (kernel_version > KVERSION(2,1,0)) {
1704 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1705 SIN_ADDR(rt.rt_genmask) = 0L;
1708 rt.rt_flags = RTF_UP;
1709 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1711 if ( ! ok_error ( errno ))
1712 error("default route ioctl(SIOCDELRT): %m");
1722 * /proc/net/ipv6_route parsing stuff.
1724 static int route_dest_plen_col;
1725 static int open_route6_table (void);
1726 static int read_route6_table (struct in6_rtmsg *rt);
1728 /********************************************************************
1730 * open_route6_table - open the interface to the route table
1732 static int open_route6_table (void)
1736 close_route_table();
1738 path = path_to_procfs("/net/ipv6_route");
1739 route_fd = fopen (path, "r");
1740 if (route_fd == NULL) {
1741 error("can't open routing table %s: %m", path);
1745 /* default to usual columns */
1747 route_dest_plen_col = 1;
1749 route_metric_col = 5;
1750 route_flags_col = 8;
1752 route_num_cols = 10;
1757 /********************************************************************
1759 * read_route6_table - read the next entry from the route table
1762 static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
1769 for (i = 0; i < 4; i++) {
1770 memcpy(hex8, s + 8*i, 8);
1771 v = strtoul(hex8, NULL, 16);
1772 addr->s6_addr32[i] = v;
1776 static int read_route6_table(struct in6_rtmsg *rt)
1778 char *cols[ROUTE_MAX_COLS], *p;
1781 memset (rt, '\0', sizeof (struct in6_rtmsg));
1783 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1787 for (col = 0; col < route_num_cols; ++col) {
1788 cols[col] = strtok(p, route_delims);
1789 if (cols[col] == NULL)
1790 return 0; /* didn't get enough columns */
1794 hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
1795 rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
1796 hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
1798 rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
1799 rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
1800 rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
1805 /********************************************************************
1807 * defaultroute6_exists - determine if there is a default route
1810 static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
1814 if (!open_route6_table())
1817 while (read_route6_table(rt) != 0) {
1818 if ((rt->rtmsg_flags & RTF_UP) == 0)
1821 if (rt->rtmsg_dst_len != 0)
1823 if (rt->rtmsg_dst.s6_addr32[0] == 0L
1824 && rt->rtmsg_dst.s6_addr32[1] == 0L
1825 && rt->rtmsg_dst.s6_addr32[2] == 0L
1826 && rt->rtmsg_dst.s6_addr32[3] == 0L
1827 && (metric < 0 || rt->rtmsg_metric == metric)) {
1833 close_route_table();
1837 /********************************************************************
1839 * sif6defaultroute - assign a default route through the address given.
1841 * If the global default_rt_repl_rest flag is set, then this function
1842 * already replaced the original system defaultroute with some other
1843 * route and it should just replace the current defaultroute with
1844 * another one, without saving the current route. Use: demand mode,
1845 * when pppd sets first a defaultroute it it's temporary ppp0 addresses
1846 * and then changes the temporary addresses to the addresses for the real
1847 * ppp connection when it has come up.
1850 int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
1852 struct in6_rtmsg rt;
1853 char buf[IF_NAMESIZE];
1855 if (defaultroute6_exists(&rt, dfl_route_metric) &&
1856 rt.rtmsg_ifindex != if_nametoindex(ifname)) {
1857 if (rt.rtmsg_flags & RTF_GATEWAY)
1858 error("not replacing existing default route via gateway");
1860 error("not replacing existing default route through %s",
1861 if_indextoname(rt.rtmsg_ifindex, buf));
1865 memset (&rt, 0, sizeof (rt));
1867 rt.rtmsg_ifindex = if_nametoindex(ifname);
1868 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1869 rt.rtmsg_dst_len = 0;
1871 rt.rtmsg_flags = RTF_UP;
1872 if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
1873 if ( ! ok_error ( errno ))
1874 error("default route ioctl(SIOCADDRT): %m");
1878 have_default_route6 = 1;
1882 /********************************************************************
1884 * cif6defaultroute - delete a default route through the address given.
1887 int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
1889 struct in6_rtmsg rt;
1891 have_default_route6 = 0;
1893 memset (&rt, '\0', sizeof (rt));
1895 rt.rtmsg_ifindex = if_nametoindex(ifname);
1896 rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
1897 rt.rtmsg_dst_len = 0;
1899 rt.rtmsg_flags = RTF_UP;
1900 if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1902 if ( ! ok_error ( errno ))
1903 error("default route ioctl(SIOCDELRT): %m");
1912 /********************************************************************
1914 * sifproxyarp - Make a proxy ARP entry for the peer.
1917 int sifproxyarp (int unit, u_int32_t his_adr)
1919 struct arpreq arpreq;
1922 if (has_proxy_arp == 0) {
1923 memset (&arpreq, '\0', sizeof(arpreq));
1925 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1926 SIN_ADDR(arpreq.arp_pa) = his_adr;
1927 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1929 * Get the hardware address of an interface on the same subnet
1930 * as our local address.
1932 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1933 sizeof(proxy_arp_dev))) {
1934 error("Cannot determine ethernet address for proxy ARP");
1937 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1939 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1940 if ( ! ok_error ( errno ))
1941 error("ioctl(SIOCSARP): %m");
1944 proxy_arp_addr = his_adr;
1948 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1949 if (forw_path != 0) {
1950 int fd = open(forw_path, O_WRONLY);
1952 if (write(fd, "1", 1) != 1)
1953 error("Couldn't enable IP forwarding: %m");
1963 /********************************************************************
1965 * cifproxyarp - Delete the proxy ARP entry for the peer.
1968 int cifproxyarp (int unit, u_int32_t his_adr)
1970 struct arpreq arpreq;
1972 if (has_proxy_arp) {
1974 memset (&arpreq, '\0', sizeof(arpreq));
1975 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1976 SIN_ADDR(arpreq.arp_pa) = his_adr;
1977 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1978 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1980 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1981 if ( ! ok_error ( errno ))
1982 warn("ioctl(SIOCDARP): %m");
1989 /********************************************************************
1991 * get_ether_addr - get the hardware address of an interface on the
1992 * the same subnet as ipaddr.
1995 static int get_ether_addr (u_int32_t ipaddr,
1996 struct sockaddr *hwaddr,
1997 char *name, int namelen)
1999 struct ifreq *ifr, *ifend;
2000 u_int32_t ina, mask;
2002 struct ifreq ifreq, bestifreq;
2004 struct ifreq ifs[MAX_IFS];
2006 u_int32_t bestmask=0;
2007 int found_interface = 0;
2009 ifc.ifc_len = sizeof(ifs);
2011 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2012 if ( ! ok_error ( errno ))
2013 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2018 * Scan through looking for an interface with an Internet
2019 * address on the same subnet as `ipaddr'.
2021 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
2022 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2023 if (ifr->ifr_addr.sa_family == AF_INET) {
2024 ina = SIN_ADDR(ifr->ifr_addr);
2025 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2027 * Check that the interface is up, and not point-to-point
2030 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2033 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2036 * Get its netmask and check that it's on the right subnet.
2038 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2041 mask = SIN_ADDR(ifreq.ifr_addr);
2043 if (((ipaddr ^ ina) & mask) != 0)
2044 continue; /* no match */
2046 if (mask >= bestmask) {
2047 /* Compare using >= instead of > -- it is possible for
2048 an interface to have a netmask of 0.0.0.0 */
2049 found_interface = 1;
2056 if (!found_interface) return 0;
2058 strlcpy(name, bestifreq.ifr_name, namelen);
2060 /* trim off the :1 in eth0:1 */
2061 aliasp = strchr(name, ':');
2065 info("found interface %s for proxy arp", name);
2067 * Now get the hardware address.
2069 memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2070 if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
2071 error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
2076 &bestifreq.ifr_hwaddr,
2077 sizeof (struct sockaddr));
2083 * get_if_hwaddr - get the hardware address for the specified
2084 * network interface device.
2087 get_if_hwaddr(u_char *addr, char *name)
2092 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
2095 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
2096 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
2097 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
2100 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
2105 * get_first_ethernet - return the name of the first ethernet-style
2106 * interface on this system.
2109 get_first_ethernet()
2114 /********************************************************************
2116 * Return user specified netmask, modified by any mask we might determine
2117 * for address `addr' (in network byte order).
2118 * Here we scan through the system's list of interfaces, looking for
2119 * any non-point-to-point interfaces which might appear to be on the same
2120 * network as `addr'. If we find any, we OR in their netmask to the
2121 * user-specified netmask.
2124 u_int32_t GetMask (u_int32_t addr)
2126 u_int32_t mask, nmask, ina;
2127 struct ifreq *ifr, *ifend, ifreq;
2129 struct ifreq ifs[MAX_IFS];
2133 if (IN_CLASSA(addr)) /* determine network mask for address class */
2134 nmask = IN_CLASSA_NET;
2135 else if (IN_CLASSB(addr))
2136 nmask = IN_CLASSB_NET;
2138 nmask = IN_CLASSC_NET;
2140 /* class D nets are disallowed by bad_ip_adrs */
2141 mask = netmask | htonl(nmask);
2143 * Scan through the system's network interfaces.
2145 ifc.ifc_len = sizeof(ifs);
2147 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
2148 if ( ! ok_error ( errno ))
2149 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
2153 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2154 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
2156 * Check the interface's internet address.
2158 if (ifr->ifr_addr.sa_family != AF_INET)
2160 ina = SIN_ADDR(ifr->ifr_addr);
2161 if (((ntohl(ina) ^ addr) & nmask) != 0)
2164 * Check that the interface is up, and not point-to-point nor loopback.
2166 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
2167 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
2170 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
2173 * Get its netmask and OR it into our mask.
2175 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
2177 mask |= SIN_ADDR(ifreq.ifr_addr);
2183 /********************************************************************
2185 * Internal routine to decode the version.modification.patch level
2188 static void decode_version (char *buf, int *version,
2189 int *modification, int *patch)
2193 *version = (int) strtoul (buf, &endp, 10);
2197 if (endp != buf && *endp == '.') {
2199 *modification = (int) strtoul (buf, &endp, 10);
2200 if (endp != buf && *endp == '.') {
2202 *patch = (int) strtoul (buf, &buf, 10);
2207 /********************************************************************
2209 * Procedure to determine if the PPP line discipline is registered.
2213 ppp_registered(void)
2221 * We used to open the serial device and set it to the ppp line
2222 * discipline here, in order to create a ppp unit. But that is
2223 * not a good idea - the user might have specified a device that
2224 * they can't open (permission, or maybe it doesn't really exist).
2225 * So we grab a pty master/slave pair and use that.
2227 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2228 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2233 * Try to put the device into the PPP discipline.
2235 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2236 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2245 /********************************************************************
2247 * ppp_available - check whether the system has any ppp interfaces
2248 * (in fact we check whether we can do an ioctl on ppp0).
2251 int ppp_available(void)
2256 int my_version, my_modification, my_patch;
2257 int osmaj, osmin, ospatch;
2259 /* get the kernel version now, since we are called before sys_init */
2261 osmaj = osmin = ospatch = 0;
2262 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2263 kernel_version = KVERSION(osmaj, osmin, ospatch);
2265 fd = open("/dev/ppp", O_RDWR);
2267 new_style_driver = 1;
2269 /* XXX should get from driver */
2271 driver_modification = 4;
2277 if (kernel_version >= KVERSION(2,3,13)) {
2278 error("Couldn't open the /dev/ppp device: %m");
2279 if (errno == ENOENT)
2281 "You need to create the /dev/ppp device node by\n"
2282 "executing the following command as root:\n"
2283 " mknod /dev/ppp c 108 0\n";
2284 else if (errno == ENODEV || errno == ENXIO)
2286 "Please load the ppp_generic kernel module.\n";
2290 /* we are running on a really really old kernel */
2292 "This system lacks kernel support for PPP. This could be because\n"
2293 "the PPP kernel module could not be loaded, or because PPP was not\n"
2294 "included in the kernel configuration. If PPP was included as a\n"
2295 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2296 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2297 "See README.linux file in the ppp distribution for more details.\n";
2300 * Open a socket for doing the ioctl operations.
2302 s = socket(AF_INET, SOCK_DGRAM, 0);
2306 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2307 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2309 * If the device did not exist then attempt to create one by putting the
2310 * current tty into the PPP discipline. If this works then obtain the
2311 * flags for the device again.
2314 if (ppp_registered()) {
2315 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2316 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2320 * Ensure that the hardware address is for PPP and not something else
2323 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2325 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2329 * This is the PPP device. Validate the version of the driver at this
2330 * point to ensure that this program will work with the driver.
2333 char abBuffer [1024];
2335 ifr.ifr_data = abBuffer;
2336 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2338 error("Couldn't read driver version: %m");
2340 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2343 decode_version(abBuffer,
2345 &driver_modification,
2348 * Validate the version of the driver against the version that we used.
2350 decode_version(VERSION,
2355 /* The version numbers must match */
2356 if (driver_version != my_version)
2359 /* The modification levels must be legal */
2360 if (driver_modification < 3) {
2361 if (driver_modification >= 2) {
2362 /* we can cope with 2.2.0 and above */
2370 slprintf(route_buffer, sizeof(route_buffer),
2371 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2372 driver_version, driver_modification, driver_patch);
2374 no_ppp_msg = route_buffer;
2382 #ifndef HAVE_LOGWTMP
2383 /********************************************************************
2385 * Update the wtmp file with the appropriate user name and tty device.
2388 void logwtmp (const char *line, const char *name, const char *host)
2390 struct utmp ut, *utp;
2391 pid_t mypid = getpid();
2397 * Update the signon database for users.
2398 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2400 utmpname(_PATH_UTMP);
2402 while ((utp = getutent()) && (utp->ut_pid != mypid))
2406 memcpy(&ut, utp, sizeof(ut));
2408 /* some gettys/telnetds don't initialize utmp... */
2409 memset(&ut, 0, sizeof(ut));
2411 if (ut.ut_id[0] == 0)
2412 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2414 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2415 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2419 ut.ut_type = USER_PROCESS;
2422 /* Insert the host name if one is supplied */
2424 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2426 /* Insert the IP address of the remote system if IP is enabled */
2427 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2428 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2429 sizeof(ut.ut_addr));
2431 /* CL: Makes sure that the logout works */
2432 if (*host == 0 && *name==0)
2438 * Update the wtmp file.
2441 updwtmp(_PATH_WTMP, &ut);
2443 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2445 flock(wtmp, LOCK_EX);
2447 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2448 warn("error writing %s: %m", _PATH_WTMP);
2450 flock(wtmp, LOCK_UN);
2456 #endif /* HAVE_LOGWTMP */
2458 /********************************************************************
2460 * sifvjcomp - config tcp header compression
2463 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2468 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2469 error("Couldn't set up TCP header compression: %m");
2474 x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2475 modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2480 /********************************************************************
2482 * sifup - Config the interface up and enable IP packets to pass.
2489 if ((ret = setifstate(u, 1)))
2495 /********************************************************************
2497 * sifdown - Disable the indicated protocol and config the interface
2498 * down if there are no remaining protocols.
2503 if (if_is_up && --if_is_up > 0)
2511 return setifstate(u, 0);
2515 /********************************************************************
2517 * sif6up - Config the interface up for IPv6
2524 if ((ret = setifstate(u, 1)))
2530 /********************************************************************
2532 * sif6down - Disable the IPv6CP protocol and config the interface
2533 * down if there are no remaining protocols.
2536 int sif6down (int u)
2543 return setifstate(u, 0);
2547 /********************************************************************
2549 * setifstate - Config the interface up or down
2552 static int setifstate (int u, int state)
2556 memset (&ifr, '\0', sizeof (ifr));
2557 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2558 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2559 if (! ok_error (errno))
2560 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2565 ifr.ifr_flags |= IFF_UP;
2567 ifr.ifr_flags &= ~IFF_UP;
2568 ifr.ifr_flags |= IFF_POINTOPOINT;
2569 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2570 if (! ok_error (errno))
2571 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2577 /********************************************************************
2579 * sifaddr - Config the interface IP addresses and netmask.
2582 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2588 memset (&ifr, '\0', sizeof (ifr));
2589 memset (&rt, '\0', sizeof (rt));
2591 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2592 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2593 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2595 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2597 * Set our IP address
2599 SIN_ADDR(ifr.ifr_addr) = our_adr;
2600 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2601 if (errno != EEXIST) {
2602 if (! ok_error (errno))
2603 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2606 warn("ioctl(SIOCSIFADDR): Address already exists");
2611 * Set the gateway address
2614 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2615 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2616 if (! ok_error (errno))
2617 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2623 * For recent kernels, force the netmask to 255.255.255.255.
2625 if (kernel_version >= KVERSION(2,1,16))
2627 if (net_mask != 0) {
2628 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2629 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2630 if (! ok_error (errno))
2631 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2636 * Add the device route
2638 if (kernel_version < KVERSION(2,1,16)) {
2639 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2640 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2643 SIN_ADDR(rt.rt_gateway) = 0L;
2644 SIN_ADDR(rt.rt_dst) = his_adr;
2645 rt.rt_flags = RTF_UP | RTF_HOST;
2647 if (kernel_version > KVERSION(2,1,0)) {
2648 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2649 SIN_ADDR(rt.rt_genmask) = -1L;
2652 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2653 if (! ok_error (errno))
2654 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2659 /* set ip_dynaddr in demand mode if address changes */
2660 if (demand && tune_kernel && !dynaddr_set
2661 && our_old_addr && our_old_addr != our_adr) {
2662 /* set ip_dynaddr if possible */
2666 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2667 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2668 if (write(fd, "1", 1) != 1)
2669 error("Couldn't enable dynamic IP addressing: %m");
2672 dynaddr_set = 1; /* only 1 attempt */
2679 /********************************************************************
2681 * cifaddr - Clear the interface IP addresses, and delete routes
2682 * through the interface if possible.
2685 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2689 if (kernel_version < KVERSION(2,1,16)) {
2691 * Delete the route through the device
2694 memset (&rt, '\0', sizeof (rt));
2696 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2697 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2700 SIN_ADDR(rt.rt_gateway) = 0;
2701 SIN_ADDR(rt.rt_dst) = his_adr;
2702 rt.rt_flags = RTF_UP | RTF_HOST;
2704 if (kernel_version > KVERSION(2,1,0)) {
2705 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2706 SIN_ADDR(rt.rt_genmask) = -1L;
2709 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2710 if (still_ppp() && ! ok_error (errno))
2711 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2716 /* This way it is possible to have an IPX-only or IPv6-only interface */
2717 memset(&ifr, 0, sizeof(ifr));
2718 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2719 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2721 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2722 if (! ok_error (errno)) {
2723 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2728 our_old_addr = our_adr;
2734 /********************************************************************
2736 * sif6addr - Config the interface with an IPv6 link-local address
2738 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2740 struct in6_ifreq ifr6;
2742 struct in6_rtmsg rt6;
2746 error("IPv6 socket creation failed: %m");
2749 memset(&ifr, 0, sizeof (ifr));
2750 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2751 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2752 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2756 /* Local interface */
2757 memset(&ifr6, 0, sizeof(ifr6));
2758 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2759 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2760 ifr6.ifr6_prefixlen = 10;
2762 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2763 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2767 /* Route to remote host */
2768 memset(&rt6, 0, sizeof(rt6));
2769 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2770 rt6.rtmsg_flags = RTF_UP;
2771 rt6.rtmsg_dst_len = 10;
2772 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2773 rt6.rtmsg_metric = 1;
2775 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2776 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2784 /********************************************************************
2786 * cif6addr - Remove IPv6 address from interface
2788 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2791 struct in6_ifreq ifr6;
2795 error("IPv6 socket creation failed: %m");
2798 memset(&ifr, 0, sizeof(ifr));
2799 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2800 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2801 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2805 memset(&ifr6, 0, sizeof(ifr6));
2806 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2807 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2808 ifr6.ifr6_prefixlen = 10;
2810 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2811 if (errno != EADDRNOTAVAIL) {
2812 if (! ok_error (errno))
2813 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2816 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2825 * get_pty - get a pty master/slave pair and chown the slave side
2826 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2829 get_pty(master_fdp, slave_fdp, slave_name, uid)
2835 int i, mfd, sfd = -1;
2837 struct termios tios;
2841 * Try the unix98 way first.
2843 mfd = open("/dev/ptmx", O_RDWR);
2846 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2847 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2848 chmod(pty_name, S_IRUSR | S_IWUSR);
2851 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2852 warn("Couldn't unlock pty slave %s: %m", pty_name);
2854 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2856 warn("Couldn't open pty slave %s: %m", pty_name);
2861 #endif /* TIOCGPTN */
2864 /* the old way - scan through the pty name space */
2865 for (i = 0; i < 64; ++i) {
2866 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2867 'p' + i / 16, i % 16);
2868 mfd = open(pty_name, O_RDWR, 0);
2871 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2873 fchown(sfd, uid, -1);
2874 fchmod(sfd, S_IRUSR | S_IWUSR);
2885 strlcpy(slave_name, pty_name, 16);
2888 if (tcgetattr(sfd, &tios) == 0) {
2889 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2890 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2891 tios.c_iflag = IGNPAR;
2894 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2895 warn("couldn't set attributes on pty: %m");
2897 warn("couldn't get attributes on pty: %m");
2902 /********************************************************************
2904 * open_loopback - open the device we use for getting packets
2905 * in demand mode. Under Linux, we use a pty master/slave pair.
2908 open_ppp_loopback(void)
2913 if (new_style_driver) {
2914 /* allocate ourselves a ppp unit */
2915 if (make_ppp_unit() < 0)
2917 modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2918 set_kdebugflag(kdebugflag);
2923 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2924 fatal("No free pty for loopback");
2926 set_ppp_fd(slave_fd);
2928 flags = fcntl(master_fd, F_GETFL);
2930 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2931 warn("couldn't set master loopback to nonblock: %m");
2933 flags = fcntl(ppp_fd, F_GETFL);
2935 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2936 warn("couldn't set slave loopback to nonblock: %m");
2938 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2939 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2941 * Find out which interface we were given.
2943 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2944 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2946 * Enable debug in the driver if requested.
2948 set_kdebugflag (kdebugflag);
2953 /********************************************************************
2955 * sifnpmode - Set the mode for handling packets for a given NP.
2959 sifnpmode(u, proto, mode)
2966 npi.protocol = proto;
2968 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2969 if (! ok_error (errno))
2970 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2977 /********************************************************************
2979 * sipxfaddr - Config the interface IPX networknumber
2982 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2989 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2991 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2993 if (! ok_error (errno))
2994 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2998 memset (&ifr, '\0', sizeof (ifr));
2999 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3001 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
3002 sipx->sipx_family = AF_IPX;
3003 sipx->sipx_port = 0;
3004 sipx->sipx_network = htonl (network);
3005 sipx->sipx_type = IPX_FRAME_ETHERII;
3006 sipx->sipx_action = IPX_CRTITF;
3008 * Set the IPX device
3010 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3012 if (errno != EEXIST) {
3013 if (! ok_error (errno))
3014 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
3017 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
3026 /********************************************************************
3028 * cipxfaddr - Clear the information for the IPX network. The IPX routes
3029 * are removed and the device is no longer able to pass IPX
3033 int cipxfaddr (int unit)
3040 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
3042 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
3044 if (! ok_error (errno))
3045 dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
3049 memset (&ifr, '\0', sizeof (ifr));
3050 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3052 sipx->sipx_type = IPX_FRAME_ETHERII;
3053 sipx->sipx_action = IPX_DLTITF;
3054 sipx->sipx_family = AF_IPX;
3056 * Set the IPX device
3058 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
3059 if (! ok_error (errno))
3060 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
3070 * Use the hostname as part of the random number seed.
3079 for (p = hostname; *p != 0; ++p)
3084 /********************************************************************
3086 * sys_check_options - check the options that the user specified
3090 sys_check_options(void)
3094 * Disable the IPX protocol if the support is not present in the kernel.
3098 if (ipxcp_protent.enabled_flag) {
3099 struct stat stat_buf;
3100 if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
3101 && (path = path_to_procfs("/net/ipx_interface")) == NULL)
3102 || lstat(path, &stat_buf) < 0) {
3103 error("IPX support is not present in the kernel\n");
3104 ipxcp_protent.enabled_flag = 0;
3108 if (demand && driver_is_old) {
3109 option_error("demand dialling is not supported by kernel driver "
3110 "version %d.%d.%d", driver_version, driver_modification,
3114 if (multilink && !new_style_driver) {
3115 warn("Warning: multilink is not supported by the kernel driver");
3123 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
3125 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
3126 * that the system has a properly configured Ethernet interface for this
3127 * function to return non-zero.
3130 ether_to_eui64(eui64_t *p_eui64)
3134 const unsigned char *ptr;
3136 skfd = socket(PF_INET6, SOCK_DGRAM, 0);
3139 warn("could not open IPv6 socket");
3143 strcpy(ifr.ifr_name, "eth0");
3144 if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
3147 warn("could not obtain hardware address for eth0");
3153 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
3155 ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data;
3156 p_eui64->e8[0] = ptr[0] | 0x02;
3157 p_eui64->e8[1] = ptr[1];
3158 p_eui64->e8[2] = ptr[2];
3159 p_eui64->e8[3] = 0xFF;
3160 p_eui64->e8[4] = 0xFE;
3161 p_eui64->e8[5] = ptr[3];
3162 p_eui64->e8[6] = ptr[4];
3163 p_eui64->e8[7] = ptr[5];
3169 /********************************************************************
3171 * get_time - Get current time, monotonic if possible.
3174 get_time(struct timeval *tv)
3176 /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
3177 * Runtime checking makes it safe. */
3178 #ifndef CLOCK_MONOTONIC
3179 #define CLOCK_MONOTONIC 1
3181 static int monotonic = -1;
3186 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
3190 tv->tv_sec = ts.tv_sec;
3191 tv->tv_usec = ts.tv_nsec / 1000;
3194 } else if (monotonic > 0)
3198 warn("Couldn't use monotonic clock source: %m");
3201 return gettimeofday(tv, NULL);