mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-01-16 07:09:58 +00:00
Fix handling of zero-padding and parse file before sname field (if overloaded, according to the RFC)
This commit is contained in:
parent
4495d9ef5b
commit
30d69d68e3
@ -1304,7 +1304,8 @@ dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p)
|
|||||||
u16_t options_idx;
|
u16_t options_idx;
|
||||||
u16_t options_idx_max;
|
u16_t options_idx_max;
|
||||||
struct pbuf *q;
|
struct pbuf *q;
|
||||||
u8_t file_overloaded = 0;
|
int parse_file_as_options = 0;
|
||||||
|
int parse_sname_as_options = 0;
|
||||||
|
|
||||||
/* clear received options */
|
/* clear received options */
|
||||||
dhcp_clear_all_options(dhcp);
|
dhcp_clear_all_options(dhcp);
|
||||||
@ -1353,11 +1354,13 @@ again:
|
|||||||
/* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */
|
/* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */
|
||||||
decode_len = len;
|
decode_len = len;
|
||||||
switch(op) {
|
switch(op) {
|
||||||
|
/* case(DHCP_OPTION_END): handled above */
|
||||||
case(DHCP_OPTION_PAD):
|
case(DHCP_OPTION_PAD):
|
||||||
/* special option: no len encoded */
|
/* special option: no len encoded */
|
||||||
decode_len = len = 0;
|
decode_len = len = 0;
|
||||||
/* will be increased below */
|
/* will be increased below */
|
||||||
offset--;
|
offset--;
|
||||||
|
break;
|
||||||
case(DHCP_OPTION_SUBNET_MASK):
|
case(DHCP_OPTION_SUBNET_MASK):
|
||||||
LWIP_ASSERT("len == 4", len == 4);
|
LWIP_ASSERT("len == 4", len == 4);
|
||||||
decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
|
decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
|
||||||
@ -1433,6 +1436,7 @@ decode_next:
|
|||||||
offset -= q->len;
|
offset -= q->len;
|
||||||
offset_max -= q->len;
|
offset_max -= q->len;
|
||||||
q = q->next;
|
q = q->next;
|
||||||
|
options = (u8_t*)q->payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* is this an overloaded message? */
|
/* is this an overloaded message? */
|
||||||
@ -1440,38 +1444,42 @@ decode_next:
|
|||||||
u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD);
|
u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD);
|
||||||
dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD);
|
dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD);
|
||||||
if (overload == DHCP_OVERLOAD_FILE) {
|
if (overload == DHCP_OVERLOAD_FILE) {
|
||||||
file_overloaded = 1;
|
parse_file_as_options = 1;
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n"));
|
||||||
options_idx = DHCP_FILE_OFS;
|
|
||||||
options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN;
|
|
||||||
goto again;
|
|
||||||
} else if (overload == DHCP_OVERLOAD_SNAME) {
|
} else if (overload == DHCP_OVERLOAD_SNAME) {
|
||||||
|
parse_sname_as_options = 1;
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n"));
|
||||||
options_idx = DHCP_SNAME_OFS;
|
|
||||||
options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN;
|
|
||||||
goto again;
|
|
||||||
} else if (overload == DHCP_OVERLOAD_SNAME_FILE) {
|
} else if (overload == DHCP_OVERLOAD_SNAME_FILE) {
|
||||||
file_overloaded = 1;
|
parse_sname_as_options = 1;
|
||||||
|
parse_file_as_options = 1;
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n"));
|
||||||
/* @todo: parse file first and then sname (RFC 2131 ch. 4.1) */
|
|
||||||
options_idx = DHCP_SNAME_OFS;
|
|
||||||
options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN + DHCP_FILE_LEN;
|
|
||||||
goto again;
|
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload));
|
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#if LWIP_DHCP_BOOTP_FILE
|
#if LWIP_DHCP_BOOTP_FILE
|
||||||
if (!file_overloaded) {
|
if (!parse_file_as_options) {
|
||||||
/* only do this for ACK messages */
|
/* only do this for ACK messages */
|
||||||
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
|
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
|
||||||
(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
|
(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
|
||||||
/* copy bootp file name, don't care for sname (server hostname) */
|
/* copy bootp file name, don't care for sname (server hostname) */
|
||||||
pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS);
|
pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS);
|
||||||
/* make sure the string is really NULL-terminated */
|
/* make sure the string is really NULL-terminated */
|
||||||
dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
|
dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
|
||||||
}
|
}
|
||||||
#endif /* LWIP_DHCP_BOOTP_FILE */
|
#endif /* LWIP_DHCP_BOOTP_FILE */
|
||||||
|
}
|
||||||
|
if (parse_file_as_options) {
|
||||||
|
/* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */
|
||||||
|
parse_file_as_options = 0;
|
||||||
|
options_idx = DHCP_FILE_OFS;
|
||||||
|
options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN;
|
||||||
|
goto again;
|
||||||
|
} else if (parse_sname_as_options) {
|
||||||
|
parse_sname_as_options = 0;
|
||||||
|
options_idx = DHCP_SNAME_OFS;
|
||||||
|
options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user