X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-osf.c;h=80ce8cbbfc6d8d7576fbb3162e71b3139ee816c4;hp=f11a9961a418056e3dba54c136f87f2e1d07e936;hb=5d490c4106f4a34864c980b925e183cf3bf575e2;hpb=cb6271cf11b1237286e53124dd7a6ac2e24f6671 diff --git a/pppd/sys-osf.c b/pppd/sys-osf.c index f11a996..80ce8cb 100644 --- a/pppd/sys-osf.c +++ b/pppd/sys-osf.c @@ -1,34 +1,81 @@ /* * System-dependent procedures for pppd under Digital UNIX (OSF/1). * - * 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-osf.c,v 1.19 1999/03/16 02:57:06 paulus Exp $"; -#endif +#define RCSID "$Id: sys-osf.c,v 1.32 2002/12/04 23:03:33 paulus Exp $" +#include #include #include #include @@ -61,6 +108,8 @@ static char rcsid[] = "$Id: sys-osf.c,v 1.19 1999/03/16 02:57:06 paulus Exp $"; #include "pppd.h" +static const char rcsid[] = RCSID; + static int pppfd; static int fdmuxid = -1; static int iffd; @@ -200,7 +249,7 @@ sys_check_options() return 1; } - +#if 0 /* * daemon - Detach us from controlling terminal session. */ @@ -224,19 +273,7 @@ daemon(nochdir, noclose) } return 0; } - -/* - * note_debug_level - note a change in the debug level. - */ -void -note_debug_level() -{ - if (debug) { - setlogmask(LOG_UPTO(LOG_DEBUG)); - } else { - setlogmask(LOG_UPTO(LOG_WARNING)); - } -} +#endif /* * ppp_available - check whether the system has any ppp interfaces @@ -344,7 +381,7 @@ streamify(int fd) /* * establish_ppp - Turn the serial port into a ppp interface. */ -void +int establish_ppp(fd) int fd; { @@ -387,15 +424,25 @@ establish_ppp(fd) if (i != fd && i != sockfd) close(i); closed_stdio = 1; + /* make sure 0, 1, 2 are open to /dev/null */ + while ((i = open("/dev/null", O_RDWR)) >= 0) { + if (i > 2) { + close(i); + break; + } + } } /* * Set device for non-blocking reads. + * XXX why do we need to do this? don't we use pppfd not fd? */ if ((initfdflags = fcntl(fd, F_GETFL)) == -1 || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { warn("Couldn't set device to non-blocking mode: %m"); } + + return pppfd; } /* @@ -704,12 +751,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 Digital Unix, we use our existing fd * to the ppp driver. */ -void +int open_ppp_loopback() { + return pppfd; } /* @@ -763,7 +811,8 @@ wait_input(timo) /* * add_fd - add an fd to the set that wait_input waits for. */ -void add_fd(int fd) +void add_fd(fd) + int fd; { int n; @@ -781,7 +830,8 @@ void add_fd(int fd) /* * remove_fd - remove an fd from the set that wait_input waits for. */ -void remove_fd(int fd) +void remove_fd(fd) + int fd; { int n; @@ -808,11 +858,13 @@ wait_loop_output(timo) wait_input(timo); } +#endif + /* * wait_time - wait for a given length of time or until a - * signal is received. + * signal is received. Called by ccp_test */ -void +static void wait_time(timo) struct timeval *timo; { @@ -822,7 +874,6 @@ wait_time(timo) if (n < 0 && errno != EINTR) fatal("select: %m"); } -#endif /* * read_packet - get a PPP packet from the serial device. @@ -843,7 +894,7 @@ read_packet(buf) flags = 0; len = getmsg(pppfd, &ctrl, &data, &flags); if (len < 0) { - if (errno = EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) return -1; fatal("Error reading packet: %m"); } @@ -1018,6 +1069,25 @@ 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; + return 1; +} + /* * ccp_fatal_error - returns 1 if decompression was disabled as a @@ -1077,7 +1147,7 @@ sifup(u) { struct ifreq ifr; - strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { error("Couldn't mark interface up (get): %m"); return 0; @@ -1100,7 +1170,8 @@ sifdown(u) { struct ifreq ifr; - strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); + bzero(&ifr, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { error("Couldn't mark interface down (get): %m"); return 0; @@ -1163,7 +1234,7 @@ sifaddr(u, o, h, m) /* flush old address, if any */ bzero(&ifr, sizeof (ifr)); - strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; if ((ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0) @@ -1173,7 +1244,7 @@ sifaddr(u, o, h, m) } bzero(&addreq, sizeof (addreq)); - strlcpy(addreq.ifra_name, sizeof (addreq.ifra_name), ifname); + strlcpy(addreq.ifra_name, ifname, sizeof (addreq.ifra_name)); SET_SA_FAMILY(addreq.ifra_addr, AF_INET); SET_SA_FAMILY(addreq.ifra_broadaddr, AF_INET); ((struct sockaddr_in *)&addreq.ifra_addr)->sin_addr.s_addr = o; @@ -1192,7 +1263,8 @@ sifaddr(u, o, h, m) ret = 0; } - ifr.ifr_metric = link_mtu; + ifr.ifr_data = (caddr_t)&link_mtu; + if (ioctl(sockfd, SIOCSIPMTU, &ifr) < 0) { error("Couldn't set IP MTU: %m"); ret = 0; @@ -1218,7 +1290,7 @@ cifaddr(u, o, h) ifaddrs[0] = 0; ifaddrs[1] = 0; bzero(&ifr, sizeof (ifr)); - strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; if (ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0) { @@ -1368,7 +1440,7 @@ get_ether_addr(ipaddr, hwaddr) * Check that the interface is up, and not point-to-point * or loopback. */ - strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & @@ -1397,7 +1469,7 @@ get_ether_addr(ipaddr, hwaddr) return 0; info("found interface %s for proxy arp", ifr->ifr_name); - strlcpy(ifdevreq.ifr_name, sizeof(ifdevreq.ifr_name), ifr->ifr_name); + strlcpy(ifdevreq.ifr_name, ifr->ifr_name, sizeof(ifdevreq.ifr_name)); if (ioctl(sockfd, (int)SIOCRPHYSADDR, &ifdevreq) < 0) { perror("ioctl(SIOCRPHYSADDR)"); @@ -1422,9 +1494,9 @@ logwtmp(line, name, host) if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { - strlcpy(ut.ut_line, sizeof(ut.ut_line), line); - strlcpy(ut.ut_name, sizeof(ut.ut_name), name); - strlcpy(ut.ut_host, sizeof(ut.ut_host), 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); @@ -1481,7 +1553,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->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)) @@ -1511,61 +1583,7 @@ GetMask(addr) */ int have_route_to(u_int32_t addr) { - char buf[sizeof(struct rt_msghdr) + (sizeof(struct sockaddr_in))]; - int status; - int s, n; - struct rt_msghdr *rtm; - struct sockaddr_in *sin; - int msglen = sizeof(*rtm) + (sizeof(*sin)); - char *cp; - char msg[2048]; - - rtm = (struct rt_msghdr *)buf; - memset(rtm, 0, msglen); - rtm->rtm_msglen = msglen; - rtm->rtm_version = RTM_VERSION; - rtm->rtm_type = RTM_GET; - rtm->rtm_addrs = RTA_DST; - /* rtm->rtm_addrs, rtm_flags should be set on output */ - - sin = (struct sockaddr_in *)((u_char *)rtm + sizeof(*rtm)); - sin->sin_len = sizeof(*sin); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = addr; - - status = 0; - - if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) - return -1; - if (write(s, (char *)rtm, msglen) != msglen) { - close(s); - return status == ESRCH? 0: -1; - } - - n = read(s, msg, 2048); - close(s); - if (n <= 0) - return -1; - - rtm = (struct rt_msghdr *) msg; - if (rtm->rtm_version != RTM_VERSION) - return -1; - - /* here we try to work out if the route is through our own interface */ - cp = (char *)(rtm + 1); - if (rtm->rtm_addrs & RTA_DST) { - struct sockaddr *sa = (struct sockaddr *) cp; - cp = (char *)(((unsigned long)cp + sa->sa_len - + sizeof(long) - 1) & ~(sizeof(long) - 1)); - } - if (rtm->rtm_addrs & RTA_GATEWAY) { - sin = (struct sockaddr_in *) cp; - if (sin->sin_addr.s_addr == ifaddrs[0] - || sin->sin_addr.s_addr == ifaddrs[1]) - return 0; /* route is through our interface */ - } - - return 1; + return -1; } static int @@ -1596,6 +1614,57 @@ get_host_seed() return gethostid(); } +/* + * 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; +} + +#if 0 /* * Code for locking/unlocking the serial device. * This code is derived from chat.c. @@ -1699,6 +1768,7 @@ unlock() lock_file = NULL; } } +#endif int set_filters(pass, active)