From 410dec1de0ee4520be8fd6840dc5974bb627101b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 1 Jan 1996 23:06:39 +0000 Subject: [PATCH] added demand-dial support, fd arg to various functions --- pppd/sys-sunos4.c | 286 ++++++++++++++++++++++++++++++---------- pppd/sys-svr4.c | 325 +++++++++++++++++++++++++++++++++------------- 2 files changed, 457 insertions(+), 154 deletions(-) diff --git a/pppd/sys-sunos4.c b/pppd/sys-sunos4.c index 730e0a7..305b6b4 100644 --- a/pppd/sys-sunos4.c +++ b/pppd/sys-sunos4.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-sunos4.c,v 1.2 1995/12/19 02:04:40 paulus Exp $"; +static char rcsid[] = "$Id: sys-sunos4.c,v 1.3 1996/01/01 23:06:37 paulus Exp $"; #endif #include @@ -75,6 +75,8 @@ static struct termios inittermios; static struct winsize wsinfo; /* Initial window size info */ static pid_t parent_pid; /* PID of our parent */ +extern u_char inpacket_buf[]; /* borrowed from main.c */ + static int link_mtu, link_mru; #define NMODULES 32 @@ -98,6 +100,8 @@ static int strioctl __P((int, int, void *, int, int)); void sys_init() { + int x; + openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); setlogmask(LOG_UPTO(LOG_INFO)); if (debug) @@ -116,6 +120,59 @@ sys_init() * parent process. */ parent_pid = getppid(); + + /* + * Open the ppp device. + */ + pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0); + if (pppfd < 0) { + syslog(LOG_ERR, "Can't open /dev/ppp: %m"); + die(1); + } + if (kdebugflag) { + x = PPPDBG_LOG + PPPDBG_DRIVER; + strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); + } + + /* Assign a new PPA and get its unit number. */ + if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) { + syslog(LOG_ERR, "Can't create new PPP interface: %m"); + die(1); + } + + /* + * Open the ppp device again and push the if_ppp module on it. + */ + iffd = open("/dev/ppp", O_RDWR, 0); + if (iffd < 0) { + syslog(LOG_ERR, "Can't open /dev/ppp (2): %m"); + die(1); + } + if (kdebugflag) { + x = PPPDBG_LOG + PPPDBG_DRIVER; + strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0); + } + if (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0) { + syslog(LOG_ERR, "Couldn't attach ppp interface to device: %m"); + die(1); + } + if (ioctl(iffd, I_PUSH, "if_ppp") < 0) { + syslog(LOG_ERR, "Can't push ppp interface module: %m"); + die(1); + } + if (kdebugflag) { + x = PPPDBG_LOG + PPPDBG_IF; + strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0); + } + if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0) { + syslog(LOG_ERR, "Couldn't create ppp interface unit: %m"); + die(1); + } + x = PPP_IP; + if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0) { + syslog(LOG_ERR, "Couldn't bind ppp interface to IP SAP: %m"); + die(1); + } } /* @@ -126,8 +183,6 @@ sys_init() void sys_cleanup() { - struct ifreq ifr; - if (if_is_up) sifdown(0); if (default_route_gateway) @@ -136,6 +191,27 @@ sys_cleanup() cifproxyarp(0, proxy_arp_addr); } +/* + * sys_close - Clean up in a child process before execing. + */ +void +sys_close() +{ + close(iffd); + close(pppfd); + close(sockfd); + closelog(); +} + +/* + * sys_check_options - check the options that the user specified + */ +void +sys_check_options() +{ +} + + /* * daemon - Detach us from controlling terminal session. */ @@ -167,7 +243,6 @@ void note_debug_level() { if (debug) { - syslog(LOG_INFO, "Debug turned ON, Level %d", debug); setlogmask(LOG_UPTO(LOG_DEBUG)); } else { setlogmask(LOG_UPTO(LOG_WARNING)); @@ -189,60 +264,10 @@ ppp_available() * establish_ppp - Turn the serial port into a ppp interface. */ void -establish_ppp() +establish_ppp(fd) + int fd; { - int i, x; - struct ifreq ifr; - - pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0); - if (pppfd < 0) { - syslog(LOG_ERR, "Can't open /dev/ppp: %m"); - die(1); - } - if (kdebugflag) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - - /* Assign a new PPA and get its unit number. */ - if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) { - syslog(LOG_ERR, "Can't create new PPP interface: %m"); - die(1); - } - - /* - * Open the ppp device again and push the if_ppp module on it. - */ - iffd = open("/dev/ppp", O_RDWR, 0); - if (iffd < 0) { - syslog(LOG_ERR, "Can't open /dev/ppp (2): %m"); - die(1); - } - if (kdebugflag) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - if (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0) { - syslog(LOG_ERR, "Couldn't attach ppp interface to device: %m"); - die(1); - } - if (ioctl(iffd, I_PUSH, "if_ppp") < 0) { - syslog(LOG_ERR, "Can't push ppp interface module: %m"); - die(1); - } - if (kdebugflag) { - x = PPPDBG_LOG + PPPDBG_IF; - strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0) { - syslog(LOG_ERR, "Couldn't create ppp interface unit: %m"); - die(1); - } - x = PPP_IP; - if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0) { - syslog(LOG_ERR, "Couldn't bind ppp interface to IP SAP: %m"); - die(1); - } + int i; /* Pop any existing modules off the tty stream. */ for (i = 0;; ++i) @@ -266,21 +291,25 @@ establish_ppp() syslog(LOG_ERR, "Can't link tty to PPP mux: %m"); die(1); } +} - do { - char buf[PPP_MRU]; - - i = read(fd, buf, PPP_MRU); - syslog(LOG_DEBUG, "read %d bytes from fd", i); - } while (i > 0); +/* + * restore_loop - reattach the ppp unit to the loopback. + * This doesn't need to do anything because disestablish_ppp does it. + */ +void +restore_loop() +{ } /* * disestablish_ppp - Restore the serial port to normal operation. - * This shouldn't call die() because it's called from die(). + * It attempts to reconstruct the stream with the previously popped + * modules. This shouldn't call die() because it's called from die(). */ void -disestablish_ppp() +disestablish_ppp(fd) + int fd; { int i; @@ -314,6 +343,38 @@ disestablish_ppp() } } +/* + * Check whether the link seems not to be 8-bit clean. + */ +void +clean_check() +{ + int x; + char *s; + + if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0) + return; + s = NULL; + switch (~x) { + case RCV_B7_0: + s = "bit 7 set to 1"; + break; + case RCV_B7_1: + s = "bit 7 set to 0"; + break; + case RCV_EVNP: + s = "odd parity"; + break; + case RCV_ODDP: + s = "even parity"; + break; + } + if (s != NULL) { + syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); + syslog(LOG_WARNING, "All received characters had %s", s); + } +} + /* * List of valid speeds. */ @@ -497,7 +558,8 @@ set_up_tty(fd, local) * restore_tty - restore the terminal to the saved settings. */ void -restore_tty() +restore_tty(fd) + int fd; { if (restore_term) { if (!default_device) { @@ -530,6 +592,16 @@ int fd, on; ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); } +/* + * open_loopback - open the device we use for getting packets + * in demand mode. Under Solaris 2, we use our existing fd + * to the ppp driver. + */ +void +open_ppp_loopback() +{ +} + /* * output - Output PPP packet. */ @@ -548,18 +620,20 @@ output(unit, p, len) data.len = len; data.buf = (caddr_t) p; + retries = 4; while (putmsg(pppfd, NULL, &data, 0) < 0) { if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) { if (errno != ENXIO) syslog(LOG_ERR, "Couldn't send packet: %m"); break; } - pfd.fd = fd; + pfd.fd = pppfd; pfd.events = POLLOUT; poll(&pfd, 1, 250); /* wait for up to 0.25 seconds */ } } + /* * wait_input - wait until there is data available on fd, * for the length of time specified by *timo (indefinite @@ -581,6 +655,34 @@ wait_input(timo) } } +/* + * wait_loop_output - wait until there is data available on the + * loopback, for the length of time specified by *timo (indefinite + * if timo is NULL). + */ +wait_loop_output(timo) + struct timeval *timo; +{ + wait_input(timo); +} + +/* + * wait_time - wait for a given length of time or until a + * signal is received. + */ +wait_time(timo) + struct timeval *timo; +{ + int n; + + n = select(0, NULL, NULL, NULL, timo); + if (n < 0 && errno != EINTR) { + syslog(LOG_ERR, "select: %m"); + die(1); + } +} + + /* * read_packet - get a PPP packet from the serial device. */ @@ -618,6 +720,24 @@ read_packet(buf) } } +/* + * get_loop_output - get outgoing packets from the ppp device, + * and detect when we want to bring the real link up. + * Return value is 1 if we need to bring up the link, 0 otherwise. + */ +int +get_loop_output() +{ + int len; + int rv = 0; + + while ((len = read_packet(inpacket_buf)) > 0) { + if (loop_frame(inpacket_buf, len)) + rv = 1; + } + return rv; +} + /* * ppp_send_config - configure the transmit characteristics of * the ppp interface. @@ -720,6 +840,18 @@ ccp_flags_set(unit, isopen, isup) } } +/* + * get_idle_time - return how long the link has been idle. + */ +int +get_idle_time(u, ip) + int u; + struct ppp_idle *ip; +{ + return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0; +} + + /* * ccp_fatal_error - returns 1 if decompression was disabled as a * result of an error detected after decompression of a packet, @@ -817,6 +949,26 @@ sifdown(u) return 1; } +/* + * sifnpmode - Set the mode for handling packets for a given NP. + */ +int +sifnpmode(u, proto, mode) + int u; + int proto; + enum NPmode mode; +{ + int npi[2]; + + npi[0] = proto; + npi[1] = (int) mode; + if (strioctl(pppfd, PPPIO_NPMODE, &npi, 2 * sizeof(int), 0) < 0) { + syslog(LOG_ERR, "ioctl(set NP %d mode to %d): %m", proto, mode); + return 0; + } + return 1; +} + #define INET_ADDR(x) (((struct sockaddr_in *) &(x))->sin_addr.s_addr) /* diff --git a/pppd/sys-svr4.c b/pppd/sys-svr4.c index 716c2bd..cccfeaa 100644 --- a/pppd/sys-svr4.c +++ b/pppd/sys-svr4.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-svr4.c,v 1.8 1995/12/11 05:18:39 paulus Exp $"; +static char rcsid[] = "$Id: sys-svr4.c,v 1.9 1996/01/01 23:06:39 paulus Exp $"; #endif #include @@ -78,6 +78,8 @@ static struct termiox inittermiox; static struct winsize wsinfo; /* Initial window size info */ static pid_t tty_sid; /* original session ID for terminal */ +extern u_char inpacket_buf[]; /* borrowed from main.c */ + static int link_mtu, link_mru; #define NMODULES 32 @@ -104,6 +106,15 @@ static int strioctl __P((int, int, void *, int, int)); void sys_init() { + int ifd, x; +#ifndef sun + struct ifreq ifr; + struct { + union DL_primitives prim; + char space[64]; + } reply; +#endif + openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); setlogmask(LOG_UPTO(LOG_INFO)); if (debug) @@ -114,6 +125,70 @@ sys_init() syslog(LOG_ERR, "Couldn't open IP device: %m"); die(1); } + + if (default_device) + tty_sid = getsid((pid_t)0); + + pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0); + if (pppfd < 0) { + syslog(LOG_ERR, "Can't open /dev/ppp: %m"); + die(1); + } + if (kdebugflag) { + x = PPPDBG_LOG + PPPDBG_DRIVER; + strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); + } + + /* Assign a new PPA and get its unit number. */ + if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) { + syslog(LOG_ERR, "Can't create new PPP interface: %m"); + die(1); + } + + /* + * Open the ppp device again and link it under the ip multiplexor. + * IP will assign a unit number which hopefully is the same as ifunit. + * I don't know any way to be certain they will be the same. :-( + */ + ifd = open("/dev/ppp", O_RDWR, 0); + if (ifd < 0) { + syslog(LOG_ERR, "Can't open /dev/ppp (2): %m"); + die(1); + } + if (kdebugflag) { + x = PPPDBG_LOG + PPPDBG_DRIVER; + strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0); + } +#ifdef sun + if (ioctl(ifd, I_PUSH, "ip") < 0) { + syslog(LOG_ERR, "Can't push IP module: %m"); + close(ifd); + die(1); + } +#else + if (dlpi_attach(ifd, ifunit) < 0 || + dlpi_get_reply(ifd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0) { + syslog(LOG_ERR, "Can't attach to ppp%d: %m", ifunit); + close(ifd); + die(1); + } +#endif + ipmuxid = ioctl(ipfd, I_LINK, ifd); + close(ifd); + if (ipmuxid < 0) { + syslog(LOG_ERR, "Can't link PPP device to IP: %m"); + die(1); + } + +#ifndef sun + /* Set the interface name for the link. */ + (void) sprintf (ifr.ifr_name, "ppp%d", ifunit); + ifr.ifr_metric = ipmuxid; + if (strioctl(ipfd, SIOCSIFNAME, (char *)&ifr, sizeof ifr, 0) < 0) { + syslog(LOG_ERR, "Can't set interface name %s: %m", ifr.ifr_name); + die(1); + } +#endif } /* @@ -134,6 +209,27 @@ sys_cleanup() cifproxyarp(0, proxy_arp_addr); } +/* + * sys_close - Clean up in a child process before execing. + */ +void +sys_close() +{ + close(ipfd); + if (pppfd >= 0) + close(pppfd); + closelog(); +} + +/* + * sys_check_options - check the options that the user specified + */ +void +sys_check_options() +{ +} + + /* * daemon - Detach us from controlling terminal session. */ @@ -165,7 +261,6 @@ void note_debug_level() { if (debug) { - syslog(LOG_INFO, "Debug turned ON, Level %d", debug); setlogmask(LOG_UPTO(LOG_DEBUG)); } else { setlogmask(LOG_UPTO(LOG_WARNING)); @@ -187,80 +282,10 @@ ppp_available() * establish_ppp - Turn the serial port into a ppp interface. */ void -establish_ppp() +establish_ppp(fd) + int fd; { - int i, ifd, x; -#ifndef sun - struct ifreq ifr; - struct { - union DL_primitives prim; - char space[64]; - } reply; -#endif - - if (default_device) - tty_sid = getsid((pid_t)0); - - pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0); - if (pppfd < 0) { - syslog(LOG_ERR, "Can't open /dev/ppp: %m"); - die(1); - } - if (kdebugflag) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - - /* Assign a new PPA and get its unit number. */ - if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) { - syslog(LOG_ERR, "Can't create new PPP interface: %m"); - die(1); - } - - /* - * Open the ppp device again and link it under the ip multiplexor. - * IP will assign a unit number which hopefully is the same as ifunit. - * I don't know any way to be certain they will be the same. :-( - */ - ifd = open("/dev/ppp", O_RDWR, 0); - if (ifd < 0) { - syslog(LOG_ERR, "Can't open /dev/ppp (2): %m"); - die(1); - } - if (kdebugflag) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0); - } -#ifdef sun - if (ioctl(ifd, I_PUSH, "ip") < 0) { - syslog(LOG_ERR, "Can't push IP module: %m"); - close(ifd); - die(1); - } -#else - if (dlpi_attach(ifd, ifunit) < 0 || - dlpi_get_reply(ifd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0) { - syslog(LOG_ERR, "Can't attach to ppp%d: %m", ifunit); - close(ifd); - die(1); - } -#endif - ipmuxid = ioctl(ipfd, I_LINK, ifd); - close(ifd); - if (ipmuxid < 0) { - syslog(LOG_ERR, "Can't link PPP device to IP: %m"); - die(1); - } - -#ifndef sun - /* Set the interface name for the link. */ - (void) sprintf (ifr.ifr_name, "ppp%d", ifunit); - ifr.ifr_metric = ipmuxid; - if (strioctl(ipfd, SIOCSIFNAME, (char *)&ifr, sizeof ifr, 0) < 0) { - syslog(LOG_ERR, "Can't set interface name %s: %m", ifr.ifr_name); - die(1); - } -#endif + int i; /* Pop any existing modules off the tty stream. */ for (i = 0;; ++i) @@ -286,22 +311,26 @@ establish_ppp() } } +/* + * restore_loop - reattach the ppp unit to the loopback. + * This doesn't need to do anything because disestablish_ppp does it. + */ +void +restore_loop() +{ +} + /* * disestablish_ppp - Restore the serial port to normal operation. - * This shouldn't call die() because it's called from die(). + * It attempts to reconstruct the stream with the previously popped + * modules. This shouldn't call die() because it's called from die(). */ void -disestablish_ppp() +disestablish_ppp(fd) + int fd; { int i; - if (ipmuxid > 0) { - if (ioctl(ipfd, I_UNLINK, ipmuxid) < 0) { - if (!hungup) - syslog(LOG_ERR, "Can't unlink PPP from IP: %m"); - } - } - if (fdmuxid >= 0) { if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) { if (!hungup) @@ -330,6 +359,38 @@ disestablish_ppp() } } +/* + * Check whether the link seems not to be 8-bit clean. + */ +void +clean_check() +{ + int x; + char *s; + + if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0) + return; + s = NULL; + switch (~x) { + case RCV_B7_0: + s = "bit 7 set to 1"; + break; + case RCV_B7_1: + s = "bit 7 set to 0"; + break; + case RCV_EVNP: + s = "odd parity"; + break; + case RCV_ODDP: + s = "even parity"; + break; + } + if (s != NULL) { + syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); + syslog(LOG_WARNING, "All received characters had %s", s); + } +} + /* * List of valid speeds. */ @@ -542,7 +603,8 @@ set_up_tty(fd, local) * restore_tty - restore the terminal to the saved settings. */ void -restore_tty() +restore_tty(fd) + int fd; { if (restore_term) { if (!default_device) { @@ -581,6 +643,16 @@ int fd, on; ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); } +/* + * open_loopback - open the device we use for getting packets + * in demand mode. Under Solaris 2, we use our existing fd + * to the ppp driver. + */ +void +open_ppp_loopback() +{ +} + /* * output - Output PPP packet. */ @@ -606,12 +678,13 @@ output(unit, p, len) syslog(LOG_ERR, "Couldn't send packet: %m"); break; } - pfd.fd = fd; + pfd.fd = pppfd; pfd.events = POLLOUT; poll(&pfd, 1, 250); /* wait for up to 0.25 seconds */ } } + /* * wait_input - wait until there is data available on fd, * for the length of time specified by *timo (indefinite @@ -633,6 +706,34 @@ wait_input(timo) } } +/* + * wait_loop_output - wait until there is data available on the + * loopback, for the length of time specified by *timo (indefinite + * if timo is NULL). + */ +wait_loop_output(timo) + struct timeval *timo; +{ + wait_input(timo); +} + +/* + * wait_time - wait for a given length of time or until a + * signal is received. + */ +wait_time(timo) + struct timeval *timo; +{ + int n; + + n = select(0, NULL, NULL, NULL, timo); + if (n < 0 && errno != EINTR) { + syslog(LOG_ERR, "select: %m"); + die(1); + } +} + + /* * read_packet - get a PPP packet from the serial device. */ @@ -663,7 +764,7 @@ read_packet(buf) /* * Got a M_PROTO or M_PCPROTO message. Interpret it - * as a DLPI primitive. + * as a DLPI primitive?? */ if (debug) syslog(LOG_DEBUG, "got dlpi prim 0x%x, len=%d", @@ -672,6 +773,24 @@ read_packet(buf) } } +/* + * get_loop_output - get outgoing packets from the ppp device, + * and detect when we want to bring the real link up. + * Return value is 1 if we need to bring up the link, 0 otherwise. + */ +int +get_loop_output() +{ + int len; + int rv = 0; + + while ((len = read_packet(inpacket_buf)) > 0) { + if (loop_frame(inpacket_buf, len)) + rv = 1; + } + return rv; +} + /* * ppp_send_config - configure the transmit characteristics of * the ppp interface. @@ -774,6 +893,18 @@ ccp_flags_set(unit, isopen, isup) } } +/* + * get_idle_time - return how long the link has been idle. + */ +int +get_idle_time(u, ip) + int u; + struct ppp_idle *ip; +{ + return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0; +} + + /* * ccp_fatal_error - returns 1 if decompression was disabled as a * result of an error detected after decompression of a packet, @@ -871,6 +1002,26 @@ sifdown(u) return 1; } +/* + * sifnpmode - Set the mode for handling packets for a given NP. + */ +int +sifnpmode(u, proto, mode) + int u; + int proto; + enum NPmode mode; +{ + int npi[2]; + + npi[0] = proto; + npi[1] = (int) mode; + if (strioctl(pppfd, PPPIO_NPMODE, &npi, 2 * sizeof(int), 0) < 0) { + syslog(LOG_ERR, "ioctl(set NP %d mode to %d): %m", proto, mode); + return 0; + } + return 1; +} + #define INET_ADDR(x) (((struct sockaddr_in *) &(x))->sin_addr.s_addr) /* -- 2.39.2