task #14270: DHCP should support user-defined additional options: added two hooks for adding and parsing user defined DHCP options

This commit is contained in:
goldsimon 2017-04-25 16:13:39 +02:00
parent 471daba011
commit 2fef874494
2 changed files with 73 additions and 4 deletions

View File

@ -78,6 +78,16 @@
#include <string.h> #include <string.h>
#ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME
#endif
#ifndef LWIP_HOOK_DHCP_APPEND_OPTIONS
#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type)
#endif
#ifndef LWIP_HOOK_DHCP_PARSE_OPTION
#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset)
#endif
/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using /** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using
* LWIP_RAND() (this overrides DHCP_GLOBAL_XID) * LWIP_RAND() (this overrides DHCP_GLOBAL_XID)
*/ */
@ -381,6 +391,7 @@ dhcp_select(struct netif *netif)
dhcp_option_hostname(dhcp, netif); dhcp_option_hostname(dhcp, netif);
#endif /* LWIP_NETIF_HOSTNAME */ #endif /* LWIP_NETIF_HOSTNAME */
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REQUESTING, dhcp->msg_out, DHCP_REQUEST);
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
/* shrink the pbuf to the actual content length */ /* shrink the pbuf to the actual content length */
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
@ -815,6 +826,7 @@ dhcp_inform(struct netif *netif)
dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif)); dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif));
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, &dhcp, DHCP_STATE_INFORMING, dhcp.msg_out, DHCP_INFORM);
dhcp_option_trailer(&dhcp); dhcp_option_trailer(&dhcp);
pbuf_realloc(dhcp.p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len); pbuf_realloc(dhcp.p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len);
@ -927,6 +939,7 @@ dhcp_decline(struct netif *netif)
dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_BACKING_OFF, dhcp->msg_out, DHCP_DECLINE);
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
/* resize pbuf to reflect true size of options */ /* resize pbuf to reflect true size of options */
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
@ -977,6 +990,7 @@ dhcp_discover(struct netif *netif)
for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); dhcp_option_byte(dhcp, dhcp_discover_request_options[i]);
} }
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_SELECTING, dhcp->msg_out, DHCP_DISCOVER);
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
@ -1146,6 +1160,7 @@ dhcp_renew(struct netif *netif)
dhcp_option_hostname(dhcp, netif); dhcp_option_hostname(dhcp, netif);
#endif /* LWIP_NETIF_HOSTNAME */ #endif /* LWIP_NETIF_HOSTNAME */
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_RENEWING, dhcp->msg_out, DHCP_REQUEST);
/* append DHCP message trailer */ /* append DHCP message trailer */
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
@ -1198,6 +1213,7 @@ dhcp_rebind(struct netif *netif)
dhcp_option_hostname(dhcp, netif); dhcp_option_hostname(dhcp, netif);
#endif /* LWIP_NETIF_HOSTNAME */ #endif /* LWIP_NETIF_HOSTNAME */
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBINDING, dhcp->msg_out, DHCP_DISCOVER);
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
@ -1246,7 +1262,7 @@ dhcp_reboot(struct netif *netif)
for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); dhcp_option_byte(dhcp, dhcp_discover_request_options[i]);
} }
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBOOTING, dhcp->msg_out, DHCP_REQUEST);
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
@ -1309,11 +1325,12 @@ dhcp_release_and_stop(struct netif *netif)
if (result == ERR_OK) { if (result == ERR_OK) {
dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr)))); dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr))));
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, dhcp->state, dhcp->msg_out, DHCP_RELEASE);
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
udp_sendto_if(dhcp_pcb, dhcp->p_out, &server_ip_addr, DHCP_SERVER_PORT, netif); udp_sendto_if(dhcp_pcb, dhcp->p_out, &server_ip_addr, DHCP_SERVER_PORT, netif);
dhcp_delete_msg(dhcp); dhcp_delete_msg(dhcp);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n"));
@ -1579,6 +1596,9 @@ again:
default: default:
decode_len = 0; decode_len = 0;
LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op)); LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op));
LWIP_HOOK_DHCP_PARSE_OPTION(ip_current_netif(), dhcp, dhcp->state, dhcp->msg_in,
dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) ? (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) : 0,
op, len, q, val_offset);
break; break;
} }
offset += len + 2; offset += len + 2;

View File

@ -2717,6 +2717,55 @@
#ifdef __DOXYGEN__ #ifdef __DOXYGEN__
#define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif) #define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif)
#endif #endif
/**
* LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type):
* Called from various dhcp functions when sending a DHCP message.
* This hook is called just before the DHCP message trailer is added, so the
* options are at the end of a DHCP message.
* Arguments:
* - netif: struct netif that the packet will be sent through
* - dhcp: struct dhcp on that netif
* - state: current dhcp state (dhcp_state_enum_t as an u8_t)
* - msg: struct dhcp_msg that will be sent
* - msg_type: dhcp message type to be sent (u8_t)
* Returns void
*
* Options need to appended like this:
* LWIP_ASSERT("dhcp option overflow", dhcp->options_out_len + option_len + 2 <= DHCP_OPTIONS_LEN);
* dhcp->msg_out->options[dhcp->options_out_len++] = <option_number>;
* dhcp->msg_out->options[dhcp->options_out_len++] = <option_len>;
* dhcp->msg_out->options[dhcp->options_out_len++] = <option_bytes>;
* [...]
*/
#ifdef __DOXYGEN__
#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type)
#endif
/**
* LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset):
* Called from dhcp_parse_reply when receiving a DHCP message.
* This hook is called for every option in the received message that is not handled internally.
* Arguments:
* - netif: struct netif that the packet will be sent through
* - dhcp: struct dhcp on that netif
* - state: current dhcp state (dhcp_state_enum_t as an u8_t)
* - msg: struct dhcp_msg that was received
* - msg_type: dhcp message type received (u8_t, ATTENTION: only valid after
* the message type option has been parsed!)
* - option: option value (u8_t)
* - len: option data length (u8_t)
* - pbuf: pbuf where option data is contained
* - offset: offset in pbuf where option *data* begins
* Returns void
*
* A nice way to get the option contents is @ref pbuf_get_contiguous:
* u8_t buf[32];
* u8_t *ptr = (u8_t*)pbuf_get_contiguous(p, buf, sizeof(buf), LWIP_MIN(option_len, sizeof(buf)), offset);
*/
#ifdef __DOXYGEN__
#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset)
#endif
/** /**
* @} * @}
*/ */