#endif
static void set_ppp_fd (int new_fd)
-{
- SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", ppp_fd));
+{
+ SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
ppp_fd = new_fd;
}
* regardless of whether the modem option was specified.
*/
-void set_up_tty (int tty_fd, int local)
+void set_up_tty(int tty_fd, int local)
{
int speed;
struct termios tios;
-
+
+ setdtr(tty_fd, 1);
if (tcgetattr(tty_fd, &tios) < 0)
{
syslog(LOG_ERR, "tcgetattr: %m(%d)", errno);
if (write(ppp_fd, p, len) < 0)
{
if (errno == EWOULDBLOCK || errno == ENOBUFS
- || errno == ENXIO || errno == EIO)
+ || errno == ENXIO || errno == EIO || errno == EINTR)
{
- syslog(LOG_WARNING, "write: warning: %m(%d)", errno);
+ syslog(LOG_WARNING, "write: warning: %m (%d)", errno);
}
else
{
- syslog(LOG_ERR, "write: %m(%d)", errno);
- die(1);
+ syslog(LOG_ERR, "write: %m (%d)", errno);
}
}
}
* Set the MTU and other parameters for the ppp device
*/
memset (&ifr, '\0', sizeof (ifr));
- strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
ifr.ifr_mtu = mtu;
if (ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
*/
int ccp_fatal_error (int unit)
- {
+{
int x = get_flags();
return x & SC_DC_FERROR;
- }
+}
/*
* path_to_route - determine the path to the proc file system data
*/
-
+#define ROUTE_MAX_COLS 12
FILE *route_fd = (FILE *) 0;
static char route_buffer [512];
+static int route_dev_col, route_dest_col, route_gw_col;
+static int route_flags_col, route_mask_col;
+static int route_num_cols;
static char *path_to_route (void);
static int open_route_table (void);
*/
static int path_to_procfs (void)
- {
+{
struct mntent *mntent;
FILE *fp;
- fp = fopen (MOUNTED, "r");
- if (fp != 0)
- {
- mntent = getmntent (fp);
- while (mntent != (struct mntent *) 0)
- {
- if (strcmp (mntent->mnt_type, MNTTYPE_IGNORE) != 0)
- {
- if (strcmp (mntent->mnt_type, "proc") == 0)
- {
- strncpy (route_buffer, mntent->mnt_dir,
- sizeof (route_buffer)-10);
- route_buffer [sizeof (route_buffer)-10] = '\0';
- fclose (fp);
- return 1;
- }
- }
- mntent = getmntent (fp);
- }
- fclose (fp);
- }
+ fp = fopen(MOUNTED, "r");
+ if (fp == NULL) {
+ /* Default the mount location of /proc */
+ strlcpy (route_buffer, sizeof (route_buffer), "/proc");
+ return 1;
+ }
+
+ while ((mntent = getmntent(fp)) != NULL) {
+ if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
+ continue;
+ if (strcmp(mntent->mnt_type, "proc") == 0)
+ break;
+ }
+ fclose (fp);
+ if (mntent == 0)
+ return 0;
- /* Default the mount location of /proc */
- strncpy (route_buffer, "/proc", sizeof (route_buffer)-10);
+ strlcpy(route_buffer, sizeof (route_buffer), mntent->mnt_dir);
return 1;
- }
+}
/********************************************************************
*
*/
static char *path_to_route (void)
- {
- if (! path_to_procfs())
- {
+{
+ if (!path_to_procfs()) {
syslog (LOG_ERR, "proc file system not mounted");
return 0;
- }
- strcat (route_buffer, "/net/route");
+ }
+ strlcat (route_buffer, sizeof(route_buffer), "/net/route");
return (route_buffer);
- }
+}
/********************************************************************
*
*/
static void close_route_table (void)
- {
- if (route_fd != (FILE *) 0)
- {
+{
+ if (route_fd != (FILE *) 0) {
fclose (route_fd);
route_fd = (FILE *) 0;
- }
- }
+ }
+}
/********************************************************************
*
* open_route_table - open the interface to the route table
*/
+static char route_delims[] = " \t\n";
static int open_route_table (void)
- {
+{
char *path;
close_route_table();
path = path_to_route();
if (path == NULL)
- {
return 0;
- }
route_fd = fopen (path, "r");
- if (route_fd == (FILE *) 0)
- {
- syslog (LOG_ERR, "can not open %s: %m(%d)", path, errno);
+ if (route_fd == NULL) {
+ syslog (LOG_ERR, "can't open %s: %m (%d)", path, errno);
return 0;
- }
+ }
+
+ route_dev_col = 0; /* default to usual columns */
+ route_dest_col = 1;
+ route_gw_col = 2;
+ route_flags_col = 3;
+ route_mask_col = 7;
+ route_num_cols = 8;
+
+ /* parse header line */
+ if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
+ char *p = route_buffer, *q;
+ int col;
+ for (col = 0; col < ROUTE_MAX_COLS; ++col) {
+ int used = 1;
+ if ((q = strtok(p, route_delims)) == 0)
+ break;
+ if (strcasecmp(q, "iface") == 0)
+ route_dev_col = col;
+ else if (strcasecmp(q, "destination") == 0)
+ route_dest_col = col;
+ else if (strcasecmp(q, "gateway") == 0)
+ route_gw_col = col;
+ else if (strcasecmp(q, "flags") == 0)
+ route_flags_col = col;
+ else if (strcasecmp(q, "mask") == 0)
+ route_mask_col = col;
+ else
+ used = 0;
+ if (used && col >= route_num_cols)
+ route_num_cols = col + 1;
+ p = NULL;
+ }
+ }
+
return 1;
- }
+}
/********************************************************************
*
* read_route_table - read the next entry from the route table
*/
-static int read_route_table (struct rtentry *rt)
- {
- static char delims[] = " \t\n";
- char *dev_ptr, *dst_ptr, *gw_ptr, *flag_ptr;
+static int read_route_table(struct rtentry *rt)
+{
+ char *cols[ROUTE_MAX_COLS], *p;
+ int col;
memset (rt, '\0', sizeof (struct rtentry));
- for (;;)
- {
- if (fgets (route_buffer, sizeof (route_buffer), route_fd) ==
- (char *) 0)
- {
- return 0;
- }
+ if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
+ return 0;
- dev_ptr = strtok (route_buffer, delims); /* interface name */
- dst_ptr = strtok (NULL, delims); /* destination address */
- gw_ptr = strtok (NULL, delims); /* gateway */
- flag_ptr = strtok (NULL, delims); /* flags */
-
- if (flag_ptr == (char *) 0) /* assume that we failed, somewhere. */
- {
- return 0;
- }
-
- /* Discard that stupid header line which should never
- * have been there in the first place !! */
- if (isxdigit (*dst_ptr) && isxdigit (*gw_ptr) && isxdigit (*flag_ptr))
- {
- break;
- }
- }
+ p = route_buffer;
+ for (col = 0; col < route_num_cols; ++col) {
+ cols[col] = strtok(p, route_delims);
+ if (cols[col] == NULL)
+ return 0; /* didn't get enough columns */
+ }
((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr =
- strtoul (dst_ptr, NULL, 16);
+ strtoul(cols[route_dest_col], NULL, 16);
((struct sockaddr_in *) &rt->rt_gateway)->sin_addr.s_addr =
- strtoul (gw_ptr, NULL, 16);
+ strtoul(cols[route_gw_col], NULL, 16);
+
+ ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr =
+ strtoul(cols[route_mask_col], NULL, 16);
- rt->rt_flags = (short) strtoul (flag_ptr, NULL, 16);
- rt->rt_dev = dev_ptr;
+ rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
+ rt->rt_dev = cols[route_dev_col];
return 1;
- }
+}
/********************************************************************
*
*/
static int defaultroute_exists (struct rtentry *rt)
- {
- int result = 0;
+{
+ int result = 0;
if (!open_route_table())
- {
return 0;
- }
- while (read_route_table(rt) != 0)
- {
+ while (read_route_table(rt) != 0) {
if ((rt->rt_flags & RTF_UP) == 0)
- {
continue;
- }
- if (((struct sockaddr_in *) (&rt->rt_dst))->sin_addr.s_addr == 0L)
- {
+ if (((struct sockaddr_in *) (&rt->rt_dst))->sin_addr.s_addr == 0L) {
result = 1;
break;
- }
- }
+ }
+ }
close_route_table();
return result;
- }
+}
+
+/*
+ * have_route_to - determine if the system has any route to
+ * a given IP address. `addr' is in network byte order.
+ * Return value is 1 if yes, 0 if no, -1 if don't know.
+ * For demand mode to work properly, we have to ignore routes
+ * through our own interface.
+ */
+int have_route_to(u_int32_t addr)
+{
+ struct rtentry rt;
+ int result = 0;
+
+ if (!open_route_table())
+ return -1; /* don't know */
+
+ while (read_route_table(&rt)) {
+ if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
+ continue;
+ if ((addr & ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr)
+ == ((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr) {
+ result = 1;
+ break;
+ }
+ }
+
+ close_route_table();
+ return result;
+}
/********************************************************************
*
{
struct rtentry rt;
- if (defaultroute_exists(&rt))
+ if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0)
{
struct in_addr old_gateway =
((struct sockaddr_in *) (&rt.rt_gateway))-> sin_addr;
{
syslog (LOG_ERR,
"not replacing existing default route to %s [%s]",
- rt.rt_dev,
- inet_ntoa (old_gateway));
+ rt.rt_dev, inet_ntoa (old_gateway));
}
return 0;
}
if (ifr->ifr_addr.sa_family == AF_INET)
{
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
- strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
+ strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name);
SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
ifreq.ifr_name));
/*
/*
* Check that the interface is up, and not point-to-point nor loopback.
*/
- strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
+ strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name);
if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
{
continue;
return 0;
}
- strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
+ strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0");
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
/*
* If the device did not exist then attempt to create one by putting the
{
if (ppp_registered())
{
- strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
+ strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0");
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
}
}
"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.5 distribution.\n";
+ "ppp-2.3.6 distribution.\n";
}
/*
* This is the PPP device. Validate the version of the driver at this
}
/* The modification levels must be legal */
- if (driver_modification < my_modification)
+ if (driver_modification < 3)
{
if (driver_modification >= 2) {
/* we can cope with 2.2.0 and above */
if (ut.ut_id[0] == 0)
{
- strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
+ strlcpy(ut.ut_id, sizeof(ut.ut_id), line + 3);
}
- strncpy(ut.ut_user, name, sizeof(ut.ut_user));
- strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ strlcpy(ut.ut_user, sizeof(ut.ut_user), name);
+ strlcpy(ut.ut_line, sizeof(ut.ut_line), line);
time(&ut.ut_time);
/* Insert the host name if one is supplied */
if (*host)
{
- strncpy (ut.ut_host, host, sizeof(ut.ut_host));
+ strlcpy (ut.ut_host, sizeof(ut.ut_host), host);
}
/* Insert the IP address of the remote system if IP is enabled */
*/
int lock (char *dev)
- {
+{
#ifdef LOCKLIB
int result;
- lock_file = malloc(strlen(dev) + 1);
+ lock_file = strdup(dev);
if (lock_file == NULL)
- {
novm("lock file name");
- }
- strcpy (lock_file, dev);
result = mklock (dev, (void *) 0);
- if (result > 0)
- {
+ if (result > 0) {
syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, result);
free (lock_file);
lock_file = NULL;
result = -1;
- }
- else
- {
- if (result < 0)
- {
+ }
+ else {
+ if (result < 0) {
syslog (LOG_ERR, "Can't create lock file %s", lock_file);
free (lock_file);
lock_file = NULL;
result = -1;
- }
- }
+ }
+ }
return (result);
#else
char hdb_lock_buffer[12];
int fd, n;
int pid = getpid();
char *p;
+ size_t l;
p = strrchr(dev, '/');
if (p != NULL)
- {
dev = ++p;
- }
- 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");
- }
- strcpy (lock_file, LOCK_PREFIX);
- strcat (lock_file, dev);
+ slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
/*
* Attempt to create the lock file at this point.
*/
- while (1)
- {
+ while (1) {
fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
- if (fd >= 0)
- {
+ if (fd >= 0) {
pid = getpid();
#ifndef PID_BINARY
sprintf (hdb_lock_buffer, "%010d\n", pid);
#endif
close(fd);
return 0;
- }
+ }
/*
* If the file exists then check to see if the pid is stale
*/
- if (errno == EEXIST)
- {
+ if (errno == EEXIST) {
fd = open(lock_file, O_RDONLY, 0);
- if (fd < 0)
- {
+ if (fd < 0) {
if (errno == ENOENT) /* This is just a timing problem. */
- {
continue;
- }
break;
- }
+ }
/* Read the lock file to find out who has the device locked */
n = read (fd, hdb_lock_buffer, 11);
close (fd);
- if (n < 0)
- {
+ if (n < 0) {
syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
break;
- }
+ }
/* See the process still exists. */
- if (n > 0)
- {
+ if (n > 0) {
#ifndef PID_BINARY
hdb_lock_buffer[n] = '\0';
sscanf (hdb_lock_buffer, " %d", &pid);
#endif
if (pid == 0 || pid == getpid()
|| (kill(pid, 0) == -1 && errno == ESRCH))
- {
n = 0;
- }
- }
+ }
/* If the process does not exist then try to remove the lock */
- if (n == 0 && unlink (lock_file) == 0)
- {
+ if (n == 0 && unlink (lock_file) == 0) {
syslog (LOG_NOTICE, "Removed stale lock on %s (pid %d)",
dev, pid);
continue;
- }
+ }
syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, pid);
break;
- }
+ }
syslog(LOG_ERR, "Can't create lock file %s: %m(%d)", lock_file, errno);
break;
- }
+ }
free(lock_file);
lock_file = NULL;
struct ifreq ifr;
memset (&ifr, '\0', sizeof (ifr));
- strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0)
{
if (! ok_error (errno))
if_is_up = 0;
memset (&ifr, '\0', sizeof (ifr));
- strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0)
{
if (! ok_error (errno))
SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
- strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
/*
* Set our IP address
*/
else
{
memset (&ifr, '\0', sizeof (ifr));
- strcpy (ifr.ifr_name, ifname);
+ strlcpy (ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
sipx->sipx_family = AF_IPX;
else
{
memset (&ifr, '\0', sizeof (ifr));
- strcpy (ifr.ifr_name, ifname);
+ strlcpy (ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
sipx->sipx_type = IPX_FRAME_ETHERII;
sipx->sipx_action = IPX_DLTITF;
* sys_check_options - check the options that the user specified
*/
-void
+int
sys_check_options(void)
{
#ifdef IPX_CHANGE
{
if (path_to_procfs())
{
- strcat (route_buffer, "/net/ipx_interface");
+ strlcat (route_buffer, sizeof(route_buffer), "/net/ipx_interface");
if (lstat (route_buffer, &stat_buf) >= 0)
{
break;
option_error("demand dialling is not supported by kernel driver version "
"%d.%d.%d", driver_version, driver_modification,
driver_patch);
- demand = 0;
+ return 0;
}
+ return 1;
}