$OpenBSD: patch-agent_mibgroup_mibII_ipAddr_c,v 1.7 2020/09/04 19:46:15 sthen Exp $

Index: agent/mibgroup/mibII/ipAddr.c
--- agent/mibgroup/mibII/ipAddr.c.orig
+++ agent/mibgroup/mibII/ipAddr.c
@@ -752,10 +752,10 @@ static int      nifs;
 static void
 get_iflist(void)
 {
-    int             naddrs, bit;
+    int             naddrs, i, gotaddr;
     static int      mib[6]
     = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, 0 };
-    char           *cp, *ifbuf;
+    char           *cp, *ifbuf, *lim;
     size_t          len;
     struct rt_msghdr *rtm;
     struct if_msghdr *ifm;
@@ -781,63 +781,57 @@ get_iflist(void)
         return;
     }
 
-  loop:
-    cp = ifbuf;
-    while (cp < &ifbuf[len]) {
-        int             gotaddr;
+    lim = ifbuf + len;
 
-        gotaddr = 0;
+#define satosin(sa) ((struct sockaddr_in *)(sa))
+#define ROUND(a) \
+        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+
+  loop:
+    for (cp = ifbuf; cp < lim; cp += rtm->rtm_msglen) {
         rtm = (struct rt_msghdr *) cp;
-        if (rtm->rtm_version != RTM_VERSION || rtm->rtm_type != RTM_IFINFO) {
-            free(ifs);
-            ifs = 0;
-            nifs = 0;
-            free(ifbuf);
-            return;
-        }
+        if (rtm->rtm_version != RTM_VERSION)
+            continue;
+        switch (rtm->rtm_type) {
+        case RTM_IFINFO:
         ifm = (struct if_msghdr *) rtm;
         flags = ifm->ifm_flags;
-        cp += ifm->ifm_msglen;
-        rtm = (struct rt_msghdr *) cp;
-        while (cp < &ifbuf[len] && rtm->rtm_type == RTM_NEWADDR) {
+            break;
+        case RTM_NEWADDR:
             ifam = (struct ifa_msghdr *) rtm;
-            cp += sizeof(*ifam);
-            /*
-             * from route.c 
-             */
-#define ROUND(a) \
-        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-            for (bit = 1; bit && cp < &ifbuf[len]; bit <<= 1) {
-                if (!(ifam->ifam_addrs & bit))
-                    continue;
-                sa = (struct sockaddr *) cp;
-                cp += ROUND(sa->sa_len);
-
-                /*
-                 * Netmasks are returned as bit
-                 * strings of type AF_UNSPEC.  The
-                 * others are pretty ok.
-                 */
-                if (bit == RTA_IFA) {
-#define satosin(sa) ((struct sockaddr_in *)(sa))
+            if ((ifam->ifam_addrs & (RTA_IFA | RTA_NETMASK |
+                RTA_BRD)) == 0)
+                break;
+            sa = (struct sockaddr *)(ifam + 1);
+            gotaddr = 0;
+            for (i = 0; i < RTAX_MAX; i++) {
+                switch (ifam->ifam_addrs & (1 << i)) {
+                case RTA_IFA:
                     if (ifs) {
                         ifs[naddrs].addr = satosin(sa)->sin_addr;
                         ifs[naddrs].index = ifam->ifam_index;
                         ifs[naddrs].flags = flags;
                     }
                     gotaddr = 1;
-                } else if (bit == RTA_NETMASK) {
+                    sa = (struct sockaddr *)((char *)(sa) +
+                        ROUND(sa->sa_len));
+                    break;
+                case RTA_NETMASK:
                     if (ifs)
                         ifs[naddrs].mask = satosin(sa)->sin_addr;
-                } else if (bit == RTA_BRD) {
+                    sa = (struct sockaddr *)((char *)(sa) +
+                        ROUND(sa->sa_len));
+                    break;
+                case RTA_BRD:
                     if (ifs)
                         ifs[naddrs].bcast = satosin(sa)->sin_addr;
+                    sa = (struct sockaddr *)((char *)(sa) +
+                        ROUND(sa->sa_len));
+                    break;
                 }
             }
             if (gotaddr)
                 naddrs++;
-            cp = (char *) rtm + rtm->rtm_msglen;
-            rtm = (struct rt_msghdr *) cp;
         }
     }
     if (ifs) {
