]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
DHCP: Improve API for privsep
authorRoy Marples <roy@marples.name>
Tue, 26 Nov 2019 19:57:30 +0000 (19:57 +0000)
committerRoy Marples <roy@marples.name>
Tue, 26 Nov 2019 19:57:30 +0000 (19:57 +0000)
src/dhcp.c

index 73ab29e610afbd311ea2701a2aa6f0905ddf85ef..686aee449ba92e913c2c9aa0d76164ffc84c744b 100644 (file)
@@ -1540,7 +1540,7 @@ dhcp_close(struct interface *ifp)
 }
 
 static int
-dhcp_openudp(struct interface *ifp)
+dhcp_openudp(struct in_addr *ia)
 {
        int s;
        struct sockaddr_in sin;
@@ -1551,29 +1551,25 @@ dhcp_openudp(struct interface *ifp)
 
        n = 1;
        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
-               goto eexit;
+               goto errexit;
 #ifdef IP_RECVIF
        if (setsockopt(s, IPPROTO_IP, IP_RECVIF, &n, sizeof(n)) == -1)
-               goto eexit;
+               goto errexit;
 #else
        if (setsockopt(s, IPPROTO_IP, IP_RECVPKTINFO, &n, sizeof(n)) == -1)
-               goto eexit;
+               goto errexit;
 #endif
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_port = htons(BOOTPC);
-       if (ifp) {
-               const struct dhcp_state *state = D_CSTATE(ifp);
-
-               if (state->addr)
-                       sin.sin_addr.s_addr = state->addr->addr.s_addr;
-       }
+       if (ia != NULL)
+               sin.sin_addr = *ia;
        if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
-               goto eexit;
+               goto errexit;
 
        return s;
 
-eexit:
+errexit:
        close(s);
        return -1;
 }
@@ -1675,7 +1671,7 @@ dhcp_sendudp(struct interface *ifp, struct in_addr *to, void *data, size_t len)
 
        fd = state->udp_fd;
        if (fd == -1) {
-               fd = dhcp_openudp(ifp);
+               fd = dhcp_openudp(state->addr != NULL ?&state->addr->addr:NULL);
                if (fd == -1)
                        return -1;
        }
@@ -1734,7 +1730,9 @@ send_message(struct interface *ifp, uint8_t type,
                goto fail;
        len = (size_t)r;
 
-       if (ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL)
+       if (!(state->added & STATE_FAKE) &&
+           state->addr != NULL &&
+           ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL)
                from.s_addr = state->lease.addr.s_addr;
        else
                from.s_addr = INADDR_ANY;
@@ -2266,10 +2264,11 @@ dhcp_bind(struct interface *ifp)
                return;
        dhcp_close(ifp);
 
+
        /* If not in master mode, open an address specific socket. */
        if (ctx->udp_fd != -1)
                return;
-       state->udp_fd = dhcp_openudp(ifp);
+       state->udp_fd = dhcp_openudp(&state->addr->addr);
        if (state->udp_fd == -1) {
                logerr(__func__);
                /* Address sharing without master mode is not supported.
@@ -2352,6 +2351,7 @@ dhcp_arp_new(struct interface *ifp, struct in_addr *addr)
 #ifdef KERNEL_RFC5227
        astate->announced_cb = dhcp_arp_announced;
 #else
+       astate->announced_cb = NULL;
        astate->defend_failed_cb = dhcp_arp_defend_failed;
 #endif
        return astate;
@@ -2501,7 +2501,7 @@ dhcp_inform(struct interface *ifp)
                        state->offer_len = dhcp_message_new(&state->offer,
                            &ifo->req_addr, &ifo->req_mask);
 #ifdef ARP
-                       if (dhcp_arp_address(ifp) == 0)
+                       if (dhcp_arp_address(ifp) != 1)
                                return;
 #endif
                        ia = ipv4_iffindaddr(ifp,
@@ -3390,7 +3390,7 @@ dhcp_handlebootp(struct interface *ifp, struct bootp *bootp, size_t len,
 }
 
 static void
-dhcp_handlebpf(struct interface *ifp, uint8_t *data, size_t len)
+dhcp_packet(struct interface *ifp, uint8_t *data, size_t len)
 {
        struct bootp *bootp;
        struct in_addr from;
@@ -3445,7 +3445,7 @@ dhcp_readbpf(void *arg)
                        }
                        break;
                }
-               dhcp_handlebpf(ifp, buf, (size_t)bytes);
+               dhcp_packet(ifp, buf, (size_t)bytes);
                /* Check we still have a state after processing. */
                if ((state = D_STATE(ifp)) == NULL)
                        break;