* sys-bsd.c - System-dependent procedures for setting up
* PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.)
*
- * Copyright (c) 1989 Carnegie Mellon University.
- * Copyright (c) 1995 The Australian National University.
- * All rights reserved.
+ * Copyright (c) 1993-2002 Paul Mackerras. All rights reserved.
*
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University and The Australian National University.
- * The names of the Universities may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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(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
+ * <paulus@samba.org>".
+ *
+ * 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-bsd.c,v 1.37 1999/03/16 02:57:06 paulus Exp $";
+#define RCSID "$Id: sys-bsd.c,v 1.49 2002/12/06 12:06:45 paulus Exp $"
/* $NetBSD: sys-bsd.c,v 1.1.1.3 1997/09/26 18:53:04 christos Exp $ */
-#endif
/*
* TODO:
#include "fsm.h"
#include "ipcp.h"
+static const char rcsid[] = RCSID;
+
static int initdisc = -1; /* Initial TTY discipline for ppp_fd */
static int initfdflags = -1; /* Initial file descriptor flags for ppp_fd */
static int ppp_fd = -1; /* fd which is set to PPP discipline */
static struct termios inittermios; /* Initial TTY termios */
static struct winsize wsinfo; /* Initial window size info */
-static char *lock_file; /* name of lock file created */
-
static int loop_slave = -1;
static int loop_master;
static char loop_name[20];
struct ifreq ifr;
if (if_is_up) {
- strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0
&& ((ifr.ifr_flags & IFF_UP) != 0)) {
ifr.ifr_flags &= ~IFF_UP;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
return 1; /* can't tell */
- strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0");
+ strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
close(s);
/*
* establish_ppp - Turn the serial port into a ppp interface.
*/
-void
+int
establish_ppp(fd)
int fd;
{
/*
* Find out which interface we were given.
*/
- if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) {
+ if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0)
fatal("ioctl(PPPIOCGUNIT): %m");
} else {
/*
* Check that we got the same unit again.
*/
- if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
+ if (ioctl(fd, PPPIOCGUNIT, &x) < 0)
fatal("ioctl(PPPIOCGUNIT): %m");
if (x != ifunit)
fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
|| fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
warn("Couldn't set device to non-blocking mode: %m");
}
+
+ return fd;
}
/*
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
}
+/*
+ * 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;
+{
+ struct termios tios;
+
+ if (openpty(master_fdp, slave_fdp, slave_name, NULL, NULL) < 0)
+ return 0;
+
+ fchown(*slave_fdp, uid, -1);
+ fchmod(*slave_fdp, S_IRUSR | S_IWUSR);
+ if (tcgetattr(*slave_fdp, &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(*slave_fdp, TCSAFLUSH, &tios) < 0)
+ warn("couldn't set attributes on pty: %m");
+ } else
+ warn("couldn't get attributes on pty: %m");
+
+ return 1;
+}
+
/*
* open_ppp_loopback - open the device we use for getting
* packets in demand mode, and connect it to a ppp interface.
* Here we use a pty.
*/
-void
+int
open_ppp_loopback()
{
int flags;
}
}
+ return loop_master;
}
/*
* add_fd - add an fd to the set that wait_input waits for.
*/
-void add_fd(int fd)
+void add_fd(fd)
+ int fd;
{
+ if (fd >= FD_SETSIZE)
+ fatal("internal error: file descriptor too large (%d)", fd);
FD_SET(fd, &in_fds);
if (fd > max_in_fd)
max_in_fd = 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;
{
FD_CLR(fd, &in_fds);
}
int n;
FD_ZERO(&ready);
+ if (loop_master >= FD_SETSIZE)
+ fatal("internal error: file descriptor too large (%d)", loop_master);
FD_SET(loop_master, &ready);
n = select(loop_master + 1, &ready, NULL, &ready, timo);
if (n < 0 && errno != EINTR)
u_int x;
struct ifreq ifr;
- strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
+ strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
ifr.ifr_mtu = mtu;
if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
fatal("ioctl(SIOCSIFMTU): %m");
fatal("ioctl (PPPIOCGFLAGS): %m");
x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT;
x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC;
+ x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0)
fatal("ioctl(PPPIOCSFLAGS): %m");
}
return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0;
}
+/*
+ * get_ppp_stats - return statistics for the link.
+ */
+int
+get_ppp_stats(u, stats)
+ int u;
+ struct pppd_stats *stats;
+{
+ struct ifpppstatsreq req;
+
+ memset (&req, 0, sizeof (req));
+ strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name));
+ if (ioctl(sockfd, SIOCGPPPSTATS, &req) < 0) {
+ error("Couldn't get PPP statistics: %m");
+ return 0;
+ }
+ stats->bytes_in = req.stats.p.ppp_ibytes;
+ stats->bytes_out = req.stats.p.ppp_obytes;
+ return 1;
+}
+
#ifdef PPP_FILTER
/*
{
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, (caddr_t) &ifr) < 0) {
error("ioctl (SIOCGIFFLAGS): %m");
return 0;
ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi);
/* ignore errors, because ppp_fd might have been closed by now. */
- strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
+ strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
error("ioctl (SIOCGIFFLAGS): %m");
rv = 0;
struct ifaliasreq ifra;
struct ifreq ifr;
- strlcpy(ifra.ifra_name, sizeof(ifra.ifra_name), ifname);
+ strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
} else
BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));
BZERO(&ifr, sizeof(ifr));
- strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) {
if (errno != EADDRNOTAVAIL)
warn("Couldn't remove interface address: %m");
struct ifaliasreq ifra;
ifaddrs[0] = 0;
- strlcpy(ifra.ifra_name, sizeof(ifra.ifra_name), ifname);
+ strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
SET_SA_FAMILY(ifra.ifra_addr, AF_INET);
((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;
SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);
((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {
if (ifr->ifr_addr.sa_family == AF_INET) {
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
- strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name);
+ strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
/*
* Check that the interface is up, and not point-to-point
* or loopback.
/*
* 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))
return gethostid();
}
+#if 0
/*
* lock - create a lock file for the named lock device
*/
#define LOCK_PREFIX "/var/spool/lock/LCK.."
+static char *lock_file; /* name of lock file created */
+
int
lock(dev)
char *dev;
lock_file = NULL;
}
}
+#endif