]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Fold all CMSG parsing into a common function.
authorRoy Marples <roy@marples.name>
Tue, 19 Feb 2019 21:46:06 +0000 (21:46 +0000)
committerRoy Marples <roy@marples.name>
Tue, 19 Feb 2019 21:46:06 +0000 (21:46 +0000)
Makes dhcpcd smaller still.

src/dhcp.c
src/dhcp6.c
src/if.c
src/if.h
src/ipv6nd.c

index 4a8f5d57fc89fedb0e89b8dc49bf4d25b9f6f1c1..fb91670096901c9e7ddd9b0260d5c6999d001fd6 100644 (file)
@@ -3477,36 +3477,9 @@ dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
        inet_ntop(AF_INET, &from.sin_addr, sfrom, sizeof(sfrom));
 
        if (ifp == NULL) {
-               struct cmsghdr *cm;
-               struct in_pktinfo pi;
-
-               pi.ipi_ifindex = 0;
-               for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&msg);
-                   cm;
-                   cm = (struct cmsghdr *)CMSG_NXTHDR(&msg, cm))
-               {
-                       if (cm->cmsg_level != IPPROTO_IP)
-                               continue;
-                       switch(cm->cmsg_type) {
-                       case IP_PKTINFO:
-                               if (cm->cmsg_len == CMSG_LEN(sizeof(pi)))
-                                       memcpy(&pi, CMSG_DATA(cm), sizeof(pi));
-                               break;
-                       }
-               }
-               if (pi.ipi_ifindex == 0) {
-                       logerrx("DHCP reply did not contain index from %s",
-                           sfrom);
-                       return;
-               }
-
-               TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-                       if (ifp->index == (unsigned int)pi.ipi_ifindex)
-                               break;
-               }
+               ifp = if_findifpfromcmsg(ctx, &msg, NULL);
                if (ifp == NULL) {
-                       logerrx("DHCP reply for unexpected interface from %s",
-                           sfrom);
+                       logerr(__func__);
                        return;
                }
        }
index c50efb66af0b4ab72ee723eb085fcbab0bad0bb0..6e83a70fdf2f6826053eb85a1af4a7568c3dfcc6 100644 (file)
@@ -3498,36 +3498,9 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
        if (ia != NULL)
                ifp = ia->iface;
        else {
-               struct cmsghdr *cm;
-               struct in6_pktinfo pi;
-
-               pi.ipi6_ifindex = 0;
-               for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&msg);
-                   cm;
-                   cm = (struct cmsghdr *)CMSG_NXTHDR(&msg, cm))
-               {
-                       if (cm->cmsg_level != IPPROTO_IPV6)
-                               continue;
-                       switch(cm->cmsg_type) {
-                       case IPV6_PKTINFO:
-                               if (cm->cmsg_len == CMSG_LEN(sizeof(pi)))
-                                       memcpy(&pi, CMSG_DATA(cm), sizeof(pi));
-                               break;
-                       }
-               }
-               if (pi.ipi6_ifindex == 0) {
-                       logerrx("DHCPv6 reply did not contain index from %s",
-                           sfrom);
-                       return;
-               }
-
-               TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-                       if (ifp->index == (unsigned int)pi.ipi6_ifindex)
-                               break;
-               }
+               ifp = if_findifpfromcmsg(ctx, &msg, NULL);
                if (ifp == NULL) {
-                       logerrx("DHCPv6 reply for unexpected interface from %s",
-                           sfrom);
+                       logerr(__func__);
                        return;
                }
        }
index 42b3e7b3b3b16326c8ac6c8c651a87681ab22974..9ba286d168e79af9d85ab0730cd52c9c9e094386 100644 (file)
--- a/src/if.c
+++ b/src/if.c
@@ -801,6 +801,68 @@ if_sortinterfaces(struct dhcpcd_ctx *ctx)
        TAILQ_CONCAT(ctx->ifaces, &sorted, next);
 }
 
