serverid checks for RENEW and REBIND DHCP(ACK|NAK) were too strict.
Use the same test that is already used for the DHCPACK sent by the server in the REQUESTING state.
This commit is contained in:
parent
b07ebb60a2
commit
d58338b70b
90
src/state.c
90
src/state.c
@ -180,28 +180,6 @@ static int bound_timeout(struct client_state_t cs[static 1], long long nowts)
|
|||||||
return renewing_timeout(cs, nowts);
|
return renewing_timeout(cs, nowts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int validate_serverid(struct client_state_t cs[static 1],
|
|
||||||
struct dhcpmsg packet[static 1],
|
|
||||||
const char typemsg[static 1])
|
|
||||||
{
|
|
||||||
int found;
|
|
||||||
uint32_t sid = get_option_serverid(packet, &found);
|
|
||||||
if (!found) {
|
|
||||||
log_line("%s: Received %s with no server id. Ignoring it.",
|
|
||||||
client_config.interface, typemsg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (cs->serverAddr != sid) {
|
|
||||||
char svrbuf[INET_ADDRSTRLEN];
|
|
||||||
inet_ntop(AF_INET, &(struct in_addr){.s_addr=sid},
|
|
||||||
svrbuf, sizeof svrbuf);
|
|
||||||
log_line("%s: Received %s with an unexpected server id: %s. Ignoring it.",
|
|
||||||
client_config.interface, typemsg, svrbuf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_leasetime(struct client_state_t cs[static 1],
|
static void get_leasetime(struct client_state_t cs[static 1],
|
||||||
struct dhcpmsg packet[static 1])
|
struct dhcpmsg packet[static 1])
|
||||||
{
|
{
|
||||||
@ -225,13 +203,39 @@ static void get_leasetime(struct client_state_t cs[static 1],
|
|||||||
cs->dhcp_wake_ts = cs->leaseStartTime + cs->renewTime * 1000;
|
cs->dhcp_wake_ts = cs->leaseStartTime + cs->renewTime * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool validate_acknak(struct client_state_t cs[static 1],
|
||||||
|
struct dhcpmsg packet[static 1],
|
||||||
|
const char typemsg[static 1],
|
||||||
|
uint32_t srcaddr)
|
||||||
|
{
|
||||||
|
// Don't validate the server id. Instead validate that the
|
||||||
|
// yiaddr matches. Some networks have multiple servers
|
||||||
|
// that don't respect the serverid that was specified in
|
||||||
|
// our DHCPREQUEST.
|
||||||
|
if (memcmp(&packet->yiaddr, &cs->clientAddr, 4))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int found;
|
||||||
|
uint32_t sid = get_option_serverid(packet, &found);
|
||||||
|
if (!found) {
|
||||||
|
log_line("%s: Received %s with no server id. Ignoring it.",
|
||||||
|
client_config.interface, typemsg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cs->serverAddr != sid) {
|
||||||
|
cs->serverAddr = sid;
|
||||||
|
cs->srcAddr = srcaddr;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int extend_packet(struct client_state_t cs[static 1],
|
static int extend_packet(struct client_state_t cs[static 1],
|
||||||
struct dhcpmsg packet[static 1], uint8_t msgtype,
|
struct dhcpmsg packet[static 1], uint8_t msgtype,
|
||||||
uint32_t srcaddr)
|
uint32_t srcaddr)
|
||||||
{
|
{
|
||||||
(void)srcaddr;
|
(void)srcaddr;
|
||||||
if (msgtype == DHCPACK) {
|
if (msgtype == DHCPACK) {
|
||||||
if (!validate_serverid(cs, packet, "a DHCP ACK"))
|
if (!validate_acknak(cs, packet, "DHCPACK", srcaddr))
|
||||||
return ANP_IGNORE;
|
return ANP_IGNORE;
|
||||||
cs->sent_renew_or_rebind = false;
|
cs->sent_renew_or_rebind = false;
|
||||||
cs->num_dhcp_renews = 0;
|
cs->num_dhcp_renews = 0;
|
||||||
@ -255,7 +259,7 @@ static int extend_packet(struct client_state_t cs[static 1],
|
|||||||
return ANP_SUCCESS;
|
return ANP_SUCCESS;
|
||||||
}
|
}
|
||||||
} else if (msgtype == DHCPNAK) {
|
} else if (msgtype == DHCPNAK) {
|
||||||
if (!validate_serverid(cs, packet, "a DHCP NAK"))
|
if (!validate_acknak(cs, packet, "DHCPNAK", srcaddr))
|
||||||
return ANP_IGNORE;
|
return ANP_IGNORE;
|
||||||
cs->sent_renew_or_rebind = false;
|
cs->sent_renew_or_rebind = false;
|
||||||
cs->num_dhcp_renews = 0;
|
cs->num_dhcp_renews = 0;
|
||||||
@ -298,33 +302,19 @@ static int selecting_packet(struct client_state_t cs[static 1],
|
|||||||
client_config.interface, clibuf, svrbuf, srcbuf);
|
client_config.interface, clibuf, svrbuf, srcbuf);
|
||||||
return ANP_SUCCESS;
|
return ANP_SUCCESS;
|
||||||
} else if (is_requesting && msgtype == DHCPACK) {
|
} else if (is_requesting && msgtype == DHCPACK) {
|
||||||
// Don't validate the server id. Instead validate that the
|
if (!validate_acknak(cs, packet, "DHCPACK", srcaddr))
|
||||||
// yiaddr matches. Some networks have multiple servers
|
return ANP_IGNORE;
|
||||||
// that don't respect the serverid that was specified in
|
get_leasetime(cs, packet);
|
||||||
// our DHCPREQUEST.
|
|
||||||
if (!memcmp(&packet->yiaddr, &cs->clientAddr, 4)) {
|
|
||||||
uint32_t sid = get_option_serverid(packet, &found);
|
|
||||||
if (!found) {
|
|
||||||
log_line("%s: Invalid offer received: it didn't have a server id.",
|
|
||||||
client_config.interface);
|
|
||||||
return ANP_IGNORE;
|
|
||||||
}
|
|
||||||
if (cs->serverAddr != sid) {
|
|
||||||
cs->serverAddr = sid;
|
|
||||||
cs->srcAddr = srcaddr;
|
|
||||||
}
|
|
||||||
get_leasetime(cs, packet);
|
|
||||||
|
|
||||||
inet_ntop(AF_INET, &(struct in_addr){.s_addr=cs->clientAddr},
|
inet_ntop(AF_INET, &(struct in_addr){.s_addr=cs->clientAddr},
|
||||||
clibuf, sizeof clibuf);
|
clibuf, sizeof clibuf);
|
||||||
inet_ntop(AF_INET, &(struct in_addr){.s_addr=cs->serverAddr},
|
inet_ntop(AF_INET, &(struct in_addr){.s_addr=cs->serverAddr},
|
||||||
svrbuf, sizeof svrbuf);
|
svrbuf, sizeof svrbuf);
|
||||||
inet_ntop(AF_INET, &(struct in_addr){.s_addr=cs->srcAddr},
|
inet_ntop(AF_INET, &(struct in_addr){.s_addr=cs->srcAddr},
|
||||||
srcbuf, sizeof srcbuf);
|
srcbuf, sizeof srcbuf);
|
||||||
log_line("%s: Received ACK: %s from server %s via %s. Validating...",
|
log_line("%s: Received ACK: %s from server %s via %s. Validating...",
|
||||||
client_config.interface, clibuf, svrbuf, srcbuf);
|
client_config.interface, clibuf, svrbuf, srcbuf);
|
||||||
return ANP_CHECK_IP;
|
return ANP_CHECK_IP;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ANP_IGNORE;
|
return ANP_IGNORE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user