X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-sunos4.c;h=2097c8afa5a3eca0f6804bf1bd5d731cd19b3538;hp=730e0a78017e145e0fe18144edb0d1184fa55f94;hb=0943e83e5acfcd6f1e7f67b2c3ca634f816e2ae3;hpb=9420784901517dbd06185b874d2a2bed3b8f6e25 diff --git a/pppd/sys-sunos4.c b/pppd/sys-sunos4.c index 730e0a7..2097c8a 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.5 1996/05/27 00:00:56 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 @@ -82,6 +84,7 @@ static int tty_nmodules; static char tty_modules[NMODULES][FMNAMESZ+1]; static int if_is_up; /* Interface has been marked up */ +static u_int32_t ifaddrs[2]; /* local and remote addresses */ static u_int32_t default_route_gateway; /* Gateway for default route added */ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ @@ -98,10 +101,7 @@ static int strioctl __P((int, int, void *, int, int)); void sys_init() { - openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); - setlogmask(LOG_UPTO(LOG_INFO)); - if (debug) - setlogmask(LOG_UPTO(LOG_DEBUG)); + int x; /* Get an internet socket for doing socket ioctl's on. */ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { @@ -116,26 +116,99 @@ 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); + } } /* * sys_cleanup - restore any system state we modified before exiting: * mark the interface down, delete default route and/or proxy arp entry. - * This should call die() because it's called from die(). + * This shouldn't call die() because it's called from die(). */ void sys_cleanup() { - struct ifreq ifr; - if (if_is_up) sifdown(0); + if (ifaddrs[0]) + cifaddr(0, ifaddrs[0], ifaddrs[1]); if (default_route_gateway) cifdefaultroute(0, default_route_gateway); if (proxy_arp_addr) cifproxyarp(0, proxy_arp_addr); } +/* + * sys_close - Clean up in a child process before execing. + */ +void +sys_close() +{ + close(iffd); + close(pppfd); + close(sockfd); +} + +/* + * sys_check_options - check the options that the user specified + */ +void +sys_check_options() +{ +} + + /* * daemon - Detach us from controlling terminal session. */ @@ -160,20 +233,6 @@ daemon(nochdir, noclose) return 0; } -/* - * note_debug_level - note a change in the debug level. - */ -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)); - } -} - /* * ppp_available - check whether the system has any ppp interfaces */ @@ -189,60 +248,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 +275,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 +327,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 +542,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 +576,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 +604,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 +639,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. */ @@ -618,6 +706,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 +826,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 +935,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) /* @@ -832,6 +970,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(sockfd, 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(sockfd, SIOCSIFADDR, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set local IP address: %m"); @@ -841,15 +984,12 @@ sifaddr(u, o, h, m) if (ioctl(sockfd, 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(sockfd, SIOCSIFNETMASK, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't set IP netmask: %m"); - } ifr.ifr_metric = link_mtu; if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set IP MTU: %m"); } + ifaddrs[0] = o; + ifaddrs[1] = h; return 1; } @@ -865,12 +1005,15 @@ cifaddr(u, o, h) { struct rtentry rt; + bzero(&rt, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = h; rt.rt_gateway.sa_family = AF_INET; INET_ADDR(rt.rt_gateway) = o; rt.rt_flags = RTF_HOST; - ioctl(sockfd, SIOCDELRT, &rt); + if (ioctl(sockfd, SIOCDELRT, &rt) < 0) + syslog(LOG_ERR, "Couldn't delete route through interface: %m"); + ifaddrs[0] = 0; return 1; } @@ -884,6 +1027,7 @@ sifdefaultroute(u, g) { struct rtentry rt; + bzero(&rt, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; rt.rt_gateway.sa_family = AF_INET; @@ -909,6 +1053,7 @@ cifdefaultroute(u, g) { struct rtentry rt; + bzero(&rt, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; rt.rt_gateway.sa_family = AF_INET; @@ -1279,3 +1424,21 @@ strtoul(str, ptr, base) { return (unsigned long) strtol(str, ptr, base); } + +/* + * Or strerror :-( + */ +extern char *sys_errlist[]; +extern int sys_nerr; + +char * +strerror(n) + int n; +{ + static char unknown[32]; + + if (n > 0 && n < sys_nerr) + return sys_errlist[n]; + sprintf(unknown, "Error %d", n); + return unknown; +}