diff --git a/ndhc/arp.c b/ndhc/arp.c index a840146..9a68df2 100644 --- a/ndhc/arp.c +++ b/ndhc/arp.c @@ -486,12 +486,7 @@ void arp_success(struct client_state_t *cs) if (cs->arpPrevState == DS_RENEWING || cs->arpPrevState == DS_REBINDING) { arp_switch_state(cs, AS_DEFENSE); } else { - ssize_t ol; - uint8_t *od = get_option_data(&arp_dhcp_packet, DCODE_ROUTER, &ol); - if (ol == 4) { - memcpy(&cs->routerAddr, od, 4); - } else - cs->routerAddr = 0; + cs->routerAddr = get_option_router(&arp_dhcp_packet); arp_get_gw_hwaddr(cs); } set_listen_none(cs); diff --git a/ndhc/dhcp.c b/ndhc/dhcp.c index af8b176..ae0b5cd 100644 --- a/ndhc/dhcp.c +++ b/ndhc/dhcp.c @@ -503,13 +503,11 @@ static int validate_dhcp_packet(struct client_state_t *cs, int len, packet->xid, cs->xid); return 0; } - ssize_t optlen; - uint8_t *temp = get_option_data(packet, DCODE_MSGTYPE, &optlen); - if (!temp) { + *msgtype = get_option_msgtype(packet); + if (!*msgtype) { log_line("Packet does not specify a DHCP message type. Ignoring."); return 0; } - *msgtype = *temp; return 1; } diff --git a/ndhc/options.c b/ndhc/options.c index 786f870..d734858 100644 --- a/ndhc/options.c +++ b/ndhc/options.c @@ -372,3 +372,49 @@ void add_option_hostname(struct dhcpmsg *packet) add_option_string(packet, DCODE_HOSTNAME, client_config.hostname, len); } +uint32_t get_option_router(struct dhcpmsg *packet) +{ + ssize_t ol; + uint32_t ret = 0; + uint8_t *od = get_option_data(packet, DCODE_ROUTER, &ol); + if (ol == sizeof ret) + memcpy(&ret, od, sizeof ret); + return ret; +} + +uint8_t get_option_msgtype(struct dhcpmsg *packet) +{ + ssize_t ol; + uint8_t ret = 0; + uint8_t *t = get_option_data(packet, DCODE_MSGTYPE, &ol); + if (t) + ret = *t; + return ret; +} + +uint32_t get_option_serverid(struct dhcpmsg *packet, int *found) +{ + ssize_t ol; + uint8_t *t; + uint32_t ret = 0; + *found = 0; + t = get_option_data(packet, DCODE_SERVER_ID, &ol); + if (ol == sizeof ret) { + *found = 1; + memcpy(&ret, t, sizeof ret); + } + return ret; +} + +uint32_t get_option_leasetime(struct dhcpmsg *packet) +{ + ssize_t ol; + uint8_t *t; + uint32_t ret = 0; + t = get_option_data(packet, DCODE_LEASET, &ol); + if (ol == sizeof ret) { + memcpy(&ret, t, sizeof ret); + ret = ntohl(ret); + } + return ret; +} diff --git a/ndhc/options.h b/ndhc/options.h index 9ae31a1..baa255e 100644 --- a/ndhc/options.h +++ b/ndhc/options.h @@ -82,4 +82,9 @@ void add_option_vendor(struct dhcpmsg *packet); void add_option_clientid(struct dhcpmsg *packet); void add_option_hostname(struct dhcpmsg *packet); +uint32_t get_option_router(struct dhcpmsg *packet); +uint8_t get_option_msgtype(struct dhcpmsg *packet); +uint32_t get_option_serverid(struct dhcpmsg *packet, int *found); +uint32_t get_option_leasetime(struct dhcpmsg *packet); + #endif diff --git a/ndhc/state.c b/ndhc/state.c index 75780b3..96cb5d8 100644 --- a/ndhc/state.c +++ b/ndhc/state.c @@ -192,17 +192,15 @@ static void released_timeout(struct client_state_t *cs, long long nowts) static int validate_serverid(struct client_state_t *cs, struct dhcpmsg *packet, char *typemsg) { - uint8_t *temp = NULL; - ssize_t optlen; - if (!(temp = get_option_data(packet, DCODE_SERVER_ID, &optlen))) { + int found; + uint32_t sid = get_option_serverid(packet, &found); + if (!found) { log_line("Received %s with no server id. Ignoring it."); return 0; } - if (memcmp(&cs->serverAddr, temp, 4)) { + if (cs->serverAddr != sid) { char svrbuf[INET_ADDRSTRLEN]; - uint32_t iptmp; - memcpy(&iptmp, temp, 4); - inet_ntop(AF_INET, &(struct in_addr){.s_addr=iptmp}, + inet_ntop(AF_INET, &(struct in_addr){.s_addr=sid}, svrbuf, sizeof svrbuf); log_line("Received %s with an unexpected server id: %s. Ignoring it.", typemsg, svrbuf); @@ -218,15 +216,12 @@ static void an_packet(struct client_state_t *cs, struct dhcpmsg *packet, if (msgtype == DHCPACK) { if (!validate_serverid(cs, packet, "a DHCP ACK")) return; - ssize_t optlen; - uint8_t *temp = get_option_data(packet, DCODE_LEASET, &optlen); + cs->lease = get_option_leasetime(packet); cs->leaseStartTime = curms(); - if (!temp) { + if (!cs->lease) { log_line("No lease time received, assuming 1h."); cs->lease = 60 * 60; } else { - memcpy(&cs->lease, temp, 4); - cs->lease = ntohl(cs->lease); if (cs->lease < 60) { log_warning("Server sent lease of <1m. Forcing lease to 1m."); cs->lease = 60; @@ -269,12 +264,12 @@ static void selecting_packet(struct client_state_t *cs, struct dhcpmsg *packet, uint8_t msgtype) { if (msgtype == DHCPOFFER) { - uint8_t *temp = NULL; - ssize_t optlen; - if ((temp = get_option_data(packet, DCODE_SERVER_ID, &optlen))) { + int found; + uint32_t sid = get_option_serverid(packet, &found); + if (found) { char clibuf[INET_ADDRSTRLEN]; char svrbuf[INET_ADDRSTRLEN]; - memcpy(&cs->serverAddr, temp, 4); + cs->serverAddr = sid; cs->xid = packet->xid; cs->clientAddr = packet->yiaddr; cs->dhcpState = DS_REQUESTING;