mirror of
https://github.com/espressif/esp-lwip.git
synced 2025-08-06 18:23:42 +08:00
lwip/dhcp: add 60 option for vendor class identify
Closes https://github.com/espressif/esp-idf/issues/6786
This commit is contained in:
@ -127,6 +127,11 @@
|
||||
#define LWIP_DHCP_PROVIDE_DNS_SERVERS 0
|
||||
#endif
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
#define DHCP_OPTION_VSI_MAX 16
|
||||
static u32_t dhcp_option_vsi[DHCP_OPTION_VSI_MAX] = {0};
|
||||
#endif
|
||||
|
||||
/** Option handling: options are parsed in dhcp_parse_reply
|
||||
* and saved in an array where other functions can load them from.
|
||||
* This might be moved into the struct dhcp (not necessarily since
|
||||
@ -144,6 +149,10 @@ enum dhcp_option_idx {
|
||||
#if ESP_DHCP
|
||||
DHCP_OPTION_IDX_MTU,
|
||||
#endif /* ESP_DHCP */
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
DHCP_OPTION_IDX_VSI,
|
||||
DHCP_OPTION_IDX_VSI_LAST = DHCP_OPTION_IDX_VSI + DHCP_OPTION_VSI_MAX -1,
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
|
||||
DHCP_OPTION_IDX_DNS_SERVER,
|
||||
DHCP_OPTION_IDX_DNS_SERVER_LAST = DHCP_OPTION_IDX_DNS_SERVER + LWIP_DHCP_PROVIDE_DNS_SERVERS - 1,
|
||||
@ -167,6 +176,9 @@ static u8_t dhcp_discover_request_options[] = {
|
||||
DHCP_OPTION_SUBNET_MASK,
|
||||
DHCP_OPTION_ROUTER,
|
||||
DHCP_OPTION_BROADCAST
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
, DHCP_OPTION_VSI
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
|
||||
, DHCP_OPTION_DNS_SERVER
|
||||
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
|
||||
@ -224,6 +236,12 @@ static u16_t dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct n
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID
|
||||
static u16_t dhcp_option_client_id(struct netif *netif, struct dhcp_msg *msg_out, u16_t options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
/* set dhcp option60 */
|
||||
static u16_t dhcp_option_vendor_class_identifier(struct netif *netif, struct dhcp_msg *msg_out, u16_t options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
/* always add the DHCP options trailer to end and pad */
|
||||
static void dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out);
|
||||
|
||||
@ -350,6 +368,14 @@ dhcp_handle_offer(struct netif *netif, struct dhcp_msg *msg_in)
|
||||
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
|
||||
(void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
|
||||
|
||||
/* Vendor Specific Information */
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
for (u8_t n = 0; (n < DHCP_OPTION_VSI_MAX) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_VSI + n); n++) {
|
||||
dhcp_option_vsi[n] = lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_VSI + n));
|
||||
}
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
/* obtain the server address */
|
||||
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
|
||||
dhcp->request_timeout = 0; /* stop timer */
|
||||
@ -410,6 +436,11 @@ dhcp_select(struct netif *netif)
|
||||
options_out_len = dhcp_option_client_id(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
options_out_len = dhcp_option_vendor_class_identifier(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
|
||||
options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4);
|
||||
options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
|
||||
|
||||
@ -658,9 +689,9 @@ dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in)
|
||||
{
|
||||
struct dhcp *dhcp = netif_dhcp_data(netif);
|
||||
|
||||
#if LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV
|
||||
#if LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV || !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
u8_t n;
|
||||
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV */
|
||||
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV || !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
#if LWIP_DHCP_GET_NTP_SRV
|
||||
ip4_addr_t ntp_server_addrs[LWIP_DHCP_MAX_NTP_SERVERS];
|
||||
#endif
|
||||
@ -694,6 +725,14 @@ dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in)
|
||||
}
|
||||
}
|
||||
#endif /* ESP_DHCP */
|
||||
|
||||
/* Vendor Specific Information */
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
for (n = 0; (n < DHCP_OPTION_VSI_MAX) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_VSI + n); n++) {
|
||||
dhcp_option_vsi[n] = lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_VSI + n));
|
||||
}
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
/* renewal period given? */
|
||||
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) {
|
||||
/* remember given rebind period */
|
||||
@ -1062,6 +1101,10 @@ dhcp_decline(struct netif *netif)
|
||||
options_out_len = dhcp_option_client_id(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
options_out_len = dhcp_option_vendor_class_identifier(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_BACKING_OFF, msg_out, DHCP_DECLINE, &options_out_len);
|
||||
dhcp_option_trailer(options_out_len, msg_out->options, p_out);
|
||||
|
||||
@ -1123,6 +1166,10 @@ dhcp_discover(struct netif *netif)
|
||||
#if !ESP_DHCP_DISABLE_CLIENT_ID
|
||||
options_out_len = dhcp_option_client_id(netif, msg_out, options_out_len);
|
||||
#endif /* !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
options_out_len = dhcp_option_vendor_class_identifier(netif, msg_out, options_out_len);
|
||||
#endif /* !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
#endif/* ESP_DHCP */
|
||||
|
||||
options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
|
||||
@ -1368,6 +1415,10 @@ dhcp_renew(struct netif *netif)
|
||||
options_out_len = dhcp_option_client_id(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
options_out_len = dhcp_option_vendor_class_identifier(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_RENEWING, msg_out, DHCP_REQUEST, &options_out_len);
|
||||
dhcp_option_trailer(options_out_len, msg_out->options, p_out);
|
||||
|
||||
@ -1427,6 +1478,10 @@ dhcp_rebind(struct netif *netif)
|
||||
options_out_len = dhcp_option_client_id(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
options_out_len = dhcp_option_vendor_class_identifier(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBINDING, msg_out, DHCP_DISCOVER, &options_out_len);
|
||||
dhcp_option_trailer(options_out_len, msg_out->options, p_out);
|
||||
|
||||
@ -1488,6 +1543,10 @@ dhcp_reboot(struct netif *netif)
|
||||
options_out_len = dhcp_option_client_id(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
options_out_len = dhcp_option_vendor_class_identifier(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBOOTING, msg_out, DHCP_REQUEST, &options_out_len);
|
||||
dhcp_option_trailer(options_out_len, msg_out->options, p_out);
|
||||
|
||||
@ -1559,6 +1618,10 @@ dhcp_release_and_stop(struct netif *netif)
|
||||
options_out_len = dhcp_option_client_id(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
options_out_len = dhcp_option_vendor_class_identifier(netif, msg_out, options_out_len);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, dhcp->state, msg_out, DHCP_RELEASE, &options_out_len);
|
||||
dhcp_option_trailer(options_out_len, msg_out->options, p_out);
|
||||
|
||||
@ -1719,6 +1782,95 @@ dhcp_option_client_id(struct netif *netif, struct dhcp_msg *msg_out, u16_t optio
|
||||
}
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_CLIENT_ID */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
static u8_t vendor_class_len = 0;
|
||||
static char *vendor_class_buf = NULL;
|
||||
|
||||
err_t
|
||||
dhcp_set_vendor_class_identifier(u8_t len, char *str)
|
||||
{
|
||||
if (len == 0 || str == NULL) {
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
if (vendor_class_buf && vendor_class_len != len) {
|
||||
mem_free(vendor_class_buf);
|
||||
vendor_class_buf = NULL;
|
||||
}
|
||||
|
||||
if (!vendor_class_buf) {
|
||||
vendor_class_buf = (char *)mem_malloc(len + 1);
|
||||
if (vendor_class_buf == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
vendor_class_len = len;
|
||||
}
|
||||
|
||||
memcpy(vendor_class_buf, str, len);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t
|
||||
dhcp_get_vendor_specific_information(u8_t len, char *str)
|
||||
{
|
||||
u8_t copy_len = 0;
|
||||
|
||||
if (len == 0 || str == NULL) {
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
copy_len = LWIP_MIN(len, sizeof(dhcp_option_vsi));
|
||||
|
||||
memcpy(str, dhcp_option_vsi, copy_len);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static u16_t
|
||||
dhcp_option_vendor_class_identifier(struct netif *netif, struct dhcp_msg *msg_out, u16_t options_out_len)
|
||||
{
|
||||
size_t i;
|
||||
int available;
|
||||
const char *p = NULL;
|
||||
u8_t len = 0;
|
||||
|
||||
if (netif == NULL || msg_out == NULL) {
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
/* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME and 1 byte for trailer) */
|
||||
|
||||
available = DHCP_OPTIONS_LEN - options_out_len - 3;
|
||||
LWIP_ASSERT("DHCP: problem unfolding DHCP options - too short on memory!", 0 <= available);
|
||||
|
||||
if (vendor_class_buf && vendor_class_len) {
|
||||
p = vendor_class_buf;
|
||||
LWIP_ASSERT("DHCP: vendor_class_len is too long!", vendor_class_len <= available);
|
||||
len = vendor_class_len;
|
||||
} else {
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
if (netif->hostname != NULL) {
|
||||
size_t namelen = strlen(netif->hostname);
|
||||
if ((namelen > 0) && (namelen < 0xFF)) {
|
||||
p = netif->hostname;
|
||||
LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available);
|
||||
len = (u8_t)namelen;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
len = LWIP_MIN(len, available);
|
||||
if (p) {
|
||||
options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_VCI, len);
|
||||
for (i = 0; i < len; i ++) {
|
||||
options_out_len = dhcp_option_byte(options_out_len, msg_out->options, p[i]);
|
||||
}
|
||||
}
|
||||
return options_out_len;
|
||||
}
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
/**
|
||||
* Extract the DHCP message and the DHCP options.
|
||||
@ -1867,6 +2019,9 @@ again:
|
||||
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
|
||||
decode_idx = DHCP_OPTION_IDX_T2;
|
||||
break;
|
||||
case (DHCP_OPTION_VSI):
|
||||
decode_idx = DHCP_OPTION_IDX_VSI;
|
||||
break;
|
||||
default:
|
||||
decode_len = 0;
|
||||
LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op));
|
||||
@ -1896,7 +2051,10 @@ decode_next:
|
||||
if (decode_len > 4) {
|
||||
/* decode more than one u32_t */
|
||||
u16_t next_val_offset;
|
||||
#if ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
/* correct DHCP VCI data might not be aligned, so remove it. */
|
||||
LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
|
||||
#endif /* ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
dhcp_got_option(dhcp, decode_idx);
|
||||
dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value));
|
||||
decode_len = (u8_t)(decode_len - 4);
|
||||
@ -1913,6 +2071,8 @@ decode_next:
|
||||
#if ESP_DHCP
|
||||
} else if (decode_len == 2) {
|
||||
value = (u32_t)lwip_htons((u16_t)value);
|
||||
} else if (decode_len == 3) {
|
||||
value = lwip_ntohl(value);
|
||||
#endif /* ESP_DHCP */
|
||||
} else {
|
||||
LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
|
||||
|
@ -159,6 +159,11 @@ void dhcp_fine_tmr(void);
|
||||
extern void dhcp_set_ntp_servers(u8_t num_ntp_servers, const ip4_addr_t* ntp_server_addrs);
|
||||
#endif /* LWIP_DHCP_GET_NTP_SRV */
|
||||
|
||||
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
|
||||
err_t dhcp_set_vendor_class_identifier(u8_t len, char *str);
|
||||
err_t dhcp_get_vendor_specific_information(u8_t len, char *str);
|
||||
#endif /* ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER */
|
||||
|
||||
#define netif_dhcp_data(netif) ((struct dhcp*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP))
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -159,7 +159,8 @@ typedef enum {
|
||||
|
||||
#define DHCP_OPTION_T1 58 /* T1 renewal time */
|
||||
#define DHCP_OPTION_T2 59 /* T2 rebinding time */
|
||||
#define DHCP_OPTION_US 60
|
||||
#define DHCP_OPTION_VCI 60
|
||||
#define DHCP_OPTION_VSI 43
|
||||
#define DHCP_OPTION_CLIENT_ID 61
|
||||
#define DHCP_OPTION_TFTP_SERVERNAME 66
|
||||
#define DHCP_OPTION_BOOTFILE 67
|
||||
|
@ -105,6 +105,7 @@
|
||||
#define ESP_DHCP_DEBUG 1
|
||||
#define ESP_THREAD_PROTECTION 0
|
||||
#define ESP_DHCP_DISABLE_CLIENT_ID 0
|
||||
#define ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER 0
|
||||
|
||||
#ifdef IP_NAPT
|
||||
#define IP_NAPT_MAX 16
|
||||
|
Reference in New Issue
Block a user