diff --git a/dhcp.c b/dhcp.c index c7a359c..b9cb7df 100644 --- a/dhcp.c +++ b/dhcp.c @@ -413,7 +413,7 @@ static void init_packet(struct dhcpmsg *packet, uint8_t type) ssize_t send_discover(struct client_state_t *cs) { - cs->xid = nk_random_u32(&cs->rnd_state); + advance_xid(cs); struct dhcpmsg packet = {.xid = cs->xid}; init_packet(&packet, DHCPDISCOVER); if (cs->clientAddr) diff --git a/ndhc.h b/ndhc.h index 3b3571d..917cf5c 100644 --- a/ndhc.h +++ b/ndhc.h @@ -86,5 +86,12 @@ void signal_exit(int status); int get_clientid_string(const char *str, size_t slen); void print_version(void); +static inline void advance_xid(struct client_state_t *cs) { + uint32_t o = cs->xid; + do { + cs->xid = nk_random_u32(&cs->rnd_state); + } while (cs->xid == o); +} + #endif diff --git a/state.c b/state.c index 474ff42..9e7ffa0 100644 --- a/state.c +++ b/state.c @@ -53,7 +53,7 @@ static int delay_timeout(struct client_state_t *cs, size_t numpackets) static void reinit_shared_deconfig(struct client_state_t *cs) { nk_random_init(&cs->rnd_state); - cs->xid = nk_random_u32(&cs->rnd_state); + advance_xid(cs); cs->clientAddr = 0; cs->num_dhcp_requests = 0; cs->num_dhcp_renews = 0; @@ -224,7 +224,7 @@ static int extend_packet(struct client_state_t *cs, clibuf, sizeof clibuf); log_line("%s: Server is now offering IP %s. Validating...", client_config.interface, clibuf); - cs->xid = nk_random_u32(&cs->rnd_state); + advance_xid(cs); return ANP_CHECK_IP; } else { log_line("%s: Lease refreshed to %u seconds.", @@ -233,7 +233,7 @@ static int extend_packet(struct client_state_t *cs, log_line("%s: Failed to create ARP defense socket.", client_config.interface); stop_dhcp_listen(cs); - cs->xid = nk_random_u32(&cs->rnd_state); + advance_xid(cs); return ANP_SUCCESS; } } else if (msgtype == DHCPNAK) {