]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Split *_recv() into *_recv() and *_recvmsg() functions
authorRoy Marples <roy@marples.name>
Fri, 25 Oct 2019 11:49:01 +0000 (12:49 +0100)
committerRoy Marples <roy@marples.name>
Fri, 25 Oct 2019 11:49:01 +0000 (12:49 +0100)
The *_recvmsg() function has the whole packet in the first and
only iov.

Serves little purpose now, but will be used in the future.

src/dhcp.c
src/dhcp6.c
src/ipv6nd.c

index 6ffd139b20e9256fbc86198af8d056331387bc22..2dd0bbda2f89e2c163794ccf237606676b303ba3 100644 (file)
@@ -3450,6 +3450,35 @@ dhcp_readbpf(void *arg)
                state->bpf_flags &= ~BPF_READING;
 }
 
+static void
+dhcp_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg)
+{
+       struct sockaddr_in *from = (struct sockaddr_in *)msg->msg_name;
+       struct iovec *iov = &msg->msg_iov[0];
+       struct interface *ifp;
+       const struct dhcp_state *state;
+
+       ifp = if_findifpfromcmsg(ctx, msg, NULL);
+       if (ifp == NULL) {
+               logerr(__func__);
+               return;
+       }
+       state = D_CSTATE(ifp);
+       if (state == NULL) {
+               logdebugx("%s: received BOOTP for inactive interface",
+                   ifp->name);
+               return;
+       }
+
+       if (state->bpf_fd != -1) {
+               /* Avoid a duplicate read if BPF is open for the interface. */
+               return;
+       }
+
+       dhcp_handlebootp(ifp, (struct bootp *)iov->iov_base, iov->iov_len,
+           &from->sin_addr);
+}
+
 static void
 dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
 {
@@ -3485,27 +3514,8 @@ dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
                return;
        }
 
-       if (ifp == NULL) {
-               ifp = if_findifpfromcmsg(ctx, &msg, NULL);
-               if (ifp == NULL) {
-                       logerr(__func__);
-                       return;
-               }
-               state = D_CSTATE(ifp);
-               if (state == NULL) {
-                       logdebugx("%s: received BOOTP for inactive interface",
-                           ifp->name);
-                       return;
-               }
-       }
-
-       if (state->bpf_fd != -1) {
-               /* Avoid a duplicate read if BPF is open for the interface. */
-               return;
-       }
-
-       dhcp_handlebootp(ifp, (struct bootp *)(void *)buf, (size_t)bytes,
-           &from.sin_addr);
+       iov.iov_len = (size_t)bytes;
+       dhcp_recvmsg(ctx, &msg);
 }
 
 static void
index 4ef2e565e96935c3acee5653efd43b8a783f221e..98d506bbee275a43e90c7752a178134f2276ff5c 100644 (file)
@@ -3465,23 +3465,10 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
 }
 
 static void
-dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
+dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, struct ipv6_addr *ia)
 {
-       struct sockaddr_in6 from;
-       unsigned char buf[64 * 1024]; /* Maximum UDP message size */
-       struct iovec iov = {
-               .iov_base = buf,
-               .iov_len = sizeof(buf),
-       };
-       unsigned char ctl[CMSG_SPACE(sizeof(struct in6_pktinfo))] = { 0 };
-       struct msghdr msg = {
-           .msg_name = &from, .msg_namelen = sizeof(from),
-           .msg_iov = &iov, .msg_iovlen = 1,
-           .msg_control = ctl, .msg_controllen = sizeof(ctl),
-       };
-       int s;
-       size_t len;
-       ssize_t bytes;
+       struct sockaddr_in6 *from = msg->msg_name;
+       size_t len = msg->msg_iov[0].iov_len;
        char sfrom[INET6_ADDRSTRLEN];
        struct interface *ifp;
        struct dhcp6_message *r;
@@ -3489,14 +3476,7 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
        uint8_t *o;
        uint16_t ol;
 
-       s = ia != NULL ? ia->dhcp6_fd : ctx->dhcp6_fd;
-       bytes = recvmsg(s, &msg, 0);
-       if (bytes == -1) {
-               logerr(__func__);
-               return;
-       }
-       len = (size_t)bytes;
-       inet_ntop(AF_INET6, &from.sin6_addr, sfrom, sizeof(sfrom));
+       inet_ntop(AF_INET6, &from->sin6_addr, sfrom, sizeof(sfrom));
        if (len < sizeof(struct dhcp6_message)) {
                logerrx("DHCPv6 packet too short from %s", sfrom);
                return;
@@ -3505,14 +3485,14 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
        if (ia != NULL)
                ifp = ia->iface;
        else {
-               ifp = if_findifpfromcmsg(ctx, &msg, NULL);
+               ifp = if_findifpfromcmsg(ctx, msg, NULL);
                if (ifp == NULL) {
                        logerr(__func__);
                        return;
                }
        }
 
-       r = (struct dhcp6_message *)buf;
+       r = (struct dhcp6_message *)msg->msg_iov[0].iov_base;
        o = dhcp6_findmoption(r, len, D6_OPTION_CLIENTID, &ol);
        if (o == NULL || ol != ctx->duid_len ||
            memcmp(o, ctx->duid, ol) != 0)
@@ -3580,6 +3560,35 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
        dhcp6_recvif(ifp, sfrom, r, len);
 }
 
+static void
+dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
+{
+       struct sockaddr_in6 from;
+       unsigned char buf[64 * 1024]; /* Maximum UDP message size */
+       struct iovec iov = {
+               .iov_base = buf,
+               .iov_len = sizeof(buf),
+       };
+       unsigned char ctl[CMSG_SPACE(sizeof(struct in6_pktinfo))] = { 0 };
+       struct msghdr msg = {
+           .msg_name = &from, .msg_namelen = sizeof(from),
+           .msg_iov = &iov, .msg_iovlen = 1,
+           .msg_control = ctl, .msg_controllen = sizeof(ctl),
+       };
+       int s;
+       ssize_t bytes;
+
+       s = ia != NULL ? ia->dhcp6_fd : ctx->dhcp6_fd;
+       bytes = recvmsg(s, &msg, 0);
+       if (bytes == -1) {
+               logerr(__func__);
+               return;
+       }
+
+       iov.iov_len = (size_t)bytes;
+       dhcp6_recvmsg(ctx, &msg, ia);
+}
+
 static void
 dhcp6_recvaddr(void *arg)
 {
index 929b071d090bd1fab3ed7b73572988a54f305a17..44beb400dd0054680a7b42c615c45098ed1550a9 100644 (file)
@@ -1718,6 +1718,51 @@ ipv6nd_drop(struct interface *ifp)
        }
 }
 
