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);
extern u_char inpacket_buf[]; /* borrowed from main.c */
*
* 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(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();
}
-/********************************************************************
- *
- * note_debug_level - note a change in the debug level.
- */
-
-void note_debug_level (void)
-{
- if (debug) {
- SYSDEBUG ((LOG_INFO, "Debug turned ON, Level %d", debug));
- setlogmask(LOG_UPTO(LOG_DEBUG));
- }
- else {
- setlogmask(LOG_UPTO(LOG_WARNING));
- }
-}
-
/********************************************************************
*
* set_kdebugflag - Define the debugging level for the kernel
*/
-int set_kdebugflag (int requested_level)
+static int set_kdebugflag (int requested_level)
{
if (ioctl(ppp_fd, PPPIOCSDEBUG, &requested_level) < 0) {
if ( ! ok_error (errno) )
fatal("tcsetattr: %m");
baud_rate = baud_rate_of(speed);
- restore_term = TRUE;
+ restore_term = 1;
}
/********************************************************************
* Set the MTU and other parameters for the ppp device
*/
memset (&ifr, '\0', sizeof (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(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
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));
+
+ req.stats_ptr = (caddr_t) &req.stats;
+ strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
+ if (ioctl(sock_fd, 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;
+}
+
/********************************************************************
*
* ccp_fatal_error - returns 1 if decompression was disabled as a
fp = fopen(MOUNTED, "r");
if (fp == NULL) {
/* Default the mount location of /proc */
- strlcpy (route_buffer, sizeof (route_buffer), "/proc");
+ strlcpy (route_buffer, "/proc", sizeof (route_buffer));
return 1;
}
if (mntent == 0)
return 0;
- strlcpy(route_buffer, sizeof (route_buffer), mntent->mnt_dir);
+ strlcpy(route_buffer, mntent->mnt_dir, sizeof (route_buffer));
return 1;
}
error("proc file system not mounted");
return 0;
}
- strlcat (route_buffer, sizeof(route_buffer), "/net/route");
+ strlcat (route_buffer, "/net/route", sizeof(route_buffer));
return (route_buffer);
}
* 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;
for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
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));
SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
ifreq.ifr_name));
/*
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.
/*
* Check that the interface is up, and not point-to-point nor 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(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
continue;
* Procedure to determine if the PPP line discipline is registered.
*/
-int
+static int
ppp_registered(void)
{
int local_fd;
if (s < 0)
return 0;
- 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;
/*
* If the device did not exist then attempt to create one by putting the
*/
if (!ok) {
if (ppp_registered()) {
- 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;
}
}
memset(&ut, 0, sizeof(ut));
if (ut.ut_id[0] == 0)
- strlcpy(ut.ut_id, sizeof(ut.ut_id), line + 3);
+ strlcpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
- strlcpy(ut.ut_user, sizeof(ut.ut_user), name);
- strlcpy(ut.ut_line, sizeof(ut.ut_line), line);
+ strlcpy(ut.ut_user, name, sizeof(ut.ut_user));
+ strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
time(&ut.ut_time);
/* Insert the host name if one is supplied */
if (*host)
- strlcpy (ut.ut_host, sizeof(ut.ut_host), host);
+ strlcpy (ut.ut_host, host, sizeof(ut.ut_host));
/* Insert the IP address of the remote system if IP is enabled */
if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
struct ifreq ifr;
memset (&ifr, '\0', sizeof (ifr));
- strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
+ strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
if (! ok_error (errno))
error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
if_is_up = 0;
memset (&ifr, '\0', sizeof (ifr));
- strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
+ strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
if (! ok_error (errno))
error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
- strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
+ strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
/*
* Set our IP address
*/
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 ||
}
else {
memset (&ifr, '\0', sizeof (ifr));
- strlcpy (ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+ strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
sipx->sipx_family = AF_IPX;
}
else {
memset (&ifr, '\0', sizeof (ifr));
- strlcpy (ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
+ strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
sipx->sipx_type = IPX_FRAME_ETHERII;
sipx->sipx_action = IPX_DLTITF;
*/
while (ipxcp_protent.enabled_flag) {
if (path_to_procfs()) {
- strlcat (route_buffer, sizeof(route_buffer), "/net/ipx_interface");
+ strlcat (route_buffer, "/net/ipx_interface", sizeof(route_buffer));
if (lstat (route_buffer, &stat_buf) >= 0)
break;
}