Skip to content
Merged
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
42 changes: 29 additions & 13 deletions netutils/dhcpd/dhcpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ static inline bool dhcpd_parseoptions(void)
{
uint32_t tmp;
uint8_t *ptr;
uint8_t option;
#ifndef CONFIG_NET_DHCP_LIGHT
uint8_t overloaded;
uint8_t currfield;
Expand Down Expand Up @@ -584,18 +585,37 @@ static inline bool dhcpd_parseoptions(void)

do
{
option = ptr[DHCPD_OPTION_CODE];

if (option == DHCP_OPTION_PAD)
{
optlen = 1;
}
else if (option != DHCP_OPTION_END)
{
if (remaining < 2)
{
return false;
}

optlen = ptr[DHCPD_OPTION_LENGTH] + 2;
if (optlen > remaining)
{
return false;
}
}

/* The form of an option is:
* code - 1 byte
* length - 1 byte
* data - variable number of bytes
*/

switch (ptr[DHCPD_OPTION_CODE])
switch (option)
{
/* Skip over any padding bytes */

case DHCP_OPTION_PAD:
optlen = 1;
break;

/* the Overload option is used to indicate that the DHCP 'sname'
Expand All @@ -617,8 +637,7 @@ static inline bool dhcpd_parseoptions(void)

#ifndef CONFIG_NET_DHCP_LIGHT
case DHCP_OPTION_OVERLOAD:
optlen = ptr[DHCPD_OPTION_LENGTH] + 2;
if (optlen >= 3 && optlen < remaining)
if (optlen >= 3)
{
overloaded = ptr[DHCPD_OPTION_DATA];
}
Expand All @@ -633,13 +652,15 @@ static inline bool dhcpd_parseoptions(void)
ptr = g_state.ds_inpacket.file;
remaining = sizeof(g_state.ds_inpacket.file);
currfield = DHCPD_FILE_FIELD;
continue;
}
else if (currfield == DHCPD_FILE_FIELD &&
(overloaded & DHCPD_SNAME_FIELD) != 0)
{
ptr = g_state.ds_inpacket.sname;
remaining = sizeof(g_state.ds_inpacket.sname);
currfield = DHCPD_SNAME_FIELD;
continue;
}
else
{
Expand All @@ -651,34 +672,30 @@ static inline bool dhcpd_parseoptions(void)
#endif

case DHCP_OPTION_REQ_IPADDR: /* Requested IP Address */
optlen = ptr[DHCPD_OPTION_LENGTH] + 2;
if (optlen >= 6 && optlen < remaining)
if (optlen >= 6)
{
memcpy(&tmp, &ptr[DHCPD_OPTION_DATA], 4);
g_state.ds_optreqip = (in_addr_t)ntohl(tmp);
}
break;

case DHCP_OPTION_LEASE_TIME: /* IP address lease time */
optlen = ptr[DHCPD_OPTION_LENGTH] + 2;
if (optlen >= 6 && optlen < remaining)
if (optlen >= 6)
{
memcpy(&tmp, &ptr[DHCPD_OPTION_DATA], 4);
g_state.ds_optleasetime = ntohl(tmp);
}
break;

case DHCP_OPTION_MSG_TYPE: /* DHCP message type */
optlen = ptr[DHCPD_OPTION_LENGTH] + 2;
if (optlen >= 3 && optlen < remaining)
if (optlen >= 3)
{
g_state.ds_optmsgtype = ptr[DHCPD_OPTION_DATA];
}
break;

case DHCP_OPTION_SERVER_ID: /* Server identifier */
optlen = ptr[DHCPD_OPTION_LENGTH] + 2;
if (optlen >= 6 && optlen < remaining)
if (optlen >= 6)
{
memcpy(&tmp, &ptr[DHCPD_OPTION_DATA], 4);
g_state.ds_optserverip = (in_addr_t)ntohl(tmp);
Expand All @@ -689,7 +706,6 @@ static inline bool dhcpd_parseoptions(void)

/* Skip over unsupported options */

optlen = ptr[DHCPD_OPTION_LENGTH] + 2;
break;
}

Expand Down
Loading