X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-svr4.c;h=d5c83b3b47c6e244728d7ddf1dad3c0ab2ae729c;hp=4e4006d0af095fdd7529be8d2c07b472227851d3;hb=180cae5bdf14b18322742e60ff5cda13651a8d05;hpb=a1988ee36635f1d72b95c8d783e98b98f003f43d diff --git a/pppd/sys-svr4.c b/pppd/sys-svr4.c index 4e4006d..d5c83b3 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.7 1995/10/27 03:52:56 paulus Exp $"; +static char rcsid[] = "$Id: sys-svr4.c,v 1.10 1996/04/04 04:07:30 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,36 @@ 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). + */ +void +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. + */ +void +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 +766,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 +775,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 +895,45 @@ 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; +} + + +/* + * set_filters - transfer the pass and active filters to the kernel. + */ +int +set_filters(pass, active) + struct bpf_program *pass, *active; +{ + int ret = 1; + + if (pass->bf_len > 0) { + if (strioctl(pppfd, PPPIO_PASSFILT, pass, + sizeof(struct bpf_program), 0) < 0) { + syslog(LOG_ERR, "Couldn't set pass-filter in kernel: %m"); + ret = 0; + } + } + if (active->bf_len > 0) { + if (strioctl(pppfd, PPPIO_ACTIVEFILT, active, + sizeof(struct bpf_program), 0) < 0) { + syslog(LOG_ERR, "Couldn't set active-filter in kernel: %m"); + ret = 0; + } + } + return ret; +} + + /* * ccp_fatal_error - returns 1 if decompression was disabled as a * result of an error detected after decompression of a packet, @@ -871,6 +1031,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) /* @@ -886,6 +1066,11 @@ sifaddr(u, o, h, m) memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); ifr.ifr_addr.sa_family = AF_INET; + INET_ADDR(ifr.ifr_addr) = m; + if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) { + syslog(LOG_ERR, "Couldn't set IP netmask: %m"); + } + ifr.ifr_addr.sa_family = AF_INET; INET_ADDR(ifr.ifr_addr) = o; if (ioctl(ipfd, SIOCSIFADDR, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set local IP address: %m"); @@ -895,11 +1080,6 @@ sifaddr(u, o, h, m) if (ioctl(ipfd, SIOCSIFDSTADDR, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set remote IP address: %m"); } - ifr.ifr_addr.sa_family = AF_INET; - INET_ADDR(ifr.ifr_addr) = m; - if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't set IP netmask: %m"); - } ifr.ifr_metric = link_mtu; if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set IP MTU: %m"); @@ -939,6 +1119,7 @@ sifdefaultroute(u, g) { struct rtentry rt; + memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; rt.rt_gateway.sa_family = AF_INET; @@ -964,6 +1145,7 @@ cifdefaultroute(u, g) { struct rtentry rt; + memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; rt.rt_gateway.sa_family = AF_INET; @@ -1143,10 +1325,12 @@ get_hw_addr(name, hwaddr) adrlen = reply.prim.info_ack.dl_addr_length; adrp = (unsigned char *)&reply + reply.prim.info_ack.dl_addr_offset; +#if DL_CURRENT_VERSION >= 2 if (reply.prim.info_ack.dl_sap_length < 0) adrlen += reply.prim.info_ack.dl_sap_length; else adrp += reply.prim.info_ack.dl_sap_length; +#endif hwaddr->sa_family = AF_UNSPEC; memcpy(hwaddr->sa_data, adrp, adrlen);