diff options
-rw-r--r-- | networking/udhcp/common.c | 19 | ||||
-rw-r--r-- | networking/udhcp/common.h | 4 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 6 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 6 |
4 files changed, 29 insertions, 6 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index e5fd74f91..41b05b855 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -272,6 +272,15 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |||
272 | goto complain; /* complain and return NULL */ | 272 | goto complain; /* complain and return NULL */ |
273 | 273 | ||
274 | if (optionptr[OPT_CODE] == code) { | 274 | if (optionptr[OPT_CODE] == code) { |
275 | if (optionptr[OPT_LEN] == 0) { | ||
276 | /* So far no valid option with length 0 known. | ||
277 | * Having this check means that searching | ||
278 | * for DHCP_MESSAGE_TYPE need not worry | ||
279 | * that returned pointer might be unsafe | ||
280 | * to dereference. | ||
281 | */ | ||
282 | goto complain; /* complain and return NULL */ | ||
283 | } | ||
275 | log_option("option found", optionptr); | 284 | log_option("option found", optionptr); |
276 | return optionptr + OPT_DATA; | 285 | return optionptr + OPT_DATA; |
277 | } | 286 | } |
@@ -289,6 +298,16 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) | |||
289 | return NULL; | 298 | return NULL; |
290 | } | 299 | } |
291 | 300 | ||
301 | uint8_t* FAST_FUNC udhcp_get_option32(struct dhcp_packet *packet, int code) | ||
302 | { | ||
303 | uint8_t *r = udhcp_get_option(packet, code); | ||
304 | if (r) { | ||
305 | if (r[-1] != 4) | ||
306 | r = NULL; | ||
307 | } | ||
308 | return r; | ||
309 | } | ||
310 | |||
292 | /* Return the position of the 'end' option (no bounds checking) */ | 311 | /* Return the position of the 'end' option (no bounds checking) */ |
293 | int FAST_FUNC udhcp_end_option(uint8_t *optionptr) | 312 | int FAST_FUNC udhcp_end_option(uint8_t *optionptr) |
294 | { | 313 | { |
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 7ad603d33..9511152ff 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -205,6 +205,10 @@ extern const uint8_t dhcp_option_lengths[] ALIGN1; | |||
205 | unsigned FAST_FUNC udhcp_option_idx(const char *name, const char *option_strings); | 205 | unsigned FAST_FUNC udhcp_option_idx(const char *name, const char *option_strings); |
206 | 206 | ||
207 | uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; | 207 | uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; |
208 | /* Same as above + ensures that option length is 4 bytes | ||
209 | * (returns NULL if size is different) | ||
210 | */ | ||
211 | uint8_t *udhcp_get_option32(struct dhcp_packet *packet, int code) FAST_FUNC; | ||
208 | int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; | 212 | int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; |
209 | void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC; | 213 | void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC; |
210 | #if ENABLE_UDHCPC || ENABLE_UDHCPD | 214 | #if ENABLE_UDHCPC || ENABLE_UDHCPD |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 4b23e4d39..5b3fd531c 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -1691,7 +1691,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1691 | * They say ISC DHCP client supports this case. | 1691 | * They say ISC DHCP client supports this case. |
1692 | */ | 1692 | */ |
1693 | server_addr = 0; | 1693 | server_addr = 0; |
1694 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); | 1694 | temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); |
1695 | if (!temp) { | 1695 | if (!temp) { |
1696 | bb_error_msg("no server ID, using 0.0.0.0"); | 1696 | bb_error_msg("no server ID, using 0.0.0.0"); |
1697 | } else { | 1697 | } else { |
@@ -1718,7 +1718,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1718 | struct in_addr temp_addr; | 1718 | struct in_addr temp_addr; |
1719 | uint8_t *temp; | 1719 | uint8_t *temp; |
1720 | 1720 | ||
1721 | temp = udhcp_get_option(&packet, DHCP_LEASE_TIME); | 1721 | temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME); |
1722 | if (!temp) { | 1722 | if (!temp) { |
1723 | bb_error_msg("no lease time with ACK, using 1 hour lease"); | 1723 | bb_error_msg("no lease time with ACK, using 1 hour lease"); |
1724 | lease_seconds = 60 * 60; | 1724 | lease_seconds = 60 * 60; |
@@ -1813,7 +1813,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1813 | uint32_t svid; | 1813 | uint32_t svid; |
1814 | uint8_t *temp; | 1814 | uint8_t *temp; |
1815 | 1815 | ||
1816 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); | 1816 | temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); |
1817 | if (!temp) { | 1817 | if (!temp) { |
1818 | non_matching_svid: | 1818 | non_matching_svid: |
1819 | log1("received DHCP NAK with wrong" | 1819 | log1("received DHCP NAK with wrong" |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index a8cd3f03b..477856d11 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -640,7 +640,7 @@ static void add_server_options(struct dhcp_packet *packet) | |||
640 | static uint32_t select_lease_time(struct dhcp_packet *packet) | 640 | static uint32_t select_lease_time(struct dhcp_packet *packet) |
641 | { | 641 | { |
642 | uint32_t lease_time_sec = server_config.max_lease_sec; | 642 | uint32_t lease_time_sec = server_config.max_lease_sec; |
643 | uint8_t *lease_time_opt = udhcp_get_option(packet, DHCP_LEASE_TIME); | 643 | uint8_t *lease_time_opt = udhcp_get_option32(packet, DHCP_LEASE_TIME); |
644 | if (lease_time_opt) { | 644 | if (lease_time_opt) { |
645 | move_from_unaligned32(lease_time_sec, lease_time_opt); | 645 | move_from_unaligned32(lease_time_sec, lease_time_opt); |
646 | lease_time_sec = ntohl(lease_time_sec); | 646 | lease_time_sec = ntohl(lease_time_sec); |
@@ -987,7 +987,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
987 | } | 987 | } |
988 | 988 | ||
989 | /* Get SERVER_ID if present */ | 989 | /* Get SERVER_ID if present */ |
990 | server_id_opt = udhcp_get_option(&packet, DHCP_SERVER_ID); | 990 | server_id_opt = udhcp_get_option32(&packet, DHCP_SERVER_ID); |
991 | if (server_id_opt) { | 991 | if (server_id_opt) { |
992 | uint32_t server_id_network_order; | 992 | uint32_t server_id_network_order; |
993 | move_from_unaligned32(server_id_network_order, server_id_opt); | 993 | move_from_unaligned32(server_id_network_order, server_id_opt); |
@@ -1011,7 +1011,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | /* Get REQUESTED_IP if present */ | 1013 | /* Get REQUESTED_IP if present */ |
1014 | requested_ip_opt = udhcp_get_option(&packet, DHCP_REQUESTED_IP); | 1014 | requested_ip_opt = udhcp_get_option32(&packet, DHCP_REQUESTED_IP); |
1015 | if (requested_ip_opt) { | 1015 | if (requested_ip_opt) { |
1016 | move_from_unaligned32(requested_nip, requested_ip_opt); | 1016 | move_from_unaligned32(requested_nip, requested_ip_opt); |
1017 | } | 1017 | } |