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>
76 #include <sys/errno.h>
79 #include <sys/utsname.h>
80 #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
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]); \
168 /* We can get an EIO error on an ioctl if the modem has hung up */
169 #define ok_error(num) ((num)==EIO)
171 static int tty_disc
= N_TTY
; /* The TTY discipline */
172 static int ppp_disc
= N_PPP
; /* The PPP discpline */
173 static int initfdflags
= -1; /* Initial file descriptor flags for fd */
174 static int ppp_fd
= -1; /* fd which is set to PPP discipline */
175 static int sock_fd
= -1; /* socket for doing interface ioctls */
176 static int slave_fd
= -1; /* pty for old-style demand mode, slave */
177 static int master_fd
= -1; /* pty for old-style demand mode, master */
179 static int sock6_fd
= -1;
183 * For the old-style kernel driver, this is the same as ppp_fd.
184 * For the new-style driver, it is the fd of an instance of /dev/ppp
185 * which is attached to the ppp unit and is used for controlling it.
187 int ppp_dev_fd
= -1; /* fd for /dev/ppp (new style driver) */
189 static int chindex
; /* channel index (new style driver) */
191 static fd_set in_fds
; /* set of fds that wait_input waits for */
192 static int max_in_fd
; /* highest fd set in in_fds */
194 static int has_proxy_arp
= 0;
195 static int driver_version
= 0;
196 static int driver_modification
= 0;
197 static int driver_patch
= 0;
198 static int driver_is_old
= 0;
199 static int restore_term
= 0; /* 1 => we've munged the terminal */
200 static struct termios inittermios
; /* Initial TTY termios */
202 int new_style_driver
= 0;
204 static char loop_name
[20];
205 static unsigned char inbuf
[512]; /* buffer for chars read from loopback */
207 static int if_is_up
; /* Interface has been marked up */
208 static int have_default_route
; /* Gateway for default route added */
209 static u_int32_t proxy_arp_addr
; /* Addr for proxy arp entry added */
210 static char proxy_arp_dev
[16]; /* Device for proxy arp entry */
211 static u_int32_t our_old_addr
; /* for detecting address changes */
212 static int dynaddr_set
; /* 1 if ip_dynaddr set */
213 static int looped
; /* 1 if using loop */
214 static int link_mtu
; /* mtu for the link (not bundle) */
216 static struct utsname utsname
; /* for the kernel version */
217 static int kernel_version
;
218 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
222 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
223 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
224 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
226 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
228 /* Prototypes for procedures local to this file. */
229 static int modify_flags(int fd
, int clear_bits
, int set_bits
);
230 static int translate_speed (int bps
);
231 static int baud_rate_of (int speed
);
232 static void close_route_table (void);
233 static int open_route_table (void);
234 static int read_route_table (struct rtentry
*rt
);
235 static int defaultroute_exists (struct rtentry
*rt
);
236 static int get_ether_addr (u_int32_t ipaddr
, struct sockaddr
*hwaddr
,
237 char *name
, int namelen
);
238 static void decode_version (char *buf
, int *version
, int *mod
, int *patch
);
239 static int set_kdebugflag(int level
);
240 static int ppp_registered(void);
241 static int make_ppp_unit(void);
243 extern u_char inpacket_buf
[]; /* borrowed from main.c */
246 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
250 #define SET_SA_FAMILY(addr, family) \
251 memset ((char *) &(addr), '\0', sizeof(addr)); \
252 addr.sa_family = (family);
255 * Determine if the PPP connection should still be present.
260 /* new_fd is the fd of a tty */
261 static void set_ppp_fd (int new_fd
)
264 if (!new_style_driver
)
268 static int still_ppp(void)
270 if (new_style_driver
)
271 return !hungup
&& ppp_fd
>= 0;
272 if (!hungup
|| ppp_fd
== slave_fd
)
275 set_ppp_fd(slave_fd
);
282 * modify_flags - set and clear flag bits controlling the kernel
285 static int modify_flags(int fd
, int clear_bits
, int set_bits
)
289 if (ioctl(fd
, PPPIOCGFLAGS
, &flags
) == -1)
291 flags
= (flags
& ~clear_bits
) | set_bits
;
292 if (ioctl(fd
, PPPIOCSFLAGS
, &flags
) == -1)
299 error("Failed to set PPP kernel option flags: %m");
303 /********************************************************************
305 * sys_init - System-dependent initialization.
310 /* Get an internet socket for doing socket ioctls. */
311 sock_fd
= socket(AF_INET
, SOCK_DGRAM
, 0);
313 fatal("Couldn't create IP socket: %m(%d)", errno
);
316 sock6_fd
= socket(AF_INET6
, SOCK_DGRAM
, 0);
318 sock6_fd
= -errno
; /* save errno for later */
325 /********************************************************************
327 * sys_cleanup - restore any system state we modified before exiting:
328 * mark the interface down, delete default route and/or proxy arp entry.
329 * This shouldn't call die() because it's called from die().
332 void sys_cleanup(void)
335 * Take down the device
342 * Delete any routes through the device.
344 if (have_default_route
)
345 cifdefaultroute(0, 0, 0);
348 cifproxyarp(0, proxy_arp_addr
);
351 /********************************************************************
353 * sys_close - Clean up in a child process before execing.
358 if (new_style_driver
&& ppp_dev_fd
>= 0)
372 /********************************************************************
374 * set_kdebugflag - Define the debugging level for the kernel
377 static int set_kdebugflag (int requested_level
)
381 if (ioctl(ppp_dev_fd
, PPPIOCSDEBUG
, &requested_level
) < 0) {
382 if ( ! ok_error (errno
) )
383 error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__
);
389 /********************************************************************
391 * tty_establish_ppp - Turn the serial port into a ppp interface.
394 int tty_establish_ppp (int tty_fd
)
399 * Ensure that the tty device is in exclusive mode.
401 if (ioctl(tty_fd
, TIOCEXCL
, 0) < 0) {
402 if ( ! ok_error ( errno
))
403 warn("Couldn't make tty exclusive: %m");
406 * Demand mode - prime the old ppp device to relinquish the unit.
408 if (!new_style_driver
&& looped
409 && ioctl(slave_fd
, PPPIOCXFERUNIT
, 0) < 0) {
410 error("ioctl(transfer ppp unit): %m, line %d", __LINE__
);
414 * Set the current tty to the PPP discpline
418 #define N_SYNC_PPP 14
420 ppp_disc
= (new_style_driver
&& sync_serial
)? N_SYNC_PPP
: N_PPP
;
421 if (ioctl(tty_fd
, TIOCSETD
, &ppp_disc
) < 0) {
422 if ( ! ok_error (errno
) ) {
423 error("Couldn't set tty to PPP discipline: %m");
428 ret_fd
= generic_establish_ppp(tty_fd
);
430 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
431 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
435 modify_flags(ppp_fd
, SC_RCVB
| SC_LOGB
,
436 (kdebugflag
* SC_DEBUG
) & SC_LOGB
);
438 if (ioctl(tty_fd
, TIOCSETD
, &tty_disc
) < 0 && !ok_error(errno
))
439 warn("Couldn't reset tty to normal line discipline: %m");
445 /********************************************************************
447 * generic_establish_ppp - Turn the fd into a ppp interface.
449 int generic_establish_ppp (int fd
)
453 if (new_style_driver
) {
456 /* if a ppp_fd is already open, close it first */
463 /* Open an instance of /dev/ppp and connect the channel to it */
464 if (ioctl(fd
, PPPIOCGCHAN
, &chindex
) == -1) {
465 error("Couldn't get channel number: %m");
468 dbglog("using channel %d", chindex
);
469 fd
= open("/dev/ppp", O_RDWR
);
471 error("Couldn't reopen /dev/ppp: %m");
474 (void) fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
475 if (ioctl(fd
, PPPIOCATTCHAN
, &chindex
) < 0) {
476 error("Couldn't attach to channel %d: %m", chindex
);
479 flags
= fcntl(fd
, F_GETFL
);
480 if (flags
== -1 || fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
) == -1)
481 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
486 if (!looped
&& !multilink
) {
488 * Create a new PPP unit.
490 if (make_ppp_unit() < 0)
495 modify_flags(ppp_dev_fd
, SC_LOOP_TRAFFIC
, 0);
499 if (ioctl(fd
, PPPIOCCONNECT
, &ifunit
) < 0) {
500 error("Couldn't attach to PPP unit %d: %m", ifunit
);
507 * Old-style driver: find out which interface we were given.
510 if (ioctl(fd
, PPPIOCGUNIT
, &x
) < 0) {
511 if (ok_error (errno
))
513 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__
);
515 /* Check that we got the same unit again. */
516 if (looped
&& x
!= ifunit
)
517 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit
, x
);
521 * Fetch the initial file flags and reset blocking mode on the file.
523 initfdflags
= fcntl(fd
, F_GETFL
);
524 if (initfdflags
== -1 ||
525 fcntl(fd
, F_SETFL
, initfdflags
| O_NONBLOCK
) == -1) {
526 if ( ! ok_error (errno
))
527 warn("Couldn't set device to non-blocking mode: %m");
532 * Enable debug in the driver if requested.
535 set_kdebugflag (kdebugflag
);
547 /********************************************************************
549 * tty_disestablish_ppp - Restore the serial port to normal operation.
550 * This shouldn't call die() because it's called from die().
553 void tty_disestablish_ppp(int tty_fd
)
557 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
559 if (tcflush(tty_fd
, TCIOFLUSH
) < 0)
561 warn("tcflush failed: %m");
565 * Restore the previous line discipline
567 if (ioctl(tty_fd
, TIOCSETD
, &tty_disc
) < 0) {
568 if ( ! ok_error (errno
))
569 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__
);
572 if (ioctl(tty_fd
, TIOCNXCL
, 0) < 0) {
573 if ( ! ok_error (errno
))
574 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__
);
577 /* Reset non-blocking mode on fd. */
578 if (initfdflags
!= -1 && fcntl(tty_fd
, F_SETFL
, initfdflags
) < 0) {
579 if ( ! ok_error (errno
))
580 warn("Couldn't restore device fd flags: %m");
586 generic_disestablish_ppp(tty_fd
);
589 /********************************************************************
591 * generic_disestablish_ppp - Restore device components to normal
592 * operation, and reconnect the ppp unit to the loopback if in demand
593 * mode. This shouldn't call die() because it's called from die().
595 void generic_disestablish_ppp(int dev_fd
)
597 if (new_style_driver
) {
601 modify_flags(ppp_dev_fd
, 0, SC_LOOP_TRAFFIC
);
603 } else if (!doing_multilink
&& ppp_dev_fd
>= 0) {
605 remove_fd(ppp_dev_fd
);
609 /* old-style driver */
611 set_ppp_fd(slave_fd
);
618 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
619 * Assumes new_style_driver.
621 static int make_ppp_unit()
625 if (ppp_dev_fd
>= 0) {
626 dbglog("in make_ppp_unit, already had /dev/ppp open?");
629 ppp_dev_fd
= open("/dev/ppp", O_RDWR
);
631 fatal("Couldn't open /dev/ppp: %m");
632 flags
= fcntl(ppp_dev_fd
, F_GETFL
);
634 || fcntl(ppp_dev_fd
, F_SETFL
, flags
| O_NONBLOCK
) == -1)
635 warn("Couldn't set /dev/ppp to nonblock: %m");
637 ifunit
= (req_unit
>= 0) ? req_unit
: req_minunit
;
639 x
= ioctl(ppp_dev_fd
, PPPIOCNEWUNIT
, &ifunit
);
640 if (x
< 0 && errno
== EEXIST
) {
641 warn("Couldn't allocate PPP unit %d as it is already in use", ifunit
);
642 ifunit
= (req_unit
>= 0) ? -1 : ++req_minunit
;
644 } while (ifunit
< MAXUNIT
);
647 error("Couldn't create new ppp unit: %m");
652 * cfg_bundle - configure the existing bundle.
653 * Used in demand mode.
655 void cfg_bundle(int mrru
, int mtru
, int rssn
, int tssn
)
657 if (!new_style_driver
)
660 /* set the mrru, mtu and flags */
661 if (ioctl(ppp_dev_fd
, PPPIOCSMRRU
, &mrru
) < 0)
662 error("Couldn't set MRRU: %m");
664 modify_flags(ppp_dev_fd
, SC_MP_SHORTSEQ
|SC_MP_XSHORTSEQ
|SC_MULTILINK
,
665 ((rssn
? SC_MP_SHORTSEQ
: 0) | (tssn
? SC_MP_XSHORTSEQ
: 0)
666 | (mrru
? SC_MULTILINK
: 0)));
668 /* connect up the channel */
669 if (ioctl(ppp_fd
, PPPIOCCONNECT
, &ifunit
) < 0)
670 fatal("Couldn't attach to PPP unit %d: %m", ifunit
);
675 * make_new_bundle - create a new PPP unit (i.e. a bundle)
676 * and connect our channel to it. This should only get called
677 * if `multilink' was set at the time establish_ppp was called.
678 * In demand mode this uses our existing bundle instead of making
681 void make_new_bundle(int mrru
, int mtru
, int rssn
, int tssn
)
683 if (!new_style_driver
)
686 /* make us a ppp unit */
687 if (make_ppp_unit() < 0)
690 /* set the mrru and flags */
691 cfg_bundle(mrru
, mtru
, rssn
, tssn
);
695 * bundle_attach - attach our link to a given PPP unit.
696 * We assume the unit is controlled by another pppd.
698 int bundle_attach(int ifnum
)
702 if (!new_style_driver
)
705 master_fd
= open("/dev/ppp", O_RDWR
);
707 fatal("Couldn't open /dev/ppp: %m");
708 if (ioctl(master_fd
, PPPIOCATTACH
, &ifnum
) < 0) {
709 if (errno
== ENXIO
) {
711 return 0; /* doesn't still exist */
713 fatal("Couldn't attach to interface unit %d: %m\n", ifnum
);
715 if (ioctl(ppp_fd
, PPPIOCCONNECT
, &ifnum
) < 0)
716 fatal("Couldn't connect to interface unit %d: %m", ifnum
);
717 modify_flags(master_fd
, 0, SC_MULTILINK
);
725 * destroy_bundle - tell the driver to destroy our bundle.
727 void destroy_bundle(void)
729 if (ppp_dev_fd
>= 0) {
731 remove_fd(ppp_dev_fd
);
736 /********************************************************************
738 * clean_check - Fetch the flags for the device and generate
739 * appropriate error messages.
741 void clean_check(void)
747 if (ioctl(ppp_fd
, PPPIOCGFLAGS
, (caddr_t
) &x
) == 0) {
749 switch (~x
& (SC_RCV_B7_0
|SC_RCV_B7_1
|SC_RCV_EVNP
|SC_RCV_ODDP
)) {
751 s
= "all had bit 7 set to 1";
755 s
= "all had bit 7 set to 0";
759 s
= "all had odd parity";
763 s
= "all had even parity";
768 warn("Receive serial link is not 8-bit clean:");
769 warn("Problem: %s", s
);
777 * List of valid speeds.
781 int speed_int
, speed_val
;
862 { 1000000, B1000000
},
865 { 1152000, B1152000
},
868 { 1500000, B1500000
},
871 { 2000000, B2000000
},
874 { 2500000, B2500000
},
877 { 3000000, B3000000
},
880 { 3500000, B3500000
},
883 { 4000000, B4000000
},
888 /********************************************************************
890 * Translate from bits/second to a speed_t.
893 static int translate_speed (int bps
)
895 struct speed
*speedp
;
898 for (speedp
= speeds
; speedp
->speed_int
; speedp
++) {
899 if (bps
== speedp
->speed_int
)
900 return speedp
->speed_val
;
902 warn("speed %d not supported", bps
);
907 /********************************************************************
909 * Translate from a speed_t to bits/second.
912 static int baud_rate_of (int speed
)
914 struct speed
*speedp
;
917 for (speedp
= speeds
; speedp
->speed_int
; speedp
++) {
918 if (speed
== speedp
->speed_val
)
919 return speedp
->speed_int
;
925 /********************************************************************
927 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
928 * at the requested speed, etc. If `local' is true, set CLOCAL
929 * regardless of whether the modem option was specified.
932 void set_up_tty(int tty_fd
, int local
)
938 if (tcgetattr(tty_fd
, &tios
) < 0) {
939 if (!ok_error(errno
))
940 fatal("tcgetattr: %m (line %d)", __LINE__
);
947 tios
.c_cflag
&= ~(CSIZE
| CSTOPB
| PARENB
| CLOCAL
);
948 tios
.c_cflag
|= CS8
| CREAD
| HUPCL
;
950 tios
.c_iflag
= IGNBRK
| IGNPAR
;
954 tios
.c_cc
[VTIME
] = 0;
957 tios
.c_cflag
^= (CLOCAL
| HUPCL
);
961 tios
.c_cflag
|= CRTSCTS
;
965 tios
.c_iflag
|= IXON
| IXOFF
;
966 tios
.c_cc
[VSTOP
] = 0x13; /* DC3 = XOFF = ^S */
967 tios
.c_cc
[VSTART
] = 0x11; /* DC1 = XON = ^Q */
971 tios
.c_cflag
&= ~CRTSCTS
;
978 speed
= translate_speed(inspeed
);
980 cfsetospeed (&tios
, speed
);
981 cfsetispeed (&tios
, speed
);
984 * We can't proceed if the serial port speed is B0,
985 * since that implies that the serial port is disabled.
988 speed
= cfgetospeed(&tios
);
990 fatal("Baud rate for %s is 0; need explicit baud rate", devnam
);
993 while (tcsetattr(tty_fd
, TCSAFLUSH
, &tios
) < 0 && !ok_error(errno
))
995 fatal("tcsetattr: %m (line %d)", __LINE__
);
997 baud_rate
= baud_rate_of(speed
);
1001 /********************************************************************
1003 * setdtr - control the DTR line on the serial port.
1004 * This is called from die(), so it shouldn't call die().
1007 void setdtr (int tty_fd
, int on
)
1009 int modembits
= TIOCM_DTR
;
1011 ioctl(tty_fd
, (on
? TIOCMBIS
: TIOCMBIC
), &modembits
);
1014 /********************************************************************
1016 * restore_tty - restore the terminal to the saved settings.
1019 void restore_tty (int tty_fd
)
1024 * Turn off echoing, because otherwise we can get into
1025 * a loop with the tty and the modem echoing to each other.
1026 * We presume we are the sole user of this tty device, so
1027 * when we close it, it will revert to its defaults anyway.
1029 if (!default_device
)
1030 inittermios
.c_lflag
&= ~(ECHO
| ECHONL
);
1032 if (tcsetattr(tty_fd
, TCSAFLUSH
, &inittermios
) < 0) {
1033 if (! ok_error (errno
))
1034 warn("tcsetattr: %m (line %d)", __LINE__
);
1039 /********************************************************************
1041 * output - Output PPP packet.
1044 void output (int unit
, unsigned char *p
, int len
)
1049 dump_packet("sent", p
, len
);
1050 if (snoop_send_hook
) snoop_send_hook(p
, len
);
1052 if (len
< PPP_HDRLEN
)
1054 if (new_style_driver
) {
1057 proto
= (p
[0] << 8) + p
[1];
1058 if (ppp_dev_fd
>= 0 && !(proto
>= 0xc000 || proto
== PPP_CCPFRAG
))
1061 if (write(fd
, p
, len
) < 0) {
1062 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
|| errno
== ENOBUFS
1063 || errno
== ENXIO
|| errno
== EIO
|| errno
== EINTR
)
1064 warn("write: warning: %m (%d)", errno
);
1066 error("write: %m (%d)", errno
);
1070 /********************************************************************
1072 * wait_input - wait until there is data available,
1073 * for the length of time specified by *timo (indefinite
1077 void wait_input(struct timeval
*timo
)
1084 n
= select(max_in_fd
+ 1, &ready
, NULL
, &exc
, timo
);
1085 if (n
< 0 && errno
!= EINTR
)
1086 fatal("select: %m");
1090 * add_fd - add an fd to the set that wait_input waits for.
1094 if (fd
>= FD_SETSIZE
)
1095 fatal("internal error: file descriptor too large (%d)", fd
);
1096 FD_SET(fd
, &in_fds
);
1102 * remove_fd - remove an fd from the set that wait_input waits for.
1104 void remove_fd(int fd
)
1106 FD_CLR(fd
, &in_fds
);
1110 /********************************************************************
1112 * read_packet - get a PPP packet from the serial device.
1115 int read_packet (unsigned char *buf
)
1119 len
= PPP_MRU
+ PPP_HDRLEN
;
1120 if (new_style_driver
) {
1121 *buf
++ = PPP_ALLSTATIONS
;
1127 nr
= read(ppp_fd
, buf
, len
);
1128 if (nr
< 0 && errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
1129 && errno
!= EIO
&& errno
!= EINTR
)
1131 if (nr
< 0 && errno
== ENXIO
)
1134 if (nr
< 0 && new_style_driver
&& ppp_dev_fd
>= 0 && !bundle_eof
) {
1135 /* N.B. we read ppp_fd first since LCP packets come in there. */
1136 nr
= read(ppp_dev_fd
, buf
, len
);
1137 if (nr
< 0 && errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
1138 && errno
!= EIO
&& errno
!= EINTR
)
1139 error("read /dev/ppp: %m");
1140 if (nr
< 0 && errno
== ENXIO
)
1142 if (nr
== 0 && doing_multilink
) {
1143 remove_fd(ppp_dev_fd
);
1147 if (new_style_driver
&& ppp_fd
< 0 && ppp_dev_fd
< 0)
1149 return (new_style_driver
&& nr
> 0)? nr
+2: nr
;
1152 /********************************************************************
1154 * get_loop_output - get outgoing packets from the ppp device,
1155 * and detect when we want to bring the real link up.
1156 * Return value is 1 if we need to bring up the link, 0 otherwise.
1159 get_loop_output(void)
1164 if (new_style_driver
) {
1165 while ((n
= read_packet(inpacket_buf
)) > 0)
1166 if (loop_frame(inpacket_buf
, n
))
1171 while ((n
= read(master_fd
, inbuf
, sizeof(inbuf
))) > 0)
1172 if (loop_chars(inbuf
, n
))
1176 fatal("eof on loopback");
1178 if (errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
)
1179 fatal("read from loopback: %m(%d)", errno
);
1185 * netif_set_mtu - set the MTU on the PPP network interface.
1188 netif_set_mtu(int unit
, int mtu
)
1192 memset (&ifr
, '\0', sizeof (ifr
));
1193 strlcpy(ifr
.ifr_name
, ifname
, sizeof (ifr
.ifr_name
));
1196 if (ifunit
>= 0 && ioctl(sock_fd
, SIOCSIFMTU
, (caddr_t
) &ifr
) < 0)
1197 error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__
);
1201 * netif_get_mtu - get the MTU on the PPP network interface.
1204 netif_get_mtu(int unit
)
1208 memset (&ifr
, '\0', sizeof (ifr
));
1209 strlcpy(ifr
.ifr_name
, ifname
, sizeof (ifr
.ifr_name
));
1211 if (ifunit
>= 0 && ioctl(sock_fd
, SIOCGIFMTU
, (caddr_t
) &ifr
) < 0) {
1212 error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__
);
1218 /********************************************************************
1220 * tty_send_config - configure the transmit characteristics of
1221 * the ppp interface.
1224 void tty_send_config(int mtu
, u_int32_t asyncmap
, int pcomp
, int accomp
)
1231 if (ioctl(ppp_fd
, PPPIOCSASYNCMAP
, (caddr_t
) &asyncmap
) < 0) {
1232 if (errno
!= EIO
&& errno
!= ENOTTY
)
1233 error("Couldn't set transmit async character map: %m");
1238 x
= (pcomp
? SC_COMP_PROT
: 0) | (accomp
? SC_COMP_AC
: 0)
1239 | (sync_serial
? SC_SYNC
: 0);
1240 modify_flags(ppp_fd
, SC_COMP_PROT
|SC_COMP_AC
|SC_SYNC
, x
);
1243 /********************************************************************
1245 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1248 void tty_set_xaccm (ext_accm accm
)
1252 if (ioctl(ppp_fd
, PPPIOCSXASYNCMAP
, accm
) < 0 && errno
!= ENOTTY
) {
1253 if ( ! ok_error (errno
))
1254 warn("ioctl(set extended ACCM): %m (line %d)", __LINE__
);
1258 /********************************************************************
1260 * tty_recv_config - configure the receive-side characteristics of
1261 * the ppp interface.
1264 void tty_recv_config(int mru
, u_int32_t asyncmap
, int pcomp
, int accomp
)
1267 * If we were called because the link has gone down then there is nothing
1268 * which may be done. Just return without incident.
1273 * Set the receiver parameters
1275 if (ioctl(ppp_fd
, PPPIOCSMRU
, (caddr_t
) &mru
) < 0) {
1276 if (errno
!= EIO
&& errno
!= ENOTTY
)
1277 error("Couldn't set channel receive MRU: %m");
1279 if (new_style_driver
&& ppp_dev_fd
>= 0
1280 && ioctl(ppp_dev_fd
, PPPIOCSMRU
, (caddr_t
) &mru
) < 0)
1281 error("Couldn't set MRU in generic PPP layer: %m");
1283 if (ioctl(ppp_fd
, PPPIOCSRASYNCMAP
, (caddr_t
) &asyncmap
) < 0) {
1284 if (errno
!= EIO
&& errno
!= ENOTTY
)
1285 error("Couldn't set channel receive asyncmap: %m");
1289 /********************************************************************
1291 * ccp_test - ask kernel whether a given compression method
1292 * is acceptable for use.
1296 ccp_test(int unit
, u_char
*opt_ptr
, int opt_len
, int for_transmit
)
1298 struct ppp_option_data data
;
1300 memset (&data
, '\0', sizeof (data
));
1302 data
.length
= opt_len
;
1303 data
.transmit
= for_transmit
;
1305 if (ioctl(ppp_dev_fd
, PPPIOCSCOMPRESS
, (caddr_t
) &data
) >= 0)
1308 return (errno
== ENOBUFS
)? 0: -1;
1311 /********************************************************************
1313 * ccp_flags_set - inform kernel about the current state of CCP.
1316 void ccp_flags_set (int unit
, int isopen
, int isup
)
1320 x
= (isopen
? SC_CCP_OPEN
: 0) | (isup
? SC_CCP_UP
: 0);
1321 if (still_ppp() && ppp_dev_fd
>= 0)
1322 modify_flags(ppp_dev_fd
, SC_CCP_OPEN
|SC_CCP_UP
, x
);
1327 * set_filters - set the active and pass filters in the kernel driver.
1329 int set_filters(struct bpf_program
*pass
, struct bpf_program
*active
)
1331 struct sock_fprog fp
;
1333 fp
.len
= pass
->bf_len
;
1334 fp
.filter
= (struct sock_filter
*) pass
->bf_insns
;
1335 if (ioctl(ppp_dev_fd
, PPPIOCSPASS
, &fp
) < 0) {
1336 if (errno
== ENOTTY
)
1337 warn("kernel does not support PPP filtering");
1339 error("Couldn't set pass-filter in kernel: %m");
1342 fp
.len
= active
->bf_len
;
1343 fp
.filter
= (struct sock_filter
*) active
->bf_insns
;
1344 if (ioctl(ppp_dev_fd
, PPPIOCSACTIVE
, &fp
) < 0) {
1345 error("Couldn't set active-filter in kernel: %m");
1350 #endif /* PPP_FILTER */
1352 /********************************************************************
1354 * get_idle_time - return how long the link has been idle.
1357 get_idle_time(u
, ip
)
1359 struct ppp_idle
*ip
;
1361 return ioctl(ppp_dev_fd
, PPPIOCGIDLE
, ip
) >= 0;
1364 /********************************************************************
1366 * get_ppp_stats - return statistics for the link.
1369 get_ppp_stats(u
, stats
)
1371 struct pppd_stats
*stats
;
1373 struct ifpppstatsreq req
;
1375 memset (&req
, 0, sizeof (req
));
1377 req
.stats_ptr
= (caddr_t
) &req
.stats
;
1378 strlcpy(req
.ifr__name
, ifname
, sizeof(req
.ifr__name
));
1379 if (ioctl(sock_fd
, SIOCGPPPSTATS
, &req
) < 0) {
1380 error("Couldn't get PPP statistics: %m");
1383 stats
->bytes_in
= req
.stats
.p
.ppp_ibytes
;
1384 stats
->bytes_out
= req
.stats
.p
.ppp_obytes
;
1385 stats
->pkts_in
= req
.stats
.p
.ppp_ipackets
;
1386 stats
->pkts_out
= req
.stats
.p
.ppp_opackets
;
1390 /********************************************************************
1392 * ccp_fatal_error - returns 1 if decompression was disabled as a
1393 * result of an error detected after decompression of a packet,
1394 * 0 otherwise. This is necessary because of patent nonsense.
1397 int ccp_fatal_error (int unit
)
1401 if (ioctl(ppp_dev_fd
, PPPIOCGFLAGS
, &flags
) < 0) {
1402 error("Couldn't read compression error flags: %m");
1405 return flags
& SC_DC_FERROR
;
1408 /********************************************************************
1410 * path_to_procfs - find the path to the proc file system mount point
1412 static char proc_path
[MAXPATHLEN
];
1413 static int proc_path_len
;
1415 static char *path_to_procfs(const char *tail
)
1417 struct mntent
*mntent
;
1420 if (proc_path_len
== 0) {
1421 /* Default the mount location of /proc */
1422 strlcpy (proc_path
, "/proc", sizeof(proc_path
));
1424 fp
= fopen(MOUNTED
, "r");
1426 while ((mntent
= getmntent(fp
)) != NULL
) {
1427 if (strcmp(mntent
->mnt_type
, MNTTYPE_IGNORE
) == 0)
1429 if (strcmp(mntent
->mnt_type
, "proc") == 0) {
1430 strlcpy(proc_path
, mntent
->mnt_dir
, sizeof(proc_path
));
1431 proc_path_len
= strlen(proc_path
);
1439 strlcpy(proc_path
+ proc_path_len
, tail
,
1440 sizeof(proc_path
) - proc_path_len
);
1445 * /proc/net/route parsing stuff.
1447 #define ROUTE_MAX_COLS 12
1448 FILE *route_fd
= (FILE *) 0;
1449 static char route_buffer
[512];
1450 static int route_dev_col
, route_dest_col
, route_gw_col
;
1451 static int route_flags_col
, route_mask_col
;
1452 static int route_num_cols
;
1454 static int open_route_table (void);
1455 static void close_route_table (void);
1456 static int read_route_table (struct rtentry
*rt
);
1458 /********************************************************************
1460 * close_route_table - close the interface to the route table
1463 static void close_route_table (void)
1465 if (route_fd
!= (FILE *) 0) {
1467 route_fd
= (FILE *) 0;
1471 /********************************************************************
1473 * open_route_table - open the interface to the route table
1475 static char route_delims
[] = " \t\n";
1477 static int open_route_table (void)
1481 close_route_table();
1483 path
= path_to_procfs("/net/route");
1484 route_fd
= fopen (path
, "r");
1485 if (route_fd
== NULL
) {
1486 error("can't open routing table %s: %m", path
);
1490 route_dev_col
= 0; /* default to usual columns */
1493 route_flags_col
= 3;
1497 /* parse header line */
1498 if (fgets(route_buffer
, sizeof(route_buffer
), route_fd
) != 0) {
1499 char *p
= route_buffer
, *q
;
1501 for (col
= 0; col
< ROUTE_MAX_COLS
; ++col
) {
1503 if ((q
= strtok(p
, route_delims
)) == 0)
1505 if (strcasecmp(q
, "iface") == 0)
1506 route_dev_col
= col
;
1507 else if (strcasecmp(q
, "destination") == 0)
1508 route_dest_col
= col
;
1509 else if (strcasecmp(q
, "gateway") == 0)
1511 else if (strcasecmp(q
, "flags") == 0)
1512 route_flags_col
= col
;
1513 else if (strcasecmp(q
, "mask") == 0)
1514 route_mask_col
= col
;
1517 if (used
&& col
>= route_num_cols
)
1518 route_num_cols
= col
+ 1;
1526 /********************************************************************
1528 * read_route_table - read the next entry from the route table
1531 static int read_route_table(struct rtentry
*rt
)
1533 char *cols
[ROUTE_MAX_COLS
], *p
;
1536 memset (rt
, '\0', sizeof (struct rtentry
));
1538 if (fgets (route_buffer
, sizeof (route_buffer
), route_fd
) == (char *) 0)
1542 for (col
= 0; col
< route_num_cols
; ++col
) {
1543 cols
[col
] = strtok(p
, route_delims
);
1544 if (cols
[col
] == NULL
)
1545 return 0; /* didn't get enough columns */
1549 SIN_ADDR(rt
->rt_dst
) = strtoul(cols
[route_dest_col
], NULL
, 16);
1550 SIN_ADDR(rt
->rt_gateway
) = strtoul(cols
[route_gw_col
], NULL
, 16);
1551 SIN_ADDR(rt
->rt_genmask
) = strtoul(cols
[route_mask_col
], NULL
, 16);
1553 rt
->rt_flags
= (short) strtoul(cols
[route_flags_col
], NULL
, 16);
1554 rt
->rt_dev
= cols
[route_dev_col
];
1559 /********************************************************************
1561 * defaultroute_exists - determine if there is a default route
1564 static int defaultroute_exists (struct rtentry
*rt
)
1568 if (!open_route_table())
1571 while (read_route_table(rt
) != 0) {
1572 if ((rt
->rt_flags
& RTF_UP
) == 0)
1575 if (kernel_version
> KVERSION(2,1,0) && SIN_ADDR(rt
->rt_genmask
) != 0)
1577 if (SIN_ADDR(rt
->rt_dst
) == 0L) {
1583 close_route_table();
1588 * have_route_to - determine if the system has any route to
1589 * a given IP address. `addr' is in network byte order.
1590 * Return value is 1 if yes, 0 if no, -1 if don't know.
1591 * For demand mode to work properly, we have to ignore routes
1592 * through our own interface.
1594 int have_route_to(u_int32_t addr
)
1599 if (!open_route_table())
1600 return -1; /* don't know */
1602 while (read_route_table(&rt
)) {
1603 if ((rt
.rt_flags
& RTF_UP
) == 0 || strcmp(rt
.rt_dev
, ifname
) == 0)
1605 if ((addr
& SIN_ADDR(rt
.rt_genmask
)) == SIN_ADDR(rt
.rt_dst
)) {
1611 close_route_table();
1615 /********************************************************************
1617 * sifdefaultroute - assign a default route through the address given.
1620 int sifdefaultroute (int unit
, u_int32_t ouraddr
, u_int32_t gateway
)
1624 if (defaultroute_exists(&rt
) && strcmp(rt
.rt_dev
, ifname
) != 0) {
1625 if (rt
.rt_flags
& RTF_GATEWAY
)
1626 error("not replacing existing default route via %I",
1627 SIN_ADDR(rt
.rt_gateway
));
1629 error("not replacing existing default route through %s",
1634 memset (&rt
, 0, sizeof (rt
));
1635 SET_SA_FAMILY (rt
.rt_dst
, AF_INET
);
1637 SET_SA_FAMILY(rt
.rt_gateway
, AF_INET
);
1638 SIN_ADDR(rt
.rt_gateway
) = gateway
;
1642 if (kernel_version
> KVERSION(2,1,0)) {
1643 SET_SA_FAMILY (rt
.rt_genmask
, AF_INET
);
1644 SIN_ADDR(rt
.rt_genmask
) = 0L;
1647 rt
.rt_flags
= RTF_UP
| RTF_GATEWAY
;
1648 if (ioctl(sock_fd
, SIOCADDRT
, &rt
) < 0) {
1649 if ( ! ok_error ( errno
))
1650 error("default route ioctl(SIOCADDRT): %m");
1654 have_default_route
= 1;
1658 /********************************************************************
1660 * cifdefaultroute - delete a default route through the address given.
1663 int cifdefaultroute (int unit
, u_int32_t ouraddr
, u_int32_t gateway
)
1667 have_default_route
= 0;
1669 memset (&rt
, '\0', sizeof (rt
));
1670 SET_SA_FAMILY (rt
.rt_dst
, AF_INET
);
1671 SET_SA_FAMILY (rt
.rt_gateway
, AF_INET
);
1675 if (kernel_version
> KVERSION(2,1,0)) {
1676 SET_SA_FAMILY (rt
.rt_genmask
, AF_INET
);
1677 SIN_ADDR(rt
.rt_genmask
) = 0L;
1680 rt
.rt_flags
= RTF_UP
;
1681 if (ioctl(sock_fd
, SIOCDELRT
, &rt
) < 0 && errno
!= ESRCH
) {
1683 if ( ! ok_error ( errno
))
1684 error("default route ioctl(SIOCDELRT): %m");
1692 /********************************************************************
1694 * sifproxyarp - Make a proxy ARP entry for the peer.
1697 int sifproxyarp (int unit
, u_int32_t his_adr
)
1699 struct arpreq arpreq
;
1702 if (has_proxy_arp
== 0) {
1703 memset (&arpreq
, '\0', sizeof(arpreq
));
1705 SET_SA_FAMILY(arpreq
.arp_pa
, AF_INET
);
1706 SIN_ADDR(arpreq
.arp_pa
) = his_adr
;
1707 arpreq
.arp_flags
= ATF_PERM
| ATF_PUBL
;
1709 * Get the hardware address of an interface on the same subnet
1710 * as our local address.
1712 if (!get_ether_addr(his_adr
, &arpreq
.arp_ha
, proxy_arp_dev
,
1713 sizeof(proxy_arp_dev
))) {
1714 error("Cannot determine ethernet address for proxy ARP");
1717 strlcpy(arpreq
.arp_dev
, proxy_arp_dev
, sizeof(arpreq
.arp_dev
));
1719 if (ioctl(sock_fd
, SIOCSARP
, (caddr_t
)&arpreq
) < 0) {
1720 if ( ! ok_error ( errno
))
1721 error("ioctl(SIOCSARP): %m");
1724 proxy_arp_addr
= his_adr
;
1728 forw_path
= path_to_procfs("/sys/net/ipv4/ip_forward");
1729 if (forw_path
!= 0) {
1730 int fd
= open(forw_path
, O_WRONLY
);
1732 if (write(fd
, "1", 1) != 1)
1733 error("Couldn't enable IP forwarding: %m");
1743 /********************************************************************
1745 * cifproxyarp - Delete the proxy ARP entry for the peer.
1748 int cifproxyarp (int unit
, u_int32_t his_adr
)
1750 struct arpreq arpreq
;
1752 if (has_proxy_arp
) {
1754 memset (&arpreq
, '\0', sizeof(arpreq
));
1755 SET_SA_FAMILY(arpreq
.arp_pa
, AF_INET
);
1756 SIN_ADDR(arpreq
.arp_pa
) = his_adr
;
1757 arpreq
.arp_flags
= ATF_PERM
| ATF_PUBL
;
1758 strlcpy(arpreq
.arp_dev
, proxy_arp_dev
, sizeof(arpreq
.arp_dev
));
1760 if (ioctl(sock_fd
, SIOCDARP
, (caddr_t
)&arpreq
) < 0) {
1761 if ( ! ok_error ( errno
))
1762 warn("ioctl(SIOCDARP): %m");
1769 /********************************************************************
1771 * get_ether_addr - get the hardware address of an interface on the
1772 * the same subnet as ipaddr.
1775 static int get_ether_addr (u_int32_t ipaddr
,
1776 struct sockaddr
*hwaddr
,
1777 char *name
, int namelen
)
1779 struct ifreq
*ifr
, *ifend
;
1780 u_int32_t ina
, mask
;
1782 struct ifreq ifreq
, bestifreq
;
1784 struct ifreq ifs
[MAX_IFS
];
1786 u_int32_t bestmask
=0;
1787 int found_interface
= 0;
1789 ifc
.ifc_len
= sizeof(ifs
);
1791 if (ioctl(sock_fd
, SIOCGIFCONF
, &ifc
) < 0) {
1792 if ( ! ok_error ( errno
))
1793 error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__
);
1798 * Scan through looking for an interface with an Internet
1799 * address on the same subnet as `ipaddr'.
1801 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
1802 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++) {
1803 if (ifr
->ifr_addr
.sa_family
== AF_INET
) {
1804 ina
= SIN_ADDR(ifr
->ifr_addr
);
1805 strlcpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
1807 * Check that the interface is up, and not point-to-point
1810 if (ioctl(sock_fd
, SIOCGIFFLAGS
, &ifreq
) < 0)
1813 if (((ifreq
.ifr_flags
^ FLAGS_GOOD
) & FLAGS_MASK
) != 0)
1816 * Get its netmask and check that it's on the right subnet.
1818 if (ioctl(sock_fd
, SIOCGIFNETMASK
, &ifreq
) < 0)
1821 mask
= SIN_ADDR(ifreq
.ifr_addr
);
1823 if (((ipaddr
^ ina
) & mask
) != 0)
1824 continue; /* no match */
1826 if (mask
>= bestmask
) {
1827 /* Compare using >= instead of > -- it is possible for
1828 an interface to have a netmask of 0.0.0.0 */
1829 found_interface
= 1;
1836 if (!found_interface
) return 0;
1838 strlcpy(name
, bestifreq
.ifr_name
, namelen
);
1840 /* trim off the :1 in eth0:1 */
1841 aliasp
= strchr(name
, ':');
1845 info("found interface %s for proxy arp", name
);
1847 * Now get the hardware address.
1849 memset (&bestifreq
.ifr_hwaddr
, 0, sizeof (struct sockaddr
));
1850 if (ioctl (sock_fd
, SIOCGIFHWADDR
, &bestifreq
) < 0) {
1851 error("SIOCGIFHWADDR(%s): %m", bestifreq
.ifr_name
);
1856 &bestifreq
.ifr_hwaddr
,
1857 sizeof (struct sockaddr
));
1863 * get_if_hwaddr - get the hardware address for the specified
1864 * network interface device.
1867 get_if_hwaddr(u_char
*addr
, char *name
)
1872 sock_fd
= socket(AF_INET
, SOCK_DGRAM
, 0);
1875 memset(&ifreq
.ifr_hwaddr
, 0, sizeof(struct sockaddr
));
1876 strlcpy(ifreq
.ifr_name
, name
, sizeof(ifreq
.ifr_name
));
1877 ret
= ioctl(sock_fd
, SIOCGIFHWADDR
, &ifreq
);
1880 memcpy(addr
, ifreq
.ifr_hwaddr
.sa_data
, 6);
1885 * get_first_ethernet - return the name of the first ethernet-style
1886 * interface on this system.
1889 get_first_ethernet()
1894 /********************************************************************
1896 * Return user specified netmask, modified by any mask we might determine
1897 * for address `addr' (in network byte order).
1898 * Here we scan through the system's list of interfaces, looking for
1899 * any non-point-to-point interfaces which might appear to be on the same
1900 * network as `addr'. If we find any, we OR in their netmask to the
1901 * user-specified netmask.
1904 u_int32_t
GetMask (u_int32_t addr
)
1906 u_int32_t mask
, nmask
, ina
;
1907 struct ifreq
*ifr
, *ifend
, ifreq
;
1909 struct ifreq ifs
[MAX_IFS
];
1913 if (IN_CLASSA(addr
)) /* determine network mask for address class */
1914 nmask
= IN_CLASSA_NET
;
1915 else if (IN_CLASSB(addr
))
1916 nmask
= IN_CLASSB_NET
;
1918 nmask
= IN_CLASSC_NET
;
1920 /* class D nets are disallowed by bad_ip_adrs */
1921 mask
= netmask
| htonl(nmask
);
1923 * Scan through the system's network interfaces.
1925 ifc
.ifc_len
= sizeof(ifs
);
1927 if (ioctl(sock_fd
, SIOCGIFCONF
, &ifc
) < 0) {
1928 if ( ! ok_error ( errno
))
1929 warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__
);
1933 ifend
= (struct ifreq
*) (ifc
.ifc_buf
+ ifc
.ifc_len
);
1934 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++) {
1936 * Check the interface's internet address.
1938 if (ifr
->ifr_addr
.sa_family
!= AF_INET
)
1940 ina
= SIN_ADDR(ifr
->ifr_addr
);
1941 if (((ntohl(ina
) ^ addr
) & nmask
) != 0)
1944 * Check that the interface is up, and not point-to-point nor loopback.
1946 strlcpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
1947 if (ioctl(sock_fd
, SIOCGIFFLAGS
, &ifreq
) < 0)
1950 if (((ifreq
.ifr_flags
^ FLAGS_GOOD
) & FLAGS_MASK
) != 0)
1953 * Get its netmask and OR it into our mask.
1955 if (ioctl(sock_fd
, SIOCGIFNETMASK
, &ifreq
) < 0)
1957 mask
|= SIN_ADDR(ifreq
.ifr_addr
);
1963 /********************************************************************
1965 * Internal routine to decode the version.modification.patch level
1968 static void decode_version (char *buf
, int *version
,
1969 int *modification
, int *patch
)
1973 *version
= (int) strtoul (buf
, &endp
, 10);
1977 if (endp
!= buf
&& *endp
== '.') {
1979 *modification
= (int) strtoul (buf
, &endp
, 10);
1980 if (endp
!= buf
&& *endp
== '.') {
1982 *patch
= (int) strtoul (buf
, &buf
, 10);
1987 /********************************************************************
1989 * Procedure to determine if the PPP line discipline is registered.
1993 ppp_registered(void)
2001 * We used to open the serial device and set it to the ppp line
2002 * discipline here, in order to create a ppp unit. But that is
2003 * not a good idea - the user might have specified a device that
2004 * they can't open (permission, or maybe it doesn't really exist).
2005 * So we grab a pty master/slave pair and use that.
2007 if (!get_pty(&mfd
, &local_fd
, slave
, 0)) {
2008 no_ppp_msg
= "Couldn't determine if PPP is supported (no free ptys)";
2013 * Try to put the device into the PPP discipline.
2015 if (ioctl(local_fd
, TIOCSETD
, &ppp_disc
) < 0) {
2016 error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__
);
2025 /********************************************************************
2027 * ppp_available - check whether the system has any ppp interfaces
2028 * (in fact we check whether we can do an ioctl on ppp0).
2031 int ppp_available(void)
2036 int my_version
, my_modification
, my_patch
;
2037 int osmaj
, osmin
, ospatch
;
2039 /* get the kernel version now, since we are called before sys_init */
2041 osmaj
= osmin
= ospatch
= 0;
2042 sscanf(utsname
.release
, "%d.%d.%d", &osmaj
, &osmin
, &ospatch
);
2043 kernel_version
= KVERSION(osmaj
, osmin
, ospatch
);
2045 fd
= open("/dev/ppp", O_RDWR
);
2047 new_style_driver
= 1;
2049 /* XXX should get from driver */
2051 driver_modification
= 4;
2058 if (kernel_version
>= KVERSION(2,3,13)) {
2059 error("Couldn't open the /dev/ppp device: %m");
2060 if (errno
== ENOENT
)
2062 "You need to create the /dev/ppp device node by\n"
2063 "executing the following command as root:\n"
2064 " mknod /dev/ppp c 108 0\n";
2065 else if (errno
== ENODEV
|| errno
== ENXIO
)
2067 "Please load the ppp_generic kernel module.\n";
2071 /* we are running on a really really old kernel */
2073 "This system lacks kernel support for PPP. This could be because\n"
2074 "the PPP kernel module could not be loaded, or because PPP was not\n"
2075 "included in the kernel configuration. If PPP was included as a\n"
2076 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2077 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2078 "See README.linux file in the ppp distribution for more details.\n";
2081 * Open a socket for doing the ioctl operations.
2083 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
2087 strlcpy (ifr
.ifr_name
, "ppp0", sizeof (ifr
.ifr_name
));
2088 ok
= ioctl(s
, SIOCGIFFLAGS
, (caddr_t
) &ifr
) >= 0;
2090 * If the device did not exist then attempt to create one by putting the
2091 * current tty into the PPP discipline. If this works then obtain the
2092 * flags for the device again.
2095 if (ppp_registered()) {
2096 strlcpy (ifr
.ifr_name
, "ppp0", sizeof (ifr
.ifr_name
));
2097 ok
= ioctl(s
, SIOCGIFFLAGS
, (caddr_t
) &ifr
) >= 0;
2101 * Ensure that the hardware address is for PPP and not something else
2104 ok
= ioctl (s
, SIOCGIFHWADDR
, (caddr_t
) &ifr
) >= 0;
2106 if (ok
&& ((ifr
.ifr_hwaddr
.sa_family
& ~0xFF) != ARPHRD_PPP
))
2110 * This is the PPP device. Validate the version of the driver at this
2111 * point to ensure that this program will work with the driver.
2114 char abBuffer
[1024];
2116 ifr
.ifr_data
= abBuffer
;
2117 size
= ioctl (s
, SIOCGPPPVER
, (caddr_t
) &ifr
);
2119 error("Couldn't read driver version: %m");
2121 no_ppp_msg
= "Sorry, couldn't verify kernel driver version\n";
2124 decode_version(abBuffer
,
2126 &driver_modification
,
2129 * Validate the version of the driver against the version that we used.
2131 decode_version(VERSION
,
2136 /* The version numbers must match */
2137 if (driver_version
!= my_version
)
2140 /* The modification levels must be legal */
2141 if (driver_modification
< 3) {
2142 if (driver_modification
>= 2) {
2143 /* we can cope with 2.2.0 and above */
2152 slprintf(route_buffer
, sizeof(route_buffer
),
2153 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2154 driver_version
, driver_modification
, driver_patch
);
2156 no_ppp_msg
= route_buffer
;
2163 /********************************************************************
2165 * Update the wtmp file with the appropriate user name and tty device.
2168 void logwtmp (const char *line
, const char *name
, const char *host
)
2171 struct utmp ut
, *utp
;
2172 pid_t mypid
= getpid();
2178 * Update the signon database for users.
2179 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2181 utmpname(_PATH_UTMP
);
2183 while ((utp
= getutent()) && (utp
->ut_pid
!= mypid
))
2187 memcpy(&ut
, utp
, sizeof(ut
));
2189 /* some gettys/telnetds don't initialize utmp... */
2190 memset(&ut
, 0, sizeof(ut
));
2192 if (ut
.ut_id
[0] == 0)
2193 strncpy(ut
.ut_id
, line
+ 3, sizeof(ut
.ut_id
));
2195 strncpy(ut
.ut_user
, name
, sizeof(ut
.ut_user
));
2196 strncpy(ut
.ut_line
, line
, sizeof(ut
.ut_line
));
2200 ut
.ut_type
= USER_PROCESS
;
2203 /* Insert the host name if one is supplied */
2205 strncpy (ut
.ut_host
, host
, sizeof(ut
.ut_host
));
2207 /* Insert the IP address of the remote system if IP is enabled */
2208 if (ipcp_protent
.enabled_flag
&& ipcp_hisoptions
[0].neg_addr
)
2209 memcpy(&ut
.ut_addr
, (char *) &ipcp_hisoptions
[0].hisaddr
,
2210 sizeof(ut
.ut_addr
));
2212 /* CL: Makes sure that the logout works */
2213 if (*host
== 0 && *name
==0)
2219 * Update the wtmp file.
2222 updwtmp(_PATH_WTMP
, &ut
);
2224 wtmp
= open(_PATH_WTMP
, O_APPEND
|O_WRONLY
);
2226 flock(wtmp
, LOCK_EX
);
2228 if (write (wtmp
, (char *)&ut
, sizeof(ut
)) != sizeof(ut
))
2229 warn("error writing %s: %m", _PATH_WTMP
);
2231 flock(wtmp
, LOCK_UN
);
2240 /********************************************************************
2242 * sifvjcomp - config tcp header compression
2245 int sifvjcomp (int u
, int vjcomp
, int cidcomp
, int maxcid
)
2250 if (ioctl(ppp_dev_fd
, PPPIOCSMAXCID
, (caddr_t
) &maxcid
) < 0)
2251 error("Couldn't set up TCP header compression: %m");
2255 x
= (vjcomp
? SC_COMP_TCP
: 0) | (cidcomp
? 0: SC_NO_TCP_CCID
);
2256 modify_flags(ppp_dev_fd
, SC_COMP_TCP
|SC_NO_TCP_CCID
, x
);
2261 /********************************************************************
2263 * sifup - Config the interface up and enable IP packets to pass.
2270 memset (&ifr
, '\0', sizeof (ifr
));
2271 strlcpy(ifr
.ifr_name
, ifname
, sizeof (ifr
.ifr_name
));
2272 if (ioctl(sock_fd
, SIOCGIFFLAGS
, (caddr_t
) &ifr
) < 0) {
2273 if (! ok_error (errno
))
2274 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__
);
2278 ifr
.ifr_flags
|= (IFF_UP
| IFF_POINTOPOINT
);
2279 if (ioctl(sock_fd
, SIOCSIFFLAGS
, (caddr_t
) &ifr
) < 0) {
2280 if (! ok_error (errno
))
2281 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__
);
2289 /********************************************************************
2291 * sifdown - Disable the indicated protocol and config the interface
2292 * down if there are no remaining protocols.
2299 if (if_is_up
&& --if_is_up
> 0)
2302 memset (&ifr
, '\0', sizeof (ifr
));
2303 strlcpy(ifr
.ifr_name
, ifname
, sizeof (ifr
.ifr_name
));
2304 if (ioctl(sock_fd
, SIOCGIFFLAGS
, (caddr_t
) &ifr
) < 0) {
2305 if (! ok_error (errno
))
2306 error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__
);
2310 ifr
.ifr_flags
&= ~IFF_UP
;
2311 ifr
.ifr_flags
|= IFF_POINTOPOINT
;
2312 if (ioctl(sock_fd
, SIOCSIFFLAGS
, (caddr_t
) &ifr
) < 0) {
2313 if (! ok_error (errno
))
2314 error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__
);
2320 /********************************************************************
2322 * sifaddr - Config the interface IP addresses and netmask.
2325 int sifaddr (int unit
, u_int32_t our_adr
, u_int32_t his_adr
,
2331 memset (&ifr
, '\0', sizeof (ifr
));
2332 memset (&rt
, '\0', sizeof (rt
));
2334 SET_SA_FAMILY (ifr
.ifr_addr
, AF_INET
);
2335 SET_SA_FAMILY (ifr
.ifr_dstaddr
, AF_INET
);
2336 SET_SA_FAMILY (ifr
.ifr_netmask
, AF_INET
);
2338 strlcpy (ifr
.ifr_name
, ifname
, sizeof (ifr
.ifr_name
));
2340 * Set our IP address
2342 SIN_ADDR(ifr
.ifr_addr
) = our_adr
;
2343 if (ioctl(sock_fd
, SIOCSIFADDR
, (caddr_t
) &ifr
) < 0) {
2344 if (errno
!= EEXIST
) {
2345 if (! ok_error (errno
))
2346 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__
);
2349 warn("ioctl(SIOCSIFADDR): Address already exists");
2354 * Set the gateway address
2357 SIN_ADDR(ifr
.ifr_dstaddr
) = his_adr
;
2358 if (ioctl(sock_fd
, SIOCSIFDSTADDR
, (caddr_t
) &ifr
) < 0) {
2359 if (! ok_error (errno
))
2360 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__
);
2366 * For recent kernels, force the netmask to 255.255.255.255.
2368 if (kernel_version
>= KVERSION(2,1,16))
2370 if (net_mask
!= 0) {
2371 SIN_ADDR(ifr
.ifr_netmask
) = net_mask
;
2372 if (ioctl(sock_fd
, SIOCSIFNETMASK
, (caddr_t
) &ifr
) < 0) {
2373 if (! ok_error (errno
))
2374 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__
);
2379 * Add the device route
2381 if (kernel_version
< KVERSION(2,1,16)) {
2382 SET_SA_FAMILY (rt
.rt_dst
, AF_INET
);
2383 SET_SA_FAMILY (rt
.rt_gateway
, AF_INET
);
2386 SIN_ADDR(rt
.rt_gateway
) = 0L;
2387 SIN_ADDR(rt
.rt_dst
) = his_adr
;
2388 rt
.rt_flags
= RTF_UP
| RTF_HOST
;
2390 if (kernel_version
> KVERSION(2,1,0)) {
2391 SET_SA_FAMILY (rt
.rt_genmask
, AF_INET
);
2392 SIN_ADDR(rt
.rt_genmask
) = -1L;
2395 if (ioctl(sock_fd
, SIOCADDRT
, &rt
) < 0) {
2396 if (! ok_error (errno
))
2397 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__
);
2402 /* set ip_dynaddr in demand mode if address changes */
2403 if (demand
&& tune_kernel
&& !dynaddr_set
2404 && our_old_addr
&& our_old_addr
!= our_adr
) {
2405 /* set ip_dynaddr if possible */
2409 path
= path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2410 if (path
!= 0 && (fd
= open(path
, O_WRONLY
)) >= 0) {
2411 if (write(fd
, "1", 1) != 1)
2412 error("Couldn't enable dynamic IP addressing: %m");
2415 dynaddr_set
= 1; /* only 1 attempt */
2422 /********************************************************************
2424 * cifaddr - Clear the interface IP addresses, and delete routes
2425 * through the interface if possible.
2428 int cifaddr (int unit
, u_int32_t our_adr
, u_int32_t his_adr
)
2432 if (kernel_version
< KVERSION(2,1,16)) {
2434 * Delete the route through the device
2437 memset (&rt
, '\0', sizeof (rt
));
2439 SET_SA_FAMILY (rt
.rt_dst
, AF_INET
);
2440 SET_SA_FAMILY (rt
.rt_gateway
, AF_INET
);
2443 SIN_ADDR(rt
.rt_gateway
) = 0;
2444 SIN_ADDR(rt
.rt_dst
) = his_adr
;
2445 rt
.rt_flags
= RTF_UP
| RTF_HOST
;
2447 if (kernel_version
> KVERSION(2,1,0)) {
2448 SET_SA_FAMILY (rt
.rt_genmask
, AF_INET
);
2449 SIN_ADDR(rt
.rt_genmask
) = -1L;
2452 if (ioctl(sock_fd
, SIOCDELRT
, &rt
) < 0 && errno
!= ESRCH
) {
2453 if (still_ppp() && ! ok_error (errno
))
2454 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__
);
2459 /* This way it is possible to have an IPX-only or IPv6-only interface */
2460 memset(&ifr
, 0, sizeof(ifr
));
2461 SET_SA_FAMILY(ifr
.ifr_addr
, AF_INET
);
2462 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
2464 if (ioctl(sock_fd
, SIOCSIFADDR
, (caddr_t
) &ifr
) < 0) {
2465 if (! ok_error (errno
)) {
2466 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__
);
2471 our_old_addr
= our_adr
;
2477 /********************************************************************
2479 * sif6addr - Config the interface with an IPv6 link-local address
2481 int sif6addr (int unit
, eui64_t our_eui64
, eui64_t his_eui64
)
2483 struct in6_ifreq ifr6
;
2485 struct in6_rtmsg rt6
;
2489 error("IPv6 socket creation failed: %m");
2492 memset(&ifr
, 0, sizeof (ifr
));
2493 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
2494 if (ioctl(sock6_fd
, SIOCGIFINDEX
, (caddr_t
) &ifr
) < 0) {
2495 error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__
);
2499 /* Local interface */
2500 memset(&ifr6
, 0, sizeof(ifr6
));
2501 IN6_LLADDR_FROM_EUI64(ifr6
.ifr6_addr
, our_eui64
);
2502 ifr6
.ifr6_ifindex
= ifr
.ifr_ifindex
;
2503 ifr6
.ifr6_prefixlen
= 10;
2505 if (ioctl(sock6_fd
, SIOCSIFADDR
, &ifr6
) < 0) {
2506 error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__
);
2510 /* Route to remote host */
2511 memset(&rt6
, 0, sizeof(rt6
));
2512 IN6_LLADDR_FROM_EUI64(rt6
.rtmsg_dst
, his_eui64
);
2513 rt6
.rtmsg_flags
= RTF_UP
;
2514 rt6
.rtmsg_dst_len
= 10;
2515 rt6
.rtmsg_ifindex
= ifr
.ifr_ifindex
;
2516 rt6
.rtmsg_metric
= 1;
2518 if (ioctl(sock6_fd
, SIOCADDRT
, &rt6
) < 0) {
2519 error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__
);
2527 /********************************************************************
2529 * cif6addr - Remove IPv6 address from interface
2531 int cif6addr (int unit
, eui64_t our_eui64
, eui64_t his_eui64
)
2534 struct in6_ifreq ifr6
;
2538 error("IPv6 socket creation failed: %m");
2541 memset(&ifr
, 0, sizeof(ifr
));
2542 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
2543 if (ioctl(sock6_fd
, SIOCGIFINDEX
, (caddr_t
) &ifr
) < 0) {
2544 error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__
);
2548 memset(&ifr6
, 0, sizeof(ifr6
));
2549 IN6_LLADDR_FROM_EUI64(ifr6
.ifr6_addr
, our_eui64
);
2550 ifr6
.ifr6_ifindex
= ifr
.ifr_ifindex
;
2551 ifr6
.ifr6_prefixlen
= 10;
2553 if (ioctl(sock6_fd
, SIOCDIFADDR
, &ifr6
) < 0) {
2554 if (errno
!= EADDRNOTAVAIL
) {
2555 if (! ok_error (errno
))
2556 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__
);
2559 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2568 * get_pty - get a pty master/slave pair and chown the slave side
2569 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2572 get_pty(master_fdp
, slave_fdp
, slave_name
, uid
)
2578 int i
, mfd
, sfd
= -1;
2580 struct termios tios
;
2584 * Try the unix98 way first.
2586 mfd
= open("/dev/ptmx", O_RDWR
);
2589 if (ioctl(mfd
, TIOCGPTN
, &ptn
) >= 0) {
2590 slprintf(pty_name
, sizeof(pty_name
), "/dev/pts/%d", ptn
);
2591 chmod(pty_name
, S_IRUSR
| S_IWUSR
);
2594 if (ioctl(mfd
, TIOCSPTLCK
, &ptn
) < 0)
2595 warn("Couldn't unlock pty slave %s: %m", pty_name
);
2597 if ((sfd
= open(pty_name
, O_RDWR
| O_NOCTTY
)) < 0)
2598 warn("Couldn't open pty slave %s: %m", pty_name
);
2601 #endif /* TIOCGPTN */
2604 /* the old way - scan through the pty name space */
2605 for (i
= 0; i
< 64; ++i
) {
2606 slprintf(pty_name
, sizeof(pty_name
), "/dev/pty%c%x",
2607 'p' + i
/ 16, i
% 16);
2608 mfd
= open(pty_name
, O_RDWR
, 0);
2611 sfd
= open(pty_name
, O_RDWR
| O_NOCTTY
, 0);
2613 fchown(sfd
, uid
, -1);
2614 fchmod(sfd
, S_IRUSR
| S_IWUSR
);
2625 strlcpy(slave_name
, pty_name
, 16);
2628 if (tcgetattr(sfd
, &tios
) == 0) {
2629 tios
.c_cflag
&= ~(CSIZE
| CSTOPB
| PARENB
);
2630 tios
.c_cflag
|= CS8
| CREAD
| CLOCAL
;
2631 tios
.c_iflag
= IGNPAR
;
2634 if (tcsetattr(sfd
, TCSAFLUSH
, &tios
) < 0)
2635 warn("couldn't set attributes on pty: %m");
2637 warn("couldn't get attributes on pty: %m");
2642 /********************************************************************
2644 * open_loopback - open the device we use for getting packets
2645 * in demand mode. Under Linux, we use a pty master/slave pair.
2648 open_ppp_loopback(void)
2653 if (new_style_driver
) {
2654 /* allocate ourselves a ppp unit */
2655 if (make_ppp_unit() < 0)
2657 modify_flags(ppp_dev_fd
, 0, SC_LOOP_TRAFFIC
);
2658 set_kdebugflag(kdebugflag
);
2663 if (!get_pty(&master_fd
, &slave_fd
, loop_name
, 0))
2664 fatal("No free pty for loopback");
2666 set_ppp_fd(slave_fd
);
2668 flags
= fcntl(master_fd
, F_GETFL
);
2670 fcntl(master_fd
, F_SETFL
, flags
| O_NONBLOCK
) == -1)
2671 warn("couldn't set master loopback to nonblock: %m");
2673 flags
= fcntl(ppp_fd
, F_GETFL
);
2675 fcntl(ppp_fd
, F_SETFL
, flags
| O_NONBLOCK
) == -1)
2676 warn("couldn't set slave loopback to nonblock: %m");
2678 if (ioctl(ppp_fd
, TIOCSETD
, &ppp_disc
) < 0)
2679 fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__
);
2681 * Find out which interface we were given.
2683 if (ioctl(ppp_fd
, PPPIOCGUNIT
, &ifunit
) < 0)
2684 fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__
);
2686 * Enable debug in the driver if requested.
2688 set_kdebugflag (kdebugflag
);
2693 /********************************************************************
2695 * sifnpmode - Set the mode for handling packets for a given NP.
2699 sifnpmode(u
, proto
, mode
)
2706 npi
.protocol
= proto
;
2708 if (ioctl(ppp_dev_fd
, PPPIOCSNPMODE
, (caddr_t
) &npi
) < 0) {
2709 if (! ok_error (errno
))
2710 error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto
, mode
);
2717 /********************************************************************
2719 * sipxfaddr - Config the interface IPX networknumber
2722 int sipxfaddr (int unit
, unsigned long int network
, unsigned char * node
)
2729 struct sockaddr_ipx
*sipx
= (struct sockaddr_ipx
*) &ifr
.ifr_addr
;
2731 skfd
= socket (AF_IPX
, SOCK_DGRAM
, 0);
2733 if (! ok_error (errno
))
2734 dbglog("socket(AF_IPX): %m (line %d)", __LINE__
);
2738 memset (&ifr
, '\0', sizeof (ifr
));
2739 strlcpy (ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
2741 memcpy (sipx
->sipx_node
, node
, IPX_NODE_LEN
);
2742 sipx
->sipx_family
= AF_IPX
;
2743 sipx
->sipx_port
= 0;
2744 sipx
->sipx_network
= htonl (network
);
2745 sipx
->sipx_type
= IPX_FRAME_ETHERII
;
2746 sipx
->sipx_action
= IPX_CRTITF
;
2748 * Set the IPX device
2750 if (ioctl(skfd
, SIOCSIFADDR
, (caddr_t
) &ifr
) < 0) {
2752 if (errno
!= EEXIST
) {
2753 if (! ok_error (errno
))
2754 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__
);
2757 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2766 /********************************************************************
2768 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2769 * are removed and the device is no longer able to pass IPX
2773 int cipxfaddr (int unit
)
2780 struct sockaddr_ipx
*sipx
= (struct sockaddr_ipx
*) &ifr
.ifr_addr
;
2782 skfd
= socket (AF_IPX
, SOCK_DGRAM
, 0);
2784 if (! ok_error (errno
))
2785 dbglog("socket(AF_IPX): %m (line %d)", __LINE__
);
2789 memset (&ifr
, '\0', sizeof (ifr
));
2790 strlcpy (ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
2792 sipx
->sipx_type
= IPX_FRAME_ETHERII
;
2793 sipx
->sipx_action
= IPX_DLTITF
;
2794 sipx
->sipx_family
= AF_IPX
;
2796 * Set the IPX device
2798 if (ioctl(skfd
, SIOCSIFADDR
, (caddr_t
) &ifr
) < 0) {
2799 if (! ok_error (errno
))
2800 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__
);
2810 * Use the hostname as part of the random number seed.
2819 for (p
= hostname
; *p
!= 0; ++p
)
2824 /********************************************************************
2826 * sys_check_options - check the options that the user specified
2830 sys_check_options(void)
2834 * Disable the IPX protocol if the support is not present in the kernel.
2838 if (ipxcp_protent
.enabled_flag
) {
2839 struct stat stat_buf
;
2840 if ( ((path
= path_to_procfs("/net/ipx/interface")) == NULL
2841 && (path
= path_to_procfs("/net/ipx_interface")) == NULL
)
2842 || lstat(path
, &stat_buf
) < 0) {
2843 error("IPX support is not present in the kernel\n");
2844 ipxcp_protent
.enabled_flag
= 0;
2848 if (demand
&& driver_is_old
) {
2849 option_error("demand dialling is not supported by kernel driver "
2850 "version %d.%d.%d", driver_version
, driver_modification
,
2854 if (multilink
&& !new_style_driver
) {
2855 warn("Warning: multilink is not supported by the kernel driver");
2863 * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2865 * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2866 * that the system has a properly configured Ethernet interface for this
2867 * function to return non-zero.
2870 ether_to_eui64(eui64_t
*p_eui64
)
2874 const unsigned char *ptr
;
2876 skfd
= socket(PF_INET6
, SOCK_DGRAM
, 0);
2879 warn("could not open IPv6 socket");
2883 strcpy(ifr
.ifr_name
, "eth0");
2884 if(ioctl(skfd
, SIOCGIFHWADDR
, &ifr
) < 0)
2887 warn("could not obtain hardware address for eth0");
2893 * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2895 ptr
= ifr
.ifr_hwaddr
.sa_data
;
2896 p_eui64
->e8
[0] = ptr
[0] | 0x02;
2897 p_eui64
->e8
[1] = ptr
[1];
2898 p_eui64
->e8
[2] = ptr
[2];
2899 p_eui64
->e8
[3] = 0xFF;
2900 p_eui64
->e8
[4] = 0xFE;
2901 p_eui64
->e8
[5] = ptr
[3];
2902 p_eui64
->e8
[6] = ptr
[4];
2903 p_eui64
->e8
[7] = ptr
[5];