2 * sys-linux.c - System-dependent procedures for setting up
3 * PPP interfaces on Linux systems
5 * Copyright (c) 1989 Carnegie Mellon University.
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by Carnegie Mellon University. The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 #include <sys/ioctl.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
25 #include <sys/errno.h>
28 #include <sys/utsname.h>
29 #include <sys/sysmacros.h>
46 /* This is in netdevice.h. However, this compile will fail miserably if
47 you attempt to include netdevice.h because it has so many references
48 to __memcpy functions which it should not attempt to do. So, since I
49 really don't use it, but it must be defined, define it now. */
52 #define MAX_ADDR_LEN 7
56 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
58 #include <net/if_arp.h>
59 #include <net/route.h>
60 #include <netinet/if_ether.h>
62 #include <linux/types.h>
64 #include <linux/if_arp.h>
65 #include <linux/route.h>
66 #include <linux/if_ether.h>
68 #include <netinet/in.h>
69 #include <arpa/inet.h>
71 #include <linux/ppp_defs.h>
72 #include <linux/if_ppp.h>
80 #if __GLIBC__ >= 2 && \
81 !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
82 #include <netipx/ipx.h>
84 #include <linux/ipx.h>
86 #endif /* IPX_CHANGE */
90 #include <linux/filter.h>
91 #endif /* PPP_FILTER */
94 #include <sys/locks.h>
100 * This is in linux/include/net/ipv6.h.
104 struct in6_addr ifr6_addr;
105 __u32 ifr6_prefixlen;
106 unsigned int ifr6_ifindex;
110 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
111 memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \
112 sin6.s6_addr16[0] = htons(0xfe80); \
113 eui64_copy(eui64, sin6.s6_addr32[2]); \
118 /* We can get an EIO error on an ioctl if the modem has hung up */
119 #define ok_error(num) ((num)==EIO)
121 static int tty_disc = N_TTY; /* The TTY discipline */
122 static int ppp_disc = N_PPP; /* The PPP discpline */
123 static int initfdflags = -1; /* Initial file descriptor flags for fd */
124 static int ppp_fd = -1; /* fd which is set to PPP discipline */
125 static int sock_fd = -1; /* socket for doing interface ioctls */
126 static int slave_fd = -1;
127 static int master_fd = -1;
129 static int sock6_fd = -1;
131 static int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
132 static int chindex; /* channel index (new style driver) */
134 static fd_set in_fds; /* set of fds that wait_input waits for */
135 static int max_in_fd; /* highest fd set in in_fds */
137 static int has_proxy_arp = 0;
138 static int driver_version = 0;
139 static int driver_modification = 0;
140 static int driver_patch = 0;
141 static int driver_is_old = 0;
142 static int restore_term = 0; /* 1 => we've munged the terminal */
143 static struct termios inittermios; /* Initial TTY termios */
145 int new_style_driver = 0;
147 static char loop_name[20];
148 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
150 static int if_is_up; /* Interface has been marked up */
151 static u_int32_t default_route_gateway; /* Gateway for default route added */
152 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
153 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
154 static u_int32_t our_old_addr; /* for detecting address changes */
155 static int dynaddr_set; /* 1 if ip_dynaddr set */
156 static int looped; /* 1 if using loop */
157 static int link_mtu; /* mtu for the link (not bundle) */
159 static struct utsname utsname; /* for the kernel version */
160 static int kernel_version;
161 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
165 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
166 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
167 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
169 #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
171 /* Prototypes for procedures local to this file. */
172 static int get_flags (int fd);
173 static void set_flags (int fd, int flags);
174 static int translate_speed (int bps);
175 static int baud_rate_of (int speed);
176 static void close_route_table (void);
177 static int open_route_table (void);
178 static int read_route_table (struct rtentry *rt);
179 static int defaultroute_exists (struct rtentry *rt);
180 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
181 char *name, int namelen);
182 static void decode_version (char *buf, int *version, int *mod, int *patch);
183 static int set_kdebugflag(int level);
184 static int ppp_registered(void);
185 static int make_ppp_unit(void);
186 static void restore_loop(void); /* Transfer ppp unit back to loopback */
188 extern u_char inpacket_buf[]; /* borrowed from main.c */
191 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
195 #define SET_SA_FAMILY(addr, family) \
196 memset ((char *) &(addr), '\0', sizeof(addr)); \
197 addr.sa_family = (family);
200 * Determine if the PPP connection should still be present.
205 //#ifdef BBB_XML_API //Wilson add, (02/13/2006)
206 #if defined(SUPPORT_XML_API) //Wilson add, (03/14/2006)
207 extern int ppp_session;
211 void dumpHex(char *direct, char *buff, int len)
216 static struct timeval dumpTime;
218 gettimeofday(&dumpTime, NULL);
220 printf("(%d.%d) %s:\n", dumpTime.tv_sec, dumpTime.tv_usec, direct);
222 printf("%02X ", buff[i]&0xff);
223 if(i%16==15) printf("\n");
231 /* new_fd is the fd of a tty */
232 static void set_ppp_fd (int new_fd)
234 SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
236 if (!new_style_driver)
240 static int still_ppp(void)
242 if (new_style_driver)
243 return !hungup && ppp_fd >= 0;
244 if (!hungup || ppp_fd == slave_fd)
247 set_ppp_fd(slave_fd);
253 /********************************************************************
255 * Functions to read and set the flags value in the device driver
258 static int get_flags (int fd)
262 if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) {
263 if ( ok_error (errno) )
266 fatal("ioctl(PPPIOCGFLAGS): %m");
269 SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags));
273 /********************************************************************/
275 static void set_flags (int fd, int flags)
277 SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
279 if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
280 if (! ok_error (errno) )
281 fatal("ioctl(PPPIOCSFLAGS, %x): %m", flags, errno);
285 /********************************************************************
287 * sys_init - System-dependent initialization.
294 if (new_style_driver) {
295 ppp_dev_fd = open("/dev/ppp", O_RDWR);
297 fatal("Couldn't open /dev/ppp: %m");
298 flags = fcntl(ppp_dev_fd, F_GETFL);
300 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
301 warn("Couldn't set /dev/ppp to nonblock: %m");
304 /* Get an internet socket for doing socket ioctls. */
305 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
307 fatal("Couldn't create IP socket: %m(%d)", errno);
310 sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
312 sock6_fd = -errno; /* save errno for later */
319 /********************************************************************
321 * sys_cleanup - restore any system state we modified before exiting:
322 * mark the interface down, delete default route and/or proxy arp entry.
323 * This shouldn't call die() because it's called from die().
326 void sys_cleanup(void)
329 * Take down the device
336 * Delete any routes through the device.
338 if (default_route_gateway != 0)
339 cifdefaultroute(0, 0, default_route_gateway);
342 cifproxyarp(0, proxy_arp_addr);
345 /********************************************************************
347 * sys_close - Clean up in a child process before execing.
352 if (new_style_driver)
363 /********************************************************************
365 * set_kdebugflag - Define the debugging level for the kernel
368 static int set_kdebugflag (int requested_level)
370 if (new_style_driver && ifunit < 0)
372 if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
373 if ( ! ok_error (errno) )
374 error("ioctl(PPPIOCSDEBUG): %m");
377 SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
385 /********************************************************************
387 * tty_establish_ppp - Turn the serial port into a ppp interface.
390 int tty_establish_ppp (int tty_fd)
394 * Ensure that the tty device is in exclusive mode.
396 if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
397 if ( ! ok_error ( errno ))
398 warn("Couldn't make tty exclusive: %m");
401 * Set the current tty to the PPP discpline
405 #define N_SYNC_PPP 14
407 ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
408 if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
409 if ( ! ok_error (errno) ) {
410 error("Couldn't set tty to PPP discipline: %m");
415 ret_fd = generic_establish_ppp(tty_fd);
416 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
417 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
420 set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB))
421 | ((kdebugflag * SC_DEBUG) & SC_LOGB)));
428 /********************************************************************
430 * generic_establish_ppp - Turn the fd into a ppp interface.
432 #if defined(ODM_LANG_LLL)
433 extern int ppp_session;
434 extern int glbppppid;
435 extern int got_ppp_down;
437 int generic_establish_ppp (int fd)
440 //#ifdef BBB_XML_API //Wilson add, (02/13/2006)
441 #if defined(SUPPORT_XML_API) //Wilson add, (03/14/2006)
446 * Demand mode - prime the old ppp device to relinquish the unit.
448 if (!new_style_driver && looped
449 && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
450 error("ioctl(transfer ppp unit): %m");
455 if (new_style_driver) {
456 /* Open another instance of /dev/ppp and connect the channel to it */
459 if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
460 error("Couldn't get channel number: %m");
461 //printf("PVC error, Bye!!\n");
462 //sprintf(cmd,"kill -9 %d",glbppppid);
464 //#ifdef BBB_XML_API //Wilson add, (02/13/2006)
465 #if defined(SUPPORT_XML_API) //Wilson add, (03/14/2006)
466 if (ppp_session == PPPOE){
467 fp = fopen("/var/pppStatus", "w+");
473 #endif //endif BBB_XML_API
475 //if (ppp_session == PPPOE){
476 // if (ioctl(fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
477 // warn("Couldn't reset tty to normal line discipline: %m");
480 #if defined(ODM_LANG_LLL)
483 if (ppp_session == PPPOE){
484 wsnfp = fopen("/var/btaolstatus", "w");
486 fprintf(wsnfp, "%d", 1);
489 //printf("PVC error, Bye!!\n");
490 sprintf(cmd,"kill -9 %d",glbppppid);
498 dbglog("using channel %d", chindex);
499 fd = open("/dev/ppp", O_RDWR);
501 error("Couldn't reopen /dev/ppp: %m");
504 if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
505 error("Couldn't attach to channel %d: %m", chindex);
508 flags = fcntl(fd, F_GETFL);
509 if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
510 warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
515 if (!looped && !multilink) {
517 * Create a new PPP unit.
519 if (make_ppp_unit() < 0)
525 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC);
529 if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
530 error("Couldn't attach to PPP unit %d: %m", ifunit);
538 * Old-style driver: find out which interface we were given.
541 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
542 if (ok_error (errno))
544 fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
546 /* Check that we got the same unit again. */
547 if (looped && x != ifunit)
548 fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
552 * Fetch the initial file flags and reset blocking mode on the file.
554 initfdflags = fcntl(fd, F_GETFL);
555 if (initfdflags == -1 ||
556 fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
557 if ( ! ok_error (errno))
558 warn("Couldn't set device to non-blocking mode: %m");
566 * Enable debug in the driver if requested.
569 set_kdebugflag (kdebugflag);
571 SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
572 driver_version, driver_modification, driver_patch));
579 if (ioctl(fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
580 warn("Couldn't reset tty to normal line discipline: %m");
586 /********************************************************************
588 * tty_disestablish_ppp - Restore the serial port to normal operation.
589 * This shouldn't call die() because it's called from die().
592 void tty_disestablish_ppp(int tty_fd)
594 generic_disestablish_ppp(tty_fd);
598 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
600 if (tcflush(tty_fd, TCIOFLUSH) < 0)
601 warn("tcflush failed: %m");
603 * Restore the previous line discipline
605 if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
606 if ( ! ok_error (errno))
607 error("ioctl(TIOCSETD, N_TTY): %m");
610 if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
611 if ( ! ok_error (errno))
612 warn("ioctl(TIOCNXCL): %m(%d)", errno);
615 /* Reset non-blocking mode on fd. */
616 if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
617 if ( ! ok_error (errno))
618 warn("Couldn't restore device fd flags: %m");
624 /********************************************************************
626 * generic_disestablish_ppp - Restore device components to normal
627 * operation, and reconnect the ppp unit to the loopback if in demand
628 * mode. This shouldn't call die() because it's called from die().
630 void generic_disestablish_ppp(int dev_fd){
631 /* Restore loop if needed */
635 /* Finally detach the device */
638 if (new_style_driver) {
641 if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
642 error("Couldn't release PPP unit: %m");
644 remove_fd(ppp_dev_fd);
650 * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
651 * Assumes new_style_driver.
653 static int make_ppp_unit()
658 if (strchr(req_name, '_')) {
659 retval = sscanf(req_name, "%d_%d_%d", num, num+1, num+2);
660 req_unit = OFFSET2*OFFSET1*num[0]+OFFSET1*num[1]+num[2];
663 req_unit = atoi(req_name);
666 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
667 if (x < 0 && req_unit >= 0 && errno == EEXIST) {
668 warn("Couldn't allocate PPP unit %d as it is already in use");
670 //x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
673 error("Couldn't create new ppp unit: %m");
678 * cfg_bundle - configure the existing bundle.
679 * Used in demand mode.
681 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
685 if (!new_style_driver)
688 /* set the mrru, mtu and flags */
689 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
690 error("Couldn't set MRRU: %m");
691 flags = get_flags(ppp_dev_fd);
692 flags &= ~(SC_MP_SHORTSEQ | SC_MP_XSHORTSEQ);
693 flags |= (rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
694 | (mrru? SC_MULTILINK: 0);
696 set_flags(ppp_dev_fd, flags);
698 /* connect up the channel */
699 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
700 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
705 * make_new_bundle - create a new PPP unit (i.e. a bundle)
706 * and connect our channel to it. This should only get called
707 * if `multilink' was set at the time establish_ppp was called.
708 * In demand mode this uses our existing bundle instead of making
711 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
713 if (!new_style_driver)
716 /* make us a ppp unit */
717 if (make_ppp_unit() < 0)
720 /* set the mrru and flags */
721 cfg_bundle(mrru, mtru, rssn, tssn);
725 * bundle_attach - attach our link to a given PPP unit.
726 * We assume the unit is controlled by another pppd.
728 int bundle_attach(int ifnum)
730 if (!new_style_driver)
733 if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) {
735 return 0; /* doesn't still exist */
736 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
738 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
739 fatal("Couldn't connect to interface unit %d: %m", ifnum);
740 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK);
746 /********************************************************************
748 * clean_check - Fetch the flags for the device and generate
749 * appropriate error messages.
751 void clean_check(void)
757 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
759 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
761 s = "all had bit 7 set to 1";
765 s = "all had bit 7 set to 0";
769 s = "all had odd parity";
773 s = "all had even parity";
778 warn("Receive serial link is not 8-bit clean:");
779 warn("Problem: %s", s);
787 * List of valid speeds.
791 int speed_int, speed_val;
874 /********************************************************************
876 * Translate from bits/second to a speed_t.
879 static int translate_speed (int bps)
881 struct speed *speedp;
884 for (speedp = speeds; speedp->speed_int; speedp++) {
885 if (bps == speedp->speed_int)
886 return speedp->speed_val;
888 warn("speed %d not supported", bps);
893 /********************************************************************
895 * Translate from a speed_t to bits/second.
898 static int baud_rate_of (int speed)
900 struct speed *speedp;
903 for (speedp = speeds; speedp->speed_int; speedp++) {
904 if (speed == speedp->speed_val)
905 return speedp->speed_int;
913 /********************************************************************
915 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
916 * at the requested speed, etc. If `local' is true, set CLOCAL
917 * regardless of whether the modem option was specified.
920 void set_up_tty(int tty_fd, int local)
926 if (tcgetattr(tty_fd, &tios) < 0) {
927 if (!ok_error(errno))
928 fatal("tcgetattr: %m(%d)", errno);
935 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
936 tios.c_cflag |= CS8 | CREAD | HUPCL;
938 tios.c_iflag = IGNBRK | IGNPAR;
942 tios.c_cc[VTIME] = 0;
945 tios.c_cflag ^= (CLOCAL | HUPCL);
949 tios.c_cflag |= CRTSCTS;
953 tios.c_iflag |= IXON | IXOFF;
954 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
955 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
959 tios.c_cflag &= ~CRTSCTS;
966 speed = translate_speed(inspeed);
968 cfsetospeed (&tios, speed);
969 cfsetispeed (&tios, speed);
972 * We can't proceed if the serial port speed is B0,
973 * since that implies that the serial port is disabled.
976 speed = cfgetospeed(&tios);
978 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
981 if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0)
982 if (!ok_error(errno))
983 fatal("tcsetattr: %m");
985 baud_rate = baud_rate_of(speed);
989 /********************************************************************
991 * setdtr - control the DTR line on the serial port.
992 * This is called from die(), so it shouldn't call die().
995 void setdtr (int tty_fd, int on)
997 int modembits = TIOCM_DTR;
999 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1002 /********************************************************************
1004 * restore_tty - restore the terminal to the saved settings.
1007 void restore_tty (int tty_fd)
1012 * Turn off echoing, because otherwise we can get into
1013 * a loop with the tty and the modem echoing to each other.
1014 * We presume we are the sole user of this tty device, so
1015 * when we close it, it will revert to its defaults anyway.
1017 if (!default_device)
1018 inittermios.c_lflag &= ~(ECHO | ECHONL);
1020 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1021 if (! ok_error (errno))
1022 warn("tcsetattr: %m");
1028 /********************************************************************
1030 * output - Output PPP packet.
1033 void output (int unit, unsigned char *p, int len)
1037 #if defined(SUPPORT_PPPDBG_SYSLOG)
1042 dbglog("sent %P", p, len);
1044 if (len < PPP_HDRLEN)
1047 #if defined(SUPPORT_PPPDBG_SYSLOG)//Dump ascii
1049 if (logstatus == 1){
1050 if (((q[2]&0xff)!=0xC0) || ((q[3]&0xff)!=0x21)|| (((q[4]&0xff)!=0x09) && ((q[4]&0xff)!=0x0A))){//Don't log LCP echo request/and echo response
1051 andydbglog("Sent %P", q, len);
1056 if (new_style_driver) {
1059 proto = (p[0] << 8) + p[1];
1060 if (ifunit >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1065 #if defined(SUPPORT_PPPDBG_SYSLOG)//Dump binary code
1067 if (len <= 128 && (((p[0]&0xff)!=0xC0) || ((p[1]&0xff)!=0x21)
1068 || (((p[2]&0xff)!=0x09) && ((p[2]&0xff)!=0x0A))) ){//Don't log LCP echo request/and echo response
1069 andydbglog("sent(binary) %P", p, len);
1075 dumpHex("OUTPUT", p, len);
1078 if (write(fd, p, len) < 0) {
1079 if (errno == EWOULDBLOCK || errno == ENOBUFS || errno == ENXIO || errno == EIO || errno == EINTR)
1080 warn("write: warning: %m (%d)", errno);
1082 error("write: %m (%d)", errno);
1086 /********************************************************************
1088 * wait_input - wait until there is data available,
1089 * for the length of time specified by *timo (indefinite
1093 void wait_input(struct timeval *timo)
1102 if (timo && (timo->tv_usec < 0))
1105 n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1106 if (n < 0 && errno != EINTR)
1107 fatal("select: %m(%d)", errno);
1111 * add_fd - add an fd to the set that wait_input waits for.
1115 FD_SET(fd, &in_fds);
1121 * remove_fd - remove an fd from the set that wait_input waits for.
1123 void remove_fd(int fd)
1125 FD_CLR(fd, &in_fds);
1129 /********************************************************************
1131 * read_packet - get a PPP packet from the serial device.
1134 int read_packet (unsigned char *buf)
1138 len = PPP_MRU + PPP_HDRLEN;
1139 if (new_style_driver) {
1140 *buf++ = PPP_ALLSTATIONS;
1146 nr = read(ppp_fd, buf, len);
1148 dumpHex("1. INPUT", buf, nr);
1150 if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
1152 if (nr < 0 && errno == ENXIO)
1155 if (nr < 0 && new_style_driver && ifunit >= 0) {
1156 /* N.B. we read ppp_fd first since LCP packets come in there. */
1157 nr = read(ppp_dev_fd, buf, len);
1159 dumpHex("2. INPUT", buf, nr);
1161 if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR)
1162 error("read /dev/ppp: %m");
1163 if (nr < 0 && errno == ENXIO)
1166 return (new_style_driver && nr > 0)? nr+2: nr;
1169 /********************************************************************
1171 * get_loop_output - get outgoing packets from the ppp device,
1172 * and detect when we want to bring the real link up.
1173 * Return value is 1 if we need to bring up the link, 0 otherwise.
1176 get_loop_output(void)
1180 if (new_style_driver) {
1181 while ((n = read_packet(inpacket_buf)) > 0){
1182 if (loop_frame(inpacket_buf, n)){
1189 while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0){
1190 if (loop_chars(inbuf, n)){
1196 fatal("eof on loopback");
1198 if (errno != EWOULDBLOCK)
1199 fatal("read from loopback: %m(%d)", errno);
1204 * netif_set_mtu - set the MTU on the PPP network interface.
1207 netif_set_mtu(int unit, int mtu)
1211 SYSDEBUG ((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu));
1213 memset (&ifr, '\0', sizeof (ifr));
1214 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1217 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1218 fatal("ioctl(SIOCSIFMTU): %m");
1223 /********************************************************************
1225 * tty_send_config - configure the transmit characteristics of
1226 * the ppp interface.
1229 void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp)
1234 * Set the asyncmap and other parameters for the ppp device
1239 SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
1240 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1241 if (!ok_error(errno))
1242 fatal("ioctl(PPPIOCSASYNCMAP): %m(%d)", errno);
1246 x = get_flags(ppp_fd);
1247 x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
1248 x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
1249 x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
1250 set_flags(ppp_fd, x);
1253 /********************************************************************
1255 * tty_set_xaccm - set the extended transmit ACCM for the interface.
1258 void tty_set_xaccm (ext_accm accm)
1260 SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
1261 accm[0], accm[1], accm[2], accm[3]));
1265 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1266 if ( ! ok_error (errno))
1267 warn("ioctl(set extended ACCM): %m(%d)", errno);
1271 /********************************************************************
1273 * tty_recv_config - configure the receive-side characteristics of
1274 * the ppp interface.
1277 void tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp)
1279 SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
1281 * If we were called because the link has gone down then there is nothing
1282 * which may be done. Just return without incident.
1287 * Set the receiver parameters
1289 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1290 if ( ! ok_error (errno))
1291 error("ioctl(PPPIOCSMRU): %m(%d)", errno);
1293 if (new_style_driver && ifunit >= 0
1294 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1295 error("Couldn't set MRU in generic PPP layer: %m");
1297 SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
1298 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1299 if (!ok_error(errno))
1300 error("ioctl(PPPIOCSRASYNCMAP): %m(%d)", errno);
1304 /********************************************************************
1306 * ccp_test - ask kernel whether a given compression method
1307 * is acceptable for use.
1310 int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1312 struct ppp_option_data data;
1314 memset (&data, '\0', sizeof (data));
1316 data.length = opt_len;
1317 data.transmit = for_transmit;
1319 if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1322 return (errno == ENOBUFS)? 0: -1;
1325 /********************************************************************
1327 * ccp_flags_set - inform kernel about the current state of CCP.
1330 void ccp_flags_set (int unit, int isopen, int isup)
1333 int x = get_flags(ppp_dev_fd);
1334 x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;
1335 x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP;
1336 set_flags (ppp_dev_fd, x);
1344 * set_filters - set the active and pass filters in the kernel driver.
1346 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1348 struct sock_fprog fp;
1350 fp.len = pass->bf_len;
1351 fp.filter = (struct sock_filter *) pass->bf_insns;
1352 if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1353 if (errno == ENOTTY)
1354 warn("kernel does not support PPP filtering");
1356 error("Couldn't set pass-filter in kernel: %m");
1359 fp.len = active->bf_len;
1360 fp.filter = (struct sock_filter *) active->bf_insns;
1361 if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1362 error("Couldn't set active-filter in kernel: %m");
1367 #endif /* PPP_FILTER */
1369 /********************************************************************
1371 * get_idle_time - return how long the link has been idle.
1374 get_idle_time(u, ip)
1376 struct ppp_idle *ip;
1378 return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1381 /********************************************************************
1383 * get_ppp_stats - return statistics for the link.
1386 get_ppp_stats(u, stats)
1388 struct pppd_stats *stats;
1390 struct ifpppstatsreq req;
1392 memset (&req, 0, sizeof (req));
1394 req.stats_ptr = (caddr_t) &req.stats;
1395 strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1396 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1397 error("Couldn't get PPP statistics: %m");
1400 stats->bytes_in = req.stats.p.ppp_ibytes;
1401 stats->bytes_out = req.stats.p.ppp_obytes;
1407 /********************************************************************
1409 * ccp_fatal_error - returns 1 if decompression was disabled as a
1410 * result of an error detected after decompression of a packet,
1411 * 0 otherwise. This is necessary because of patent nonsense.
1414 int ccp_fatal_error (int unit)
1416 int x = get_flags(ppp_dev_fd);
1418 return x & SC_DC_FERROR;
1423 /********************************************************************
1425 * path_to_procfs - find the path to the proc file system mount point
1427 static char proc_path[MAXPATHLEN];
1428 static int proc_path_len;
1430 static char *path_to_procfs(const char *tail)
1432 struct mntent *mntent;
1435 if (proc_path_len == 0) {
1436 /* Default the mount location of /proc */
1437 strlcpy (proc_path, "/proc", sizeof(proc_path));
1439 fp = fopen(MOUNTED, "r");
1441 while ((mntent = getmntent(fp)) != NULL) {
1442 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1444 if (strcmp(mntent->mnt_type, "proc") == 0) {
1445 strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1446 proc_path_len = strlen(proc_path);
1454 strlcpy(proc_path + proc_path_len, tail,
1455 sizeof(proc_path) - proc_path_len);
1460 * /proc/net/route parsing stuff.
1462 #define ROUTE_MAX_COLS 12
1463 FILE *route_fd = (FILE *) 0;
1464 static char route_buffer[512];
1465 static int route_dev_col, route_dest_col, route_gw_col;
1466 static int route_flags_col, route_mask_col;
1467 static int route_num_cols;
1469 static int open_route_table (void);
1470 static void close_route_table (void);
1471 static int read_route_table (struct rtentry *rt);
1473 /********************************************************************
1475 * close_route_table - close the interface to the route table
1478 static void close_route_table (void)
1480 if (route_fd != (FILE *) 0) {
1482 route_fd = (FILE *) 0;
1486 /********************************************************************
1488 * open_route_table - open the interface to the route table
1490 static char route_delims[] = " \t\n";
1492 static int open_route_table (void)
1496 close_route_table();
1498 path = path_to_procfs("/net/route");
1499 route_fd = fopen (path, "r");
1500 if (route_fd == NULL) {
1501 error("can't open routing table %s: %m", path);
1505 route_dev_col = 0; /* default to usual columns */
1508 route_flags_col = 3;
1512 /* parse header line */
1513 if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1514 char *p = route_buffer, *q;
1516 for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1518 if ((q = strtok(p, route_delims)) == 0)
1520 if (strcasecmp(q, "iface") == 0)
1521 route_dev_col = col;
1522 else if (strcasecmp(q, "destination") == 0)
1523 route_dest_col = col;
1524 else if (strcasecmp(q, "gateway") == 0)
1526 else if (strcasecmp(q, "flags") == 0)
1527 route_flags_col = col;
1528 else if (strcasecmp(q, "mask") == 0)
1529 route_mask_col = col;
1532 if (used && col >= route_num_cols)
1533 route_num_cols = col + 1;
1541 /********************************************************************
1543 * read_route_table - read the next entry from the route table
1546 static int read_route_table(struct rtentry *rt)
1548 char *cols[ROUTE_MAX_COLS], *p;
1551 memset (rt, '\0', sizeof (struct rtentry));
1553 if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1557 for (col = 0; col < route_num_cols; ++col) {
1558 cols[col] = strtok(p, route_delims);
1559 if (cols[col] == NULL)
1560 return 0; /* didn't get enough columns */
1564 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1565 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1566 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1568 rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1569 rt->rt_dev = cols[route_dev_col];
1574 /********************************************************************
1576 * defaultroute_exists - determine if there is a default route
1579 static int defaultroute_exists (struct rtentry *rt)
1583 if (!open_route_table())
1586 while (read_route_table(rt) != 0) {
1587 if ((rt->rt_flags & RTF_UP) == 0)
1590 if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1592 if (SIN_ADDR(rt->rt_dst) == 0L) {
1598 close_route_table();
1603 * have_route_to - determine if the system has any route to
1604 * a given IP address. `addr' is in network byte order.
1605 * Return value is 1 if yes, 0 if no, -1 if don't know.
1606 * For demand mode to work properly, we have to ignore routes
1607 * through our own interface.
1609 int have_route_to(u_int32_t addr)
1614 if (!open_route_table())
1615 return -1; /* don't know */
1617 while (read_route_table(&rt)) {
1618 if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1620 if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1626 close_route_table();
1630 /********************************************************************
1632 * sifdefaultroute - assign a default route through the address given.
1635 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1639 if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1640 u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
1642 if (old_gateway != gateway)
1643 error("not replacing existing default route to %s [%I]",
1644 rt.rt_dev, old_gateway);
1648 memset (&rt, '\0', sizeof (rt));
1649 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1650 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1652 if (kernel_version > KVERSION(2,1,0)) {
1653 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1654 SIN_ADDR(rt.rt_genmask) = 0L;
1657 SIN_ADDR(rt.rt_gateway) = gateway;
1659 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1660 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1661 if ( ! ok_error ( errno ))
1662 error("default route ioctl(SIOCADDRT): %m(%d)", errno);
1666 default_route_gateway = gateway;
1670 /********************************************************************
1672 * cifdefaultroute - delete a default route through the address given.
1675 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1678 default_route_gateway = 0;
1680 memset (&rt, '\0', sizeof (rt));
1681 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1682 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1684 if (kernel_version > KVERSION(2,1,0)) {
1685 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1686 SIN_ADDR(rt.rt_genmask) = 0L;
1689 SIN_ADDR(rt.rt_gateway) = gateway;
1691 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1692 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1694 if ( ! ok_error ( errno ))
1695 error("default route ioctl(SIOCDELRT): %m (%d)", errno);
1702 /********************************************************************
1704 * sifproxyarp - Make a proxy ARP entry for the peer.
1707 int sifproxyarp (int unit, u_int32_t his_adr)
1709 struct arpreq arpreq;
1712 if (has_proxy_arp == 0) {
1713 memset (&arpreq, '\0', sizeof(arpreq));
1715 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1716 SIN_ADDR(arpreq.arp_pa) = his_adr;
1717 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1719 * Get the hardware address of an interface on the same subnet
1720 * as our local address.
1722 if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1723 sizeof(proxy_arp_dev))) {
1724 error("Cannot determine ethernet address for proxy ARP");
1727 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1729 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1730 if ( ! ok_error ( errno ))
1731 error("ioctl(SIOCSARP): %m(%d)", errno);
1734 proxy_arp_addr = his_adr;
1738 forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1739 if (forw_path != 0) {
1740 int fd = open(forw_path, O_WRONLY);
1742 if (write(fd, "1", 1) != 1)
1743 error("Couldn't enable IP forwarding: %m");
1753 /********************************************************************
1755 * cifproxyarp - Delete the proxy ARP entry for the peer.
1758 int cifproxyarp (int unit, u_int32_t his_adr)
1760 struct arpreq arpreq;
1762 if (has_proxy_arp) {
1764 memset (&arpreq, '\0', sizeof(arpreq));
1765 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1766 SIN_ADDR(arpreq.arp_pa) = his_adr;
1767 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1768 strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1770 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1771 if ( ! ok_error ( errno ))
1772 warn("ioctl(SIOCDARP): %m(%d)", errno);
1779 /********************************************************************
1781 * get_ether_addr - get the hardware address of an interface on the
1782 * the same subnet as ipaddr.
1785 static int get_ether_addr (u_int32_t ipaddr,
1786 struct sockaddr *hwaddr,
1787 char *name, int namelen)
1789 struct ifreq *ifr, *ifend;
1790 u_int32_t ina, mask;
1794 struct ifreq ifs[MAX_IFS];
1796 ifc.ifc_len = sizeof(ifs);
1798 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1799 if ( ! ok_error ( errno ))
1800 error("ioctl(SIOCGIFCONF): %m(%d)", errno);
1804 SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1805 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1807 * Scan through looking for an interface with an Internet
1808 * address on the same subnet as `ipaddr'.
1810 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1811 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1812 if (ifr->ifr_addr.sa_family == AF_INET) {
1813 ina = SIN_ADDR(ifr->ifr_addr);
1814 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1815 SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1818 * Check that the interface is up, and not point-to-point
1821 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1824 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1827 * Get its netmask and check that it's on the right subnet.
1829 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1832 mask = SIN_ADDR(ifreq.ifr_addr);
1833 SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1834 ip_ntoa(ina), ntohl(mask)));
1836 if (((ipaddr ^ ina) & mask) != 0)
1845 strlcpy(name, ifreq.ifr_name, namelen);
1847 /* trim off the :1 in eth0:1 */
1848 aliasp = strchr(name, ':');
1852 info("found interface %s for proxy arp", name);
1854 * Now get the hardware address.
1856 memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1857 if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0) {
1858 error("SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno);
1864 sizeof (struct sockaddr));
1866 SYSDEBUG ((LOG_DEBUG,
1867 "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1868 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1869 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1870 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1871 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1872 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1873 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1874 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1875 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1880 * get_if_hwaddr - get the hardware address for the specified
1881 * network interface device.
1884 get_if_hwaddr(u_char *addr, char *name)
1889 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1892 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1893 strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1894 ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1897 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1902 * get_first_ethernet - return the name of the first ethernet-style
1903 * interface on this system.
1906 get_first_ethernet()
1911 /********************************************************************
1913 * Return user specified netmask, modified by any mask we might determine
1914 * for address `addr' (in network byte order).
1915 * Here we scan through the system's list of interfaces, looking for
1916 * any non-point-to-point interfaces which might appear to be on the same
1917 * network as `addr'. If we find any, we OR in their netmask to the
1918 * user-specified netmask.
1921 u_int32_t GetMask (u_int32_t addr)
1923 u_int32_t mask, nmask, ina;
1924 struct ifreq *ifr, *ifend, ifreq;
1926 struct ifreq ifs[MAX_IFS];
1930 if (IN_CLASSA(addr)) /* determine network mask for address class */
1931 nmask = IN_CLASSA_NET;
1932 else if (IN_CLASSB(addr))
1933 nmask = IN_CLASSB_NET;
1935 nmask = IN_CLASSC_NET;
1937 /* class D nets are disallowed by bad_ip_adrs */
1938 mask = netmask | htonl(nmask);
1940 * Scan through the system's network interfaces.
1942 ifc.ifc_len = sizeof(ifs);
1944 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1945 if ( ! ok_error ( errno ))
1946 warn("ioctl(SIOCGIFCONF): %m(%d)", errno);
1950 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1951 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1953 * Check the interface's internet address.
1955 if (ifr->ifr_addr.sa_family != AF_INET)
1957 ina = SIN_ADDR(ifr->ifr_addr);
1958 if (((ntohl(ina) ^ addr) & nmask) != 0)
1961 * Check that the interface is up, and not point-to-point nor loopback.
1963 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1964 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1967 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1970 * Get its netmask and OR it into our mask.
1972 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1974 mask |= SIN_ADDR(ifreq.ifr_addr);
1980 /********************************************************************
1982 * Internal routine to decode the version.modification.patch level
1985 static void decode_version (char *buf, int *version,
1986 int *modification, int *patch)
1990 *version = (int) strtoul (buf, &endp, 10);
1994 if (endp != buf && *endp == '.') {
1996 *modification = (int) strtoul (buf, &endp, 10);
1997 if (endp != buf && *endp == '.') {
1999 *patch = (int) strtoul (buf, &buf, 10);
2004 /********************************************************************
2006 * Procedure to determine if the PPP line discipline is registered.
2010 ppp_registered(void)
2018 * We used to open the serial device and set it to the ppp line
2019 * discipline here, in order to create a ppp unit. But that is
2020 * not a good idea - the user might have specified a device that
2021 * they can't open (permission, or maybe it doesn't really exist).
2022 * So we grab a pty master/slave pair and use that.
2024 if (!get_pty(&mfd, &local_fd, slave, 0)) {
2025 no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2030 * Try to put the device into the PPP discipline.
2032 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2033 error("ioctl(TIOCSETD(PPP)): %m(%d)", errno);
2042 /********************************************************************
2044 * ppp_available - check whether the system has any ppp interfaces
2045 * (in fact we check whether we can do an ioctl on ppp0).
2048 int ppp_available(void)
2053 int my_version, my_modification, my_patch;
2054 int osmaj, osmin, ospatch;
2057 "This system lacks kernel support for PPP. This could be because\n"
2058 "the PPP kernel module could not be loaded, or because PPP was not\n"
2059 "included in the kernel configuration. If PPP was included as a\n"
2060 "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
2061 "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2062 "See README.linux file in the ppp distribution for more details.\n";
2064 /* get the kernel version now, since we are called before sys_init */
2066 osmaj = osmin = ospatch = 0;
2067 sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2068 kernel_version = KVERSION(osmaj, osmin, ospatch);
2070 fd = open("/dev/ppp", O_RDWR);
2072 if (fd < 0 && errno == ENOENT) {
2073 /* try making it and see if that helps. */
2074 if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR,
2075 makedev(108, 0)) >= 0) {
2076 fd = open("/dev/ppp", O_RDWR);
2078 info("Created /dev/ppp device node");
2080 unlink("/dev/ppp"); /* didn't work, undo the mknod */
2081 } else if (errno == EEXIST) {
2082 fd = open("/dev/ppp", O_RDWR);
2087 new_style_driver = 1;
2089 /* XXX should get from driver */
2091 driver_modification = 4;
2096 if (kernel_version >= KVERSION(2,3,13)) {
2097 if (errno == ENOENT)
2099 "pppd is unable to open the /dev/ppp device.\n"
2100 "You need to create the /dev/ppp device node by\n"
2101 "executing the following command as root:\n"
2102 " mknod /dev/ppp c 108 0\n";
2107 * Open a socket for doing the ioctl operations.
2109 s = socket(AF_INET, SOCK_DGRAM, 0);
2113 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2114 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2116 * If the device did not exist then attempt to create one by putting the
2117 * current tty into the PPP discipline. If this works then obtain the
2118 * flags for the device again.
2121 if (ppp_registered()) {
2122 strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2123 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2127 * Ensure that the hardware address is for PPP and not something else
2130 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2132 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2136 * This is the PPP device. Validate the version of the driver at this
2137 * point to ensure that this program will work with the driver.
2140 char abBuffer [1024];
2142 ifr.ifr_data = abBuffer;
2143 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2145 error("Couldn't read driver version: %m");
2147 no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2150 decode_version(abBuffer,
2152 &driver_modification,
2155 * Validate the version of the driver against the version that we used.
2157 decode_version(VERSION,
2162 /* The version numbers must match */
2163 if (driver_version != my_version)
2166 /* The modification levels must be legal */
2167 if (driver_modification < 3) {
2168 if (driver_modification >= 2) {
2169 /* we can cope with 2.2.0 and above */
2178 slprintf(route_buffer, sizeof(route_buffer),
2179 "Sorry - PPP driver version %d.%d.%d is out of date\n",
2180 driver_version, driver_modification, driver_patch);
2182 no_ppp_msg = route_buffer;
2189 /********************************************************************
2191 * Update the wtmp file with the appropriate user name and tty device.
2194 void logwtmp (const char *line, const char *name, const char *host)
2196 struct utmp ut, *utp;
2197 pid_t mypid = getpid();
2203 * Update the signon database for users.
2204 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2206 utmpname(_PATH_UTMP);
2208 while ((utp = getutent()) && (utp->ut_pid != mypid))
2211 /* Is this call really necessary? There is another one after the 'put' */
2215 memcpy(&ut, utp, sizeof(ut));
2217 /* some gettys/telnetds don't initialize utmp... */
2218 memset(&ut, 0, sizeof(ut));
2220 if (ut.ut_id[0] == 0)
2221 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2223 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2224 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2228 ut.ut_type = USER_PROCESS;
2231 /* Insert the host name if one is supplied */
2233 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2235 /* Insert the IP address of the remote system if IP is enabled */
2236 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2237 memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2238 sizeof(ut.ut_addr));
2240 /* CL: Makes sure that the logout works */
2241 if (*host == 0 && *name==0)
2247 * Update the wtmp file.
2250 updwtmp(_PATH_WTMP, &ut);
2252 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2254 flock(wtmp, LOCK_EX);
2256 if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2257 warn("error writing %s: %m", _PATH_WTMP);
2259 flock(wtmp, LOCK_UN);
2267 /********************************************************************
2269 * sifvjcomp - config tcp header compression
2272 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2274 u_int x = get_flags(ppp_dev_fd);
2277 if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2278 if (! ok_error (errno))
2279 error("ioctl(PPPIOCSMAXCID): %m(%d)", errno);
2284 x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP;
2285 x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
2286 set_flags (ppp_dev_fd, x);
2291 /********************************************************************
2293 * sifup - Config the interface up and enable IP packets to pass.
2300 memset (&ifr, '\0', sizeof (ifr));
2301 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2302 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2303 if (! ok_error (errno))
2304 error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
2308 ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2309 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2310 if (! ok_error (errno))
2311 error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
2319 /********************************************************************
2321 * sifdown - Disable the indicated protocol and config the interface
2322 * down if there are no remaining protocols.
2329 if (if_is_up && --if_is_up > 0)
2332 memset (&ifr, '\0', sizeof (ifr));
2333 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2334 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2335 if (! ok_error (errno))
2336 error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
2340 ifr.ifr_flags &= ~IFF_UP;
2341 ifr.ifr_flags |= IFF_POINTOPOINT;
2342 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2343 if (! ok_error (errno))
2344 error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
2350 /********************************************************************
2352 * sifaddr - Config the interface IP addresses and netmask.
2355 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2360 memset (&ifr, '\0', sizeof (ifr));
2361 memset (&rt, '\0', sizeof (rt));
2363 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2364 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2365 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2367 strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2369 * Set our IP address
2371 SIN_ADDR(ifr.ifr_addr) = our_adr;
2372 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2373 if (errno != EEXIST) {
2374 if (! ok_error (errno))
2375 error("ioctl(SIOCSIFADDR): %m(%d)", errno);
2378 warn("ioctl(SIOCSIFADDR): Address already exists");
2383 * Set the gateway address
2385 SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2386 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2387 if (! ok_error (errno))
2388 error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno);
2393 * For recent kernels, force the netmask to 255.255.255.255.
2395 if (kernel_version >= KVERSION(2,1,16))
2397 if (net_mask != 0) {
2398 SIN_ADDR(ifr.ifr_netmask) = net_mask;
2399 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2400 if (! ok_error (errno))
2401 error("ioctl(SIOCSIFNETMASK): %m(%d)", errno);
2406 * Add the device route
2408 if (kernel_version < KVERSION(2,1,16)) {
2409 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2410 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2413 SIN_ADDR(rt.rt_gateway) = 0L;
2414 SIN_ADDR(rt.rt_dst) = his_adr;
2415 rt.rt_flags = RTF_UP | RTF_HOST;
2417 if (kernel_version > KVERSION(2,1,0)) {
2418 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2419 SIN_ADDR(rt.rt_genmask) = -1L;
2422 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2423 if (! ok_error (errno))
2424 error("ioctl(SIOCADDRT) device route: %m(%d)", errno);
2429 /* set ip_dynaddr in demand mode if address changes */
2430 if (demand && tune_kernel && !dynaddr_set
2431 && our_old_addr && our_old_addr != our_adr) {
2432 /* set ip_dynaddr if possible */
2436 path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2437 if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2438 if (write(fd, "1", 1) != 1)
2439 error("Couldn't enable dynamic IP addressing: %m");
2442 dynaddr_set = 1; /* only 1 attempt */
2449 /********************************************************************
2451 * cifaddr - Clear the interface IP addresses, and delete routes
2452 * through the interface if possible.
2455 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2459 create_msg(BCM_PPPOE_CLIENT_STATE_DOWN);
2460 //syslog(LOG_CRIT,"Clear IP addresses. PPP connection DOWN.\n");
2462 if (kernel_version < KVERSION(2,1,16)) {
2464 * Delete the route through the device
2467 memset (&rt, '\0', sizeof (rt));
2469 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2470 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2473 SIN_ADDR(rt.rt_gateway) = 0;
2474 SIN_ADDR(rt.rt_dst) = his_adr;
2475 rt.rt_flags = RTF_UP | RTF_HOST;
2477 if (kernel_version > KVERSION(2,1,0)) {
2478 SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2479 SIN_ADDR(rt.rt_genmask) = -1L;
2482 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2483 if (still_ppp() && ! ok_error (errno))
2484 error("ioctl(SIOCDELRT) device route: %m(%d)", errno);
2489 /* This way it is possible to have an IPX-only or IPv6-only interface */
2490 memset(&ifr, 0, sizeof(ifr));
2491 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2492 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2494 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2495 if (! ok_error (errno)) {
2496 error("ioctl(SIOCSIFADDR): %m(%d)", errno);
2501 our_old_addr = our_adr;
2507 /********************************************************************
2509 * sif6addr - Config the interface with an IPv6 link-local address
2511 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2513 struct in6_ifreq ifr6;
2515 struct in6_rtmsg rt6;
2519 error("IPv6 socket creation failed: %m");
2522 memset(&ifr, 0, sizeof (ifr));
2523 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2524 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2525 error("sif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno);
2529 /* Local interface */
2530 memset(&ifr6, 0, sizeof(ifr6));
2531 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2532 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2533 ifr6.ifr6_prefixlen = 10;
2535 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2536 error("sif6addr: ioctl(SIOCSIFADDR): %m (%d)", errno);
2540 /* Route to remote host */
2541 memset(&rt6, 0, sizeof(rt6));
2542 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2543 rt6.rtmsg_flags = RTF_UP;
2544 rt6.rtmsg_dst_len = 10;
2545 rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2546 rt6.rtmsg_metric = 1;
2548 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2549 error("sif6addr: ioctl(SIOCADDRT): %m (%d)", errno);
2557 /********************************************************************
2559 * cif6addr - Remove IPv6 address from interface
2561 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2564 struct in6_ifreq ifr6;
2568 error("IPv6 socket creation failed: %m");
2571 memset(&ifr, 0, sizeof(ifr));
2572 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2573 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2574 error("cif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno);
2578 memset(&ifr6, 0, sizeof(ifr6));
2579 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2580 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2581 ifr6.ifr6_prefixlen = 10;
2583 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2584 if (errno != EADDRNOTAVAIL) {
2585 if (! ok_error (errno))
2586 error("cif6addr: ioctl(SIOCDIFADDR): %m (%d)", errno);
2589 warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2598 * get_pty - get a pty master/slave pair and chown the slave side
2599 * to the uid given. Assumes slave_name points to >= 16 bytes of space.
2602 get_pty(master_fdp, slave_fdp, slave_name, uid)
2608 int i, mfd, sfd = -1;
2610 struct termios tios;
2614 * Try the unix98 way first.
2616 mfd = open("/dev/ptmx", O_RDWR);
2619 if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2620 slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2621 chmod(pty_name, S_IRUSR | S_IWUSR);
2624 if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2625 warn("Couldn't unlock pty slave %s: %m", pty_name);
2627 if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2628 warn("Couldn't open pty slave %s: %m", pty_name);
2631 #endif /* TIOCGPTN */
2634 /* the old way - scan through the pty name space */
2635 for (i = 0; i < 64; ++i) {
2636 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2637 'p' + i / 16, i % 16);
2638 mfd = open(pty_name, O_RDWR, 0);
2641 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2643 fchown(sfd, uid, -1);
2644 fchmod(sfd, S_IRUSR | S_IWUSR);
2655 strlcpy(slave_name, pty_name, 16);
2658 if (tcgetattr(sfd, &tios) == 0) {
2659 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2660 tios.c_cflag |= CS8 | CREAD | CLOCAL;
2661 tios.c_iflag = IGNPAR;
2664 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2665 warn("couldn't set attributes on pty: %m");
2667 warn("couldn't get attributes on pty: %m");
2672 /********************************************************************
2674 * open_loopback - open the device we use for getting packets
2675 * in demand mode. Under Linux, we use a pty master/slave pair.
2678 open_ppp_loopback(void)
2683 if (new_style_driver) {
2684 /* allocate ourselves a ppp unit */
2685 if (make_ppp_unit() < 0)
2687 set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC);
2688 set_kdebugflag(kdebugflag);
2693 if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2694 fatal("No free pty for loopback");
2695 SYSDEBUG(("using %s for loopback", loop_name));
2697 set_ppp_fd(slave_fd);
2699 flags = fcntl(master_fd, F_GETFL);
2701 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2702 warn("couldn't set master loopback to nonblock: %m(%d)", errno);
2704 flags = fcntl(ppp_fd, F_GETFL);
2706 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2707 warn("couldn't set slave loopback to nonblock: %m(%d)", errno);
2709 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2710 fatal("ioctl(TIOCSETD): %m(%d)", errno);
2712 * Find out which interface we were given.
2714 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2715 fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
2717 * Enable debug in the driver if requested.
2719 set_kdebugflag (kdebugflag);
2724 /********************************************************************
2726 * restore_loop - reattach the ppp unit to the loopback.
2728 * The kernel ppp driver automatically reattaches the ppp unit to
2729 * the loopback if the serial port is set to a line discipline other
2730 * than ppp, or if it detects a modem hangup. The former will happen
2731 * in disestablish_ppp if the latter hasn't already happened, so we
2732 * shouldn't need to do anything.
2734 * Just to be sure, set the real serial port to the normal discipline.
2741 if (new_style_driver) {
2742 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC);
2745 if (ppp_fd != slave_fd) {
2746 (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
2747 set_ppp_fd(slave_fd);
2751 /********************************************************************
2753 * sifnpmode - Set the mode for handling packets for a given NP.
2757 sifnpmode(u, proto, mode)
2764 npi.protocol = proto;
2766 if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2767 if (! ok_error (errno))
2768 error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)",
2769 proto, mode, errno);
2776 /********************************************************************
2778 * sipxfaddr - Config the interface IPX networknumber
2781 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2788 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2790 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2792 if (! ok_error (errno))
2793 dbglog("socket(AF_IPX): %m (%d)", errno);
2797 memset (&ifr, '\0', sizeof (ifr));
2798 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2800 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2801 sipx->sipx_family = AF_IPX;
2802 sipx->sipx_port = 0;
2803 sipx->sipx_network = htonl (network);
2804 sipx->sipx_type = IPX_FRAME_ETHERII;
2805 sipx->sipx_action = IPX_CRTITF;
2807 * Set the IPX device
2809 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2811 if (errno != EEXIST) {
2812 if (! ok_error (errno))
2813 dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno);
2816 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2825 /********************************************************************
2827 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2828 * are removed and the device is no longer able to pass IPX
2832 int cipxfaddr (int unit)
2839 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2841 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2843 if (! ok_error (errno))
2844 dbglog("socket(AF_IPX): %m (%d)", errno);
2848 memset (&ifr, '\0', sizeof (ifr));
2849 strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2851 sipx->sipx_type = IPX_FRAME_ETHERII;
2852 sipx->sipx_action = IPX_DLTITF;
2853 sipx->sipx_family = AF_IPX;
2855 * Set the IPX device
2857 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2858 if (! ok_error (errno))
2859 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno);
2869 * Use the hostname as part of the random number seed.
2878 for (p = hostname; *p != 0; ++p)
2885 /********************************************************************
2887 * sys_check_options - check the options that the user specified
2891 sys_check_options(void)
2895 * Disable the IPX protocol if the support is not present in the kernel.
2899 if (ipxcp_protent.enabled_flag) {
2900 struct stat stat_buf;
2901 if ((path = path_to_procfs("/net/ipx_interface")) == 0
2902 || lstat(path, &stat_buf) < 0) {
2903 error("IPX support is not present in the kernel\n");
2904 ipxcp_protent.enabled_flag = 0;
2908 if (demand && driver_is_old) {
2909 option_error("demand dialling is not supported by kernel driver "
2910 "version %d.%d.%d", driver_version, driver_modification,
2914 if (multilink && !new_style_driver) {
2915 warn("Warning: multilink is not supported by the kernel driver");