From 549c5cd11828a1682d54fed898312c9150174a61 Mon Sep 17 00:00:00 2001 From: Colin McInnes Date: Tue, 1 Sep 2026 15:32:14 +0000 Subject: [PATCH 1/4] Add support for RFC 2132 Message option in NAK handling --- hooks/dhcpcd-run-hooks.8.in | 7 +++++++ src/dhcp.c | 5 +++++ src/dhcp.h | 1 + src/script.c | 12 ++++++++++++ 4 files changed, 25 insertions(+) diff --git a/hooks/dhcpcd-run-hooks.8.in b/hooks/dhcpcd-run-hooks.8.in index 8672a22f9..935dfd904 100644 --- a/hooks/dhcpcd-run-hooks.8.in +++ b/hooks/dhcpcd-run-hooks.8.in @@ -124,6 +124,9 @@ dhcpcd's lease or state expired and it failed to obtain a new one. .It Dv NAK dhcpcd received a NAK from the DHCP server. This should be treated as EXPIRE. +If the server included a Message option (RFC 2132 option 56), +.Ev $message +is set to that text. .It Dv RECONFIGURE dhcpcd has been instructed to reconfigure an interface. .It Dv ROUTERADVERT @@ -158,6 +161,10 @@ the name of the interface. the protocol that triggered the event. .It Ev $reason as described above. +.It Ev $message +the RFC 2132 Message option (code 56) included with a +.Dv NAK +reason, if present. .It Ev $pid the pid of .Nm dhcpcd . diff --git a/src/dhcp.c b/src/dhcp.c index 078f6927e..9f019aa46 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -3271,6 +3271,10 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len, if (state->state == DHS_INFORM) /* INFORM should not be NAKed */ return; if (!(ifp->ctx->options & DHCPCD_TEST)) { + if (state->message) + free(state->message); + state->message = get_option_string(ifp->ctx, bootp, + bootp_len, DHO_MESSAGE); dhcp_drop(ifp, "NAK"); dhcp_unlink(ifp->ctx, state->leasefile); } @@ -3914,6 +3918,7 @@ dhcp_free(struct interface *ifp) free(state->new); free(state->offer); free(state->clientid); + free(state->message); free(state); ifp->if_data[IF_DATA_DHCP] = NULL; } diff --git a/src/dhcp.h b/src/dhcp.h index 5dbea7d5e..5b100b14f 100644 --- a/src/dhcp.h +++ b/src/dhcp.h @@ -236,6 +236,7 @@ struct dhcp_state { #ifdef ARPING ssize_t arping_index; #endif + char *message; /* RFC 2132 option 56 from NAK */ }; #ifdef INET diff --git a/src/script.c b/src/script.c index e059472e2..3108aea8f 100644 --- a/src/script.c +++ b/src/script.c @@ -470,6 +470,18 @@ make_env(struct dhcpcd_ctx *ctx, const struct interface *ifp, if_up = false_str; if_down = true_str; } +#ifdef INET + if (strcmp(reason, "NAK") == 0) { + struct dhcp_state *dstate = D_STATE(ifp); + + if (dstate != NULL && dstate->message != NULL) { + if (efprintf(fp, "message=%s", dstate->message) == -1) + goto eexit; + free(dstate->message); + dstate->message = NULL; + } + } +#endif if (efprintf(fp, "if_up=%s", if_up) == -1) goto eexit; if (efprintf(fp, "if_down=%s", if_down) == -1) From 324f1e19b164d9e590a915536198f507d9c272b2 Mon Sep 17 00:00:00 2001 From: Colin McInnes Date: Tue, 1 Sep 2026 16:14:00 +0000 Subject: [PATCH 2/4] Add support for RFC 2132 Message option in NAK handling --- src/dhcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dhcp.h b/src/dhcp.h index 5b100b14f..a2159061f 100644 --- a/src/dhcp.h +++ b/src/dhcp.h @@ -236,7 +236,7 @@ struct dhcp_state { #ifdef ARPING ssize_t arping_index; #endif - char *message; /* RFC 2132 option 56 from NAK */ + char *message; /* RFC 2132 option 56 from NAK */ }; #ifdef INET From 8b73afe23a42d970e02d4c11d2c2b34c14469841 Mon Sep 17 00:00:00 2001 From: Colin McInnes Date: Tue, 1 Sep 2026 10:41:09 -0600 Subject: [PATCH 3/4] Clarify comment for DHCPv4 NAK message --- src/dhcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dhcp.h b/src/dhcp.h index a2159061f..0cc6566d5 100644 --- a/src/dhcp.h +++ b/src/dhcp.h @@ -236,7 +236,7 @@ struct dhcp_state { #ifdef ARPING ssize_t arping_index; #endif - char *message; /* RFC 2132 option 56 from NAK */ + char *message; /* RFC 2132 option 56 from DHCPv4 NAK */ }; #ifdef INET From 860739c93bb96a5bb457f02063a13bcd4be4cbf0 Mon Sep 17 00:00:00 2001 From: Colin McInnes Date: Tue, 1 Sep 2026 17:32:35 +0000 Subject: [PATCH 4/4] Format DHCP NAK message handling --- src/dhcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dhcp.c b/src/dhcp.c index 9f019aa46..adbc48c1d 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -3274,7 +3274,7 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len, if (state->message) free(state->message); state->message = get_option_string(ifp->ctx, bootp, - bootp_len, DHO_MESSAGE); + bootp_len, DHO_MESSAGE); dhcp_drop(ifp, "NAK"); dhcp_unlink(ifp->ctx, state->leasefile); }