diff options
-rw-r--r-- | gdhcp/common.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/gdhcp/common.c b/gdhcp/common.c index 91c428c1..8d5c284b 100644 --- a/gdhcp/common.c +++ b/gdhcp/common.c @@ -155,14 +155,16 @@ uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len, rem = pkt_len - 1 - 3; if (rem <= 0) - /* Bad packet */ - return NULL; + goto bad_packet; while (1) { opt_code = optionptr[0] << 8 | optionptr[1]; opt_len = len = optionptr[2] << 8 | optionptr[3]; len += 2 + 2; /* skip code and len */ + if (len < 4) + goto bad_packet; + rem -= len; if (rem < 0) break; @@ -170,7 +172,10 @@ uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len, if (opt_code == code) { if (option_len != NULL) *option_len = opt_len; - found = optionptr + 2 + 2; + if (rem == 0) + found = NULL; + else + found = optionptr + 2 + 2; count++; } @@ -184,6 +189,13 @@ uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len, *option_count = count; return found; + +bad_packet: + if (option_len != NULL) + *option_len = 0; + if (option_count != NULL) + *option_count = 0; + return NULL; } uint8_t *dhcpv6_get_sub_option(unsigned char *option, uint16_t max_len, |