From dc5cbcda16a9ac1c20ab7207b8060a99983adcaa Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Sun, 6 Sep 2026 18:03:18 +0200 Subject: [PATCH 1/2] dhcp: fix transaction-id check so it actually compares The guard read `if (!DHCP_P->tid == HTONS(...))`. Unary `!` binds tighter than `==`, so this evaluated `(!tid) == HTONS(id)`, i.e. `(tid ? 0 : 1) == HTONS(id)`, which is false for any non-zero id and never returns. The reply was therefore accepted regardless of its transaction id, so a broadcast reply meant for another client on the segment was parsed as ours. Compare the field directly. The id is stored network-order in the packet and host-order in the state, matching the HTONS() used when the request is built, so `DHCP_P->tid != HTONS(dhcp_state.transaction_id)` is the intended test. --- dhcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dhcp.c b/dhcp.c index d821f805..9d92acb5 100644 --- a/dhcp.c +++ b/dhcp.c @@ -300,7 +300,7 @@ void parse_opts(void) void parse_dhcp(void) { - if (!DHCP_P->tid == HTONS(dhcp_state.transaction_id)) + if (DHCP_P->tid != HTONS(dhcp_state.transaction_id)) return; if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63) return; From 97d44fbf4b379c0fd196256689227ae6e980081e Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Sun, 6 Sep 2026 20:30:40 +0200 Subject: [PATCH 2/2] dhcp: drop the 16-bit swap on the 32-bit transaction id The id was built and checked with HTONS(), which casts to 16 bits, so the top half of the 32-bit transaction id was thrown away and the rest byte swapped. The id is opaque: the client only has to receive its own value back, so there is no byte order to honour and no reason to narrow it. Assign and compare the field directly, so the full 32-bit id round-trips. --- dhcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dhcp.c b/dhcp.c index 9d92acb5..6cfa373a 100644 --- a/dhcp.c +++ b/dhcp.c @@ -94,7 +94,7 @@ void dhcp_prepare_request(void) DHCP_P->hw_len = 6; DHCP_P->hops = 0; - DHCP_P->tid = HTONS(dhcp_state.transaction_id); + DHCP_P->tid = dhcp_state.transaction_id; DHCP_P->delay = HTONS(0); DHCP_P->flags = 0; // Clear fields client_ip to bootp_file @@ -300,7 +300,7 @@ void parse_opts(void) void parse_dhcp(void) { - if (DHCP_P->tid != HTONS(dhcp_state.transaction_id)) + if (DHCP_P->tid != dhcp_state.transaction_id) return; if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63) return;