X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-sunos4.c;h=f4cabda3ff90c1c54bf7acbfccdcf576337ad3fa;hp=75bc29f4552665f14f376b271ed56849b8015528;hb=f7f3636134176758c561855d77fb165646949916;hpb=baef0b4051b99779132e712a304c0fe52ab9042e diff --git a/pppd/sys-sunos4.c b/pppd/sys-sunos4.c index 75bc29f..f4cabda 100644 --- a/pppd/sys-sunos4.c +++ b/pppd/sys-sunos4.c @@ -1,33 +1,79 @@ /* * System-dependent procedures for pppd under SunOS 4. * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Derived from main.c and pppd.h, which are: + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef lint -static char rcsid[] = "$Id: sys-sunos4.c,v 1.12 1999/03/08 05:34:46 paulus Exp $"; -#endif +#define RCSID "$Id: sys-sunos4.c,v 1.32 2003/04/07 00:01:46 paulus Exp $" #include #include @@ -47,7 +93,6 @@ static char rcsid[] = "$Id: sys-sunos4.c,v 1.12 1999/03/08 05:34:46 paulus Exp $ #include #include #include -#include #include #include #include @@ -68,6 +113,8 @@ extern void *alloca(); #endif #endif /*sparc*/ +static const char rcsid[] = RCSID; + static int pppfd; static int fdmuxid = -1; static int iffd; @@ -80,6 +127,10 @@ static pid_t parent_pid; /* PID of our parent */ extern u_char inpacket_buf[]; /* borrowed from main.c */ +#define MAX_POLLFDS 32 +static struct pollfd pollfds[MAX_POLLFDS]; +static int n_pollfds; + static int link_mtu, link_mru; #define NMODULES 32 @@ -107,10 +158,8 @@ sys_init() int x; /* Get an internet socket for doing socket ioctl's on. */ - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "Couldn't create IP socket: %m"); - die(1); - } + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + fatal("Couldn't create IP socket: %m"); /* * We may want to send a SIGHUP to the session leader associated @@ -124,54 +173,42 @@ sys_init() * 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 (pppfd < 0) + fatal("Can't open /dev/ppp: %m"); 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); - } + if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) + fatal("Can't create new PPP interface: %m"); /* * 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 (iffd < 0) + fatal("Can't open /dev/ppp (2): %m"); 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 (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0) + fatal("Couldn't attach ppp interface to device: %m"); + if (ioctl(iffd, I_PUSH, "if_ppp") < 0) + fatal("Can't push ppp interface module: %m"); 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); - } + if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0) + fatal("Couldn't create ppp interface unit: %m"); 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); - } + if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0) + fatal("Couldn't bind ppp interface to IP SAP: %m"); + + n_pollfds = 0; } /* @@ -212,7 +249,7 @@ sys_check_options() return 1; } - +#if 0 /* * daemon - Detach us from controlling terminal session. */ @@ -236,6 +273,7 @@ daemon(nochdir, noclose) } return 0; } +#endif /* * ppp_available - check whether the system has any ppp interfaces @@ -249,10 +287,10 @@ ppp_available() } /* - * establish_ppp - Turn the serial port into a ppp interface. + * tty_establish_ppp - Turn the serial port into a ppp interface. */ -void -establish_ppp(fd) +int +tty_establish_ppp(fd) int fd; { int i; @@ -265,29 +303,16 @@ establish_ppp(fd) tty_nmodules = i; /* Push the async hdlc module and the compressor module. */ - if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0) { - syslog(LOG_ERR, "Couldn't push PPP Async HDLC module: %m"); - die(1); - } - if (ioctl(fd, I_PUSH, "ppp_comp") < 0) { - syslog(LOG_ERR, "Couldn't push PPP compression module: %m"); -/* die(1); */ - } + if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0) + fatal("Couldn't push PPP Async HDLC module: %m"); + if (ioctl(fd, I_PUSH, "ppp_comp") < 0) + error("Couldn't push PPP compression module: %m"); /* Link the serial port under the PPP multiplexor. */ - if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) { - syslog(LOG_ERR, "Can't link tty to PPP mux: %m"); - die(1); - } -} + if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) + fatal("Can't link tty to PPP mux: %m"); -/* - * restore_loop - reattach the ppp unit to the loopback. - * This doesn't need to do anything because disestablish_ppp does it. - */ -void -restore_loop() -{ + return pppfd; } /* @@ -296,7 +321,7 @@ restore_loop() * modules. This shouldn't call die() because it's called from die(). */ void -disestablish_ppp(fd) +tty_disestablish_ppp(fd) int fd; { int i; @@ -304,7 +329,7 @@ disestablish_ppp(fd) if (fdmuxid >= 0) { if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) { if (!hungup) - syslog(LOG_ERR, "Can't unlink tty from PPP mux: %m"); + error("Can't unlink tty from PPP mux: %m"); } fdmuxid = -1; @@ -313,7 +338,7 @@ disestablish_ppp(fd) ; for (i = tty_nmodules - 1; i >= 0; --i) if (ioctl(fd, I_PUSH, tty_modules[i]) < 0) - syslog(LOG_ERR, "Couldn't restore tty module %s: %m", + error("Couldn't restore tty module %s: %m", tty_modules[i]); } if (hungup && default_device && parent_pid > 0) { @@ -358,8 +383,8 @@ clean_check() break; } if (s != NULL) { - syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); - syslog(LOG_WARNING, "All received characters had %s", s); + warn("Serial link is not 8-bit clean:"); + warn("All received characters had %s", s); } } @@ -452,7 +477,7 @@ translate_speed(bps) for (speedp = speeds; speedp->speed_int; speedp++) if (bps == speedp->speed_int) return speedp->speed_val; - syslog(LOG_WARNING, "speed %d not supported", bps); + warn("speed %d not supported", bps); return 0; } @@ -485,10 +510,8 @@ set_up_tty(fd, local) int speed; struct termios tios; - if (tcgetattr(fd, &tios) < 0) { - syslog(LOG_ERR, "tcgetattr: %m"); - die(1); - } + if (tcgetattr(fd, &tios) < 0) + fatal("tcgetattr: %m"); if (!restore_term) { inittermios = tios; @@ -526,17 +549,12 @@ set_up_tty(fd, local) * We can't proceed if the serial port speed is 0, * since that implies that the serial port is disabled. */ - if (speed == B0) { - syslog(LOG_ERR, "Baud rate for %s is 0; need explicit baud rate", - devnam); - die(1); - } + if (speed == B0) + fatal("Baud rate for %s is 0; need explicit baud rate", devnam); } - if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { - syslog(LOG_ERR, "tcsetattr: %m"); - die(1); - } + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) + fatal("tcsetattr: %m"); baud_rate = inspeed = baud_rate_of(speed); restore_term = 1; @@ -561,7 +579,7 @@ restore_tty(fd) } if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) if (!hungup && errno != ENXIO) - syslog(LOG_WARNING, "tcsetattr: %m"); + warn("tcsetattr: %m"); ioctl(fd, TIOCSWINSZ, &wsinfo); restore_term = 0; } @@ -582,12 +600,13 @@ int fd, on; /* * open_loopback - open the device we use for getting packets - * in demand mode. Under Solaris 2, we use our existing fd + * in demand mode. Under SunOS, we use our existing fd * to the ppp driver. */ -void +int open_ppp_loopback() { + return pppfd; } /* @@ -603,8 +622,8 @@ output(unit, p, len) int retries; struct pollfd pfd; - if (debug) - log_packet(p, len, "sent ", LOG_DEBUG); + dump_packet("sent", p, len); + if (snoop_send_hook) snoop_send_hook(p, len); data.len = len; data.buf = (caddr_t) p; @@ -612,7 +631,7 @@ output(unit, p, len) 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"); + error("Couldn't send packet: %m"); break; } pfd.fd = pppfd; @@ -623,7 +642,7 @@ output(unit, p, len) /* - * wait_input - wait until there is data available on fd, + * wait_input - wait until there is data available, * for the length of time specified by *timo (indefinite * if timo is NULL). */ @@ -632,17 +651,55 @@ wait_input(timo) struct timeval *timo; { int t; - struct pollfd pfd; t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000; - pfd.fd = pppfd; - pfd.events = POLLIN | POLLPRI | POLLHUP; - if (poll(&pfd, 1, t) < 0 && errno != EINTR) { - syslog(LOG_ERR, "poll: %m"); - die(1); + if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR) { + if (errno != EAGAIN) + fatal("poll: %m"); + /* we can get EAGAIN on a heavily loaded system, + * just wait a short time and try again. */ + usleep(50000); } } +/* + * add_fd - add an fd to the set that wait_input waits for. + */ +void add_fd(fd) + int fd; +{ + int n; + + for (n = 0; n < n_pollfds; ++n) + if (pollfds[n].fd == fd) + return; + if (n_pollfds < MAX_POLLFDS) { + pollfds[n_pollfds].fd = fd; + pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP; + ++n_pollfds; + } else + error("Too many inputs!"); +} + +/* + * remove_fd - remove an fd from the set that wait_input waits for. + */ +void remove_fd(fd) + int fd; +{ + int n; + + for (n = 0; n < n_pollfds; ++n) { + if (pollfds[n].fd == fd) { + while (++n < n_pollfds) + pollfds[n-1] = pollfds[n]; + --n_pollfds; + break; + } + } +} + +#if 0 /* * wait_loop_output - wait until there is data available on the * loopback, for the length of time specified by *timo (indefinite @@ -666,12 +723,10 @@ wait_time(timo) int n; n = select(0, NULL, NULL, NULL, timo); - if (n < 0 && errno != EINTR) { - syslog(LOG_ERR, "select: %m"); - die(1); - } + if (n < 0 && errno != EINTR) + fatal("select: %m"); } - +#endif /* * read_packet - get a PPP packet from the serial device. @@ -692,10 +747,9 @@ read_packet(buf) flags = 0; len = getmsg(pppfd, &ctrl, &data, &flags); if (len < 0) { - if (errno = EAGAIN || errno == EINTR) + if (errno == EAGAIN || errno == EINTR) return -1; - syslog(LOG_ERR, "Error reading packet: %m"); - die(1); + fatal("Error reading packet: %m"); } if (ctrl.len <= 0) @@ -705,7 +759,7 @@ read_packet(buf) * Got a M_PROTO or M_PCPROTO message. Huh? */ if (debug) - syslog(LOG_DEBUG, "got ctrl msg len=%d", ctrl.len); + dbglog("got ctrl msg len=%d", ctrl.len); } } @@ -729,63 +783,71 @@ get_loop_output() } /* - * ppp_send_config - configure the transmit characteristics of - * the ppp interface. + * netif_set_mtu - set the MTU on the PPP network interface. */ void -ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) +netif_set_mtu(unit, mtu) int unit, mtu; +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + ifr.ifr_metric = link_mtu; + if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { + error("Couldn't set IP MTU: %m"); + } +} + +/* + * tty_send_config - configure the transmit characteristics of + * the ppp interface. + */ +int +tty_send_config(mtu, asyncmap, pcomp, accomp) + int mtu; u_int32_t asyncmap; int pcomp, accomp; { int cf[2]; - struct ifreq ifr; link_mtu = mtu; if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) { - if (hungup && errno == ENXIO) + if (hungup && errno == ENXIO) { + ++error_count; return; - syslog(LOG_ERR, "Couldn't set MTU: %m"); - } - if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { - syslog(LOG_ERR, "Couldn't set transmit ACCM: %m"); + } + error("Couldn't set MTU: %m"); } + if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) + error("Couldn't set transmit ACCM: %m"); cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0); cf[1] = COMP_PROT | COMP_AC; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - syslog(LOG_ERR, "Couldn't set prot/AC compression: %m"); - } - - /* set mtu for ip as well */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - ifr.ifr_metric = link_mtu; - if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't set IP MTU: %m"); - } + if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) + error("Couldn't set prot/AC compression: %m"); } /* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. + * tty_set_xaccm - set the extended transmit ACCM for the interface. */ void -ppp_set_xaccm(unit, accm) +tty_set_xaccm(unit, accm) int unit; ext_accm accm; { if (strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) { if (!hungup || errno != ENXIO) - syslog(LOG_WARNING, "Couldn't set extended ACCM: %m"); + warn("Couldn't set extended ACCM: %m"); } } /* - * ppp_recv_config - configure the receive-side characteristics of + * tty_recv_config - configure the receive-side characteristics of * the ppp interface. */ void -ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) - int unit, mru; +tty_recv_config(mru, asyncmap, pcomp, accomp) + int mru; u_int32_t asyncmap; int pcomp, accomp; { @@ -793,18 +855,18 @@ ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) link_mru = mru; if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) { - if (hungup && errno == ENXIO) + if (hungup && errno == ENXIO) { + ++error_count; return; - syslog(LOG_ERR, "Couldn't set MRU: %m"); - } - if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { - syslog(LOG_ERR, "Couldn't set receive ACCM: %m"); + } + error("Couldn't set MRU: %m"); } + if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) + error("Couldn't set receive ACCM: %m"); cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0); cf[1] = DECOMP_PROT | DECOMP_AC; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - syslog(LOG_ERR, "Couldn't set prot/AC decompression: %m"); - } + if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) + error("Couldn't set prot/AC decompression: %m"); } /* @@ -835,7 +897,7 @@ ccp_flags_set(unit, isopen, isup) cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR; if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { if (!hungup || errno != ENXIO) - syslog(LOG_ERR, "Couldn't set kernel CCP state: %m"); + error("Couldn't set kernel CCP state: %m"); } } @@ -850,6 +912,27 @@ get_idle_time(u, ip) return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0; } +/* + * get_ppp_stats - return statistics for the link. + */ +int +get_ppp_stats(u, stats) + int u; + struct pppd_stats *stats; +{ + struct ppp_stats s; + + if (strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) { + error("Couldn't get link statistics: %m"); + return 0; + } + stats->bytes_in = s.p.ppp_ibytes; + stats->bytes_out = s.p.ppp_obytes; + stats->pkts_in = s.p.ppp_ipackets; + stats->pkts_out = s.p.ppp_opackets; + return 1; +} + /* * ccp_fatal_error - returns 1 if decompression was disabled as a @@ -865,7 +948,7 @@ ccp_fatal_error(unit) cf[0] = cf[1] = 0; if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { if (errno != ENXIO && errno != EINVAL) - syslog(LOG_ERR, "Couldn't get compression flags: %m"); + error("Couldn't get compression flags: %m"); return 0; } return cf[0] & CCP_FATALERROR; @@ -885,7 +968,7 @@ sifvjcomp(u, vjcomp, xcidcomp, xmaxcid) maxcid[0] = xcidcomp; maxcid[1] = 15; /* XXX should be rmaxcid */ if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) { - syslog(LOG_ERR, "Couldn't initialize VJ compression: %m"); + error("Couldn't initialize VJ compression: %m"); } } @@ -894,7 +977,7 @@ sifvjcomp(u, vjcomp, xcidcomp, xmaxcid) cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID; if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { if (vjcomp) - syslog(LOG_ERR, "Couldn't enable VJ compression: %m"); + error("Couldn't enable VJ compression: %m"); } return 1; @@ -909,14 +992,14 @@ sifup(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't mark interface up (get): %m"); + error("Couldn't mark interface up (get): %m"); return 0; } ifr.ifr_flags |= IFF_UP; if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't mark interface up (set): %m"); + error("Couldn't mark interface up (set): %m"); return 0; } if_is_up = 1; @@ -932,15 +1015,15 @@ sifdown(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't mark interface down (get): %m"); + error("Couldn't mark interface down (get): %m"); return 0; } if ((ifr.ifr_flags & IFF_UP) != 0) { ifr.ifr_flags &= ~IFF_UP; if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't mark interface down (set): %m"); + error("Couldn't mark interface down (set): %m"); return 0; } } @@ -962,7 +1045,7 @@ sifnpmode(u, proto, mode) 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); + error("ioctl(set NP %d mode to %d): %m", proto, mode); return 0; } return 1; @@ -981,26 +1064,26 @@ sifaddr(u, o, h, m) struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(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"); + error("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"); + error("Couldn't set local IP address: %m"); } ifr.ifr_dstaddr.sa_family = AF_INET; INET_ADDR(ifr.ifr_dstaddr) = h; if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't set remote IP address: %m"); + error("Couldn't set remote IP address: %m"); } #if 0 /* now done in ppp_send_config */ ifr.ifr_metric = link_mtu; if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { - syslog(LOG_ERR, "Couldn't set IP MTU: %m"); + error("Couldn't set IP MTU: %m"); } #endif ifaddrs[0] = o; @@ -1027,7 +1110,7 @@ cifaddr(u, o, h) INET_ADDR(rt.rt_gateway) = o; rt.rt_flags = RTF_HOST; if (ioctl(sockfd, SIOCDELRT, &rt) < 0) - syslog(LOG_ERR, "Couldn't delete route through interface: %m"); + error("Couldn't delete route through interface: %m"); ifaddrs[0] = 0; return 1; } @@ -1050,7 +1133,7 @@ sifdefaultroute(u, l, g) rt.rt_flags = RTF_GATEWAY; if (ioctl(sockfd, SIOCADDRT, &rt) < 0) { - syslog(LOG_ERR, "Can't add default route: %m"); + error("Can't add default route: %m"); return 0; } @@ -1076,7 +1159,7 @@ cifdefaultroute(u, l, g) rt.rt_flags = RTF_GATEWAY; if (ioctl(sockfd, SIOCDELRT, &rt) < 0) { - syslog(LOG_ERR, "Can't delete default route: %m"); + error("Can't delete default route: %m"); return 0; } @@ -1102,7 +1185,7 @@ sifproxyarp(unit, hisaddr) INET_ADDR(arpreq.arp_pa) = hisaddr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ioctl(sockfd, SIOCSARP, (caddr_t) &arpreq) < 0) { - syslog(LOG_ERR, "Couldn't set proxy ARP entry: %m"); + error("Couldn't set proxy ARP entry: %m"); return 0; } @@ -1124,7 +1207,7 @@ cifproxyarp(unit, hisaddr) arpreq.arp_pa.sa_family = AF_INET; INET_ADDR(arpreq.arp_pa) = hisaddr; if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) { - syslog(LOG_ERR, "Couldn't delete proxy ARP entry: %m"); + error("Couldn't delete proxy ARP entry: %m"); return 0; } @@ -1153,7 +1236,7 @@ get_ether_addr(ipaddr, hwaddr) ifc.ifc_len = sizeof(ifs); ifc.ifc_req = ifs; if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { - syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m"); + error("ioctl(SIOCGIFCONF): %m"); return 0; } @@ -1170,7 +1253,7 @@ get_ether_addr(ipaddr, hwaddr) * Check that the interface is up, and not point-to-point * or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & @@ -1194,19 +1277,19 @@ get_ether_addr(ipaddr, hwaddr) if (ifr >= ifend) return 0; - syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name); + info("found interface %s for proxy arp", ifr->ifr_name); /* * Grab the physical address for this interface. */ if ((nit_fd = open("/dev/nit", O_RDONLY)) < 0) { - syslog(LOG_ERR, "Couldn't open /dev/nit: %m"); + error("Couldn't open /dev/nit: %m"); return 0; } - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(nit_fd, NIOCBIND, &ifreq) < 0 || ioctl(nit_fd, SIOCGIFADDR, &ifreq) < 0) { - syslog(LOG_ERR, "Couldn't get hardware address for %s: %m", + error("Couldn't get hardware address for %s: %m", ifreq.ifr_name); close(nit_fd); return 0; @@ -1243,9 +1326,9 @@ logwtmp(line, name, host) if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + strncpy(ut.ut_line, line, sizeof(ut.ut_line)); + strncpy(ut.ut_name, name, sizeof(ut.ut_name)); + strncpy(ut.ut_host, host, sizeof(ut.ut_host)); (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) (void)ftruncate(fd, buf.st_size); @@ -1287,7 +1370,7 @@ GetMask(addr) if (ifc.ifc_req == 0) return mask; if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { - syslog(LOG_WARNING, "Couldn't get system interface list: %m"); + warn("Couldn't get system interface list: %m"); return mask; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); @@ -1303,7 +1386,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1334,7 +1417,7 @@ strioctl(fd, cmd, ptr, ilen, olen) if (ioctl(fd, I_STR, &str) == -1) return -1; if (str.ic_len != olen) - syslog(LOG_DEBUG, "strioctl: expected %d bytes, got %d for cmd %x\n", + dbglog("strioctl: expected %d bytes, got %d for cmd %x\n", olen, str.ic_len, cmd); return 0; } @@ -1348,6 +1431,7 @@ get_host_seed() return gethostid(); } +#if 0 /* * Code for locking/unlocking the serial device. * This code is derived from chat.c. @@ -1378,13 +1462,15 @@ lock(dev) char hdb_lock_buffer[12]; int fd, pid, n; char *p; + size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + l = strlen(LOCK_PREFIX) + strlen(dev) + 1; + lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); - strcat(strcpy(lock_file, LOCK_PREFIX), dev); + slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST @@ -1400,33 +1486,33 @@ lock(dev) n = read(fd, &pid, sizeof(pid)); #endif if (n <= 0) { - syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file); + error("Can't read pid from lock file %s", lock_file); close(fd); } else { if (kill(pid, 0) == -1 && errno == ESRCH) { /* pid no longer exists - remove the lock file */ if (unlink(lock_file) == 0) { close(fd); - syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)", + notice("Removed stale lock on %s (pid %d)", dev, pid); continue; } else - syslog(LOG_WARNING, "Couldn't remove stale lock on %s", + warn("Couldn't remove stale lock on %s", dev); } else - syslog(LOG_NOTICE, "Device %s is locked by pid %d", + notice("Device %s is locked by pid %d", dev, pid); } close(fd); } else - syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file); + error("Can't create lock file %s: %m", lock_file); free(lock_file); lock_file = NULL; return -1; } #ifdef PIDSTRING - sprintf(hdb_lock_buffer, "%10d\n", getpid()); + slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%10d\n", getpid()); write(fd, hdb_lock_buffer, 11); #else pid = getpid(); @@ -1449,6 +1535,57 @@ unlock() lock_file = NULL; } } +#endif /* lock stuff removed */ + +/* + * get_pty - get a pty master/slave pair and chown the slave side + * to the uid given. Assumes slave_name points to >= 12 bytes of space. + */ +int +get_pty(master_fdp, slave_fdp, slave_name, uid) + int *master_fdp; + int *slave_fdp; + char *slave_name; + int uid; +{ + int i, mfd, sfd; + char pty_name[12]; + struct termios tios; + + sfd = -1; + for (i = 0; i < 64; ++i) { + slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", + 'p' + i / 16, i % 16); + mfd = open(pty_name, O_RDWR, 0); + if (mfd >= 0) { + pty_name[5] = 't'; + sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); + if (sfd >= 0) + break; + close(mfd); + } + } + if (sfd < 0) + return 0; + + strlcpy(slave_name, pty_name, 12); + *master_fdp = mfd; + *slave_fdp = sfd; + fchown(sfd, uid, -1); + fchmod(sfd, S_IRUSR | S_IWUSR); + if (tcgetattr(sfd, &tios) == 0) { + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); + tios.c_cflag |= CS8 | CREAD; + tios.c_iflag = IGNPAR | CLOCAL; + tios.c_oflag = 0; + tios.c_lflag = 0; + if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) + warn("couldn't set attributes on pty: %m"); + } else + warn("couldn't get attributes on pty: %m"); + + return 1; +} /* * SunOS doesn't have strtoul :-( @@ -1475,6 +1612,6 @@ strerror(n) if (n > 0 && n < sys_nerr) return sys_errlist[n]; - sprintf(unknown, "Error %d", n); + slprintf(unknown, sizeof(unknown), "Error %d", n); return unknown; }