Browse Source

lwip: Added support for configurable LwIP hooks

Added lwIP hooks which could be optionally overwritten in the
application code. These three options are provided in Kconfig:
* NONE: No hook support
* DEFAULT: Default implementation is provided. If IDF doesn't
have a specific hook implementation, an empty stub is provided, which
could be overwritten by strong implementation in application code.
* CUSTOM: Hooks are declared only to be implemented in application code.

Merges https://github.com/espressif/esp-idf/pull/6034
Paweł pidpawel Kozubal 5 years ago
parent
commit
cf60ec0ffc

+ 3 - 3
components/esp_netif/lwip/esp_netif_lwip.c

@@ -33,8 +33,8 @@
 #include "lwip/dns.h"
 #include "lwip/dns.h"
 #endif
 #endif
 
 
-#if CONFIG_LWIP_TCP_ISN_HOOK
-#include "tcp_isn.h"
+#if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
+#include "lwip_default_hooks.h"
 #endif
 #endif
 
 
 #include "esp_netif_lwip_ppp.h"
 #include "esp_netif_lwip_ppp.h"
@@ -273,7 +273,7 @@ esp_err_t esp_netif_init(void)
 {
 {
     if (tcpip_initialized == false) {
     if (tcpip_initialized == false) {
         tcpip_initialized = true;
         tcpip_initialized = true;
-#if CONFIG_LWIP_TCP_ISN_HOOK
+#if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
         uint8_t rand_buf[16];
         uint8_t rand_buf[16];
         /*
         /*
          * This is early startup code where WiFi/BT is yet to be enabled and hence
          * This is early startup code where WiFi/BT is yet to be enabled and hence

+ 2 - 5
components/lwip/CMakeLists.txt

@@ -4,7 +4,6 @@ set(include_dirs
     lwip/src/include
     lwip/src/include
     port/esp32/include
     port/esp32/include
     port/esp32/include/arch
     port/esp32/include/arch
-    port/esp32/tcp_isn
     )
     )
 
 
 set(srcs
 set(srcs
@@ -87,6 +86,8 @@ set(srcs
     "lwip/src/netif/ppp/upap.c"
     "lwip/src/netif/ppp/upap.c"
     "lwip/src/netif/ppp/utils.c"
     "lwip/src/netif/ppp/utils.c"
     "lwip/src/netif/ppp/vj.c"
     "lwip/src/netif/ppp/vj.c"
+    "port/esp32/hooks/tcp_isn_default.c"
+    "port/esp32/hooks/lwip_default_hooks.c"
     "port/esp32/debug/lwip_debug.c"
     "port/esp32/debug/lwip_debug.c"
     "port/esp32/freertos/sys_arch.c"
     "port/esp32/freertos/sys_arch.c"
     "port/esp32/netif/dhcp_state.c"
     "port/esp32/netif/dhcp_state.c"
@@ -136,10 +137,6 @@ else()
     list(APPEND srcs "port/esp32/no_vfs_syscalls.c")
     list(APPEND srcs "port/esp32/no_vfs_syscalls.c")
 endif()
 endif()
 
 
-if(CONFIG_LWIP_TCP_ISN_HOOK)
-    list(APPEND srcs "port/esp32/tcp_isn/tcp_isn.c")
-endif()
-
 idf_component_register(SRCS "${srcs}"
 idf_component_register(SRCS "${srcs}"
                     INCLUDE_DIRS "${include_dirs}"
                     INCLUDE_DIRS "${include_dirs}"
                     LDFRAGMENTS linker.lf
                     LDFRAGMENTS linker.lf

+ 68 - 11
components/lwip/Kconfig

@@ -327,17 +327,6 @@ menu "LWIP"
 
 
     menu "TCP"
     menu "TCP"
 
 
-        config LWIP_TCP_ISN_HOOK
-            bool "Enable TCP ISN Hook"
-            default y
-            help
-                Enables custom TCP ISN hook to randomize initial sequence
-                number in TCP connection. This is recommended as default
-                lwIP implementation (`tcp_next_iss`) is not very strong,
-                as it does not take into consideration any platform
-                specific entropy source.
-
-
         config LWIP_MAX_ACTIVE_TCP
         config LWIP_MAX_ACTIVE_TCP
             int "Maximum active TCP Connections"
             int "Maximum active TCP Connections"
             range 1 1024
             range 1 1024
@@ -750,6 +739,74 @@ menu "LWIP"
             Enable this option allows lwip to check assert.
             Enable this option allows lwip to check assert.
             It is recommended to keep it open, do not close it.
             It is recommended to keep it open, do not close it.
 
 
+    menu "Hooks"
+
+        choice LWIP_HOOK_TCP_ISN
+            prompt "TCP ISN Hook"
+            default LWIP_HOOK_TCP_ISN_DEFAULT
+            help
+                Enables to define a TCP ISN hook to randomize initial sequence
+                number in TCP connection.
+                The default TCP ISN algorithm used in IDF (standardized in RFC 6528)
+                produces ISN by combining an MD5 of the new TCP id and a stable
+                secret with the current time.
+                This is because the lwIP implementation (`tcp_next_iss`) is not
+                very strong, as it does not take into consideration any platform
+                specific entropy source.
+
+                Set to LWIP_HOOK_TCP_ISN_CUSTOM to provide custom implementation.
+                Set to LWIP_HOOK_TCP_ISN_NONE to use lwIP implementation.
+
+
+            config LWIP_HOOK_TCP_ISN_NONE
+                bool "No hook declared"
+            config LWIP_HOOK_TCP_ISN_DEFAULT
+                bool "Default implementation"
+            config LWIP_HOOK_TCP_ISN_CUSTOM
+                bool "Custom implementation"
+
+        endchoice
+
+        choice LWIP_HOOK_IP6_ROUTE
+            prompt "IPv6 route Hook"
+            default LWIP_HOOK_IP6_ROUTE_NONE
+            help
+                Enables custom IPv6 route hook.
+                Setting this to "default" provides weak implementation
+                stub that could be overwritten in application code.
+                Setting this to "custom" provides hook's declaration
+                only and expects the application to implement it.
+
+            config LWIP_HOOK_IP6_ROUTE_NONE
+                bool "No hook declared"
+            config LWIP_HOOK_IP6_ROUTE_DEFAULT
+                bool "Default (weak) implementation"
+            config LWIP_HOOK_IP6_ROUTE_CUSTOM
+                bool "Custom implementation"
+
+        endchoice
+
+        choice LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE
+            prompt "Netconn external resolve Hook"
+            default LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE
+            help
+                Enables custom DNS resolve hook.
+                Setting this to "default" provides weak implementation
+                stub that could be overwritten in application code.
+                Setting this to "custom" provides hook's declaration
+                only and expects the application to implement it.
+
+            config LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE
+                bool "No hook declared"
+            config LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT
+                bool "Default (weak) implementation"
+            config LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM
+                bool "Custom implementation"
+
+        endchoice
+
+    endmenu # Hooks
+
     menu "Debug"
     menu "Debug"
 
 
         config LWIP_NETIF_DEBUG
         config LWIP_NETIF_DEBUG

+ 2 - 6
components/lwip/component.mk

@@ -8,8 +8,7 @@ COMPONENT_ADD_INCLUDEDIRS := \
 	include/apps/sntp \
 	include/apps/sntp \
 	lwip/src/include \
 	lwip/src/include \
 	port/esp32/include \
 	port/esp32/include \
-	port/esp32/include/arch \
-	port/esp32/tcp_isn
+	port/esp32/include/arch
 
 
 COMPONENT_SRCDIRS := \
 COMPONENT_SRCDIRS := \
 	apps/dhcpserver \
 	apps/dhcpserver \
@@ -24,6 +23,7 @@ COMPONENT_SRCDIRS := \
 	lwip/src/netif \
 	lwip/src/netif \
 	port/esp32 \
 	port/esp32 \
 	port/esp32/freertos \
 	port/esp32/freertos \
+	port/esp32/hooks \
 	port/esp32/netif \
 	port/esp32/netif \
 	port/esp32/debug
 	port/esp32/debug
 
 
@@ -40,10 +40,6 @@ ifdef CONFIG_LWIP_PPP_SUPPORT
     COMPONENT_SRCDIRS += lwip/src/netif/ppp lwip/src/netif/ppp/polarssl
     COMPONENT_SRCDIRS += lwip/src/netif/ppp lwip/src/netif/ppp/polarssl
 endif
 endif
 
 
-ifdef CONFIG_LWIP_TCP_ISN_HOOK
-    COMPONENT_SRCDIRS += port/esp32/tcp_isn
-endif
-
 CFLAGS += -Wno-address  # lots of LWIP source files evaluate macros that check address of stack variables
 CFLAGS += -Wno-address  # lots of LWIP source files evaluate macros that check address of stack variables
 
 
 lwip/src/netif/ppp/ppp.o: CFLAGS += -Wno-uninitialized
 lwip/src/netif/ppp/ppp.o: CFLAGS += -Wno-uninitialized

+ 40 - 0
components/lwip/port/esp32/hooks/lwip_default_hooks.c

@@ -0,0 +1,40 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "lwip_default_hooks.h"
+
+#define __weak __attribute__((weak))
+
+#ifdef CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT
+struct netif *__weak
+lwip_hook_ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+{
+    LWIP_UNUSED_ARG(src);
+    LWIP_UNUSED_ARG(dest);
+
+    return NULL;
+}
+#endif
+
+#ifdef CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT
+int __weak lwip_hook_netconn_external_resolve(const char *name, ip_addr_t *addr, u8_t addrtype, err_t *err)
+{
+    LWIP_UNUSED_ARG(name);
+    LWIP_UNUSED_ARG(addr);
+    LWIP_UNUSED_ARG(addrtype);
+    LWIP_UNUSED_ARG(err);
+
+    return 0;
+}
+#endif

+ 2 - 2
components/lwip/port/esp32/tcp_isn/tcp_isn.c → components/lwip/port/esp32/hooks/tcp_isn_default.c

@@ -70,13 +70,13 @@
  * Author: David van Moolenbroek <david@minix3.org>
  * Author: David van Moolenbroek <david@minix3.org>
  */
  */
 
 
-#include "tcp_isn.h"
+#include "lwip_default_hooks.h"
 #include "lwip/ip_addr.h"
 #include "lwip/ip_addr.h"
 #include "lwip/sys.h"
 #include "lwip/sys.h"
 #include <string.h>
 #include <string.h>
 #include "esp_rom_md5.h"
 #include "esp_rom_md5.h"
 
 
-#ifdef LWIP_HOOK_TCP_ISN
+#ifdef CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
 
 
 static u8_t input[64];
 static u8_t input[64];
 static u32_t base_time;
 static u32_t base_time;

+ 51 - 0
components/lwip/port/esp32/include/lwip_default_hooks.h

@@ -0,0 +1,51 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _LWIP_DEFAULT_HOOKS_H_
+#define _LWIP_DEFAULT_HOOKS_H_
+#include "lwip/ip_addr.h"
+#include "lwip/arch.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
+void lwip_init_tcp_isn(u32_t boot_time, const u8_t *secret_16_bytes);
+#endif
+#if defined(CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM) || defined(CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT)
+u32_t lwip_hook_tcp_isn(const ip_addr_t *local_ip, u16_t local_port,
+                        const ip_addr_t *remote_ip, u16_t remote_port);
+#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
+#endif /* CONFIG_LWIP_HOOK_TCP_ISN... */
+
+#if defined(CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM) || defined(CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT)
+struct netif *
+lwip_hook_ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest);
+
+#define LWIP_HOOK_IP6_ROUTE lwip_hook_ip6_route
+#endif /* CONFIG_LWIP_HOOK_IP6_ROUTE... */
+
+#if defined(CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM) || defined(CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT)
+int lwip_hook_netconn_external_resolve(const char *name, ip_addr_t *addr, u8_t addrtype, err_t *err);
+
+#define LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE lwip_hook_netconn_external_resolve
+#endif /* CONFIG_LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE... */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LWIP_DEFAULT_HOOKS_H_ */

+ 2 - 11
components/lwip/port/esp32/include/lwipopts.h

@@ -420,17 +420,6 @@
  */
  */
 #define LWIP_TCP_RTO_TIME             CONFIG_LWIP_TCP_RTO_TIME
 #define LWIP_TCP_RTO_TIME             CONFIG_LWIP_TCP_RTO_TIME
 
 
-/**
- * Set TCP hook for Initial Sequence Number (ISN)
- */
-#ifdef CONFIG_LWIP_TCP_ISN_HOOK
-#include <lwip/arch.h>
-struct ip_addr;
-u32_t lwip_hook_tcp_isn(const struct ip_addr *local_ip, u16_t local_port,
-                        const struct ip_addr *remote_ip, u16_t remote_port);
-#define LWIP_HOOK_TCP_ISN               lwip_hook_tcp_isn
-#endif
-
 /*
 /*
    ----------------------------------
    ----------------------------------
    ---------- Pbuf options ----------
    ---------- Pbuf options ----------
@@ -778,7 +767,9 @@ u32_t lwip_hook_tcp_isn(const struct ip_addr *local_ip, u16_t local_port,
    ---------- Hook options ---------------
    ---------- Hook options ---------------
    ---------------------------------------
    ---------------------------------------
 */
 */
+#define LWIP_HOOK_FILENAME              "lwip_default_hooks.h"
 #define LWIP_HOOK_IP4_ROUTE_SRC         ip4_route_src_hook
 #define LWIP_HOOK_IP4_ROUTE_SRC         ip4_route_src_hook
+
 /*
 /*
    ---------------------------------------
    ---------------------------------------
    ---------- Debugging options ----------
    ---------- Debugging options ----------

+ 0 - 48
components/lwip/port/esp32/tcp_isn/tcp_isn.h

@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2016 The MINIX 3 Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * Author: David van Moolenbroek <david@minix3.org>
- */
-
-#ifndef LWIP_TCP_ISN_H
-#define LWIP_TCP_ISN_H
-
-#include "lwip/opt.h"
-#include "lwip/ip_addr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void lwip_init_tcp_isn(u32_t boot_time, const u8_t *secret_16_bytes);
-u32_t lwip_hook_tcp_isn(const ip_addr_t *local_ip, u16_t local_port,
-                        const ip_addr_t *remote_ip, u16_t remote_port);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_TCP_ISN_H */