mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'fix/fix_lost_ip_event_issue_v55' into 'release/v5.5'
fix(lwip): add some feature for dhcp and improve api v55 See merge request espressif/esp-idf!48105
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -682,7 +682,19 @@ esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif);
|
|||||||
*/
|
*/
|
||||||
esp_err_t esp_netif_dhcps_get_clients_by_mac(esp_netif_t *esp_netif, int num, esp_netif_pair_mac_ip_t *mac_ip_pair);
|
esp_err_t esp_netif_dhcps_get_clients_by_mac(esp_netif_t *esp_netif, int num, esp_netif_pair_mac_ip_t *mac_ip_pair);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Populate IP addresses of client from the lwIP ARP cache on this interface
|
||||||
|
*
|
||||||
|
* Walks the ARP table and fills in ip when the Ethernet address matches and the entry belongs to esp_netif.
|
||||||
|
*
|
||||||
|
* @param[in] esp_netif Handle to esp-netif instance
|
||||||
|
* @param[in,out] mac_ip_pair MAC/IP pair to fill in the IP
|
||||||
|
* @return
|
||||||
|
* - ESP_OK on success (including when nothing was found in ARP)
|
||||||
|
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS on invalid params
|
||||||
|
* - ESP_ERR_NOT_SUPPORTED if ARP is disabled in lwIP
|
||||||
|
*/
|
||||||
|
esp_err_t esp_netif_arp_get_client_by_mac(esp_netif_t *esp_netif, esp_netif_pair_mac_ip_t *mac_ip_pair);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set DNS Server information
|
* @brief Set DNS Server information
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -1406,7 +1406,7 @@ esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_LWIP_IPV4
|
#if CONFIG_LWIP_IPV4
|
||||||
static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif);
|
static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif, bool renew);
|
||||||
|
|
||||||
//
|
//
|
||||||
// DHCP:
|
// DHCP:
|
||||||
@@ -1469,7 +1469,7 @@ static void esp_netif_internal_dhcpc_cb(struct netif *netif)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!ip4_addr_cmp(&ip_info->ip, IP4_ADDR_ANY4)) {
|
if (!ip4_addr_cmp(&ip_info->ip, IP4_ADDR_ANY4)) {
|
||||||
esp_netif_start_ip_lost_timer(esp_netif);
|
esp_netif_start_ip_lost_timer(esp_netif, false);
|
||||||
if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT && esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
|
if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT && esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
|
||||||
// Only for active DHCP client (in case of static IP, we keep the last configure value in ip_info)
|
// Only for active DHCP client (in case of static IP, we keep the last configure value in ip_info)
|
||||||
// synchronize lwip netif with esp_netif setting ip_info to 0,
|
// synchronize lwip netif with esp_netif setting ip_info to 0,
|
||||||
@@ -1519,19 +1519,22 @@ static void esp_netif_ip_lost_timer(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif)
|
static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif, bool renew)
|
||||||
{
|
{
|
||||||
esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info;
|
esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info;
|
||||||
struct netif *netif = esp_netif->lwip_netif;
|
struct netif *netif = esp_netif->lwip_netif;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
|
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
|
||||||
|
|
||||||
if (esp_netif->timer_running) {
|
|
||||||
ESP_LOGD(TAG, "if%p start ip lost tmr: already started", esp_netif);
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( netif && (CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL > 0)) {
|
if ( netif && (CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL > 0)) {
|
||||||
|
if (esp_netif->timer_running) {
|
||||||
|
if (renew) {
|
||||||
|
sys_untimeout(esp_netif_ip_lost_timer, (void *)esp_netif);
|
||||||
|
} else{
|
||||||
|
ESP_LOGD(TAG, "if%p start ip lost tmr: already started", esp_netif);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
esp_netif->timer_running = true;
|
esp_netif->timer_running = true;
|
||||||
sys_timeout(CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL * 1000, esp_netif_ip_lost_timer, (void *)esp_netif);
|
sys_timeout(CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL * 1000, esp_netif_ip_lost_timer, (void *)esp_netif);
|
||||||
ESP_LOGD(TAG, "if%p start ip lost tmr: interval=%d", esp_netif, CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL);
|
ESP_LOGD(TAG, "if%p start ip lost tmr: interval=%d", esp_netif, CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL);
|
||||||
@@ -1561,7 +1564,7 @@ static esp_err_t esp_netif_dhcpc_stop_api(esp_netif_api_msg_t *msg)
|
|||||||
if (p_netif != NULL) {
|
if (p_netif != NULL) {
|
||||||
dhcp_stop(p_netif);
|
dhcp_stop(p_netif);
|
||||||
esp_netif_reset_ip_info(esp_netif);
|
esp_netif_reset_ip_info(esp_netif);
|
||||||
esp_netif_start_ip_lost_timer(esp_netif);
|
esp_netif_start_ip_lost_timer(esp_netif, false);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGD(TAG, "dhcp client if not ready");
|
ESP_LOGD(TAG, "dhcp client if not ready");
|
||||||
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
|
return ESP_ERR_ESP_NETIF_IF_NOT_READY;
|
||||||
@@ -1624,7 +1627,7 @@ static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg)
|
|||||||
ip_addr_set_zero(&p_netif->ip_addr);
|
ip_addr_set_zero(&p_netif->ip_addr);
|
||||||
ip_addr_set_zero(&p_netif->netmask);
|
ip_addr_set_zero(&p_netif->netmask);
|
||||||
ip_addr_set_zero(&p_netif->gw);
|
ip_addr_set_zero(&p_netif->gw);
|
||||||
esp_netif_start_ip_lost_timer(esp_netif);
|
esp_netif_start_ip_lost_timer(esp_netif, true);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGD(TAG, "dhcp client re init");
|
ESP_LOGD(TAG, "dhcp client re init");
|
||||||
esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
|
esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
|
||||||
@@ -1875,7 +1878,7 @@ static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg)
|
|||||||
|
|
||||||
if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
|
if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
|
||||||
#if CONFIG_LWIP_IPV4
|
#if CONFIG_LWIP_IPV4
|
||||||
esp_netif_start_ip_lost_timer(esp_netif);
|
esp_netif_start_ip_lost_timer(esp_netif, false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2055,6 +2058,52 @@ esp_err_t esp_netif_dhcps_get_clients_by_mac(esp_netif_t *esp_netif, int num, es
|
|||||||
#endif // CONFIG_LWIP_DHCPS
|
#endif // CONFIG_LWIP_DHCPS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_LWIP_IPV4 && LWIP_ARP
|
||||||
|
static esp_err_t esp_netif_arp_get_client_by_mac_api(esp_netif_api_msg_t *msg)
|
||||||
|
{
|
||||||
|
esp_netif_t *esp_netif = msg->esp_netif;
|
||||||
|
esp_netif_pair_mac_ip_t *mac_ip_pair = msg->data;
|
||||||
|
struct netif *lwip_netif = esp_netif ? esp_netif->lwip_netif : NULL;
|
||||||
|
|
||||||
|
if (lwip_netif == NULL || mac_ip_pair == NULL) {
|
||||||
|
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
mac_ip_pair->ip.addr = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ARP_TABLE_SIZE; i++) {
|
||||||
|
ip4_addr_t *ip_ptr = NULL;
|
||||||
|
struct netif *nif = NULL;
|
||||||
|
struct eth_addr *eth_ptr = NULL;
|
||||||
|
|
||||||
|
if (!etharp_get_entry(i, &ip_ptr, &nif, ð_ptr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nif != lwip_netif) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (memcmp(eth_ptr->addr, mac_ip_pair->mac, ETH_HWADDR_LEN) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mac_ip_pair->ip.addr = ip_ptr->addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_LWIP_IPV4 && LWIP_ARP */
|
||||||
|
|
||||||
|
esp_err_t esp_netif_arp_get_client_by_mac(esp_netif_t *esp_netif, esp_netif_pair_mac_ip_t *mac_ip_pair)
|
||||||
|
{
|
||||||
|
#if CONFIG_LWIP_IPV4 && LWIP_ARP
|
||||||
|
if (esp_netif == NULL || mac_ip_pair == NULL) {
|
||||||
|
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
|
||||||
|
}
|
||||||
|
return esp_netif_lwip_ipc_call(esp_netif_arp_get_client_by_mac_api, esp_netif, (void *)mac_ip_pair);
|
||||||
|
#else
|
||||||
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
|
#endif /* CONFIG_LWIP_IPV4 && LWIP_ARP */
|
||||||
|
}
|
||||||
|
|
||||||
static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg)
|
static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg)
|
||||||
{
|
{
|
||||||
esp_netif_t *esp_netif = msg->esp_netif;
|
esp_netif_t *esp_netif = msg->esp_netif;
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ typedef struct {
|
|||||||
/**
|
/**
|
||||||
* @brief Get IP information for stations connected to the Wi-Fi AP interface
|
* @brief Get IP information for stations connected to the Wi-Fi AP interface
|
||||||
*
|
*
|
||||||
* @note If `CONFIG_LWIP_DHCPS` is disabled then `ip` address field will not be populated in sta list
|
* @note If `CONFIG_LWIP_DHCPS` is disabled then DHCP lookup is skipped; IPv4 may still be filled from the lwIP ARP cache when available.
|
||||||
|
* After DHCP (when enabled), any station still without an IP is resolved via ARP table on the same interface.
|
||||||
*
|
*
|
||||||
* @warning This API works only for the default Wi-Fi AP interface, i.e. esp-netif with key="WIFI_AP_DEF"
|
* @warning This API works only for the default Wi-Fi AP interface, i.e. esp-netif with key="WIFI_AP_DEF"
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_netif_types.h"
|
||||||
|
#include "esp_wifi_types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ESP_WIFI_MAX_CONN_NUM
|
||||||
|
// Number of maximum wifi connection may be undefined if we have no native wifi support on this target
|
||||||
|
// and at the same time there's no native interface injected by the wifi_remote component.
|
||||||
|
// In this case, we just let the header compilable, since no wifi API could be used (let's make a sanity check)
|
||||||
|
#if !CONFIG_SOC_WIFI_SUPPORTED && !CONFIG_ESP_WIFI_REMOTE_ENABLED && !CONFIG_ESP_HOST_WIFI_ENABLED
|
||||||
|
#define ESP_WIFI_MAX_CONN_NUM (15)
|
||||||
|
typedef struct wifi_sta_list_t wifi_sta_list_t;
|
||||||
|
#else
|
||||||
|
#error WiFi header mismatch! Please make sure you use the correct version of WiFi API
|
||||||
|
#endif
|
||||||
|
#endif // ESP_WIFI_MAX_CONN_NUM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief station list structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int num; /**< Number of connected stations */
|
||||||
|
esp_netif_pair_mac_ip_t sta[ESP_WIFI_MAX_CONN_NUM]; /**< Connected stations */
|
||||||
|
} wifi_sta_mac_ip_list_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get IP information for stations connected to the Wi-Fi AP interface
|
||||||
|
*
|
||||||
|
* @note If `CONFIG_LWIP_DHCPS` is disabled then DHCP lookup is skipped; IPv4 may still be filled from the lwIP ARP cache when available.
|
||||||
|
* After DHCP (when enabled), any station still without an IP is resolved via ARP table on the same interface.
|
||||||
|
*
|
||||||
|
* @warning This API works only for the default Wi-Fi AP interface, i.e. esp-netif with key="WIFI_AP_DEF"
|
||||||
|
*
|
||||||
|
* @param[in] wifi_sta_list Wi-Fi station info list, returned from esp_wifi_ap_get_sta_list()
|
||||||
|
* @param[out] wifi_sta_ip_mac_list IP layer station info list, corresponding to MAC addresses provided in wifi_sta_list
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK
|
||||||
|
* - ESP_ERR_ESP_NETIF_NO_MEM
|
||||||
|
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
|
||||||
|
*/
|
||||||
|
esp_err_t esp_wifi_ap_get_sta_list_with_ip(const wifi_sta_list_t *wifi_sta_list, wifi_sta_mac_ip_list_t *wifi_sta_ip_mac_list);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -30,7 +30,17 @@ esp_err_t esp_wifi_ap_get_sta_list_with_ip(const wifi_sta_list_t *wifi_sta_list,
|
|||||||
memcpy(wifi_sta_ip_mac_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6);
|
memcpy(wifi_sta_ip_mac_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6);
|
||||||
memset(&wifi_sta_ip_mac_list->sta[i].ip, 0, sizeof(esp_ip4_addr_t));
|
memset(&wifi_sta_ip_mac_list->sta[i].ip, 0, sizeof(esp_ip4_addr_t));
|
||||||
}
|
}
|
||||||
return esp_netif_dhcps_get_clients_by_mac(ap, num, wifi_sta_ip_mac_list->sta);
|
esp_err_t err = esp_netif_dhcps_get_clients_by_mac(ap, num, wifi_sta_ip_mac_list->sta);
|
||||||
|
if (err != ESP_OK && err != ESP_ERR_NOT_SUPPORTED) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
if (wifi_sta_ip_mac_list->sta[i].ip.addr == 0) {
|
||||||
|
// Try to get the IP from the ARP table, and not care about the result
|
||||||
|
esp_netif_arp_get_client_by_mac(ap, &wifi_sta_ip_mac_list->sta[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
#else
|
#else
|
||||||
return ESP_ERR_NOT_SUPPORTED;
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "lwip/dhcp.h"
|
#include "lwip/dhcp.h"
|
||||||
#include "lwip/err.h"
|
#include "lwip/err.h"
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
#define DHCPACK 5
|
#define DHCPACK 5
|
||||||
#define DHCPNAK 6
|
#define DHCPNAK 6
|
||||||
#define DHCPRELEASE 7
|
#define DHCPRELEASE 7
|
||||||
|
#define DHCPINFORM 8
|
||||||
|
|
||||||
#define DHCP_OPTION_PAD 0
|
#define DHCP_OPTION_PAD 0
|
||||||
#define DHCP_OPTION_SUBNET_MASK 1
|
#define DHCP_OPTION_SUBNET_MASK 1
|
||||||
@@ -101,6 +103,7 @@
|
|||||||
#define DHCPS_STATE_NAK 4
|
#define DHCPS_STATE_NAK 4
|
||||||
#define DHCPS_STATE_IDLE 5
|
#define DHCPS_STATE_IDLE 5
|
||||||
#define DHCPS_STATE_RELEASE 6
|
#define DHCPS_STATE_RELEASE 6
|
||||||
|
#define DHCPS_STATE_INFORM_ACK 7
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DHCPS_HANDLE_CREATED = 0,
|
DHCPS_HANDLE_CREATED = 0,
|
||||||
@@ -428,7 +431,7 @@ static u8_t *add_msg_type(u8_t *optptr, u8_t type)
|
|||||||
* Parameters : optptr -- the addr of DHCP message option
|
* Parameters : optptr -- the addr of DHCP message option
|
||||||
* Returns : the addr of DHCP message option
|
* Returns : the addr of DHCP message option
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr)
|
static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr, bool include_lease_time)
|
||||||
{
|
{
|
||||||
u32_t i;
|
u32_t i;
|
||||||
ip4_addr_t ipadd;
|
ip4_addr_t ipadd;
|
||||||
@@ -439,12 +442,14 @@ static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr)
|
|||||||
*optptr++ = 4;
|
*optptr++ = 4;
|
||||||
optptr = dhcps_option_ip(optptr, &dhcps->dhcps_mask);
|
optptr = dhcps_option_ip(optptr, &dhcps->dhcps_mask);
|
||||||
|
|
||||||
*optptr++ = DHCP_OPTION_LEASE_TIME;
|
if (include_lease_time) {
|
||||||
*optptr++ = 4;
|
*optptr++ = DHCP_OPTION_LEASE_TIME;
|
||||||
*optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 24) & 0xFF;
|
*optptr++ = 4;
|
||||||
*optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 16) & 0xFF;
|
*optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 24) & 0xFF;
|
||||||
*optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 8) & 0xFF;
|
*optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 16) & 0xFF;
|
||||||
*optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 0) & 0xFF;
|
*optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 8) & 0xFF;
|
||||||
|
*optptr++ = ((dhcps->dhcps_lease_time * DHCPS_LEASE_UNIT) >> 0) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
*optptr++ = DHCP_OPTION_SERVER_ID;
|
*optptr++ = DHCP_OPTION_SERVER_ID;
|
||||||
*optptr++ = 4;
|
*optptr++ = 4;
|
||||||
@@ -535,6 +540,44 @@ static u8_t *add_end(u8_t *optptr)
|
|||||||
return optptr;
|
return optptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read DHCP message type (option 53) from the variable-length option area
|
||||||
|
* (starts after the magic cookie at options[4]).
|
||||||
|
*/
|
||||||
|
static u8_t dhcps_get_option_msg_type(u8_t *optptr, u16_t len)
|
||||||
|
{
|
||||||
|
u8_t *end;
|
||||||
|
|
||||||
|
if (len <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
end = optptr + len;
|
||||||
|
|
||||||
|
while (optptr < end) {
|
||||||
|
u8_t code = *optptr;
|
||||||
|
if (code == DHCP_OPTION_END) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (code == 0) {
|
||||||
|
/* Pad */
|
||||||
|
optptr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (optptr + 1 >= end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
u8_t optlen = optptr[1];
|
||||||
|
if ((optptr + 2 + optlen) > end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (code == DHCP_OPTION_MSG_TYPE && optlen >= 1) {
|
||||||
|
return optptr[2];
|
||||||
|
}
|
||||||
|
optptr += (u16_t)optlen + 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FunctionName : create_msg
|
* FunctionName : create_msg
|
||||||
* Description : create response message
|
* Description : create response message
|
||||||
@@ -592,7 +635,11 @@ static void dhcps_response_ip_set(dhcps_t *dhcps, struct dhcps_msg *m, ip4_addr_
|
|||||||
/* If the 'giaddr' field is zero and the 'ciaddr' is nonzero,
|
/* If the 'giaddr' field is zero and the 'ciaddr' is nonzero,
|
||||||
* the server unicasts DHCPOFFER and DHCPACK message to the address in 'ciaddr'*/
|
* the server unicasts DHCPOFFER and DHCPACK message to the address in 'ciaddr'*/
|
||||||
ip4_addr_set(ip4_out, &ip4_ciaddr);
|
ip4_addr_set(ip4_out, &ip4_ciaddr);
|
||||||
etharp_add_static_entry(&ip4_ciaddr, &chaddr);
|
/* when 'yiaddr' is zero, means DHCPACK INFO, no need to add static entry */
|
||||||
|
if (!ip4_addr_isany_val(ip4_yiaddr)) {
|
||||||
|
/* add the IP<->MAC as static entry into the arp table. */
|
||||||
|
etharp_add_static_entry(&ip4_ciaddr, &chaddr);
|
||||||
|
}
|
||||||
} else if (!BROADCAST_BIT_IS_SET(htons(m->flags))) {
|
} else if (!BROADCAST_BIT_IS_SET(htons(m->flags))) {
|
||||||
/* If the 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is not set,
|
/* If the 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is not set,
|
||||||
* the server unicasts DHCPOFFER and DHCPACK message to the client's hardware address and
|
* the server unicasts DHCPOFFER and DHCPACK message to the client's hardware address and
|
||||||
@@ -643,7 +690,7 @@ static void send_offer(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
|
|||||||
create_msg(dhcps, m);
|
create_msg(dhcps, m);
|
||||||
|
|
||||||
end = add_msg_type(&m->options[4], DHCPOFFER);
|
end = add_msg_type(&m->options[4], DHCPOFFER);
|
||||||
end = add_offer_options(dhcps, end);
|
end = add_offer_options(dhcps, end, true);
|
||||||
LWIP_HOOK_DHCPS_POST_APPEND_OPTS(dhcps->dhcps_netif, dhcps, DHCPOFFER, &end)
|
LWIP_HOOK_DHCPS_POST_APPEND_OPTS(dhcps->dhcps_netif, dhcps, DHCPOFFER, &end)
|
||||||
end = add_end(end);
|
end = add_end(end);
|
||||||
|
|
||||||
@@ -826,7 +873,7 @@ static void send_ack(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
|
|||||||
create_msg(dhcps, m);
|
create_msg(dhcps, m);
|
||||||
|
|
||||||
end = add_msg_type(&m->options[4], DHCPACK);
|
end = add_msg_type(&m->options[4], DHCPACK);
|
||||||
end = add_offer_options(dhcps, end);
|
end = add_offer_options(dhcps, end, true);
|
||||||
LWIP_HOOK_DHCPS_POST_APPEND_OPTS(dhcps->dhcps_netif, dhcps, DHCPACK, &end)
|
LWIP_HOOK_DHCPS_POST_APPEND_OPTS(dhcps->dhcps_netif, dhcps, DHCPACK, &end)
|
||||||
end = add_end(end);
|
end = add_end(end);
|
||||||
|
|
||||||
@@ -893,6 +940,50 @@ static void send_ack(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FunctionName : send_ack_inform
|
||||||
|
* Description : DHCPACK response to DHCPINFORM (RFC 2131: yiaddr = 0, no lease time)
|
||||||
|
* Parameters : m -- DHCP message info
|
||||||
|
* Returns : none
|
||||||
|
*******************************************************************************/
|
||||||
|
static void send_ack_inform(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
|
||||||
|
{
|
||||||
|
u8_t *end;
|
||||||
|
struct pbuf *p, *q;
|
||||||
|
u8_t *data;
|
||||||
|
u16_t cnt = 0;
|
||||||
|
u16_t i;
|
||||||
|
create_msg(dhcps, m);
|
||||||
|
memset(m->yiaddr, 0, sizeof(m->yiaddr));
|
||||||
|
|
||||||
|
end = add_msg_type(&m->options[4], DHCPACK);
|
||||||
|
end = add_offer_options(dhcps, end, false);
|
||||||
|
LWIP_HOOK_DHCPS_POST_APPEND_OPTS(dhcps->dhcps_netif, dhcps, DHCPACK, &end)
|
||||||
|
end = add_end(end);
|
||||||
|
|
||||||
|
p = dhcps_pbuf_alloc(len);
|
||||||
|
if (p == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
q = p;
|
||||||
|
while (q != NULL) {
|
||||||
|
data = (u8_t *)q->payload;
|
||||||
|
for (i = 0; i < q->len; i++) {
|
||||||
|
data[i] = ((u8_t *) m)[cnt++];
|
||||||
|
}
|
||||||
|
q = q->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_addr_t ip_temp = IPADDR4_INIT(0x0);
|
||||||
|
dhcps_response_ip_set(dhcps, m, ip_2_ip4(&ip_temp));
|
||||||
|
udp_sendto(dhcps->dhcps_pcb, p, &ip_temp, DHCPS_CLIENT_PORT);
|
||||||
|
|
||||||
|
if (p->ref != 0) {
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FunctionName : parse_options
|
* FunctionName : parse_options
|
||||||
* Description : parse DHCP message options
|
* Description : parse DHCP message options
|
||||||
@@ -1025,6 +1116,23 @@ static s16_t parse_msg(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
|
|||||||
#if DHCPS_DEBUG
|
#if DHCPS_DEBUG
|
||||||
DHCPS_LOG("dhcps: len = %d\n", len);
|
DHCPS_LOG("dhcps: len = %d\n", len);
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
u8_t msg_type = dhcps_get_option_msg_type(&m->options[4], (s16_t)len);
|
||||||
|
if (msg_type == DHCPINFORM) {
|
||||||
|
ip4_addr_t ciaddr;
|
||||||
|
memcpy(&ciaddr.addr, m->ciaddr, sizeof(ciaddr.addr));
|
||||||
|
if (ip4_addr_isany(&ciaddr)) {
|
||||||
|
/* RFC 2131: client MUST set ciaddr to its configured address */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!ip4_addr_netcmp(&ciaddr, &dhcps->server_address, &dhcps->dhcps_mask)) {
|
||||||
|
/* No configuration for this client */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return DHCPS_STATE_INFORM_ACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ip4_addr_t addr_tmp;
|
ip4_addr_t addr_tmp;
|
||||||
|
|
||||||
struct dhcps_pool *pdhcps_pool = NULL;
|
struct dhcps_pool *pdhcps_pool = NULL;
|
||||||
@@ -1276,6 +1384,13 @@ static void handle_dhcp(void *arg,
|
|||||||
send_nak(dhcps, pmsg_dhcps, malloc_len);
|
send_nak(dhcps, pmsg_dhcps, malloc_len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DHCPS_STATE_INFORM_ACK://7
|
||||||
|
#if DHCPS_DEBUG
|
||||||
|
DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_INFORM_ACK\n");
|
||||||
|
#endif
|
||||||
|
send_ack_inform(dhcps, pmsg_dhcps, malloc_len);
|
||||||
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ typedef enum
|
|||||||
* - MAX_STATION_NUM: Maximum number of clients, set to Kconfig value CONFIG_LWIP_DHCPS_MAX_STATION_NUM
|
* - MAX_STATION_NUM: Maximum number of clients, set to Kconfig value CONFIG_LWIP_DHCPS_MAX_STATION_NUM
|
||||||
* - LWIP_HOOK_DHCPS_POST_STATE: Used to inject user code after parsing DHCP message, not defined
|
* - LWIP_HOOK_DHCPS_POST_STATE: Used to inject user code after parsing DHCP message, not defined
|
||||||
* - could be enabled in lwipopts.h or via CC_FLAGS
|
* - could be enabled in lwipopts.h or via CC_FLAGS
|
||||||
|
* - parse states include DHCPS_STATE_OFFER (1), ACK (3), NAK (4), INFORM_ACK (7), etc.
|
||||||
* - basic usage of the hook to print hex representation of the entire option field is below:
|
* - basic usage of the hook to print hex representation of the entire option field is below:
|
||||||
* #define LWIP_HOOK_DHCPS_POST_STATE(msg, len, state) \
|
* #define LWIP_HOOK_DHCPS_POST_STATE(msg, len, state) \
|
||||||
* ({ s16_t ret = state; if (state == DHCPS_STATE_ACK) { ESP_LOG_BUFFER_HEXDUMP("DHCPS",msg->options, 312, ESP_LOG_INFO);} ret; })
|
* ({ s16_t ret = state; if (state == DHCPS_STATE_ACK) { ESP_LOG_BUFFER_HEXDUMP("DHCPS",msg->options, 312, ESP_LOG_INFO);} ret; })
|
||||||
|
|||||||
Reference in New Issue
Block a user