Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 76 additions & 41 deletions src/dhcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -3091,6 +3091,7 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
bool bootp_copied;
uint32_t v6only_time = 0;
bool use_v6only = false, has_auto_conf = false;
bool bootp_must_reject_dhcp = false;
struct dhcp_policy dp = {
.ctx = ifp->ctx,
.bootp = bootp,
Expand Down Expand Up @@ -3128,13 +3129,53 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
return;
}

/* We may have found a BOOTP server */
if (get_option_uint8(ifp->ctx, &type, bootp, bootp_len,
DHO_MESSAGETYPE) == -1)
type = 0;
else
bootp_must_reject_dhcp = (ifo->options & DHCPCD_BOOTP) != 0;

#ifdef AUTH
if (type == DHCP_FORCERENEW) {
auth = get_option(ifp->ctx, bootp, bootp_len,
DHO_AUTHENTICATION, &auth_len);
if (auth == NULL) {
LOGDHCP(LOG_ERR, "unauthenticated Force Renew");
return;
}
if (dhcp_auth_validate(&state->auth, &ifo->auth,
(uint8_t *)bootp, bootp_len, 4, type, auth,
auth_len) == NULL) {
LOGDHCP0(LOG_ERR, "authentication failed");
return;
}
if (state->auth.token)
logdebugx("%s: validated using 0x%08" PRIu32, ifp->name,
state->auth.token->secretid);
else
loginfox("%s: accepted reconfigure key", ifp->name);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop this to debug as renew is now debug

}
#endif

if (state->xid != ntohl(bootp->xid)) {
if (IS_STATE_ACTIVE(state))
logdebugx("%s: wrong xid 0x%x (expecting 0x%x) from %s",
ifp->name, ntohl(bootp->xid), state->xid,
inet_ntoa(*from));
dhcp_redirect_dhcp(ifp, bootp, bootp_len, from);
return;
/* AUTH has already run; this only skips redirect for
* MikroTik xid 0 FORCERENEW. Non-FORCERENEW xid
* mismatches still redirect. */
if (bootp->xid == 0 && type == DHCP_FORCERENEW) {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if (IS_STATE_ACTIVE(state))
logdebugx(
"%s: xid 0 in a BOOTP reply FORCERENEW from %s",
ifp->name, inet_ntoa(*from));
} else {
if (IS_STATE_ACTIVE(state))
logdebugx(
"%s: wrong xid 0x%x (expecting 0x%x) from %s",
ifp->name, ntohl(bootp->xid), state->xid,
inet_ntoa(*from));
dhcp_redirect_dhcp(ifp, bootp, bootp_len, from);
return;
}
}

if (ifp->hwlen <= sizeof(bootp->chaddr) &&
Expand Down Expand Up @@ -3170,38 +3211,31 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
}
}

/* We may have found a BOOTP server */
if (get_option_uint8(ifp->ctx, &type, bootp, bootp_len,
DHO_MESSAGETYPE) == -1)
type = 0;
else if (ifo->options & DHCPCD_BOOTP) {
logdebugx("%s: ignoring DHCP reply (expecting BOOTP)",
ifp->name);
return;
}

#ifdef AUTH
/* Authenticate the message */
auth = get_option(ifp->ctx, bootp, bootp_len, DHO_AUTHENTICATION,
&auth_len);
if (auth) {
if (dhcp_auth_validate(&state->auth, &ifo->auth,
(uint8_t *)bootp, bootp_len, 4, type, auth,
auth_len) == NULL) {
LOGDHCP0(LOG_ERR, "authentication failed");
return;
}
if (state->auth.token)
logdebugx("%s: validated using 0x%08" PRIu32, ifp->name,
state->auth.token->secretid);
else
loginfox("%s: accepted reconfigure key", ifp->name);
} else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
LOGDHCP0(LOG_ERR, "no authentication");
return;
if (type != DHCP_FORCERENEW) {
/* Authenticate the message */
auth = get_option(ifp->ctx, bootp, bootp_len,
DHO_AUTHENTICATION, &auth_len);
if (auth) {
if (dhcp_auth_validate(&state->auth, &ifo->auth,
(uint8_t *)bootp, bootp_len, 4, type, auth,
auth_len) == NULL) {
LOGDHCP0(LOG_ERR, "authentication failed");
return;
}
if (state->auth.token)
logdebugx("%s: validated using 0x%08" PRIu32,
ifp->name, state->auth.token->secretid);
else
loginfox("%s: accepted reconfigure key",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same, renew msgs are debug level, so consider dropping the log level here too

ifp->name);
} else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
LOGDHCP0(LOG_ERR, "no authentication");
return;
}
LOGDHCP0(LOG_WARNING, "no authentication");
}
LOGDHCP0(LOG_WARNING, "no authentication");
}
#endif

Expand All @@ -3213,11 +3247,6 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
return;
}
#ifdef AUTH
if (auth == NULL) {
LOGDHCP(LOG_ERR, "unauthenticated Force Renew");
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
return;
}
if (state->state != DHS_BOUND && state->state != DHS_INFORM) {
LOGDHCP(LOG_DEBUG, "not bound, ignoring Force Renew");
return;
Expand All @@ -3237,6 +3266,12 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
return;
}

if (bootp_must_reject_dhcp) {
logdebugx("%s: ignoring DHCP reply (expecting BOOTP)",
ifp->name);
return;
}

if (state->state == DHS_BOUND) {
LOGDHCP(LOG_DEBUG, "bound, ignoring");
return;
Expand Down