From: Roy Marples Date: Tue, 26 Nov 2019 19:57:30 +0000 (+0000) Subject: DHCP: Improve API for privsep X-Git-Tag: v8.1.3~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3bf57d1eb52fe05aec05cc7de2b6f6d6129e60a3;p=thirdparty%2Fdhcpcd.git DHCP: Improve API for privsep --- diff --git a/src/dhcp.c b/src/dhcp.c index 73ab29e6..686aee44 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -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;