static int if_is_up; /* Interface has been marked up */
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 */
+static char proxy_arp_dev[16]; /* Device for proxy arp entry */
static char *lock_file;
static int read_route_table (struct rtentry *rt);
static int defaultroute_exists (struct rtentry *rt);
static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
- char *name);
+ char *name, int namelen);
static void decode_version (char *buf, int *version, int *mod, int *patch);
static int set_kdebugflag(int level);
static int ppp_registered(void);
void
sys_close(void)
{
- close(sock_fd);
- sock_fd = -1;
+ if (sock_fd >= 0)
+ close(sock_fd);
+ if (slave_fd >= 0)
+ close(slave_fd);
+ if (master_fd >= 0)
+ close(master_fd);
closelog();
}
x = get_flags();
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;
set_flags(x);
}
int
get_ppp_stats(u, stats)
int u;
- struct ppp_stats *stats;
+ struct pppd_stats *stats;
{
struct ifpppstatsreq req;
error("Couldn't get PPP statistics: %m");
return 0;
}
- *stats = req.stats;
+ stats->bytes_in = req.stats.p.ppp_ibytes;
+ stats->bytes_out = req.stats.p.ppp_obytes;
return 1;
-}
+}
/********************************************************************
*
* Get the hardware address of an interface on the same subnet
* as our local address.
*/
- if (!get_ether_addr(his_adr, &arpreq.arp_ha, arpreq.arp_dev)) {
+ if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
+ sizeof(proxy_arp_dev))) {
error("Cannot determine ethernet address for proxy ARP");
return 0;
}
-
+ strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
+
if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
if ( ! ok_error ( errno ))
error("ioctl(SIOCSARP): %m(%d)", errno);
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
+ strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
if ( ! ok_error ( errno ))
static int get_ether_addr (u_int32_t ipaddr,
struct sockaddr *hwaddr,
- char *name)
+ char *name, int namelen)
{
struct ifreq *ifr, *ifend;
u_int32_t ina, mask;
if (ifr >= ifend)
return 0;
- memcpy (name, ifreq.ifr_name, sizeof(ifreq.ifr_name));
+ strlcpy(name, ifreq.ifr_name, namelen);
info("found interface %s for proxy arp", name);
/*
* Now get the hardware address.
{
int local_fd;
int init_disc = -1;
- int initfdflags;
-
- local_fd = open(devnam, O_NONBLOCK | O_RDWR, 0);
- if (local_fd < 0) {
- error("Failed to open %s: %m(%d)", devnam, errno);
- return 0;
- }
+ int mfd = -1;
+ int ret = 0;
- initfdflags = fcntl(local_fd, F_GETFL);
- if (initfdflags == -1) {
- error("Couldn't get device fd flags: %m(%d)", errno);
- close (local_fd);
- return 0;
+ if (devnam[0] == 0) {
+ /* running with notty or pty option */
+ char slave[16];
+ if (!get_pty(&mfd, &local_fd, slave, 0))
+ return 0;
+ } else {
+ local_fd = open(devnam, O_NONBLOCK | O_RDWR, 0);
+ if (local_fd < 0) {
+ error("Failed to open %s: %m(%d)", devnam, errno);
+ return 0;
+ }
}
- initfdflags &= ~O_NONBLOCK;
- fcntl(local_fd, F_SETFL, initfdflags);
/*
- * Read the initial line dicipline and try to put the device into the
+ * Read the initial line discipline and try to put the device into the
* PPP dicipline.
*/
if (ioctl(local_fd, TIOCGETD, &init_disc) < 0) {
error("ioctl(TIOCGETD): %m(%d)", errno);
- close (local_fd);
- return 0;
- }
-
- if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
- error("ioctl(TIOCSETD): %m(%d)", errno);
- close (local_fd);
- return 0;
- }
-
- if (ioctl(local_fd, TIOCSETD, &init_disc) < 0) {
- error("ioctl(TIOCSETD): %m(%d)", errno);
- close (local_fd);
- return 0;
- }
+ } else if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
+ error("ioctl(TIOCSETD(PPP)): %m(%d)", errno);
+ } else if (ioctl(local_fd, TIOCSETD, &init_disc) < 0) {
+ error("ioctl(TIOCSETD(%d)): %m(%d)", init_disc, errno);
+ } else
+ ret = 1;
close (local_fd);
- return 1;
+ if (mfd >= 0)
+ close(mfd);
+ return ret;
}
/********************************************************************
"This system lacks kernel support for PPP. This could be because\n"
"the PPP kernel module is not loaded, or because the kernel is\n"
"not configured for PPP. See the README.linux file in the\n"
- "ppp-2.3.6 distribution.\n";
+ "ppp-2.3.7 distribution.\n";
/*
* This is the PPP device. Validate the version of the driver at this
if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
if (errno != EEXIST) {
if (! ok_error (errno))
- error("ioctl(SIOCAIFADDR): %m(%d)", errno);
+ error("ioctl(SIOCSIFADDR): %m(%d)", errno);
}
else {
- warn("ioctl(SIOCAIFADDR): Address already exists");
+ warn("ioctl(SIOCSIFADDR): Address already exists");
}
return (0);
}
return 1;
}
-/********************************************************************
- *
- * open_loopback - open the device we use for getting packets
- * in demand mode. Under Linux, we use a pty master/slave pair.
+/*
+ * 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
-open_ppp_loopback(void)
+get_pty(master_fdp, slave_fdp, slave_name, uid)
+ int *master_fdp;
+ int *slave_fdp;
+ char *slave_name;
+ int uid;
{
- int flags, i;
+ int i, mfd, sfd;
+ char pty_name[12];
struct termios tios;
- master_fd = -1;
+ sfd = -1;
for (i = 0; i < 64; ++i) {
- slprintf(loop_name, sizeof(loop_name), "/dev/pty%c%x",
+ slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
'p' + i / 16, i % 16);
- master_fd = open(loop_name, O_RDWR | O_NOCTTY, 0);
- if (master_fd >= 0)
- break;
+ 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 (master_fd < 0)
- fatal("No free pty for loopback");
- SYSDEBUG(("using %s for loopback", loop_name));
- loop_name[5] = 't';
- slave_fd = open(loop_name, O_RDWR | O_NOCTTY, 0);
- if (slave_fd < 0)
- fatal("Couldn't open %s for loopback: %m", loop_name);
-
- set_ppp_fd(slave_fd);
+ if (sfd < 0)
+ return 0;
- if (tcgetattr(ppp_fd, &tios) == 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(ppp_fd, TCSAFLUSH, &tios) < 0)
- warn("couldn't set attributes on loopback: %m(%d)", errno);
- }
+ 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;
+}
+
+/********************************************************************
+ *
+ * open_loopback - open the device we use for getting packets
+ * in demand mode. Under Linux, we use a pty master/slave pair.
+ */
+int
+open_ppp_loopback(void)
+{
+ int flags;
+
+ if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
+ fatal("No free pty for loopback");
+ SYSDEBUG(("using %s for loopback", loop_name));
+
+ set_ppp_fd(slave_fd);
flags = fcntl(master_fd, F_GETFL);
if (flags == -1 ||
result = 0;
if (errno != EEXIST) {
if (! ok_error (errno))
- dbglog("ioctl(SIOCAIFADDR, CRTITF): %m (%d)", errno);
+ dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno);
}
else {
- warn("ioctl(SIOCAIFADDR, CRTITF): Address already exists");
+ warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
}
}
close (skfd);
*/
if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
if (! ok_error (errno))
- info("ioctl(SIOCAIFADDR, IPX_DLTITF): %m (%d)", errno);
+ info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno);
result = 0;
}
close (skfd);