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>
40 /* This is in netdevice.h. However, this compile will fail miserably if
41 you attempt to include netdevice.h because it has so many references
42 to __memcpy functions which it should not attempt to do. So, since I
43 really don't use it, but it must be defined, define it now. */
46 #define MAX_ADDR_LEN 7
50 #include <linux/ppp_defs.h>
51 #include <net/if_arp.h>
52 #include <linux/if_ppp.h>
53 #include <net/route.h>
54 #include <linux/if_ether.h>
55 #include <netinet/in.h>
65 #define ok_error(num) ((num)==EIO)
67 static int tty_disc = N_TTY; /* The TTY discipline */
68 static int ppp_disc = N_PPP; /* The PPP discpline */
69 static int initfdflags = -1; /* Initial file descriptor flags for fd */
70 static int ppp_fd = -1; /* fd which is set to PPP discipline */
71 static int sock_fd = -1; /* socket for doing interface ioctls */
72 static int slave_fd = -1;
73 static int master_fd = -1;
75 static int has_proxy_arp = 0;
76 static int driver_version = 0;
77 static int driver_modification = 0;
78 static int driver_patch = 0;
79 static int restore_term = 0; /* 1 => we've munged the terminal */
80 static struct termios inittermios; /* Initial TTY termios */
82 static char loop_name[20];
83 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
85 static int if_is_up; /* Interface has been marked up */
86 static u_int32_t default_route_gateway; /* Gateway for default route added */
87 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
89 static char *lock_file;
93 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
94 #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
95 IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
97 /* Prototypes for procedures local to this file. */
98 static int get_flags (void);
99 static void set_flags (int flags);
100 static int translate_speed (int bps);
101 static int baud_rate_of (int speed);
102 static char *path_to_route (void);
103 static void close_route_table (void);
104 static int open_route_table (void);
105 static int read_route_table (struct rtentry *rt);
106 static int defaultroute_exists (struct rtentry *rt);
107 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
109 static void decode_version (char *buf, int *version, int *mod, int *patch);
111 extern u_char inpacket_buf[]; /* borrowed from main.c */
114 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
118 #define SET_SA_FAMILY(addr, family) \
119 memset ((char *) &(addr), '\0', sizeof(addr)); \
120 addr.sa_family = (family);
123 * Determine if the PPP connection should still be present.
127 #define still_ppp() (hungup == 0)
130 #define LOCK_PREFIX "/var/lock/LCK.."
133 /********************************************************************
135 * Functions to read and set the flags value in the device driver
138 static void set_ppp_fd (int new_fd)
140 SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", ppp_fd));
144 /********************************************************************
146 * Functions to read and set the flags value in the device driver
149 static int get_flags (void)
153 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0)
155 if ( ok_error (errno) )
161 syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m");
166 SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags));
170 /********************************************************************/
172 static void set_flags (int flags)
174 SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
176 if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0)
178 if (! ok_error (errno) )
180 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS, %x): %m(%d)", flags, errno);
186 /********************************************************************
188 * sys_init - System-dependent initialization.
193 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
194 setlogmask(LOG_UPTO(LOG_INFO));
197 setlogmask(LOG_UPTO(LOG_DEBUG));
200 /* Get an internet socket for doing socket ioctls. */
201 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
204 if ( ! ok_error ( errno ))
206 syslog(LOG_ERR, "Couldn't create IP socket: %m(%d)", errno);
212 /********************************************************************
214 * sys_cleanup - restore any system state we modified before exiting:
215 * mark the interface down, delete default route and/or proxy arp entry.
216 * This should call die() because it's called from die().
219 void sys_cleanup(void)
223 * Take down the device
230 * Delete any routes through the device.
232 if (default_route_gateway != 0)
234 cifdefaultroute(0, default_route_gateway);
239 cifproxyarp(0, proxy_arp_addr);
243 /********************************************************************
245 * sys_close - Clean up in a child process before execing.
255 /********************************************************************
257 * note_debug_level - note a change in the debug level.
260 void note_debug_level (void)
264 SYSDEBUG ((LOG_INFO, "Debug turned ON, Level %d", debug));
265 setlogmask(LOG_UPTO(LOG_DEBUG));
269 setlogmask(LOG_UPTO(LOG_WARNING));
273 /********************************************************************
275 * set_kdebugflag - Define the debugging level for the kernel
278 int set_kdebugflag (int requested_level)
280 if (ioctl(ppp_fd, PPPIOCSDEBUG, &requested_level) < 0)
282 if ( ! ok_error (errno) )
284 syslog (LOG_ERR, "ioctl(PPPIOCSDEBUG): %m");
288 SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
293 /********************************************************************
295 * establish_ppp - Turn the serial port into a ppp interface.
298 void establish_ppp (int tty_fd)
302 * The current PPP device will be the tty file.
306 * Ensure that the tty device is in exclusive mode.
308 if (ioctl(tty_fd, TIOCEXCL, 0) < 0)
310 if ( ! ok_error ( errno ))
312 syslog (LOG_WARNING, "ioctl(TIOCEXCL): %m");
316 * Demand mode - prime the old ppp device to relinquish the unit.
318 if (demand && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0)
320 if ( ! ok_error ( errno ))
322 syslog(LOG_ERR, "ioctl(transfer ppp unit): %m(%d)", errno);
327 * Set the current tty to the PPP discpline
329 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
331 if ( ! ok_error (errno) )
333 syslog(LOG_ERR, "ioctl(TIOCSETD): %m(%d)", errno);
338 * Find out which interface we were given.
340 if (ioctl(ppp_fd, PPPIOCGUNIT, &x) < 0)
342 if ( ! ok_error (errno))
344 syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m(%d)", errno);
349 * Check that we got the same unit again.
355 syslog(LOG_ERR, "transfer_ppp failed: wanted unit %d, got %d",
359 ioctl(slave_fd, TIOCSETD, &tty_disc);
364 * Enable debug in the driver if requested.
366 set_kdebugflag (kdebugflag);
368 set_flags (get_flags() & ~(SC_RCV_B7_0 | SC_RCV_B7_1 |
369 SC_RCV_EVNP | SC_RCV_ODDP));
371 SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
372 driver_version, driver_modification, driver_patch));
374 * Fetch the initial file flags and reset blocking mode on the file.
376 initfdflags = fcntl(ppp_fd, F_GETFL);
378 if (initfdflags == -1 ||
379 fcntl(ppp_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1)
381 if ( ! ok_error (errno))
384 "Couldn't set device to non-blocking mode: %m");
389 /********************************************************************
391 * disestablish_ppp - Restore the serial port to normal operation.
392 * This shouldn't call die() because it's called from die().
395 void disestablish_ppp(int tty_fd)
400 * Do nothing if the PPP device is controlled by the loopback device
402 if (tty_fd != ppp_fd)
407 * Attempt to restore the previous tty settings
413 * Restore the previous line discipline
415 if (ioctl(ppp_fd, TIOCSETD, &tty_disc) < 0)
417 if ( ! ok_error (errno))
419 syslog(LOG_ERR, "ioctl(TIOCSETD, N_TTY): %m");
423 if (ioctl(ppp_fd, TIOCNXCL, 0) < 0)
425 if ( ! ok_error (errno))
427 syslog (LOG_WARNING, "ioctl(TIOCNXCL): %m(%d)", errno);
431 /* Reset non-blocking mode on fd. */
432 if (initfdflags != -1 && fcntl(ppp_fd, F_SETFL, initfdflags) < 0)
434 if ( ! ok_error (errno))
437 "Couldn't restore device fd flags: %m");
444 /********************************************************************
446 * clean_check - Fetch the flags for the device and generate
447 * appropriate error messages.
449 void clean_check(void)
456 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0)
459 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP))
461 case SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP:
462 s = "nothing was received";
466 case SC_RCV_B7_0 | SC_RCV_EVNP:
467 case SC_RCV_B7_0 | SC_RCV_ODDP:
468 case SC_RCV_B7_0 | SC_RCV_ODDP | SC_RCV_EVNP:
469 s = "all had bit 7 set to 1";
473 case SC_RCV_B7_1 | SC_RCV_EVNP:
474 case SC_RCV_B7_1 | SC_RCV_ODDP:
475 case SC_RCV_B7_1 | SC_RCV_ODDP | SC_RCV_EVNP:
476 s = "all had bit 7 set to 0";
480 s = "all had odd parity";
484 s = "all had even parity";
490 syslog(LOG_WARNING, "Receive serial link is not"
492 syslog(LOG_WARNING, "Problem: %s", s);
500 * List of valid speeds.
504 int speed_int, speed_val;
575 /********************************************************************
577 * Translate from bits/second to a speed_t.
580 static int translate_speed (int bps)
582 struct speed *speedp;
586 for (speedp = speeds; speedp->speed_int; speedp++)
588 if (bps == speedp->speed_int)
590 return speedp->speed_val;
593 syslog(LOG_WARNING, "speed %d not supported", bps);
598 /********************************************************************
600 * Translate from a speed_t to bits/second.
603 static int baud_rate_of (int speed)
605 struct speed *speedp;
609 for (speedp = speeds; speedp->speed_int; speedp++)
611 if (speed == speedp->speed_val)
613 return speedp->speed_int;
620 /********************************************************************
622 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
623 * at the requested speed, etc. If `local' is true, set CLOCAL
624 * regardless of whether the modem option was specified.
627 void set_up_tty (int tty_fd, int local)
632 if (tcgetattr(tty_fd, &tios) < 0)
634 syslog(LOG_ERR, "tcgetattr: %m(%d)", errno);
643 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
644 tios.c_cflag |= CS8 | CREAD | HUPCL;
646 tios.c_iflag = IGNBRK | IGNPAR;
650 tios.c_cc[VTIME] = 0;
654 tios.c_cflag ^= (CLOCAL | HUPCL);
660 tios.c_cflag |= CRTSCTS;
664 tios.c_iflag |= IXON | IXOFF;
665 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
666 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
670 tios.c_cflag &= ~CRTSCTS;
677 speed = translate_speed(inspeed);
680 cfsetospeed (&tios, speed);
681 cfsetispeed (&tios, speed);
684 * We can't proceed if the serial port speed is B0,
685 * since that implies that the serial port is disabled.
689 speed = cfgetospeed(&tios);
692 syslog(LOG_ERR, "Baud rate for %s is 0; need explicit baud rate",
698 if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0)
700 syslog(LOG_ERR, "tcsetattr: %m");
704 baud_rate = baud_rate_of(speed);
708 /********************************************************************
710 * setdtr - control the DTR line on the serial port.
711 * This is called from die(), so it shouldn't call die().
714 void setdtr (int tty_fd, int on)
716 int modembits = TIOCM_DTR;
718 ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
721 /********************************************************************
723 * restore_tty - restore the terminal to the saved settings.
726 void restore_tty (int tty_fd)
732 * Turn off echoing, because otherwise we can get into
733 * a loop with the tty and the modem echoing to each other.
734 * We presume we are the sole user of this tty device, so
735 * when we close it, it will revert to its defaults anyway.
739 inittermios.c_lflag &= ~(ECHO | ECHONL);
742 if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0)
744 if (! ok_error (errno))
746 syslog(LOG_WARNING, "tcsetattr: %m");
752 /********************************************************************
754 * output - Output PPP packet.
757 void output (int unit, unsigned char *p, int len)
761 log_packet(p, len, "sent ");
764 if (write(ppp_fd, p, len) < 0)
766 if (errno == EWOULDBLOCK || errno == ENOBUFS
767 || errno == ENXIO || errno == EIO)
769 syslog(LOG_WARNING, "write: warning: %m(%d)", errno);
773 syslog(LOG_ERR, "write: %m(%d)", errno);
779 /********************************************************************
781 * wait_input - wait until there is data available on ppp_fd,
782 * for the length of time specified by *timo (indefinite
786 void wait_input (struct timeval *timo)
792 FD_SET(ppp_fd, &ready);
794 n = select(ppp_fd + 1, &ready, NULL, &ready, timo);
795 if (n < 0 && errno != EINTR)
797 syslog(LOG_ERR, "select: %m(%d)", errno);
802 /********************************************************************
804 * wait_loop_output - wait until there is data available on the
805 * loopback, for the length of time specified by *timo (indefinite
808 void wait_loop_output(timo)
809 struct timeval *timo;
815 FD_SET(master_fd, &ready);
816 n = select(master_fd + 1, &ready, NULL, &ready, timo);
817 if (n < 0 && errno != EINTR)
819 syslog(LOG_ERR, "select: %m(%d)", errno);
824 /********************************************************************
826 * wait_time - wait for a given length of time or until a
827 * signal is received.
831 struct timeval *timo;
835 n = select(0, NULL, NULL, NULL, timo);
836 if (n < 0 && errno != EINTR) {
837 syslog(LOG_ERR, "select: %m(%d)", errno);
842 /********************************************************************
844 * read_packet - get a PPP packet from the serial device.
847 int read_packet (unsigned char *buf)
851 len = read(ppp_fd, buf, PPP_MTU + PPP_HDRLEN);
854 if (errno == EWOULDBLOCK)
858 syslog(LOG_ERR, "read: %m(%d)", errno);
864 /********************************************************************
866 * get_loop_output - get outgoing packets from the ppp device,
867 * and detect when we want to bring the real link up.
868 * Return value is 1 if we need to bring up the link, 0 otherwise.
871 get_loop_output(void)
874 int n = read(master_fd, inbuf, sizeof(inbuf));
878 if (loop_chars(inbuf, n))
882 n = read(master_fd, inbuf, sizeof(inbuf));
887 syslog(LOG_ERR, "eof on loopback");
891 if (errno != EWOULDBLOCK)
893 syslog(LOG_ERR, "read from loopback: %m(%d)", errno);
900 /********************************************************************
902 * ppp_send_config - configure the transmit characteristics of
906 void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp)
911 SYSDEBUG ((LOG_DEBUG, "send_config: mtu = %d\n", mtu));
913 * Ensure that the link is still up.
918 * Set the MTU and other parameters for the ppp device
920 memset (&ifr, '\0', sizeof (ifr));
921 strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
924 if (ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
926 syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m(%d)", errno);
930 SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
931 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0)
933 syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m(%d)", errno);
938 x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
939 x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
944 /********************************************************************
946 * ppp_set_xaccm - set the extended transmit ACCM for the interface.
949 void ppp_set_xaccm (int unit, ext_accm accm)
951 SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
952 accm[0], accm[1], accm[2], accm[3]));
954 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)
956 if ( ! ok_error (errno))
958 syslog(LOG_WARNING, "ioctl(set extended ACCM): %m(%d)", errno);
963 /********************************************************************
965 * ppp_recv_config - configure the receive-side characteristics of
969 void ppp_recv_config (int unit,int mru,u_int32_t asyncmap,int pcomp,int accomp)
973 SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
975 * If we were called because the link has gone down then there is nothing
976 * which may be done. Just return without incident.
983 * Set the receiver parameters
985 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
987 if ( ! ok_error (errno))
989 syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m(%d)", errno);
993 SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
994 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0)
996 syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m(%d)", errno);
1001 x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;
1005 /********************************************************************
1007 * ccp_test - ask kernel whether a given compression method
1008 * is acceptable for use.
1011 int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1013 struct ppp_option_data data;
1015 memset (&data, '\0', sizeof (data));
1017 data.length = opt_len;
1018 data.transmit = for_transmit;
1020 if (ioctl(ppp_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1025 return (errno == ENOBUFS)? 0: -1;
1028 /********************************************************************
1030 * ccp_flags_set - inform kernel about the current state of CCP.
1033 void ccp_flags_set (int unit, int isopen, int isup)
1037 int x = get_flags();
1038 x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;
1039 x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP;
1044 /********************************************************************
1046 * get_idle_time - return how long the link has been idle.
1049 get_idle_time(u, ip)
1051 struct ppp_idle *ip;
1053 return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0;
1056 /********************************************************************
1058 * ccp_fatal_error - returns 1 if decompression was disabled as a
1059 * result of an error detected after decompression of a packet,
1060 * 0 otherwise. This is necessary because of patent nonsense.
1063 int ccp_fatal_error (int unit)
1065 int x = get_flags();
1067 return x & SC_DC_FERROR;
1071 * path_to_route - determine the path to the proc file system data
1074 FILE *route_fd = (FILE *) 0;
1075 static char route_buffer [512];
1077 static char *path_to_route (void);
1078 static int open_route_table (void);
1079 static void close_route_table (void);
1080 static int read_route_table (struct rtentry *rt);
1082 /********************************************************************
1084 * path_to_procfs - find the path to the proc file system mount point
1087 static int path_to_procfs (void)
1089 struct mntent *mntent;
1092 fp = fopen (MOUNTED, "r");
1095 mntent = getmntent (fp);
1096 while (mntent != (struct mntent *) 0)
1098 if (strcmp (mntent->mnt_type, MNTTYPE_IGNORE) != 0)
1100 if (strcmp (mntent->mnt_type, "proc") == 0)
1102 strncpy (route_buffer, mntent->mnt_dir,
1103 sizeof (route_buffer)-10);
1104 route_buffer [sizeof (route_buffer)-10] = '\0';
1109 mntent = getmntent (fp);
1116 /********************************************************************
1118 * path_to_route - find the path to the route tables in the proc file system
1121 static char *path_to_route (void)
1123 if (! path_to_procfs())
1125 syslog (LOG_ERR, "proc file system not mounted");
1128 strcat (route_buffer, "/net/route");
1129 return (route_buffer);
1132 /********************************************************************
1134 * close_route_table - close the interface to the route table
1137 static void close_route_table (void)
1139 if (route_fd != (FILE *) 0)
1142 route_fd = (FILE *) 0;
1146 /********************************************************************
1148 * open_route_table - open the interface to the route table
1151 static int open_route_table (void)
1155 close_route_table();
1157 path = path_to_route();
1163 route_fd = fopen (path, "r");
1164 if (route_fd == (FILE *) 0)
1166 syslog (LOG_ERR, "can not open %s: %m(%d)", path, errno);
1172 /********************************************************************
1174 * read_route_table - read the next entry from the route table
1177 static int read_route_table (struct rtentry *rt)
1179 static char delims[] = " \t\n";
1180 char *dev_ptr, *ptr, *dst_ptr, *gw_ptr, *flag_ptr;
1182 memset (rt, '\0', sizeof (struct rtentry));
1186 if (fgets (route_buffer, sizeof (route_buffer), route_fd) ==
1192 dev_ptr = strtok (route_buffer, delims); /* interface name */
1193 dst_ptr = strtok (NULL, delims); /* destination address */
1194 gw_ptr = strtok (NULL, delims); /* gateway */
1195 flag_ptr = strtok (NULL, delims); /* flags */
1197 if (flag_ptr == (char *) 0) /* assume that we failed, somewhere. */
1202 /* Discard that stupid header line which should never
1203 * have been there in the first place !! */
1204 if (isxdigit (*dst_ptr) && isxdigit (*gw_ptr) && isxdigit (*flag_ptr))
1210 ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr =
1211 strtoul (dst_ptr, NULL, 16);
1213 ((struct sockaddr_in *) &rt->rt_gateway)->sin_addr.s_addr =
1214 strtoul (gw_ptr, NULL, 16);
1216 rt->rt_flags = (short) strtoul (flag_ptr, NULL, 16);
1217 rt->rt_dev = dev_ptr;
1222 /********************************************************************
1224 * defaultroute_exists - determine if there is a default route
1227 static int defaultroute_exists (struct rtentry *rt)
1231 if (!open_route_table())
1236 while (read_route_table(rt) != 0)
1238 if ((rt->rt_flags & RTF_UP) == 0)
1243 if (((struct sockaddr_in *) (&rt->rt_dst))->sin_addr.s_addr == 0L)
1250 close_route_table();
1254 /********************************************************************
1256 * sifdefaultroute - assign a default route through the address given.
1259 int sifdefaultroute (int unit, u_int32_t gateway)
1263 if (defaultroute_exists(&rt))
1265 u_int32_t old_gateway = ((struct sockaddr_in *) (&rt.rt_gateway))->
1268 if (old_gateway != gateway)
1271 "ppp not replacing existing default route to %s[%s]",
1273 inet_ntoa (old_gateway));
1278 memset (&rt, '\0', sizeof (rt));
1279 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1280 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1281 ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
1283 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1284 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0)
1286 if ( ! ok_error ( errno ))
1288 syslog (LOG_ERR, "default route ioctl(SIOCADDRT): %m(%d)", errno);
1293 default_route_gateway = gateway;
1297 /********************************************************************
1299 * cifdefaultroute - delete a default route through the address given.
1302 int cifdefaultroute (int unit, u_int32_t gateway)
1306 default_route_gateway = 0;
1308 memset (&rt, '\0', sizeof (rt));
1309 SET_SA_FAMILY (rt.rt_dst, AF_INET);
1310 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1311 ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
1313 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1314 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1318 if ( ! ok_error ( errno ))
1321 "default route ioctl(SIOCDELRT): %m(%d)", errno);
1330 /********************************************************************
1332 * sifproxyarp - Make a proxy ARP entry for the peer.
1335 int sifproxyarp (int unit, u_int32_t his_adr)
1337 struct arpreq arpreq;
1339 if (has_proxy_arp == 0)
1341 memset (&arpreq, '\0', sizeof(arpreq));
1343 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1344 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
1345 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1347 * Get the hardware address of an interface on the same subnet
1348 * as our local address.
1350 if (!get_ether_addr(his_adr, &arpreq.arp_ha, arpreq.arp_dev))
1352 syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
1356 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0)
1358 if ( ! ok_error ( errno ))
1360 syslog(LOG_ERR, "ioctl(SIOCSARP): %m(%d)", errno);
1366 proxy_arp_addr = his_adr;
1371 /********************************************************************
1373 * cifproxyarp - Delete the proxy ARP entry for the peer.
1376 int cifproxyarp (int unit, u_int32_t his_adr)
1378 struct arpreq arpreq;
1380 if (has_proxy_arp == 1)
1382 memset (&arpreq, '\0', sizeof(arpreq));
1383 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1385 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
1386 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0)
1388 if ( ! ok_error ( errno ))
1390 syslog(LOG_WARNING, "ioctl(SIOCDARP): %m(%d)", errno);
1399 /********************************************************************
1401 * get_ether_addr - get the hardware address of an interface on the
1402 * the same subnet as ipaddr.
1405 static int get_ether_addr (u_int32_t ipaddr,
1406 struct sockaddr *hwaddr,
1409 struct ifreq *ifr, *ifend, *ifp;
1411 u_int32_t ina, mask;
1412 struct sockaddr_dl *dla;
1415 struct ifreq ifs[MAX_IFS];
1417 ifc.ifc_len = sizeof(ifs);
1419 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0)
1421 if ( ! ok_error ( errno ))
1423 syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m(%d)", errno);
1428 SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1429 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1431 * Scan through looking for an interface with an Internet
1432 * address on the same subnet as `ipaddr'.
1434 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1435 for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
1437 if (ifr->ifr_addr.sa_family == AF_INET)
1439 ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1440 strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1441 SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1444 * Check that the interface is up, and not point-to-point
1447 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1452 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1457 * Get its netmask and check that it's on the right subnet.
1459 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1464 mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
1465 SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1466 ip_ntoa(ina), ntohl(mask)));
1468 if (((ipaddr ^ ina) & mask) != 0)
1481 memcpy (name, ifreq.ifr_name, sizeof(ifreq.ifr_name));
1482 syslog(LOG_INFO, "found interface %s for proxy arp", name);
1484 * Now get the hardware address.
1486 memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1487 if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0)
1489 syslog(LOG_ERR, "SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno);
1495 sizeof (struct sockaddr));
1497 SYSDEBUG ((LOG_DEBUG,
1498 "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1499 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1500 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1501 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1502 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1503 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1504 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1505 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1506 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1510 /********************************************************************
1512 * Return user specified netmask, modified by any mask we might determine
1513 * for address `addr' (in network byte order).
1514 * Here we scan through the system's list of interfaces, looking for
1515 * any non-point-to-point interfaces which might appear to be on the same
1516 * network as `addr'. If we find any, we OR in their netmask to the
1517 * user-specified netmask.
1520 u_int32_t GetMask (u_int32_t addr)
1522 u_int32_t mask, nmask, ina;
1523 struct ifreq *ifr, *ifend, ifreq;
1525 struct ifreq ifs[MAX_IFS];
1529 if (IN_CLASSA(addr)) /* determine network mask for address class */
1531 nmask = IN_CLASSA_NET;
1535 if (IN_CLASSB(addr))
1537 nmask = IN_CLASSB_NET;
1541 nmask = IN_CLASSC_NET;
1545 /* class D nets are disallowed by bad_ip_adrs */
1546 mask = netmask | htonl(nmask);
1548 * Scan through the system's network interfaces.
1550 ifc.ifc_len = sizeof(ifs);
1552 if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0)
1554 if ( ! ok_error ( errno ))
1556 syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m(%d)", errno);
1561 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1562 for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
1565 * Check the interface's internet address.
1567 if (ifr->ifr_addr.sa_family != AF_INET)
1571 ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1572 if (((ntohl(ina) ^ addr) & nmask) != 0)
1577 * Check that the interface is up, and not point-to-point nor loopback.
1579 strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1580 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1585 if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1590 * Get its netmask and OR it into our mask.
1592 if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1596 mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
1602 /********************************************************************
1604 * Internal routine to decode the version.modification.patch level
1607 static void decode_version (char *buf, int *version,
1608 int *modification, int *patch)
1610 *version = (int) strtoul (buf, &buf, 10);
1617 *modification = (int) strtoul (buf, &buf, 10);
1621 *patch = (int) strtoul (buf, &buf, 10);
1633 /********************************************************************
1635 * Procedure to determine if the PPP line dicipline is registered.
1639 ppp_registered(void)
1645 local_fd = open(devnam, O_NONBLOCK | O_RDWR, 0);
1648 syslog(LOG_ERR, "Failed to open %s: %m(%d)", devnam, errno);
1652 initfdflags = fcntl(local_fd, F_GETFL);
1653 if (initfdflags == -1)
1655 syslog(LOG_ERR, "Couldn't get device fd flags: %m(%d)", errno);
1660 initfdflags &= ~O_NONBLOCK;
1661 fcntl(local_fd, F_SETFL, initfdflags);
1663 * Read the initial line dicipline and try to put the device into the
1666 if (ioctl(local_fd, TIOCGETD, &init_disc) < 0)
1668 syslog(LOG_ERR, "ioctl(TIOCGETD): %m(%d)", errno);
1673 if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0)
1675 syslog(LOG_ERR, "ioctl(TIOCSETD): %m(%d)", errno);
1680 if (ioctl(local_fd, TIOCSETD, &init_disc) < 0)
1682 syslog(LOG_ERR, "ioctl(TIOCSETD): %m(%d)", errno);
1691 /********************************************************************
1693 * ppp_available - check whether the system has any ppp interfaces
1694 * (in fact we check whether we can do an ioctl on ppp0).
1697 int ppp_available(void)
1702 int my_version, my_modification, my_patch;
1703 extern char *no_ppp_msg;
1705 * Open a socket for doing the ioctl operations.
1707 s = socket(AF_INET, SOCK_DGRAM, 0);
1713 strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1714 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1716 * If the device did not exist then attempt to create one by putting the
1717 * current tty into the PPP discipline. If this works then obtain the
1718 * flags for the device again.
1722 if (ppp_registered())
1724 strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1725 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1729 * Ensure that the hardware address is for PPP and not something else
1733 ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
1736 if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
1744 "This system lacks kernel support for PPP. To include PPP support\n"
1745 "in the kernel, please follow the steps detailed in the "
1746 "README.linux\nfile in the ppp-2.3 distribution.\n";
1749 * This is the PPP device. Validate the version of the driver at this
1750 * point to ensure that this program will work with the driver.
1754 char abBuffer [1024];
1756 ifr.ifr_data = abBuffer;
1757 size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
1762 decode_version (abBuffer,
1764 &driver_modification,
1771 driver_modification =
1775 * Validate the version of the driver against the version that we used.
1777 decode_version (PPP_VERSION,
1782 /* The version numbers must match */
1783 if (driver_version != my_version)
1788 /* The modification levels must be legal */
1789 if (driver_modification < my_modification)
1797 sprintf (route_buffer,
1798 "Sorry - PPP driver version %d.%d.%d is out of date\n",
1799 driver_version, driver_modification, driver_patch);
1801 no_ppp_msg = route_buffer;
1807 /********************************************************************
1809 * Update the wtmp file with the appropriate user name and tty device.
1812 int logwtmp (char *line, char *name, char *host)
1815 struct utmp ut, *utp;
1816 pid_t mypid = getpid();
1818 * Update the signon database for users.
1819 * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
1821 utmpname(_PATH_UTMP);
1823 while ((utp = getutent()) && (utp->ut_pid != mypid))
1826 /* Is this call really necessary? There is another one after the 'put' */
1831 memcpy(&ut, utp, sizeof(ut));
1835 /* some gettys/telnetds don't initialize utmp... */
1836 memset(&ut, 0, sizeof(ut));
1839 if (ut.ut_id[0] == 0)
1841 strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
1844 strncpy(ut.ut_user, name, sizeof(ut.ut_user));
1845 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1849 ut.ut_type = USER_PROCESS;
1852 /* Insert the host name if one is supplied */
1855 strncpy (ut.ut_host, host, sizeof(ut.ut_host));
1858 /* Insert the IP address of the remote system if IP is enabled */
1859 if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
1861 memcpy (&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
1862 sizeof(ut.ut_addr));
1865 /* CL: Makes sure that the logout works */
1866 if (*host == 0 && *name==0)
1874 * Update the wtmp file.
1876 wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
1879 flock(wtmp, LOCK_EX);
1881 /* we really should check for error on the write for a full disk! */
1882 write (wtmp, (char *)&ut, sizeof(ut));
1885 flock(wtmp, LOCK_UN);
1889 /********************************************************************
1890 * Code for locking/unlocking the serial device.
1891 * This code is derived from chat.c.
1895 * lock - create a lock file for the named device
1898 int lock (char *dev)
1900 char hdb_lock_buffer[12];
1905 p = strrchr(dev, '/');
1911 lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
1912 if (lock_file == NULL)
1914 novm("lock file name");
1917 strcpy (lock_file, LOCK_PREFIX);
1918 strcat (lock_file, dev);
1920 * Attempt to create the lock file at this point.
1924 fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
1929 sprintf (hdb_lock_buffer, "%010d\n", pid);
1930 write (fd, hdb_lock_buffer, 11);
1932 write(fd, &pid, sizeof (pid));
1938 * If the file exists then check to see if the pid is stale
1940 if (errno == EEXIST)
1942 fd = open(lock_file, O_RDONLY, 0);
1945 if (errno == ENOENT) /* This is just a timing problem. */
1952 /* Read the lock file to find out who has the device locked */
1953 n = read (fd, hdb_lock_buffer, 11);
1957 syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
1961 /* See the process still exists. */
1965 hdb_lock_buffer[n] = '\0';
1966 sscanf (hdb_lock_buffer, " %d", &pid);
1968 pid = ((int *) hdb_lock_buffer)[0];
1970 if (pid == 0 || (kill(pid, 0) == -1 && errno == ESRCH))
1976 /* If the process does not exist then try to remove the lock */
1977 if (n == 0 && unlink (lock_file) == 0)
1979 syslog (LOG_NOTICE, "Removed stale lock on %s (pid %d)",
1984 syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, pid);
1988 syslog(LOG_ERR, "Can't create lock file %s: %m(%d)", lock_file, errno);
1998 /********************************************************************
2000 * unlock - remove our lockfile
2013 /********************************************************************
2015 * sifvjcomp - config tcp header compression
2018 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2020 u_int x = get_flags();
2024 if (ioctl (ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)
2026 if (! ok_error (errno))
2028 syslog (LOG_ERR, "ioctl(PPPIOCSFLAGS): %m(%d)", errno);
2034 x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP;
2035 x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
2041 /********************************************************************
2043 * sifup - Config the interface up and enable IP packets to pass.
2050 memset (&ifr, '\0', sizeof (ifr));
2051 strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2052 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0)
2054 if (! ok_error (errno))
2056 syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m(%d)", errno);
2061 ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2062 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0)
2064 if (! ok_error (errno))
2066 syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m(%d)", errno);
2074 /********************************************************************
2076 * sifdown - Config the interface down and disable IP.
2085 memset (&ifr, '\0', sizeof (ifr));
2086 strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2087 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0)
2089 if (! ok_error (errno))
2091 syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m(%d)", errno);
2096 ifr.ifr_flags &= ~IFF_UP;
2097 ifr.ifr_flags |= IFF_POINTOPOINT;
2098 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0)
2100 if (! ok_error (errno))
2102 syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m(%d)", errno);
2109 /********************************************************************
2111 * sifaddr - Config the interface IP addresses and netmask.
2114 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2120 memset (&ifr, '\0', sizeof (ifr));
2121 memset (&rt, '\0', sizeof (rt));
2123 SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
2124 SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2125 SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2127 strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2129 * Set our IP address
2131 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = our_adr;
2132 if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0)
2134 if (errno != EEXIST)
2136 if (! ok_error (errno))
2138 syslog (LOG_ERR, "ioctl(SIOCAIFADDR): %m(%d)", errno);
2143 syslog (LOG_WARNING, "ioctl(SIOCAIFADDR): Address already exists");
2148 * Set the gateway address
2150 ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = his_adr;
2151 if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0)
2153 if (! ok_error (errno))
2155 syslog (LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m(%d)", errno);
2164 ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask;
2165 if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0)
2167 if (! ok_error (errno))
2169 syslog (LOG_ERR, "ioctl(SIOCSIFNETMASK): %m(%d)", errno);
2175 * Add the device route
2177 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2178 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2179 rt.rt_dev = ifname; /* MJC */
2181 ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0L;
2182 ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = his_adr;
2183 rt.rt_flags = RTF_UP | RTF_HOST;
2185 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0)
2187 if (! ok_error (errno))
2189 syslog (LOG_ERR, "ioctl(SIOCADDRT) device route: %m(%d)", errno);
2196 /********************************************************************
2198 * cifaddr - Clear the interface IP addresses, and delete routes
2199 * through the interface if possible.
2202 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2206 * Delete the route through the device
2208 memset (&rt, '\0', sizeof (rt));
2210 SET_SA_FAMILY (rt.rt_dst, AF_INET);
2211 SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2212 rt.rt_dev = ifname; /* MJC */
2214 ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
2215 ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = his_adr;
2216 rt.rt_flags = RTF_UP | RTF_HOST;
2218 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH)
2220 if (still_ppp() && ! ok_error (errno))
2222 syslog (LOG_ERR, "ioctl(SIOCDELRT) device route: %m(%d)", errno);
2229 /********************************************************************
2231 * open_loopback - open the device we use for getting packets
2232 * in demand mode. Under Linux, we use our existing fd
2233 * to the ppp driver.
2236 open_ppp_loopback(void)
2239 struct termios tios;
2241 if (openpty (&master_fd, &slave_fd, loop_name, NULL, NULL) < 0)
2243 syslog(LOG_ERR, "No free pty for loopback");
2246 SYSDEBUG((LOG_DEBUG, "using %s for loopback", loop_name));
2248 set_ppp_fd(slave_fd);
2250 if (tcgetattr(ppp_fd, &tios) == 0)
2252 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2253 tios.c_cflag |= CS8 | CREAD;
2254 tios.c_iflag = IGNPAR | CLOCAL;
2257 if (tcsetattr(ppp_fd, TCSAFLUSH, &tios) < 0)
2259 syslog(LOG_WARNING, "couldn't set attributes on loopback: %m(%d)", errno);
2263 flags = fcntl(master_fd, F_GETFL);
2265 fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2267 syslog(LOG_WARNING, "couldn't set master loopback to nonblock: %m(%d)", errno);
2270 flags = fcntl(ppp_fd, F_GETFL);
2272 fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2274 syslog(LOG_WARNING, "couldn't set slave loopback to nonblock: %m(%d)", errno);
2277 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2279 syslog(LOG_ERR, "ioctl(TIOCSETD): %m(%d)", errno);
2283 * Find out which interface we were given.
2285 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2287 syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m(%d)", errno);
2291 * Enable debug in the driver if requested.
2293 set_kdebugflag (kdebugflag);
2296 /********************************************************************
2298 * restore_loop - reattach the ppp unit to the loopback.
2300 * The problem with the Linux variant is that the POSIX tty drivers will
2301 * sieze the line when it is disconnected. In addition, when the device
2302 * goes down all of the routes are deleted. This means that the tty needs
2303 * to be re-opened, reconfigured, and the device reconfigured and the routes
2314 * Take down the existing interface
2317 (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
2319 * Find the existing flags. This works even if the tty has stolen the
2322 fdflags = fcntl(ppp_fd, F_GETFL);
2325 syslog (LOG_ERR, "retrieve file flags failed: %m(%d)", errno);
2326 fdflags = O_NONBLOCK | O_RDWR;
2329 * Re-open the file so the we can re-establish the previous discipline
2331 sprintf (fname, "/proc/self/fd/%d", ppp_fd);
2332 x = open (fname, O_RDWR | O_NONBLOCK, 0);
2335 syslog (LOG_ERR, "reopen of tty file failed: %m(%d)", errno);
2338 * Transfer the newly opened file (to the same tty) back to the tty
2345 fcntl (ppp_fd, F_SETFL, fdflags);
2346 set_up_tty(ppp_fd, 0);
2349 * Switch to the tty slave and put that into the PPP discipline.
2351 set_ppp_fd(slave_fd);
2353 if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2355 syslog(LOG_ERR, "ioctl(TIOCSETD): %m(%d)", errno);
2359 * Fetch the current unit identifier.
2361 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2363 syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m(%d)", errno);
2367 * Restore the parameters for the PPP link.
2369 ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
2370 ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
2372 * Reconfigure the IP addresses for the demand dial system.
2377 /********************************************************************
2379 * sifnpmode - Set the mode for handling packets for a given NP.
2383 sifnpmode(u, proto, mode)
2390 npi.protocol = proto;
2392 if (ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0)
2394 if (! ok_error (errno))
2396 syslog(LOG_ERR, "ioctl(PPPIOCSNPMODE, %d, %d): %m(%d)",
2397 proto, mode, errno);
2405 #include <linux/ipx.h>
2407 /********************************************************************
2409 * sipxfaddr - Config the interface IPX networknumber
2412 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2416 struct sockaddr_ipx ipx_addr;
2418 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2421 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2424 if (! ok_error (errno))
2426 syslog (LOG_DEBUG, "socket(AF_IPX): %m(%d)", errno);
2432 memset (&ifr, '\0', sizeof (ifr));
2433 strcpy (ifr.ifr_name, ifname);
2435 memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2436 sipx->sipx_family = AF_IPX;
2437 sipx->sipx_port = 0;
2438 sipx->sipx_network = htonl (network);
2439 sipx->sipx_type = IPX_FRAME_ETHERII;
2440 sipx->sipx_action = IPX_CRTITF;
2442 * Set the IPX device
2444 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0)
2447 if (errno != EEXIST)
2449 if (! ok_error (errno))
2452 "ioctl(SIOCAIFADDR, CRTITF): %m(%d)", errno);
2457 syslog (LOG_WARNING,
2458 "ioctl(SIOCAIFADDR, CRTITF): Address already exists");
2467 /********************************************************************
2469 * cipxfaddr - Clear the information for the IPX network. The IPX routes
2470 * are removed and the device is no longer able to pass IPX
2474 int cipxfaddr (int unit)
2478 struct sockaddr_ipx ipx_addr;
2480 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2483 skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2486 if (! ok_error (errno))
2488 syslog (LOG_DEBUG, "socket(AF_IPX): %m(%d)", errno);
2494 memset (&ifr, '\0', sizeof (ifr));
2495 strcpy (ifr.ifr_name, ifname);
2497 sipx->sipx_type = IPX_FRAME_ETHERII;
2498 sipx->sipx_action = IPX_DLTITF;
2499 sipx->sipx_family = AF_IPX;
2501 * Set the IPX device
2503 if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0)
2505 if (! ok_error (errno))
2508 "ioctl(SIOCAIFADDR, IPX_DLTITF): %m(%d)", errno);
2518 /********************************************************************
2520 * sys_check_options - check the options that the user specified
2524 sys_check_options(void)
2527 struct stat stat_buf;
2529 * Disable the IPX protocol if the support is not present in the kernel.
2530 * If we disable it then ensure that IP support is enabled.
2532 while (ipxcp_protent.enabled_flag)
2534 if (path_to_procfs())
2536 strcat (route_buffer, "/net/ipx_interface");
2537 if (lstat (route_buffer, &stat_buf) >= 0)
2542 syslog (LOG_ERR, "IPX support is not present in the kernel\n");
2543 ipxcp_protent.enabled_flag = 0;
2544 ipcp_protent.enabled_flag = 1;