+struct interface *
+if_findifpfromcmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, int *hoplimit)
+{
+       struct cmsghdr *cm;
+       unsigned int ifindex = 0;
+       struct interface *ifp;
+#ifdef INET
+       struct in_pktinfo ipi;
+#endif
+#ifdef INET6
+       struct in6_pktinfo ipi6;
+#else
+       UNUSED(hoplimit);
+#endif
+
+       for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(msg);
+            cm;
+            cm = (struct cmsghdr *)CMSG_NXTHDR(msg, cm))
+       {
+#ifdef INET
+               if (cm->cmsg_level == IPPROTO_IP) {
+                       switch(cm->cmsg_type) {
+                       case IP_PKTINFO:
+                               if (cm->cmsg_len != CMSG_LEN(sizeof(ipi)))
+                                       continue;
+                               memcpy(&ipi, CMSG_DATA(cm), sizeof(ipi));
+                               ifindex = (unsigned int)ipi.ipi_ifindex;
+                               break;
+                       }
+               }
+#endif
+#ifdef INET6
+               if (cm->cmsg_level == IPPROTO_IPV6) {
+                       switch(cm->cmsg_type) {
+                       case IPV6_PKTINFO:
+                               if (cm->cmsg_len != CMSG_LEN(sizeof(ipi6)))
+                                       continue;
+                               memcpy(&ipi6, CMSG_DATA(cm), sizeof(ipi6));
+                               ifindex = (unsigned int)ipi6.ipi6_ifindex;
+                               break;
+                       case IPV6_HOPLIMIT:
+                               if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
+                                       continue;
+                               if (hoplimit == NULL)
+                                       break;
+                               memcpy(hoplimit, CMSG_DATA(cm), sizeof(int));
+                               break;
+                       }
+               }
+#endif
+       }
+
+       /* Find the receiving interface */
+       TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+               if (ifp->index == ifindex)
+                       break;
+       }
+       if (ifp == NULL)
+               errno = ESRCH;
+       return ifp;
+}
+
 int
 xsocket(int domain, int type, int protocol)
 {
index d260d2d1a99150687db35ac75446037d5150230f..2f20764c01f401830c9565f7e28fe37d4aec0dc0 100644 (file)
--- a/src/if.h
+++ b/src/if.h
@@ -209,5 +209,7 @@ int if_getlifetime6(struct ipv6_addr *);
 #endif
 
 int if_machinearch(char *, size_t);
+struct interface *if_findifpfromcmsg(struct dhcpcd_ctx *,
+    struct msghdr *, int *);
 int xsocket(int, int, int);
 #endif
index 7f67287ced86fba0c810375b72d298db3c880ff6..bef77b2a328e5897c6be751096a4e5dfc7b70dc5 100644 (file)
@@ -1672,10 +1672,8 @@ ipv6nd_handledata(void *arg)
            .msg_control = ctl, .msg_controllen = sizeof(ctl),
        };
        ssize_t len;
-       struct cmsghdr *cm;
        char sfrom[INET6_ADDRSTRLEN];
-       int hoplimit;
-       struct in6_pktinfo pkt;
+       int hoplimit = 0;
        struct icmp6_hdr *icp;
        struct interface *ifp;
 
@@ -1691,41 +1689,15 @@ ipv6nd_handledata(void *arg)
                return;
        }
 
-       pkt.ipi6_ifindex = 0;
-       hoplimit = 0;
-       for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&msg);
-            cm;
-            cm = (struct cmsghdr *)CMSG_NXTHDR(&msg, cm))
-       {
-               if (cm->cmsg_level != IPPROTO_IPV6)
-                       continue;
-               switch(cm->cmsg_type) {
-               case IPV6_PKTINFO:
-                       if (cm->cmsg_len == CMSG_LEN(sizeof(pkt)))
-                               memcpy(&pkt, CMSG_DATA(cm), sizeof(pkt));
-                       break;
-               case IPV6_HOPLIMIT:
-                       if (cm->cmsg_len == CMSG_LEN(sizeof(int)))
-                               memcpy(&hoplimit, CMSG_DATA(cm), sizeof(int));
-                       break;
-               }
-       }
-
-       if (pkt.ipi6_ifindex == 0) {
-               logerrx("IPv6 RA/NA did not contain index from %s", sfrom);
+       ifp = if_findifpfromcmsg(ctx, &msg, &hoplimit);
+       if (ifp == NULL) {
+               logerr(__func__);
                return;
        }
 
-       /* Find the receiving interface */
-       TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-               if (ifp->index == (unsigned int)pkt.ipi6_ifindex)
-                       break;
-       }
-
        /* Don't do anything if the user hasn't configured it. */
-       if (ifp != NULL &&
-           (ifp->active != IF_ACTIVE_USER ||
-           !(ifp->options->options & DHCPCD_IPV6)))
+       if (ifp->active != IF_ACTIVE_USER ||
+           !(ifp->options->options & DHCPCD_IPV6))
                return;
 
        icp = (struct icmp6_hdr *)buf;