From 4d739acbdd9e2d5a39f58e8529dec9207a35d150 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Sun, 28 Aug 2022 04:41:11 -0400 Subject: [PATCH] Use a helper to ensure xid always changes when we advance it. The purpose of the changing xid is to prevent misinterpreting delayed messages, and the rare chance where it's randomly the same breaks this sequence-id property. --- dhcp.c | 2 +- ndhc.h | 7 +++++++ state.c | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) 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) {