}
static int
-dhcp_openudp(struct interface *ifp)
+dhcp_openudp(struct in_addr *ia)
{
int s;
struct sockaddr_in sin;
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;
}
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;
}
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;
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.
#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;
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,
}
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;
}
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;