diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index bdd4d678567..ca8e86e81f3 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -182,14 +182,21 @@ static esp_err_t esp_tls_hostname_to_fd(const char *host, size_t hostlen, int po return ESP_ERR_ESP_TLS_CANNOT_CREATE_SOCKET; } +#if CONFIG_LWIP_IPV4 if (address_info->ai_family == AF_INET) { struct sockaddr_in *p = (struct sockaddr_in *)address_info->ai_addr; p->sin_port = htons(port); ESP_LOGD(TAG, "[sock=%d] Resolved IPv4 address: %s", *fd, ipaddr_ntoa((const ip_addr_t*)&p->sin_addr.s_addr)); memcpy(address, p, sizeof(struct sockaddr )); } +#endif + +#if defined(CONFIG_LWIP_IPV4) && defined(CONFIG_LWIP_IPV6) + else +#endif + #if CONFIG_LWIP_IPV6 - else if (address_info->ai_family == AF_INET6) { + if (address_info->ai_family == AF_INET6) { struct sockaddr_in6 *p = (struct sockaddr_in6 *)address_info->ai_addr; p->sin6_port = htons(port); p->sin6_family = AF_INET6; diff --git a/components/esp_http_server/src/httpd_main.c b/components/esp_http_server/src/httpd_main.c index 3d1923542d4..c93d8b3bdf9 100644 --- a/components/esp_http_server/src/httpd_main.c +++ b/components/esp_http_server/src/httpd_main.c @@ -56,7 +56,7 @@ static esp_err_t httpd_accept_conn(struct httpd_data *hd, int listen_fd) } } - struct sockaddr_in addr_from; + struct sockaddr_storage addr_from; socklen_t addr_from_len = sizeof(addr_from); int new_fd = accept(listen_fd, (struct sockaddr *)&addr_from, &addr_from_len); if (new_fd < 0) { diff --git a/components/esp_http_server/src/util/ctrl_sock.c b/components/esp_http_server/src/util/ctrl_sock.c index eaf4a3423ab..83ffc8c90b5 100644 --- a/components/esp_http_server/src/util/ctrl_sock.c +++ b/components/esp_http_server/src/util/ctrl_sock.c @@ -24,11 +24,18 @@ int cs_create_ctrl_sock(int port) } int ret; - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - inet_aton("127.0.0.1", &addr.sin_addr); + struct sockaddr_storage addr = {}; +#ifdef CONFIG_LWIP_IPV4 + struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; + addr4->sin_family = AF_INET; + addr4->sin_port = htons(port); + inet_aton("127.0.0.1", &addr4->sin_addr); +#else + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(port); + inet6_aton("::1", &addr6->sin6_addr); +#endif ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { close(fd); @@ -45,10 +52,18 @@ void cs_free_ctrl_sock(int fd) int cs_send_to_ctrl_sock(int send_fd, int port, void *data, unsigned int data_len) { int ret; - struct sockaddr_in to_addr; - to_addr.sin_family = AF_INET; - to_addr.sin_port = htons(port); - inet_aton("127.0.0.1", &to_addr.sin_addr); + struct sockaddr_storage to_addr = {}; +#ifdef CONFIG_LWIP_IPV4 + struct sockaddr_in *addr4 = (struct sockaddr_in *)&to_addr; + addr4->sin_family = AF_INET; + addr4->sin_port = htons(port); + inet_aton("127.0.0.1", &addr4->sin_addr); +#else + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&to_addr; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(port); + inet6_aton("::1", &addr6->sin6_addr); +#endif ret = sendto(send_fd, data, data_len, 0, (struct sockaddr *)&to_addr, sizeof(to_addr)); if (ret < 0) { diff --git a/components/esp_netif/esp_netif_handlers.c b/components/esp_netif/esp_netif_handlers.c index 95a046898ca..4752106250b 100644 --- a/components/esp_netif/esp_netif_handlers.c +++ b/components/esp_netif/esp_netif_handlers.c @@ -34,7 +34,6 @@ void esp_netif_action_stop(void *esp_netif, esp_event_base_t base, int32_t event void esp_netif_action_connected(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data) { - esp_netif_dhcp_status_t status; ESP_LOGD(TAG, "esp_netif action connected with netif%p from event_id=%d", esp_netif, event_id); esp_netif_up(esp_netif); @@ -43,7 +42,8 @@ void esp_netif_action_connected(void *esp_netif, esp_event_base_t base, int32_t // No more actions for interfaces without DHCP client flag return; } - +#if CONFIG_LWIP_IPV4 + esp_netif_dhcp_status_t status; ESP_NETIF_CALL_CHECK("connected action: dhcpc failed", esp_netif_dhcpc_get_status(esp_netif, &status), ESP_OK); if (status == ESP_NETIF_DHCP_INIT) { esp_netif_dhcpc_start(esp_netif); @@ -76,6 +76,7 @@ void esp_netif_action_connected(void *esp_netif, esp_event_base_t base, int32_t ESP_LOGE(TAG, "invalid static ip"); } } +#endif } void esp_netif_action_disconnected(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data) diff --git a/components/esp_netif/include/esp_netif_defaults.h b/components/esp_netif/include/esp_netif_defaults.h index 80cb95489f4..78c6535c1b1 100644 --- a/components/esp_netif/include/esp_netif_defaults.h +++ b/components/esp_netif/include/esp_netif_defaults.h @@ -24,9 +24,15 @@ extern "C" { #define ESP_NETIF_DEFAULT_ARP_FLAGS (0) #endif +#ifdef CONFIG_LWIP_IPV4 +#define ESP_NETIF_IPV4_ONLY_FLAGS(flags) (flags) +#else +#define ESP_NETIF_IPV4_ONLY_FLAGS(flags) (0) +#endif + #define ESP_NETIF_INHERENT_DEFAULT_WIFI_STA() \ { \ - .flags = (esp_netif_flags_t)(ESP_NETIF_DHCP_CLIENT | ESP_NETIF_DEFAULT_ARP_FLAGS | ESP_NETIF_FLAG_EVENT_IP_MODIFIED), \ + .flags = (esp_netif_flags_t)(ESP_NETIF_IPV4_ONLY_FLAGS(ESP_NETIF_DHCP_CLIENT) | ESP_NETIF_DEFAULT_ARP_FLAGS | ESP_NETIF_FLAG_EVENT_IP_MODIFIED), \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ .get_ip_event = IP_EVENT_STA_GOT_IP, \ @@ -40,7 +46,7 @@ extern "C" { #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT #define ESP_NETIF_INHERENT_DEFAULT_WIFI_AP() \ { \ - .flags = (esp_netif_flags_t)(ESP_NETIF_DHCP_SERVER | ESP_NETIF_FLAG_AUTOUP), \ + .flags = (esp_netif_flags_t)(ESP_NETIF_IPV4_ONLY_FLAGS(ESP_NETIF_DHCP_SERVER) | ESP_NETIF_FLAG_AUTOUP), \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ .ip_info = &_g_esp_netif_soft_ap_ip, \ .get_ip_event = 0, \ @@ -54,7 +60,7 @@ extern "C" { #define ESP_NETIF_INHERENT_DEFAULT_ETH() \ { \ - .flags = (esp_netif_flags_t)(ESP_NETIF_DHCP_CLIENT | ESP_NETIF_DEFAULT_ARP_FLAGS | ESP_NETIF_FLAG_EVENT_IP_MODIFIED), \ + .flags = (esp_netif_flags_t)(ESP_NETIF_IPV4_ONLY_FLAGS(ESP_NETIF_DHCP_CLIENT) | ESP_NETIF_DEFAULT_ARP_FLAGS | ESP_NETIF_FLAG_EVENT_IP_MODIFIED), \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ .get_ip_event = IP_EVENT_ETH_GOT_IP, \ diff --git a/components/esp_netif/include/esp_netif_ip_addr.h b/components/esp_netif/include/esp_netif_ip_addr.h index 57f10999b31..354da5814ba 100644 --- a/components/esp_netif/include/esp_netif_ip_addr.h +++ b/components/esp_netif/include/esp_netif_ip_addr.h @@ -9,6 +9,7 @@ #include #include +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { @@ -81,6 +82,19 @@ extern "C" { #define ESP_IP4ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V4, .u_addr = { .ip4 = { .addr = ESP_IP4TOADDR(a, b, c, d) }}}; #define ESP_IP6ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V6, .u_addr = { .ip6 = { .addr = { a, b, c, d }, .zone = 0 }}}; +#ifndef IP4ADDR_STRLEN_MAX +#define IP4ADDR_STRLEN_MAX 16 +#endif + +#if defined(CONFIG_LWIP_IPV4) && defined(CONFIG_LWIP_IPV6) +#define ESP_IP_IS_ANY(addr) ((addr.type == ESP_IPADDR_TYPE_V4 && ip4_addr_isany_val(addr.u_addr.ip4)) || \ + (addr.type == ESP_IPADDR_TYPE_V6 && ip6_addr_isany_val(addr.u_addr.ip6))) +#elif defined(CONFIG_LWIP_IPV4) +#define ESP_IP_IS_ANY(addr) (ip4_addr_isany_val(addr.u_addr.ip4)) +#elif defined(CONFIG_LWIP_IPV6) +#define ESP_IP_IS_ANY(addr) (ip6_addr_isany_val(addr.u_addr.ip6)) +#endif + /** * @brief IPv6 address * diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 38426c7123f..43b4b83ebdd 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -40,8 +40,10 @@ #endif // CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT #include "esp_netif_lwip_ppp.h" +#if ESP_DHCPS #include "dhcpserver/dhcpserver.h" #include "dhcpserver/dhcpserver_options.h" +#endif #include "netif/dhcp_state.h" #include "esp_event.h" #include "esp_log.h" @@ -75,6 +77,26 @@ return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); \ } +/** + * @brief Utility macros to convert esp-ip addresses (both IPv6+IPv4 versions unconditionally) + * and lwip-ip addresses (contain only enabled portion of the address for each IP stack) +*/ + +#if LWIP_IPV4 && LWIP_IPV6 +#define ESPIP_TO_IP(espip, ip) memcpy((ip), (espip), sizeof(ip_addr_t)); +#define IP_TO_ESPIP(ip, espip) memcpy((espip), (ip), sizeof(ip_addr_t)); +#elif LWIP_IPV4 +#define ESPIP_TO_IP(espip, ip) memcpy((ip), &((espip)->u_addr.ip4), sizeof(ip_addr_t)); +#define IP_TO_ESPIP(ip, espip) do { memcpy(&((espip)->u_addr.ip4), (ip), sizeof(ip4_addr_t)); \ + (espip)->type = ESP_IPADDR_TYPE_V4; \ + } while(0) +#elif LWIP_IPV6 +#define ESPIP_TO_IP(espip, ip) memcpy((ip), &((espip)->u_addr.ip6), sizeof(ip_addr_t)); +#define IP_TO_ESPIP(ip, espip) do { memcpy(&((espip)->u_addr.ip6), (ip), sizeof(ip6_addr_t)); \ + (espip)->type = ESP_IPADDR_TYPE_V6; \ + } while(0) +#endif + /** * @brief If netif protocol not enabled in menuconfig, log the error and return appropriate code indicating failure */ @@ -107,16 +129,20 @@ static esp_netif_t *s_last_default_esp_netif = NULL; static bool s_is_last_default_esp_netif_overridden = false; static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL }; +#if LWIP_IPV4 static void esp_netif_internal_dhcpc_cb(struct netif *netif); +#endif #if LWIP_IPV6 static void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index); #endif /* LWIP_IPV6 */ static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args) { +#if LWIP_IPV4 if (reason & DHCP_CB_CHANGE) { esp_netif_internal_dhcpc_cb(netif); } +#endif /* LWIP_IPV4 */ #if LWIP_IPV6 if ((reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) && (args != NULL)) { s8_t addr_idx = args->ipv6_addr_state_changed.addr_index; @@ -152,19 +178,6 @@ static esp_err_t remove_lwip_netif_callback(struct esp_netif_api_msg_s *msg) return ESP_OK; } -static void dns_clear_servers(bool keep_fallback) -{ - u8_t numdns = 0; - - for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) { - if (keep_fallback && numdns == DNS_FALLBACK_SERVER_INDEX) { - continue; - } - - dns_setserver(numdns, NULL); - } -} - #ifdef CONFIG_LWIP_GARP_TMR_INTERVAL static void netif_send_garp(void *arg) @@ -436,6 +449,7 @@ esp_err_t esp_netif_bridge_fdb_remove(esp_netif_t *esp_netif_br, uint8_t *addr) } #endif // CONFIG_ESP_NETIF_BRIDGE_EN +#if CONFIG_LWIP_IPV4 void esp_netif_set_ip4_addr(esp_ip4_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d) { ip4_addr_t *address = (ip4_addr_t*)addr; @@ -451,6 +465,7 @@ uint32_t esp_ip4addr_aton(const char *addr) { return ipaddr_addr(addr); } +#endif esp_err_t esp_netif_str_to_ip4(const char *src, esp_ip4_addr_t *dst) { @@ -579,6 +594,7 @@ static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_ // Configure general esp-netif properties memcpy(esp_netif->mac, cfg->base->mac, NETIF_MAX_HWADDR_LEN); +#if CONFIG_LWIP_IPV4 if (cfg->base->ip_info == NULL) { ip4_addr_set_zero(&esp_netif->ip_info->ip); ip4_addr_set_zero(&esp_netif->ip_info->gw); @@ -587,7 +603,7 @@ static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_ memcpy(esp_netif->ip_info, cfg->base->ip_info, sizeof(esp_netif_ip_info_t)); } memcpy(esp_netif->ip_info_old, esp_netif->ip_info, sizeof(esp_netif_ip_info_t)); - +#endif // Setup main config parameters esp_netif->lost_ip_event = cfg->base->lost_ip_event; esp_netif->get_ip_event = cfg->base->get_ip_event; @@ -786,7 +802,9 @@ static void esp_netif_lwip_remove(esp_netif_t *esp_netif) } #endif if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) { +#if CONFIG_LWIP_IPV4 dhcp_cleanup(esp_netif->lwip_netif); +#endif } } @@ -828,8 +846,12 @@ static esp_err_t esp_netif_lwip_add(esp_netif_t *esp_netif) } } else { #endif // CONFIG_ESP_NETIF_BRIDGE_EN - if (NULL == netif_add(esp_netif->lwip_netif, (struct ip4_addr*)&esp_netif->ip_info->ip, - (struct ip4_addr*)&esp_netif->ip_info->netmask, (struct ip4_addr*)&esp_netif->ip_info->gw, + if (NULL == netif_add(esp_netif->lwip_netif, +#if CONFIG_LWIP_IPV4 + (struct ip4_addr*)&esp_netif->ip_info->ip, + (struct ip4_addr*)&esp_netif->ip_info->netmask, + (struct ip4_addr*)&esp_netif->ip_info->gw, +#endif esp_netif, esp_netif->lwip_init_fn, tcpip_input)) { esp_netif_lwip_remove(esp_netif); return ESP_ERR_ESP_NETIF_IF_NOT_READY; @@ -907,6 +929,7 @@ esp_err_t esp_netif_set_driver_config(esp_netif_t *esp_netif, return ESP_OK; } +#if CONFIG_LWIP_IPV4 static esp_err_t esp_netif_reset_ip_info(esp_netif_t *esp_netif) { ip4_addr_set_zero(&(esp_netif->ip_info->ip)); @@ -914,6 +937,7 @@ static esp_err_t esp_netif_reset_ip_info(esp_netif_t *esp_netif) ip4_addr_set_zero(&(esp_netif->ip_info->netmask)); return ESP_OK; } +#endif esp_err_t esp_netif_set_mac_api(esp_netif_api_msg_t *msg) { @@ -1051,6 +1075,7 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED); #endif } else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) { +#if CONFIG_LWIP_IPV4 if (esp_netif->dhcpc_status != ESP_NETIF_DHCP_STARTED) { if (p_netif != NULL) { struct dhcp *dhcp_data = NULL; @@ -1064,6 +1089,9 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) } } } +#else + LOG_NETIF_DISABLED_AND_DO("IPv4's DHCP Client", return ESP_ERR_NOT_SUPPORTED); +#endif } esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); @@ -1110,6 +1138,7 @@ static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg) LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED); #endif } else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) { +#if CONFIG_LWIP_IPV4 dhcp_release(lwip_netif); dhcp_stop(lwip_netif); dhcp_cleanup(lwip_netif); @@ -1117,6 +1146,9 @@ static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg) esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT; esp_netif_reset_ip_info(esp_netif); +#else + LOG_NETIF_DISABLED_AND_DO("IPv4's DHCP Client", return ESP_ERR_NOT_SUPPORTED); +#endif } netif_set_down(lwip_netif); @@ -1176,6 +1208,7 @@ esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, vo return ESP_OK; } +#if CONFIG_LWIP_IPV4 static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif); // @@ -1272,7 +1305,6 @@ static void esp_netif_ip_lost_timer(void *arg) } } - static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif) { esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info; @@ -1337,6 +1369,19 @@ static esp_err_t esp_netif_dhcpc_stop_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_stop_api, esp_netif, NULL) +static void dns_clear_servers(bool keep_fallback) +{ + u8_t numdns = 0; + + for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) { + if (keep_fallback && numdns == DNS_FALLBACK_SERVER_INDEX) { + continue; + } + + dns_setserver(numdns, NULL); + } +} + static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg) { esp_netif_t *esp_netif = msg->esp_netif; @@ -1388,6 +1433,7 @@ static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg) } esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_start_api, esp_netif, NULL) +#endif /* CONFIG_LWIP_IPV4 */ #if ESP_DHCPS esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status) @@ -1556,8 +1602,10 @@ static esp_err_t esp_netif_up_api(esp_netif_api_msg_t *msg) struct netif *lwip_netif = esp_netif->lwip_netif; +#if CONFIG_LWIP_IPV4 /* use last obtained ip, or static ip */ netif_set_addr(lwip_netif, (ip4_addr_t*)&esp_netif->ip_info->ip, (ip4_addr_t*)&esp_netif->ip_info->netmask, (ip4_addr_t*)&esp_netif->ip_info->gw); +#endif netif_set_up(lwip_netif); netif_set_link_up(lwip_netif); @@ -1581,11 +1629,13 @@ static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg) struct netif *lwip_netif = esp_netif->lwip_netif; if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT && esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) { +#if CONFIG_LWIP_IPV4 dhcp_stop(esp_netif->lwip_netif); esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT; esp_netif_reset_ip_info(esp_netif); +#endif } #if CONFIG_LWIP_IPV6 for(int8_t i = 0 ;i < LWIP_IPV6_NUM_ADDRESSES ;i++) { @@ -1595,12 +1645,16 @@ static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg) netif_ip6_addr_set_state(lwip_netif, i, IP6_ADDR_INVALID); } #endif +#if CONFIG_LWIP_IPV4 netif_set_addr(lwip_netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); +#endif netif_set_down(lwip_netif); netif_set_link_down(lwip_netif); if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) { +#if CONFIG_LWIP_IPV4 esp_netif_start_ip_lost_timer(esp_netif); +#endif } esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED); @@ -1626,6 +1680,7 @@ bool esp_netif_is_netif_up(esp_netif_t *esp_netif) } } +#if CONFIG_LWIP_IPV4 esp_err_t esp_netif_get_old_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info) { ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif); @@ -1746,6 +1801,7 @@ static esp_err_t esp_netif_set_ip_info_api(esp_netif_api_msg_t *msg) } esp_err_t esp_netif_set_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_info_api, esp_netif, ip_info) +#endif /* CONFIG_LWIP_IPV4 */ struct array_mac_ip_t { int num; @@ -1786,12 +1842,8 @@ static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg) ESP_LOGD(TAG, "esp_netif_set_dns_info: if=%p type=%d dns=%x", esp_netif, type, dns->ip.u_addr.ip4.addr); - ip_addr_t *lwip_ip = (ip_addr_t*)&dns->ip; -#if CONFIG_LWIP_IPV6 && LWIP_IPV4 - if (!IP_IS_V4(lwip_ip) && !IP_IS_V6(lwip_ip)) { - lwip_ip->type = IPADDR_TYPE_V4; - } -#endif + ip_addr_t lwip_ip = {}; + ESPIP_TO_IP(&dns->ip, &lwip_ip); if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) { #if ESP_DHCPS // if DHCP server configured to set DNS in dhcps API @@ -1799,13 +1851,13 @@ static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg) ESP_LOGD(TAG, "set dns invalid type"); return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } else { - dhcps_dns_setserver(esp_netif->dhcps, lwip_ip); + dhcps_dns_setserver(esp_netif->dhcps, &lwip_ip); } #else LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED); #endif } else { - dns_setserver(type, lwip_ip); + dns_setserver(type, &lwip_ip); } return ESP_OK; @@ -1822,7 +1874,7 @@ esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t ty return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } - if (ip4_addr_isany_val(dns->ip.u_addr.ip4)) { + if (ESP_IP_IS_ANY(dns->ip)) { ESP_LOGD(TAG, "set dns invalid dns"); return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } @@ -1856,7 +1908,7 @@ static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg) const ip_addr_t* dns_ip = NULL; dns_ip = dns_getserver(type); if(dns_ip != NULL) { - memcpy(&dns->ip, dns_ip, sizeof(ip_addr_t)); + IP_TO_ESPIP(dns_ip, &dns->ip); } } @@ -2187,7 +2239,9 @@ esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_m struct dhcp_params opts = { .op = opt_op, .id = opt_id, .len = opt_len, .val = opt_val }; return esp_netif_lwip_ipc_call(esp_netif_dhcps_option_api, esp_netif, &opts); } -#endif +#endif // ESP_DHCPS + +#if CONFIG_LWIP_IPV4 esp_err_t esp_netif_dhcpc_option_api(esp_netif_api_msg_t *msg) { @@ -2248,6 +2302,8 @@ esp_err_t esp_netif_dhcpc_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_m return esp_netif_lwip_ipc_call(esp_netif_dhcpc_option_api, esp_netif, &opts); } +#endif /* CONFIG_LWIP_IPV4 */ + int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif) { if (esp_netif == NULL || esp_netif->lwip_netif == NULL) { diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index 30ecdb71eb4..18a50d955f2 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -9,7 +9,9 @@ #include "esp_netif.h" #include "esp_netif_ppp.h" #include "lwip/netif.h" +#ifdef CONFIG_LWIP_DHCPS #include "dhcpserver/dhcpserver.h" +#endif struct esp_netif_api_msg_s; diff --git a/components/esp_netif/lwip/netif/ethernetif.c b/components/esp_netif/lwip/netif/ethernetif.c index c46775915d1..9403b515a6d 100644 --- a/components/esp_netif/lwip/netif/ethernetif.c +++ b/components/esp_netif/lwip/netif/ethernetif.c @@ -36,7 +36,7 @@ static void ethernet_low_level_init(struct netif *netif) { /* set MAC hardware address length */ - netif->hwaddr_len = ETHARP_HWADDR_LEN; + netif->hwaddr_len = ETH_HWADDR_LEN; /* maximum transfer unit */ netif->mtu = 1500; @@ -170,7 +170,9 @@ err_t ethernetif_init(struct netif *netif) netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; +#if LWIP_IPV4 netif->output = etharp_output; +#endif #if LWIP_IPV6 netif->output_ip6 = ethip6_output; #endif /* LWIP_IPV6 */ diff --git a/components/esp_netif/lwip/netif/wlanif.c b/components/esp_netif/lwip/netif/wlanif.c index 92129ea262c..17337fe23df 100644 --- a/components/esp_netif/lwip/netif/wlanif.c +++ b/components/esp_netif/lwip/netif/wlanif.c @@ -36,7 +36,7 @@ static void low_level_init(struct netif *netif) { /* set MAC hardware address length */ - netif->hwaddr_len = ETHARP_HWADDR_LEN; + netif->hwaddr_len = ETH_HWADDR_LEN; /* set MAC hardware address */ @@ -205,7 +205,9 @@ wlanif_init(struct netif *netif) * You can instead declare your own function an call etharp_output() * from it if you have to do some checks before sending (e.g. if link * is available...) */ +#if LWIP_IPV4 netif->output = etharp_output; +#endif #if LWIP_IPV6 netif->output_ip6 = ethip6_output; #endif /* LWIP_IPV6 */ diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index a78c2739984..c3343a6647d 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -25,7 +25,7 @@ if(CONFIG_ESP_WIFI_ENABLED) "src/wifi_default_ap.c" "${idf_target}/esp_adapter.c") - if(CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API) + if(CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API AND CONFIG_LWIP_IPV4) list(APPEND srcs "src/smartconfig_ack.c") endif() diff --git a/components/esp_wifi/include/esp_mesh.h b/components/esp_wifi/include/esp_mesh.h index 0ba31b36187..78f65945051 100644 --- a/components/esp_wifi/include/esp_mesh.h +++ b/components/esp_wifi/include/esp_mesh.h @@ -278,7 +278,7 @@ typedef enum { * @brief IP address and port */ typedef struct { - ip4_addr_t ip4; /**< IP address */ + esp_ip4_addr_t ip4; /**< IP address */ uint16_t port; /**< port */ } __attribute__((packed)) mip_t; diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index ea863870bc3..e583f7d4815 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -147,6 +147,7 @@ menu "LWIP" config LWIP_IP4_FRAG bool "Enable fragment outgoing IP4 packets" default y + depends on LWIP_IPV4 help Enabling this option allows fragmenting outgoing IP4 packets if their size exceeds MTU. @@ -162,6 +163,7 @@ menu "LWIP" config LWIP_IP4_REASSEMBLY bool "Enable reassembly incoming fragmented IP4 packets" default n + depends on LWIP_IPV4 help Enabling this option allows reassemblying incoming fragmented IP4 packets. @@ -201,6 +203,7 @@ menu "LWIP" config LWIP_ESP_GRATUITOUS_ARP bool "Send gratuitous ARP periodically" default y + depends on LWIP_IPV4 help Enable this option allows to send gratuitous ARP periodically. @@ -227,6 +230,7 @@ menu "LWIP" config LWIP_DHCP_DOES_ARP_CHECK bool "DHCP: Perform ARP check on any offered address" default y + depends on LWIP_IPV4 help Enabling this option performs a check (via ARP request) if the offered IP address is not already in use by another host on the network. @@ -234,6 +238,7 @@ menu "LWIP" config LWIP_DHCP_DISABLE_CLIENT_ID bool "DHCP: Disable Use of HW address as client identification" default n + depends on LWIP_IPV4 help This option could be used to disable DHCP client identification with its MAC address. (Client id is used by DHCP servers to uniquely identify clients and are included @@ -243,6 +248,7 @@ menu "LWIP" config LWIP_DHCP_DISABLE_VENDOR_CLASS_ID bool "DHCP: Disable Use of vendor class identification" default y + depends on LWIP_IPV4 help This option could be used to disable DHCP client vendor class identification. Set this option to "y" in order to exclude option 60 from DHCP packets. @@ -250,6 +256,7 @@ menu "LWIP" config LWIP_DHCP_RESTORE_LAST_IP bool "DHCP: Restore last IP obtained from DHCP server" default n + depends on LWIP_IPV4 help When this option is enabled, DHCP client tries to re-obtain last valid IP address obtained from DHCP server. Last valid DHCP configuration is stored in nvs and restored after reset/power-up. If IP is still @@ -260,6 +267,7 @@ menu "LWIP" default 68 if LWIP_DHCP_DISABLE_VENDOR_CLASS_ID default 108 if !LWIP_DHCP_DISABLE_VENDOR_CLASS_ID range 68 255 + depends on LWIP_IPV4 help Set total length of outgoing DHCP option msg. Generally bigger value means it can carry more options and values. If your code meets LWIP_ASSERT due to option value is too long. @@ -285,6 +293,7 @@ menu "LWIP" config LWIP_DHCPS bool "DHCPS: Enable IPv4 Dynamic Host Configuration Protocol Server (DHCPS)" default y + depends on LWIP_IPV4 help Enabling this option allows the device to run the DHCP server (to dynamically assign IPv4 addresses to clients). @@ -314,6 +323,7 @@ menu "LWIP" menuconfig LWIP_AUTOIP bool "Enable IPV4 Link-Local Addressing (AUTOIP)" default n + depends on LWIP_IPV4 help Enabling this option allows the device to self-assign an address in the 169.256/16 range if none is assigned statically or via DHCP. @@ -352,6 +362,12 @@ menu "LWIP" If rate limiting self-assignment requests, wait this long between each request. + config LWIP_IPV4 + bool "Enable IPv4" + default y + help + Enable IPv4 stack. If you want to use IPv6 only TCP/IP stack, disable this. + config LWIP_IPV6 bool "Enable IPv6" default y diff --git a/components/lwip/apps/ping/ping_sock.c b/components/lwip/apps/ping/ping_sock.c index b85692781ca..94cf8b525e9 100644 --- a/components/lwip/apps/ping/ping_sock.c +++ b/components/lwip/apps/ping/ping_sock.c @@ -92,6 +92,7 @@ static int esp_ping_receive(esp_ping_t *ep) uint16_t data_head = 0; while ((len = recvfrom(ep->sock, buf, sizeof(buf), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen)) > 0) { +#if CONFIG_LWIP_IPV4 if (from.ss_family == AF_INET) { // IPv4 struct sockaddr_in *from4 = (struct sockaddr_in *)&from; @@ -99,8 +100,9 @@ static int esp_ping_receive(esp_ping_t *ep) IP_SET_TYPE_VAL(ep->recv_addr, IPADDR_TYPE_V4); data_head = (uint16_t)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)); } +#endif #if CONFIG_LWIP_IPV6 - else { + if (from.ss_family == AF_INET6) { // IPv6 struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from; inet6_addr_to_ip6addr(ip_2_ip6(&ep->recv_addr), &from6->sin6_addr); @@ -109,6 +111,7 @@ static int esp_ping_receive(esp_ping_t *ep) } #endif if (len >= data_head) { +#if CONFIG_LWIP_IPV4 if (IP_IS_V4_VAL(ep->recv_addr)) { // Currently we process IPv4 struct ip_hdr *iphdr = (struct ip_hdr *)buf; struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); @@ -120,8 +123,9 @@ static int esp_ping_receive(esp_ping_t *ep) return len; } } +#endif // CONFIG_LWIP_IPV4 #if CONFIG_LWIP_IPV6 - else if (IP_IS_V6_VAL(ep->recv_addr)) { // Currently we process IPv6 + if (IP_IS_V6_VAL(ep->recv_addr)) { // Currently we process IPv6 struct ip6_hdr *iphdr = (struct ip6_hdr *)buf; struct icmp6_echo_hdr *iecho6 = (struct icmp6_echo_hdr *)(buf + sizeof(struct ip6_hdr)); // IPv6 head length is 40 if ((iecho6->id == ep->packet_hdr->id) && (iecho6->seqno == ep->packet_hdr->seqno)) { @@ -130,7 +134,7 @@ static int esp_ping_receive(esp_ping_t *ep) return len; } } -#endif +#endif // CONFIG_LWIP_IPV6 } fromlen = sizeof(from); } @@ -278,12 +282,14 @@ esp_err_t esp_ping_new_session(const esp_ping_config_t *config, const esp_ping_c setsockopt(ep->sock, IPPROTO_IP, IP_TTL, &config->ttl, sizeof(config->ttl)); /* set socket address */ +#if CONFIG_LWIP_IPV4 if (IP_IS_V4(&config->target_addr)) { struct sockaddr_in *to4 = (struct sockaddr_in *)&ep->target_addr; to4->sin_family = AF_INET; inet_addr_from_ip4addr(&to4->sin_addr, ip_2_ip4(&config->target_addr)); ep->packet_hdr->type = ICMP_ECHO; } +#endif #if CONFIG_LWIP_IPV6 if (IP_IS_V6(&config->target_addr)) { struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ep->target_addr; diff --git a/components/lwip/port/debug/lwip_debug.c b/components/lwip/port/debug/lwip_debug.c index d9be733c54b..b8b08f2419c 100644 --- a/components/lwip/port/debug/lwip_debug.c +++ b/components/lwip/port/debug/lwip_debug.c @@ -15,10 +15,12 @@ #include "lwip/memp.h" #include "esp_log.h" -#if CONFIG_LWIP_IPV6 +#if CONFIG_LWIP_IPV6 && CONFIG_LWIP_IPV4 #define DBG_LWIP_IP_SHOW(info, ip) ESP_LWIP_LOGI("%s type=%d ip=%x", (info), (ip).type, (ip).u_addr.ip4.addr) -#else +#elif CONFIG_LWIP_IPV4 #define DBG_LWIP_IP_SHOW(info, ip) ESP_LWIP_LOGI("%s type=%d ip=%x", (info), IPADDR_TYPE_V4, (ip).addr) +#elif CONFIG_LWIP_IPV6 +#define DBG_LWIP_IP_SHOW(info, ip) ESP_LWIP_LOGI("%s type=%d ip=%x,%x,5x,%x", (info), IPADDR_TYPE_V6, (ip).addr[0], (ip).addr[1], (ip).addr[2], (ip).addr[3]) #endif #define DBG_LWIP_IP_PCB_SHOW(pcb) \ DBG_LWIP_IP_SHOW("local ip", (pcb)->local_ip);\ diff --git a/components/lwip/port/hooks/lwip_default_hooks.c b/components/lwip/port/hooks/lwip_default_hooks.c index e198ee018b7..2e92d364588 100644 --- a/components/lwip/port/hooks/lwip_default_hooks.c +++ b/components/lwip/port/hooks/lwip_default_hooks.c @@ -55,6 +55,8 @@ int __weak lwip_hook_ip6_input(struct pbuf *p, struct netif *inp) } #endif +#ifdef CONFIG_LWIP_IPV4 + #ifdef LWIP_HOOK_IP4_ROUTE_SRC #if ESP_IP4_ROUTE #include "lwip/netif.h" @@ -270,3 +272,5 @@ void dhcp_append_extra_opts(struct netif *netif, uint8_t state, struct dhcp_msg #endif /* LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS */ } + +#endif /* CONFIG_LWIP_IPV4 */ diff --git a/components/lwip/port/include/lwip_default_hooks.h b/components/lwip/port/include/lwip_default_hooks.h index 28220ba75cc..6c273bd3ab8 100644 --- a/components/lwip/port/include/lwip_default_hooks.h +++ b/components/lwip/port/include/lwip_default_hooks.h @@ -55,6 +55,7 @@ int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp); #define LWIP_HOOK_IP6_INPUT lwip_hook_ip6_input #endif /* CONFIG_LWIP_HOOK_IP6_INPUT_CUSTIOM... */ +#ifdef CONFIG_LWIP_IPV4 struct netif * ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest); @@ -68,6 +69,7 @@ void dhcp_append_extra_opts(struct netif *netif, uint8_t state, struct dhcp_msg int dhcp_set_vendor_class_identifier(uint8_t len, const char * str); int dhcp_get_vendor_specific_information(uint8_t len, char * str); void dhcp_free_vendor_class_identifier(void); +#endif /* CONFIG_LWIP_IPV4 */ #ifdef __cplusplus } diff --git a/components/lwip/port/include/lwipopts.h b/components/lwip/port/include/lwipopts.h index d97f82829dc..cc77901b483 100644 --- a/components/lwip/port/include/lwipopts.h +++ b/components/lwip/port/include/lwipopts.h @@ -164,7 +164,11 @@ extern "C" { /** * LWIP_IPV4==1: Enable IPv4 */ +#ifdef CONFIG_LWIP_IPV4 #define LWIP_IPV4 1 +#else +#define LWIP_IPV4 0 +#endif /** * IP_REASSEMBLY==1: Reassemble incoming fragmented IP4 packets. Note that @@ -273,6 +277,7 @@ extern "C" { ---------- DHCP options ---------- ---------------------------------- */ +#if CONFIG_LWIP_IPV4 /** * LWIP_DHCP==1: Enable DHCP module. */ @@ -381,6 +386,7 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr) \ dhcp_append_extra_opts(netif, state, msg, options_len_ptr); +#endif /* CONFIG_LWIP_IPV4 */ /* ------------------------------------ ---------- AUTOIP options ---------- @@ -1544,6 +1550,14 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define mem_clib_calloc calloc #endif /* CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP */ + +/* + * Check if the lwIP configuration is sane + */ +#if !LWIP_IPV4 && !LWIP_IPV6 +#error "Please enable at least one IP stack (either IPv4 or IPv6 or both)" +#endif + #ifdef __cplusplus } #endif diff --git a/components/mbedtls/port/net_sockets.c b/components/mbedtls/port/net_sockets.c index 6736cb32c65..b646870d92d 100644 --- a/components/mbedtls/port/net_sockets.c +++ b/components/mbedtls/port/net_sockets.c @@ -107,7 +107,7 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char { int ret; struct addrinfo hints, *addr_list, *cur; - struct sockaddr_in *serv_addr = NULL; + struct sockaddr_storage *serv_addr = NULL; #if SO_REUSE int n = 1; #endif @@ -144,9 +144,22 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char continue; } #endif - /*bind interface dafault don't process the addr is 0xffffffff for TCP Protocol*/ - serv_addr = (struct sockaddr_in *)cur->ai_addr; - serv_addr->sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + serv_addr = (struct sockaddr_storage *) cur->ai_addr; +#if CONFIG_LWIP_IPV4 + if (cur->ai_family == AF_INET) { + /*bind interface dafault don't process the addr is 0xffffffff for TCP Protocol*/ + struct sockaddr_in *p = (struct sockaddr_in *)serv_addr; + p->sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + } +#endif // CONFIG_LWIP_IPV4 +#if CONFIG_LWIP_IPV6 + if (cur->ai_family == AF_INET6) { + struct sockaddr_in6 *p = (struct sockaddr_in6 *) serv_addr; + struct in6_addr inaddr_any = IN6ADDR_ANY_INIT; + p->sin6_addr = inaddr_any; + } +#endif // CONFIG_LWIP_IPV6 + if ( bind( fd, (struct sockaddr *)serv_addr, cur->ai_addrlen ) != 0 ) { close( fd ); ret = MBEDTLS_ERR_NET_BIND_FAILED; @@ -206,7 +219,7 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, int ret; int type; - struct sockaddr_in client_addr; + struct sockaddr_storage client_addr; socklen_t n = (socklen_t) sizeof( client_addr ); socklen_t type_len = (socklen_t) sizeof( type ); @@ -242,7 +255,7 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, /* UDP: hijack the listening socket to communicate with the client, * then bind a new socket to accept new connections */ if ( type != SOCK_STREAM ) { - struct sockaddr_in local_addr; + struct sockaddr_storage local_addr; int one = 1; if ( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) { @@ -252,10 +265,10 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, client_ctx->fd = bind_ctx->fd; bind_ctx->fd = -1; /* In case we exit early */ - n = sizeof( struct sockaddr_in ); + n = sizeof( struct sockaddr_storage ); if ( getsockname( client_ctx->fd, (struct sockaddr *) &local_addr, &n ) != 0 || - ( bind_ctx->fd = (int) socket( AF_INET, + ( bind_ctx->fd = (int) socket( local_addr.ss_family, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 || setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &one, sizeof( one ) ) != 0 ) { @@ -268,14 +281,32 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, } if ( client_ip != NULL ) { - struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; - *ip_len = sizeof( addr4->sin_addr.s_addr ); +#ifdef CONFIG_LWIP_IPV4 + if( client_addr.ss_family == AF_INET ) + { + struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; + *ip_len = sizeof( addr4->sin_addr.s_addr ); + + if ( buf_size < *ip_len ) { + return ( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + } - if ( buf_size < *ip_len ) { - return ( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); } +#endif // CONFIG_LWIP_IPV4 +#ifdef CONFIG_LWIP_IPV6 + if( client_addr.ss_family == AF_INET6 ) + { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; + *ip_len = sizeof( addr6->sin6_addr.s6_addr ); + + if( buf_size < *ip_len ) { + return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + } - memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); + memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len); + } +#endif // CONFIG_LWIP_IPV6 } return ( 0 ); diff --git a/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h b/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h index 95cb2d87ed6..6c9d11f5ab1 100644 --- a/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h +++ b/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h @@ -7,7 +7,8 @@ #ifndef _WIFI_PROV_CONFIG_H_ #define _WIFI_PROV_CONFIG_H_ -#include +#include "esp_netif_ip_addr.h" +#include "esp_err.h" #ifdef __cplusplus extern "C" { diff --git a/docs/en/api-guides/lwip.rst b/docs/en/api-guides/lwip.rst index 5832a38fcc2..5720d7ea462 100644 --- a/docs/en/api-guides/lwip.rst +++ b/docs/en/api-guides/lwip.rst @@ -290,7 +290,7 @@ A number of configuration items are available to modify the task and the queues IPv6 Support ------------ -Both IPv4 and IPv6 are supported as dual stack and enabled by default (IPv6 may be disabled if it's not needed, see :ref:`lwip-ram-usage`). +Both IPv4 and IPv6 are supported as a dual stack and are enabled by default. Both IPv6 and IPv4 may be disabled separately if they are not needed (see :ref:`lwip-ram-usage`). IPv6 support is limited to *Stateless Autoconfiguration* only, *Stateful configuration* is not supported in ESP-IDF (not in upstream lwip). IPv6 Address configuration is defined by means of these protocols or services: @@ -454,8 +454,9 @@ Most lwIP RAM usage is on-demand, as RAM is allocated from the heap as needed. T - Reducing :ref:`CONFIG_LWIP_MAX_SOCKETS` reduces the maximum number of sockets in the system. This will also cause TCP sockets in the ``WAIT_CLOSE`` state to be closed and recycled more rapidly (if needed to open a new socket), further reducing peak RAM usage. - Reducing :ref:`CONFIG_LWIP_TCPIP_RECVMBOX_SIZE`, :ref:`CONFIG_LWIP_TCP_RECVMBOX_SIZE` and :ref:`CONFIG_LWIP_UDP_RECVMBOX_SIZE` reduce memory usage at the expense of throughput, depending on usage. -- Reducing :ref:`CONFIG_LWIP_TCP_MSL`, :ref:`CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT` reduces the maximum segment lifetime in the system. This will also cause TCP sockets in the ``TIME_WAIT``, ``FIN_WAIT_2`` state to be closed and recycled more rapidly -- Disable :ref:`CONFIG_LWIP_IPV6` can save about 39 KB for firmware size and 2KB RAM when system power up and 7KB RAM when TCPIP stack running. If there is no requirement for supporting IPV6 then it can be disabled to save flash and RAM footprint. +- Reducing :ref:`CONFIG_LWIP_TCP_MSL`, :ref:`CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT` reduces the maximum segment lifetime in the system. This will also cause TCP sockets in the ``TIME_WAIT``, ``FIN_WAIT_2`` state to be closed and recycled more rapidly +- Disabling :ref:`CONFIG_LWIP_IPV6` can save about 39 KB for firmware size and 2KB RAM when the system is powered up and 7KB RAM when the TCPIP stack is running. If there is no requirement for supporting IPV6 then it can be disabled to save flash and RAM footprint. +- Disabling :ref:`CONFIG_LWIP_IPV4` can save about 26 KB of firmware size and 600B RAM on power up and 6 KB RAM when the TCP/IP stack is running. If the local network supports IPv6-only configuration then IPv4 can be disabled to save flash and RAM footprint. .. only:: SOC_WIFI_SUPPORTED diff --git a/docs/en/api-guides/performance/size.rst b/docs/en/api-guides/performance/size.rst index 0322d53b0b8..2ac2f97977a 100644 --- a/docs/en/api-guides/performance/size.rst +++ b/docs/en/api-guides/performance/size.rst @@ -354,6 +354,14 @@ lwIP IPv6 IPv6 is required by some components such as ``coap`` and :doc:`/api-reference/protocols/asio`, These components will not be available if IPV6 is disabled. +lwIP IPv4 +@@@@@@@@@ + +- If IPv4 connectivity is not required, setting :ref:`CONFIG_LWIP_IPV4` to false will reduce the size of the lwIP, supporting IPv6 only TCP/IP stack. + + .. note:: + + Before disabling IPv4 support, please note that IPv6 only network environments are not ubiquitous and must be supported in the local network, e.g. by your internet service provider or using constrained local network settings. .. _newlib-nano-formatting: diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index f839bb5e21b..fe92d24db4b 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -306,6 +306,11 @@ menu "Example Connection Configuration" Set PHY address according your board schematic. endif # EXAMPLE_CONNECT_ETHERNET + config EXAMPLE_CONNECT_IPV4 + bool + depends on LWIP_IPV4 + default y + config EXAMPLE_CONNECT_IPV6 depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET bool "Obtain IPv6 address" diff --git a/examples/common_components/protocol_examples_common/addr_from_stdin.c b/examples/common_components/protocol_examples_common/addr_from_stdin.c index 5c79be614fa..e4c94b1a142 100644 --- a/examples/common_components/protocol_examples_common/addr_from_stdin.c +++ b/examples/common_components/protocol_examples_common/addr_from_stdin.c @@ -41,6 +41,7 @@ esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *ad } for( cur = addr_list; cur != NULL; cur = cur->ai_next ) { memcpy(dest_addr, cur->ai_addr, sizeof(*dest_addr)); +#if CONFIG_EXAMPLE_CONNECT_IPV4 if (cur->ai_family == AF_INET) { *ip_protocol = IPPROTO_IP; *addr_family = AF_INET; @@ -48,10 +49,10 @@ esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *ad ((struct sockaddr_in*)dest_addr)->sin_port = htons(port); freeaddrinfo( addr_list ); return ESP_OK; - } +#endif // IPV4 #if CONFIG_EXAMPLE_CONNECT_IPV6 - else if (cur->ai_family == AF_INET6) { + if (cur->ai_family == AF_INET6) { *ip_protocol = IPPROTO_IPV6; *addr_family = AF_INET6; // add port and interface number and return on first IPv6 match @@ -60,7 +61,7 @@ esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *ad freeaddrinfo( addr_list ); return ESP_OK; } -#endif +#endif // IPV6 } // no match found freeaddrinfo( addr_list ); diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index 6debc208133..d40870eb02d 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -58,14 +58,16 @@ void example_print_all_netif_ips(const char *prefix) { // iterate over active interfaces, and print out IPs of "our" netifs esp_netif_t *netif = NULL; - esp_netif_ip_info_t ip; for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) { netif = esp_netif_next(netif); if (example_is_our_netif(prefix, netif)) { ESP_LOGI(TAG, "Connected to %s", esp_netif_get_desc(netif)); +#if CONFIG_LWIP_IPV4 + esp_netif_ip_info_t ip; ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip)); ESP_LOGI(TAG, "- IPv4 address: " IPSTR ",", IP2STR(&ip.ip)); +#endif #if CONFIG_EXAMPLE_CONNECT_IPV6 esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF]; int ip6_addrs = esp_netif_get_all_ip6(netif, ip6); diff --git a/examples/common_components/protocol_examples_common/eth_connect.c b/examples/common_components/protocol_examples_common/eth_connect.c index 0b7d8f4b1a7..fce806c6aa3 100644 --- a/examples/common_components/protocol_examples_common/eth_connect.c +++ b/examples/common_components/protocol_examples_common/eth_connect.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -214,10 +214,12 @@ void example_ethernet_shutdown(void) esp_err_t example_ethernet_connect(void) { +#if CONFIG_EXAMPLE_CONNECT_IPV4 s_semph_get_ip_addrs = xSemaphoreCreateBinary(); if (s_semph_get_ip_addrs == NULL) { return ESP_ERR_NO_MEM; } +#endif #if CONFIG_EXAMPLE_CONNECT_IPV6 s_semph_get_ip6_addrs = xSemaphoreCreateBinary(); if (s_semph_get_ip6_addrs == NULL) { @@ -227,7 +229,9 @@ esp_err_t example_ethernet_connect(void) #endif eth_start(); ESP_LOGI(TAG, "Waiting for IP(s)."); +#if CONFIG_EXAMPLE_CONNECT_IPV4 xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY); +#endif #if CONFIG_EXAMPLE_CONNECT_IPV6 xSemaphoreTake(s_semph_get_ip6_addrs, portMAX_DELAY); #endif diff --git a/examples/common_components/protocol_examples_common/wifi_connect.c b/examples/common_components/protocol_examples_common/wifi_connect.c index 3e10407d93e..e4e14686887 100644 --- a/examples/common_components/protocol_examples_common/wifi_connect.c +++ b/examples/common_components/protocol_examples_common/wifi_connect.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -196,7 +196,9 @@ esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait) } if (wait) { ESP_LOGI(TAG, "Waiting for IP(s)"); +#if CONFIG_EXAMPLE_CONNECT_IPV4 xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY); +#endif #if CONFIG_EXAMPLE_CONNECT_IPV6 xSemaphoreTake(s_semph_get_ip6_addrs, portMAX_DELAY); #endif diff --git a/examples/common_components/protocol_examples_tapif_io/Kconfig.projbuild b/examples/common_components/protocol_examples_tapif_io/Kconfig.projbuild index 7c842a3c412..6eb2c459ee5 100644 --- a/examples/common_components/protocol_examples_tapif_io/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_tapif_io/Kconfig.projbuild @@ -6,21 +6,36 @@ menu "Example Connection Configuration" default n if EXAMPLE_CONNECT_LWIP_TAPIF + config EXAMPLE_CONNECT_IPV4 + bool + depends on LWIP_IPV4 + default y + + config EXAMPLE_CONNECT_IPV6 + bool "Obtain IPv6 address" + depends on LWIP_IPV6 + default y + help + Set to true to setup link local address and wait until it's valid + config EXAMPLE_CONNECT_TAPIF_IP_ADDR string "Static IP address" default "192.168.5.100" + depends on EXAMPLE_CONNECT_IPV4 help Set static IP address. config EXAMPLE_CONNECT_TAPIF_NETMASK string "Static netmask address" default "255.255.255.0" + depends on EXAMPLE_CONNECT_IPV4 help Set static netmask address. config EXAMPLE_CONNECT_TAPIF_GW string "Static gateway address" default "192.168.5.1" + depends on EXAMPLE_CONNECT_IPV4 help Set static gateway address. diff --git a/examples/mesh/ip_internal_network/README.md b/examples/mesh/ip_internal_network/README.md index d3cec3f7ee2..08234b65f67 100644 --- a/examples/mesh/ip_internal_network/README.md +++ b/examples/mesh/ip_internal_network/README.md @@ -15,6 +15,8 @@ API to exchange data, such as routing table from root to all nodes and an event to all other nodes in the mesh. As a demonstration, the same event is also published at the mqtt broker on a subscribed topic, so both internal mesh_recv() notification as well as mqtt data event are to be received. +Note, that this example in not supported for IPv6-only configuration. + ### Hardware Required This example can be executed on any platform board, the only required interface is WiFi and connection to internet. diff --git a/examples/protocols/coap_client/README.md b/examples/protocols/coap_client/README.md index 76c67008fc5..96d95ab40b1 100644 --- a/examples/protocols/coap_client/README.md +++ b/examples/protocols/coap_client/README.md @@ -107,3 +107,5 @@ optional `path`, and begins with `coap://`, `coaps://`, `coap+tcp://` or `coaps+ * CoAP logging can be enabled by running 'idf.py menuconfig -> Component config -> CoAP Configuration -> Enable CoAP debugging' and setting appropriate log level. If Mbed TLS logging is required, this needs to be configured separately under mbedTLS Component Configuration and the CoAP logging level set to mbedTLS. + +* CoAP library does not support IPv6 only configuration, so it is necessary to enable `LWIP_IPv4` diff --git a/examples/protocols/coap_client/main/Kconfig.projbuild b/examples/protocols/coap_client/main/Kconfig.projbuild index 206b2fa7128..add9065972c 100644 --- a/examples/protocols/coap_client/main/Kconfig.projbuild +++ b/examples/protocols/coap_client/main/Kconfig.projbuild @@ -1,5 +1,11 @@ menu "Example CoAP Client Configuration" + # Hidden option that selects IPv4 + config EXAMPLE_COAP_NEEDS_IPV4 + bool + default true + select LWIP_IPV4 + config EXAMPLE_TARGET_DOMAIN_URI string "Target Uri" default "coaps://californium.eclipseprojects.io" diff --git a/examples/protocols/coap_server/README.md b/examples/protocols/coap_server/README.md index eb8d365b908..d0e5de64e3a 100644 --- a/examples/protocols/coap_server/README.md +++ b/examples/protocols/coap_server/README.md @@ -92,3 +92,5 @@ fetches `/.well-known/core` * CoAP logging can be enabled by running 'idf.py menuconfig -> Component config -> CoAP Configuration -> Enable CoAP debugging' and setting appropriate log level. If Mbed TLS logging is required, this needs to be configured separately under mbedTLS Component Configuration and the CoAP logging level set to mbedTLS. + +* CoAP library does not support IPv6 only configuration, so it is necessary to enable `LWIP_IPv4` diff --git a/examples/protocols/coap_server/main/Kconfig.projbuild b/examples/protocols/coap_server/main/Kconfig.projbuild index 3c0fbfc230f..7821b779cef 100644 --- a/examples/protocols/coap_server/main/Kconfig.projbuild +++ b/examples/protocols/coap_server/main/Kconfig.projbuild @@ -1,5 +1,11 @@ menu "Example CoAP Server Configuration" + # Hidden option that selects IPv4 + config EXAMPLE_COAP_NEEDS_IPV4 + bool + default true + select LWIP_IPV4 + config EXAMPLE_COAP_PSK_KEY string "Preshared Key (PSK) to used in the connection from the CoAP client" depends on COAP_MBEDTLS_PSK diff --git a/examples/protocols/esp_local_ctrl/README.md b/examples/protocols/esp_local_ctrl/README.md index b01a31bca52..5df67bec5e3 100644 --- a/examples/protocols/esp_local_ctrl/README.md +++ b/examples/protocols/esp_local_ctrl/README.md @@ -9,6 +9,8 @@ See the `esp_local_ctrl` component documentation for details. Before using the example, run `idf.py menuconfig` (or `idf.py menuconfig` if using CMake build system) to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details. +Note, that this example in not supported for IPv6-only configuration. + ## Client Side Implementation A python test script `scripts/esp_local_ctrl.py` has been provided for as a client side application for controlling the device over the same Wi-Fi network. The script relies on a pre-generated `main/certs/rootCA.pem` to verify the server certificate. The server side private key and certificate can also be found under `main/certs`, namely `prvtkey.pem` and `cacert.pem`. diff --git a/examples/protocols/http_server/simple/sdkconfig.ci.ipv6_only b/examples/protocols/http_server/simple/sdkconfig.ci.ipv6_only new file mode 100644 index 00000000000..87f16680578 --- /dev/null +++ b/examples/protocols/http_server/simple/sdkconfig.ci.ipv6_only @@ -0,0 +1,5 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y +CONFIG_EXAMPLE_CONNECT_IPV4=n +CONFIG_EXAMPLE_CONNECT_IPV6=y +CONFIG_LWIP_IPV4=n +CONFIG_LWIP_IPV6=y diff --git a/examples/protocols/sockets/tcp_server/main/Kconfig.projbuild b/examples/protocols/sockets/tcp_server/main/Kconfig.projbuild index 967184d59ee..80e41ee6056 100644 --- a/examples/protocols/sockets/tcp_server/main/Kconfig.projbuild +++ b/examples/protocols/sockets/tcp_server/main/Kconfig.projbuild @@ -3,6 +3,7 @@ menu "Example Configuration" config EXAMPLE_IPV4 bool "IPV4" default y + depends on LWIP_IPV4 config EXAMPLE_IPV6 bool "IPV6" diff --git a/examples/protocols/sockets/tcp_server/main/tcp_server.c b/examples/protocols/sockets/tcp_server/main/tcp_server.c index 157a19784e9..5f1c284960f 100644 --- a/examples/protocols/sockets/tcp_server/main/tcp_server.c +++ b/examples/protocols/sockets/tcp_server/main/tcp_server.c @@ -73,6 +73,7 @@ static void tcp_server_task(void *pvParameters) int keepCount = KEEPALIVE_COUNT; struct sockaddr_storage dest_addr; +#ifdef CONFIG_EXAMPLE_IPV4 if (addr_family == AF_INET) { struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr; dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY); @@ -80,8 +81,9 @@ static void tcp_server_task(void *pvParameters) dest_addr_ip4->sin_port = htons(PORT); ip_protocol = IPPROTO_IP; } +#endif #ifdef CONFIG_EXAMPLE_IPV6 - else if (addr_family == AF_INET6) { + if (addr_family == AF_INET6) { struct sockaddr_in6 *dest_addr_ip6 = (struct sockaddr_in6 *)&dest_addr; bzero(&dest_addr_ip6->sin6_addr.un, sizeof(dest_addr_ip6->sin6_addr.un)); dest_addr_ip6->sin6_family = AF_INET6; @@ -138,11 +140,13 @@ static void tcp_server_task(void *pvParameters) setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &keepInterval, sizeof(int)); setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &keepCount, sizeof(int)); // Convert ip address to string +#ifdef CONFIG_EXAMPLE_IPV4 if (source_addr.ss_family == PF_INET) { inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1); } +#endif #ifdef CONFIG_EXAMPLE_IPV6 - else if (source_addr.ss_family == PF_INET6) { + if (source_addr.ss_family == PF_INET6) { inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1); } #endif diff --git a/examples/protocols/sockets/tcp_server/sdkconfig.ci.ipv6_only b/examples/protocols/sockets/tcp_server/sdkconfig.ci.ipv6_only new file mode 100644 index 00000000000..db0d6baa34a --- /dev/null +++ b/examples/protocols/sockets/tcp_server/sdkconfig.ci.ipv6_only @@ -0,0 +1,6 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y +CONFIG_EXAMPLE_IPV4=n +CONFIG_EXAMPLE_IPV6=y +CONFIG_EXAMPLE_CONNECT_IPV6=y +CONFIG_LWIP_IPV4=n +CONFIG_LWIP_IPV6=y diff --git a/examples/provisioning/wifi_prov_mgr/README.md b/examples/provisioning/wifi_prov_mgr/README.md index 0e38eccc21c..1006ac55767 100644 --- a/examples/provisioning/wifi_prov_mgr/README.md +++ b/examples/provisioning/wifi_prov_mgr/README.md @@ -54,7 +54,7 @@ To install the dependency packages needed, please refer to the top level [README ``` idf.py menuconfig ``` -* Set the BLE/Soft AP transport under "Example Configuration" options. ESP32-S2 will have only SoftAP option. +* Set the BLE/Soft AP transport under "Example Configuration" options. ESP32-S2 will have only SoftAP option (SoftAP option cannot be used if IPv4 is disabled in lwIP) ### Build and Flash diff --git a/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild b/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild index d103d6f7741..be36720ad3c 100644 --- a/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild +++ b/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild @@ -13,6 +13,7 @@ menu "Example Configuration" depends on !IDF_TARGET_ESP32S2 config EXAMPLE_PROV_TRANSPORT_SOFTAP bool "Soft AP" + select LWIP_IPV4 endchoice choice EXAMPLE_PROV_SECURITY_VERSION