+static void
+ipv6nd_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg)
+{
+       struct sockaddr_in6 *from = (struct sockaddr_in6 *)msg->msg_name;
+       char sfrom[INET6_ADDRSTRLEN];
+       int hoplimit = 0;
+       struct icmp6_hdr *icp;
+       struct interface *ifp;
+       size_t len = msg->msg_iov[0].iov_len;
+
+       inet_ntop(AF_INET6, &from->sin6_addr, sfrom, sizeof(sfrom));
+       if ((size_t)len < sizeof(struct icmp6_hdr)) {
+               logerrx("IPv6 ICMP packet too short from %s", sfrom);
+               return;
+       }
+
+#ifdef __sun
+       if_findifpfromcmsg(ctx, msg, &hoplimit);
+#else
+       ifp = if_findifpfromcmsg(ctx, msg, &hoplimit);
+       if (ifp == NULL) {
+               logerr(__func__);
+               return;
+       }
+#endif
+
+       /* Don't do anything if the user hasn't configured it. */
+       if (ifp->active != IF_ACTIVE_USER ||
+           !(ifp->options->options & DHCPCD_IPV6))
+               return;
+
+       icp = (struct icmp6_hdr *)msg->msg_iov[0].iov_base;
+       if (icp->icmp6_code == 0) {
+               switch(icp->icmp6_type) {
+                       case ND_ROUTER_ADVERT:
+                               ipv6nd_handlera(ctx, from, sfrom,
+                                   ifp, icp, (size_t)len, hoplimit);
+                               return;
+               }
+       }
+
+       logerrx("invalid IPv6 type %d or code %d from %s",
+           icp->icmp6_type, icp->icmp6_code, sfrom);
+}
+
 static void
 ipv6nd_handledata(void *arg)
 {
@@ -1736,10 +1781,6 @@ ipv6nd_handledata(void *arg)
            .msg_control = ctl, .msg_controllen = sizeof(ctl),
        };
        ssize_t len;
-       char sfrom[INET6_ADDRSTRLEN];
-       int hoplimit = 0;
-       struct icmp6_hdr *icp;
-       struct interface *ifp;
 
 #ifdef __sun
        struct rs_state *state;
@@ -1757,39 +1798,9 @@ ipv6nd_handledata(void *arg)
                logerr(__func__);
                return;
        }
-       inet_ntop(AF_INET6, &from.sin6_addr, sfrom, sizeof(sfrom));
-       if ((size_t)len < sizeof(struct icmp6_hdr)) {
-               logerrx("IPv6 ICMP packet too short from %s", sfrom);
-               return;
-       }
-
-#ifdef __sun
-       if_findifpfromcmsg(ctx, &msg, &hoplimit);
-#else
-       ifp = if_findifpfromcmsg(ctx, &msg, &hoplimit);
-       if (ifp == NULL) {
-               logerr(__func__);
-               return;
-       }
-#endif
 
-       /* Don't do anything if the user hasn't configured it. */
-       if (ifp->active != IF_ACTIVE_USER ||
-           !(ifp->options->options & DHCPCD_IPV6))
-               return;
-
-       icp = (struct icmp6_hdr *)buf;
-       if (icp->icmp6_code == 0) {
-               switch(icp->icmp6_type) {
-                       case ND_ROUTER_ADVERT:
-                               ipv6nd_handlera(ctx, &from, sfrom,
-                                   ifp, icp, (size_t)len, hoplimit);
-                               return;
-               }
-       }
-
-       logerrx("invalid IPv6 type %d or code %d from %s",
-           icp->icmp6_type, icp->icmp6_code, sfrom);
+       iov.iov_len = (size_t)len;
+       ipv6nd_recvmsg(ctx, &msg);
 }
 
 static void