]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/sys-osf.c
use strlcpy, strlcat, slprintf everywhere
[ppp.git] / pppd / sys-osf.c
index 93070e558ccb2c02c843781af1a6ca6b6d61b98b..cba5e356ee5674e1b752e92b940ed14e22e4da6a 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: sys-osf.c,v 1.14 1998/11/07 06:59:31 paulus Exp $";
+static char rcsid[] = "$Id: sys-osf.c,v 1.18 1999/03/12 06:07:22 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -50,12 +50,15 @@ static char rcsid[] = "$Id: sys-osf.c,v 1.14 1998/11/07 06:59:31 paulus Exp $";
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/poll.h>
+#include <sys/ioctl.h>
 #include <net/if.h>
+#include <net/if_dl.h>
 #include <net/if_arp.h>
 #include <net/route.h>
 #include <net/ppp_defs.h>
 #include <net/pppio.h>
 #include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include "pppd.h"
 
@@ -1074,7 +1077,7 @@ sifup(u)
 {
     struct ifreq ifr;
 
-    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
     if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
        syslog(LOG_ERR, "Couldn't mark interface up (get): %m");
        return 0;
@@ -1097,7 +1100,7 @@ sifdown(u)
 {
     struct ifreq ifr;
 
-    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+    strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
     if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
        syslog(LOG_ERR, "Couldn't mark interface down (get): %m");
        return 0;
@@ -1160,7 +1163,7 @@ sifaddr(u, o, h, m)
     /* flush old address, if any
      */
     bzero(&ifr, sizeof (ifr));
-    strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+    strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
     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)
@@ -1170,7 +1173,7 @@ sifaddr(u, o, h, m)
     }
 
     bzero(&addreq, sizeof (addreq));
-    strncpy(addreq.ifra_name, ifname, sizeof (addreq.ifra_name));
+    strlcpy(addreq.ifra_name, sizeof (addreq.ifra_name), ifname);
     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;
@@ -1213,8 +1216,9 @@ cifaddr(u, o, h)
     struct ifreq ifr;
 
     ifaddrs[0] = 0;
+    ifaddrs[1] = 0;
     bzero(&ifr, sizeof (ifr));
-    strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+    strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname);
     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) {
@@ -1364,7 +1368,7 @@ get_ether_addr(ipaddr, hwaddr)
              * Check that the interface is up, and not point-to-point
              * or 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(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
                 continue;
             if ((ifreq.ifr_flags &
@@ -1393,7 +1397,7 @@ get_ether_addr(ipaddr, hwaddr)
        return 0;
     syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name);
 
-    strncpy(ifdevreq.ifr_name, ifr->ifr_name, sizeof(ifdevreq.ifr_name));
+    strlcpy(ifdevreq.ifr_name, sizeof(ifdevreq.ifr_name), ifr->ifr_name);
 
     if (ioctl(sockfd, (int)SIOCRPHYSADDR, &ifdevreq) < 0) {
         perror("ioctl(SIOCRPHYSADDR)");
@@ -1418,9 +1422,9 @@ logwtmp(line, name, host)
     if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
        return;
     if (!fstat(fd, &buf)) {
-       (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
-       (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
-       (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+       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);
        (void)time(&ut.ut_time);
        if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
            (void)ftruncate(fd, buf.st_size);
@@ -1477,7 +1481,7 @@ GetMask(addr)
            /*
             * Check that the interface is up, and not point-to-point or 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(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
                continue;
            if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
@@ -1499,6 +1503,71 @@ GetMask(addr)
     return mask;
 }
 
+/*
+ * have_route_to - determine if the system has any route to
+ * a given IP address.  `addr' is in network byte order.
+ * For demand mode to work properly, we have to ignore routes
+ * through our own interface.
+ */
+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;
+}
+
 static int
 strioctl(fd, cmd, ptr, ilen, olen)
     int fd, cmd, ilen, olen;
@@ -1557,13 +1626,15 @@ lock(dev)
     char hdb_lock_buffer[12];
     int fd, pid, n;
     char *p;
+    size_t l;
 
     if ((p = strrchr(dev, '/')) != NULL)
        dev = p + 1;
-    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");
-    strcat(strcpy(lock_file, LOCK_PREFIX), dev);
+    slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
 
     while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
        if (errno == EEXIST