mirror of
https://github.com/espressif/esp-lwip.git
synced 2026-06-05 21:04:45 +00:00
napt: cosmetic updates on NAPT functionality implemented by martin-ger
Overview of the changes: - moved NAPT specific code from ip4.c to ip4_napt.c - formatting updates to keep the changes easier to review - updated per C-90 style used for lwip upstream (fixed warning, renaming, lwip types) - esp_random() -> LWIP_RAND() - drop the connection with routing err if failed to add new napt record - prepared for lwip unit testing
This commit is contained in:
@@ -61,6 +61,7 @@ set(lwipcore4_SRCS
|
||||
${LWIP_DIR}/src/core/ipv4/igmp.c
|
||||
${LWIP_DIR}/src/core/ipv4/ip4_frag.c
|
||||
${LWIP_DIR}/src/core/ipv4/ip4.c
|
||||
${LWIP_DIR}/src/core/ipv4/ip4_napt.c
|
||||
${LWIP_DIR}/src/core/ipv4/ip4_addr.c
|
||||
)
|
||||
set(lwipcore6_SRCS
|
||||
|
||||
@@ -58,6 +58,7 @@ CORE4FILES=$(LWIPDIR)/core/ipv4/autoip.c \
|
||||
$(LWIPDIR)/core/ipv4/igmp.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4_frag.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4_napt.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4_addr.c
|
||||
|
||||
CORE6FILES=$(LWIPDIR)/core/ipv6/dhcp6.c \
|
||||
|
||||
+75
-85
@@ -57,7 +57,6 @@
|
||||
#include "lwip/nd6.h"
|
||||
#include "lwip/mld6.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/lwip_napt.h"
|
||||
|
||||
#include "netif/ppp/ppp_opts.h"
|
||||
#include "netif/ppp/ppp_impl.h"
|
||||
@@ -68,8 +67,7 @@
|
||||
# include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct packed_struct_test
|
||||
{
|
||||
struct packed_struct_test {
|
||||
PACK_STRUCT_FLD_8(u8_t dummy1);
|
||||
PACK_STRUCT_FIELD(u32_t dummy2);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
@@ -85,187 +83,183 @@ PACK_STRUCT_END
|
||||
* These can be done independently of LWIP_DEBUG, without penalty.
|
||||
*/
|
||||
#ifndef BYTE_ORDER
|
||||
#error "BYTE_ORDER is not defined, you have to define it in your cc.h"
|
||||
#error "BYTE_ORDER is not defined, you have to define it in your cc.h"
|
||||
#endif
|
||||
#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV)
|
||||
#error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h"
|
||||
#error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (!LWIP_UDP && LWIP_UDPLITE)
|
||||
#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||
#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (!LWIP_UDP && LWIP_DHCP)
|
||||
#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||
#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (!LWIP_UDP && LWIP_MULTICAST_TX_OPTIONS)
|
||||
#error "If you want to use IGMP/LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||
#if (!LWIP_UDP && !LWIP_RAW && LWIP_MULTICAST_TX_OPTIONS)
|
||||
#error "If you want to use LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 and/or LWIP_RAW=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (!LWIP_UDP && LWIP_DNS)
|
||||
#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||
#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */
|
||||
#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0))
|
||||
#error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h"
|
||||
#error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0))
|
||||
#error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h"
|
||||
#error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0))
|
||||
#error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h"
|
||||
#error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0))
|
||||
#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
|
||||
#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
|
||||
#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
|
||||
#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_IGMP && !LWIP_MULTICAST_TX_OPTIONS)
|
||||
#error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h"
|
||||
#error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_IGMP && !LWIP_IPV4)
|
||||
#error "IGMP needs LWIP_IPV4 enabled in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_MULTICAST_TX_OPTIONS && !LWIP_IPV4)
|
||||
#error "LWIP_MULTICAST_TX_OPTIONS needs LWIP_IPV4 enabled in your lwipopts.h"
|
||||
#error "IGMP needs LWIP_IPV4 enabled in your lwipopts.h"
|
||||
#endif
|
||||
#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0))
|
||||
#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h"
|
||||
#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h"
|
||||
#endif
|
||||
/* There must be sufficient timeouts, taking into account requirements of the subsystems. */
|
||||
#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)))
|
||||
#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
|
||||
#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < LWIP_NUM_SYS_TIMEOUT_INTERNAL)
|
||||
#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
|
||||
#endif
|
||||
#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS))
|
||||
#error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!"
|
||||
#error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!"
|
||||
#endif
|
||||
#endif /* !MEMP_MEM_MALLOC */
|
||||
#if LWIP_WND_SCALE
|
||||
#if (LWIP_TCP && (TCP_WND > 0xffffffff))
|
||||
#error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h"
|
||||
#error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_TCP && (TCP_RCV_SCALE > 14))
|
||||
#error "The maximum valid window scale value is 14!"
|
||||
#error "The maximum valid window scale value is 14!"
|
||||
#endif
|
||||
#if (LWIP_TCP && (TCP_WND > (0xFFFFU << TCP_RCV_SCALE)))
|
||||
#error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!"
|
||||
#error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!"
|
||||
#endif
|
||||
#if (LWIP_TCP && ((TCP_WND >> TCP_RCV_SCALE) == 0))
|
||||
#error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!"
|
||||
#error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!"
|
||||
#endif
|
||||
#else /* LWIP_WND_SCALE */
|
||||
#if (LWIP_TCP && (TCP_WND > 0xffff))
|
||||
#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)"
|
||||
#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)"
|
||||
#endif
|
||||
#endif /* LWIP_WND_SCALE */
|
||||
#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
|
||||
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
|
||||
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2))
|
||||
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
|
||||
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
|
||||
#endif
|
||||
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
|
||||
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
|
||||
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)))
|
||||
#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
|
||||
#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
|
||||
#endif
|
||||
#if (LWIP_TCP && LWIP_TCP_SACK_OUT && !TCP_QUEUE_OOSEQ)
|
||||
#error "To use LWIP_TCP_SACK_OUT, TCP_QUEUE_OOSEQ needs to be enabled"
|
||||
#endif
|
||||
#if (LWIP_TCP && LWIP_TCP_SACK_OUT && (LWIP_TCP_MAX_SACK_NUM < 1))
|
||||
#error "LWIP_TCP_MAX_SACK_NUM must be greater than 0"
|
||||
#endif
|
||||
#if (LWIP_NETIF_API && (NO_SYS==1))
|
||||
#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h"
|
||||
#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h"
|
||||
#endif
|
||||
#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1))
|
||||
#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
|
||||
#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_PPP_API && (NO_SYS==1))
|
||||
#error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h"
|
||||
#error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_PPP_API && (PPP_SUPPORT==0))
|
||||
#error "If you want to use PPP API, you have to enable PPP_SUPPORT in your lwipopts.h"
|
||||
#error "If you want to use PPP API, you have to enable PPP_SUPPORT in your lwipopts.h"
|
||||
#endif
|
||||
#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP)
|
||||
#error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h"
|
||||
#error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK)
|
||||
#error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h"
|
||||
#error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (!LWIP_ARP && LWIP_AUTOIP)
|
||||
#error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h"
|
||||
#error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API)))
|
||||
#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h"
|
||||
#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_ALTCP && LWIP_EVENT_API)
|
||||
#error "The application layered tcp API does not work with LWIP_EVENT_API"
|
||||
#endif
|
||||
#if (MEM_LIBC_MALLOC && MEM_USE_POOLS)
|
||||
#error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h"
|
||||
#error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h"
|
||||
#endif
|
||||
#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS)
|
||||
#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h"
|
||||
#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h"
|
||||
#endif
|
||||
#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT)
|
||||
#error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf"
|
||||
#error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf"
|
||||
#endif
|
||||
#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT)))
|
||||
#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
|
||||
#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
|
||||
#endif
|
||||
#if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT && !PPPOL2TP_SUPPORT
|
||||
#error "PPP_SUPPORT needs at least one of PPPOS_SUPPORT, PPPOE_SUPPORT or PPPOL2TP_SUPPORT turned on"
|
||||
#error "PPP_SUPPORT needs at least one of PPPOS_SUPPORT, PPPOE_SUPPORT or PPPOL2TP_SUPPORT turned on"
|
||||
#endif
|
||||
#if PPP_SUPPORT && !PPP_IPV4_SUPPORT && !PPP_IPV6_SUPPORT
|
||||
#error "PPP_SUPPORT needs PPP_IPV4_SUPPORT and/or PPP_IPV6_SUPPORT turned on"
|
||||
#error "PPP_SUPPORT needs PPP_IPV4_SUPPORT and/or PPP_IPV6_SUPPORT turned on"
|
||||
#endif
|
||||
#if PPP_SUPPORT && PPP_IPV4_SUPPORT && !LWIP_IPV4
|
||||
#error "PPP_IPV4_SUPPORT needs LWIP_IPV4 turned on"
|
||||
#error "PPP_IPV4_SUPPORT needs LWIP_IPV4 turned on"
|
||||
#endif
|
||||
#if PPP_SUPPORT && PPP_IPV6_SUPPORT && !LWIP_IPV6
|
||||
#error "PPP_IPV6_SUPPORT needs LWIP_IPV6 turned on"
|
||||
#error "PPP_IPV6_SUPPORT needs LWIP_IPV6 turned on"
|
||||
#endif
|
||||
#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT)
|
||||
#error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT"
|
||||
#error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT"
|
||||
#endif
|
||||
#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING
|
||||
#error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too"
|
||||
#error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too"
|
||||
#endif
|
||||
#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE
|
||||
#error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets"
|
||||
#error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets"
|
||||
#endif
|
||||
#if LWIP_NETCONN && LWIP_TCP
|
||||
#if NETCONN_COPY != TCP_WRITE_FLAG_COPY
|
||||
#error "NETCONN_COPY != TCP_WRITE_FLAG_COPY"
|
||||
#error "NETCONN_COPY != TCP_WRITE_FLAG_COPY"
|
||||
#endif
|
||||
#if NETCONN_MORE != TCP_WRITE_FLAG_MORE
|
||||
#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
|
||||
#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
|
||||
#endif
|
||||
#endif /* LWIP_NETCONN && LWIP_TCP */
|
||||
#if LWIP_SOCKET
|
||||
/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */
|
||||
#if SO_REUSEADDR != SOF_REUSEADDR
|
||||
#error "WARNING: SO_REUSEADDR != SOF_REUSEADDR"
|
||||
#endif
|
||||
#if SO_KEEPALIVE != SOF_KEEPALIVE
|
||||
#error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE"
|
||||
#endif
|
||||
#if SO_BROADCAST != SOF_BROADCAST
|
||||
#error "WARNING: SO_BROADCAST != SOF_BROADCAST"
|
||||
#endif
|
||||
#endif /* LWIP_SOCKET */
|
||||
|
||||
|
||||
/* Compile-time checks for deprecated options.
|
||||
*/
|
||||
#ifdef MEMP_NUM_TCPIP_MSG
|
||||
#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h."
|
||||
#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h."
|
||||
#endif
|
||||
#ifdef TCP_REXMIT_DEBUG
|
||||
#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h."
|
||||
#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h."
|
||||
#endif
|
||||
#ifdef RAW_STATS
|
||||
#error "RAW_STATS option is deprecated. Remove it from your lwipopts.h."
|
||||
#error "RAW_STATS option is deprecated. Remove it from your lwipopts.h."
|
||||
#endif
|
||||
#ifdef ETHARP_QUEUE_FIRST
|
||||
#error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h."
|
||||
#error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h."
|
||||
#endif
|
||||
#ifdef ETHARP_ALWAYS_INSERT
|
||||
#error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h."
|
||||
#error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h."
|
||||
#endif
|
||||
#if !NO_SYS && LWIP_TCPIP_CORE_LOCKING && LWIP_COMPAT_MUTEX && !defined(LWIP_COMPAT_MUTEX_ALLOWED)
|
||||
#error "LWIP_COMPAT_MUTEX cannot prevent priority inversion. It is recommended to implement priority-aware mutexes. (Define LWIP_COMPAT_MUTEX_ALLOWED to disable this error.)"
|
||||
#error "LWIP_COMPAT_MUTEX cannot prevent priority inversion. It is recommended to implement priority-aware mutexes. (Define LWIP_COMPAT_MUTEX_ALLOWED to disable this error.)"
|
||||
#endif
|
||||
|
||||
#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS
|
||||
@@ -300,31 +294,31 @@ PACK_STRUCT_END
|
||||
#if !LWIP_DISABLE_TCP_SANITY_CHECKS
|
||||
#if LWIP_TCP
|
||||
#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN)
|
||||
#error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#endif
|
||||
#if TCP_SND_BUF < (2 * TCP_MSS)
|
||||
#error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#endif
|
||||
#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS))
|
||||
#error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#endif
|
||||
#if TCP_SNDLOWAT >= TCP_SND_BUF
|
||||
#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#endif
|
||||
#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS))
|
||||
#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!"
|
||||
#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!"
|
||||
#endif
|
||||
#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN
|
||||
#error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#endif
|
||||
#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
|
||||
#error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#endif
|
||||
#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))))
|
||||
#error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#endif
|
||||
#if TCP_WND < TCP_MSS
|
||||
#error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
|
||||
#endif
|
||||
#endif /* LWIP_TCP */
|
||||
#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */
|
||||
@@ -340,7 +334,7 @@ lwip_init(void)
|
||||
#ifndef LWIP_SKIP_CONST_CHECK
|
||||
int a = 0;
|
||||
LWIP_UNUSED_ARG(a);
|
||||
LWIP_ASSERT("LWIP_CONST_CAST not implemented correctly. Check your lwIP port.", LWIP_CONST_CAST(void*, &a) == &a);
|
||||
LWIP_ASSERT("LWIP_CONST_CAST not implemented correctly. Check your lwIP port.", LWIP_CONST_CAST(void *, &a) == &a);
|
||||
#endif
|
||||
#ifndef LWIP_SKIP_PACKING_CHECK
|
||||
LWIP_ASSERT("Struct packing not implemented correctly. Check your lwIP port.", sizeof(struct packed_struct_test) == PACKED_STRUCT_TEST_EXPECTED_SIZE);
|
||||
@@ -379,12 +373,8 @@ lwip_init(void)
|
||||
#if PPP_SUPPORT
|
||||
ppp_init();
|
||||
#endif
|
||||
|
||||
|
||||
#if LWIP_TIMERS
|
||||
sys_timeouts_init();
|
||||
#endif /* LWIP_TIMERS */
|
||||
|
||||
#if IP_NAPT && !IP_NAPT_DYNAMIC
|
||||
ip_napt_init(IP_NAPT_MAX, IP_PORTMAP_MAX);
|
||||
#endif /* IP_NAPT */
|
||||
}
|
||||
|
||||
+17
-696
@@ -42,7 +42,6 @@
|
||||
|
||||
#if LWIP_IPV4
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
@@ -57,7 +56,7 @@
|
||||
#include "lwip/autoip.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/prot/iana.h"
|
||||
#include "lwip/lwip_napt.h"
|
||||
#include "lwip/ip4_napt.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -281,699 +280,6 @@ ip4_route(const ip4_addr_t *dest)
|
||||
}
|
||||
|
||||
#if IP_FORWARD
|
||||
#if IP_NAPT
|
||||
|
||||
#define NO_IDX ((u16_t)-1)
|
||||
#define NT(x) ((x) == NO_IDX ? NULL : &ip_napt_table[x])
|
||||
|
||||
u16_t napt_list = NO_IDX, napt_list_last = NO_IDX, napt_free = 0;
|
||||
|
||||
static struct napt_table *ip_napt_table;
|
||||
struct portmap_table *ip_portmap_table;
|
||||
|
||||
int nr_active_napt_tcp = 0, nr_active_napt_udp = 0, nr_active_napt_icmp = 0;
|
||||
uint16_t ip_napt_max = 0;
|
||||
uint8_t ip_portmap_max = 0;
|
||||
|
||||
#if NAPT_DEBUG
|
||||
/* Print NAPT table using LWIP_DEBUGF
|
||||
*/
|
||||
void
|
||||
napt_debug_print()
|
||||
{
|
||||
int i, next;
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("NAPT table:\n"));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, (" src dest sport dport mport \n"));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("+-----------------------+-----------------------+-------+-------+-------+\n"));
|
||||
|
||||
for (i = napt_list; i != NO_IDX; i = next) {
|
||||
struct napt_table *t = &ip_napt_table[i];
|
||||
next = t->next;
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" |",
|
||||
((const u8_t*) (&t->src))[0],
|
||||
((const u8_t*) (&t->src))[1],
|
||||
((const u8_t*) (&t->src))[2],
|
||||
((const u8_t*) (&t->src))[3]));
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, (" %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" |",
|
||||
((const u8_t*) (&t->dest))[0],
|
||||
((const u8_t*) (&t->dest))[1],
|
||||
((const u8_t*) (&t->dest))[2],
|
||||
((const u8_t*) (&t->dest))[3]));
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, (" %5"U16_F" | %5"U16_F" | %5"U16_F" |\n",
|
||||
lwip_htons(t->sport),
|
||||
lwip_htons(t->dport),
|
||||
lwip_htons(t->mport)));
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* NAPT_DEBUG */
|
||||
|
||||
void
|
||||
ip_napt_init(uint16_t max_nat, uint8_t max_portmap)
|
||||
{
|
||||
u16_t i;
|
||||
|
||||
ip_napt_max = max_nat;
|
||||
ip_portmap_max = max_portmap;
|
||||
|
||||
ip_napt_table = (struct napt_table*)calloc(1, sizeof(struct napt_table[ip_napt_max]));
|
||||
ip_portmap_table = (struct portmap_table*)calloc(1, sizeof(struct portmap_table[ip_portmap_max]));
|
||||
|
||||
for (i = 0; i < ip_napt_max - 1; i++)
|
||||
ip_napt_table[i].next = i + 1;
|
||||
ip_napt_table[i].next = NO_IDX;
|
||||
}
|
||||
|
||||
void
|
||||
ip_napt_enable(u32_t addr, int enable)
|
||||
{
|
||||
struct netif *netif;
|
||||
for (netif = netif_list; netif; netif = netif->next) {
|
||||
if (netif_is_up(netif) && !ip_addr_isany(&netif->ip_addr) && netif->ip_addr.u_addr.ip4.addr == addr) {
|
||||
netif->napt = !!enable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ip_napt_enable_no(u8_t number, int enable)
|
||||
{
|
||||
struct netif *netif;
|
||||
for (netif = netif_list; netif; netif = netif->next) {
|
||||
if (netif->num == number) {
|
||||
netif->napt = !!enable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checksumadjust(unsigned char *chksum, unsigned char *optr,
|
||||
int olen, unsigned char *nptr, int nlen)
|
||||
/* assuming: unsigned char is 8 bits, long is 32 bits.
|
||||
- chksum points to the chksum in the packet
|
||||
- optr points to the old data in the packet
|
||||
- nptr points to the new data in the packet
|
||||
*/
|
||||
{
|
||||
long x, old, new;
|
||||
x=chksum[0]*256+chksum[1];
|
||||
x=~x & 0xFFFF;
|
||||
while (olen)
|
||||
{
|
||||
old=optr[0]*256+optr[1]; optr+=2;
|
||||
x-=old & 0xffff;
|
||||
if (x<=0) { x--; x&=0xffff; }
|
||||
olen-=2;
|
||||
}
|
||||
while (nlen)
|
||||
{
|
||||
new=nptr[0]*256+nptr[1]; nptr+=2;
|
||||
x+=new & 0xffff;
|
||||
if (x & 0x10000) { x++; x&=0xffff; }
|
||||
nlen-=2;
|
||||
}
|
||||
x=~x & 0xFFFF;
|
||||
chksum[0]=x/256; chksum[1]=x & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/* t must be indexed by napt_free */
|
||||
static void
|
||||
ip_napt_insert(struct napt_table *t)
|
||||
{
|
||||
u16_t ti = t - ip_napt_table;
|
||||
if (ti != napt_free) *((int*)1)=1; //DEBUG
|
||||
napt_free = t->next;
|
||||
t->prev = NO_IDX;
|
||||
t->next = napt_list;
|
||||
if (napt_list != NO_IDX)
|
||||
NT(napt_list)->prev = ti;
|
||||
napt_list = ti;
|
||||
if (napt_list_last == NO_IDX)
|
||||
napt_list_last = ti;
|
||||
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP)
|
||||
nr_active_napt_tcp++;
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP)
|
||||
nr_active_napt_udp++;
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP)
|
||||
nr_active_napt_icmp++;
|
||||
#endif
|
||||
//os_printf("T: %d, U: %d, I: %d\r\n", nr_active_napt_tcp, nr_active_napt_udp, nr_active_napt_icmp);
|
||||
}
|
||||
|
||||
static void
|
||||
ip_napt_free(struct napt_table *t)
|
||||
{
|
||||
u16_t ti = t - ip_napt_table;
|
||||
if (ti == napt_list)
|
||||
napt_list = t->next;
|
||||
if (ti == napt_list_last)
|
||||
napt_list_last = t->prev;
|
||||
if (t->next != NO_IDX)
|
||||
NT(t->next)->prev = t->prev;
|
||||
if (t->prev != NO_IDX)
|
||||
NT(t->prev)->next = t->next;
|
||||
t->prev = NO_IDX;
|
||||
t->next = napt_free;
|
||||
napt_free = ti;
|
||||
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP)
|
||||
nr_active_napt_tcp--;
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP)
|
||||
nr_active_napt_udp--;
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP)
|
||||
nr_active_napt_icmp--;
|
||||
#endif
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_free\n"));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
static u8_t
|
||||
ip_napt_find_port(u8_t proto, u16_t port)
|
||||
{
|
||||
int i, next;
|
||||
for (i = napt_list; i != NO_IDX; i = next) {
|
||||
struct napt_table *t = &ip_napt_table[i];
|
||||
next = t->next;
|
||||
if (t->proto == proto && t->mport == port)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct portmap_table *
|
||||
ip_portmap_find(u8_t proto, u16_t mport);
|
||||
|
||||
static u8_t
|
||||
tcp_listening(u16_t port)
|
||||
{
|
||||
struct tcp_pcb_listen *t;
|
||||
for (t = tcp_listen_pcbs.listen_pcbs; t; t = t->next)
|
||||
if (t->local_port == port)
|
||||
return 1;
|
||||
if (ip_portmap_find(IP_PROTO_TCP, port))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif // LWIP_TCP
|
||||
|
||||
#if LWIP_UDP
|
||||
static u8_t
|
||||
udp_listening(u16_t port)
|
||||
{
|
||||
struct udp_pcb *pcb;
|
||||
for (pcb = udp_pcbs; pcb; pcb = pcb->next)
|
||||
if (pcb->local_port == port)
|
||||
return 1;
|
||||
if (ip_portmap_find(IP_PROTO_UDP, port))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif // LWIP_UDP
|
||||
|
||||
static u16_t
|
||||
ip_napt_new_port(u8_t proto, u16_t port)
|
||||
{
|
||||
if (PP_NTOHS(port) >= IP_NAPT_PORT_RANGE_START && PP_NTOHS(port) <= IP_NAPT_PORT_RANGE_END)
|
||||
if (!ip_napt_find_port(proto, port) && !tcp_listening(port))
|
||||
return port;
|
||||
for (;;) {
|
||||
port = PP_HTONS(IP_NAPT_PORT_RANGE_START +
|
||||
esp_random() % (IP_NAPT_PORT_RANGE_END - IP_NAPT_PORT_RANGE_START + 1));
|
||||
if (ip_napt_find_port(proto, port))
|
||||
continue;
|
||||
#if LWIP_TCP
|
||||
if (proto == IP_PROTO_TCP && tcp_listening(port))
|
||||
continue;
|
||||
#endif // LWIP_TCP
|
||||
#if LWIP_UDP
|
||||
if (proto == IP_PROTO_UDP && udp_listening(port))
|
||||
continue;
|
||||
#endif // LWIP_UDP
|
||||
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
static struct napt_table*
|
||||
ip_napt_find(u8_t proto, u32_t addr, u16_t port, u16_t mport, u8_t dest)
|
||||
{
|
||||
u16_t i, next;
|
||||
struct napt_table *t;
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_find\n"));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("looking up in table %s: %"U16_F".%"U16_F".%"U16_F".%"U16_F", port: %u, mport: %u\n",
|
||||
(dest ? "dest" : "src"),
|
||||
((const u8_t*) (&addr))[0], ((const u8_t*) (&addr))[1],
|
||||
((const u8_t*) (&addr))[2], ((const u8_t*) (&addr))[3],
|
||||
PP_HTONS(port),
|
||||
PP_HTONS(mport)));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
|
||||
u32_t now = sys_now();
|
||||
for (i = napt_list; i != NO_IDX; i = next) {
|
||||
t = NT(i);
|
||||
next = t->next;
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP &&
|
||||
((((t->finack1 && t->finack2) || !t->synack) &&
|
||||
now - t->last > IP_NAPT_TIMEOUT_MS_TCP_DISCON) ||
|
||||
now - t->last > IP_NAPT_TIMEOUT_MS_TCP)) {
|
||||
ip_napt_free(t);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP && now - t->last > IP_NAPT_TIMEOUT_MS_UDP) {
|
||||
ip_napt_free(t);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP && now - t->last > IP_NAPT_TIMEOUT_MS_ICMP) {
|
||||
ip_napt_free(t);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (dest == 0 && t->proto == proto && t->src == addr && t->sport == port) {
|
||||
t->last = now;
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("found\n"));
|
||||
return t;
|
||||
}
|
||||
if (dest == 1 && t->proto == proto && t->dest == addr && t->dport == port
|
||||
&& t->mport == mport) {
|
||||
t->last = now;
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("found\n"));
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("not found\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u16_t
|
||||
ip_napt_add(u8_t proto, u32_t src, u16_t sport, u32_t dest, u16_t dport)
|
||||
{
|
||||
struct napt_table *t = ip_napt_find(proto, src, sport, 0, 0);
|
||||
if (t) {
|
||||
t->last = sys_now();
|
||||
t->dest = dest;
|
||||
t->dport = dport;
|
||||
/* move this entry to the top of napt_list */
|
||||
ip_napt_free(t);
|
||||
ip_napt_insert(t);
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_add\n"));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
|
||||
return t->mport;
|
||||
}
|
||||
t = NT(napt_free);
|
||||
if (t) {
|
||||
u16_t mport = sport;
|
||||
#if LWIP_TCP
|
||||
if (proto == IP_PROTO_TCP)
|
||||
mport = ip_napt_new_port(IP_PROTO_TCP, sport);
|
||||
#endif
|
||||
#if LWIP_TCP
|
||||
if (proto == IP_PROTO_UDP)
|
||||
mport = ip_napt_new_port(IP_PROTO_UDP, sport);
|
||||
#endif
|
||||
t->last = sys_now();
|
||||
t->src = src;
|
||||
t->dest = dest;
|
||||
t->sport = sport;
|
||||
t->dport = dport;
|
||||
t->mport = mport;
|
||||
t->proto = proto;
|
||||
t->fin1 = t->fin2 = t->finack1 = t->finack2 = t->synack = t->rst = 0;
|
||||
ip_napt_insert(t);
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_add\n"));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
|
||||
return mport;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8_t
|
||||
ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport)
|
||||
{
|
||||
mport = PP_HTONS(mport);
|
||||
dport = PP_HTONS(dport);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ip_portmap_max; i++) {
|
||||
struct portmap_table *p = &ip_portmap_table[i];
|
||||
if (p->valid && p->proto == proto && p->mport == mport) {
|
||||
p->dport = dport;
|
||||
p->daddr = daddr;
|
||||
} else if (!p->valid) {
|
||||
p->maddr = maddr;
|
||||
p->daddr = daddr;
|
||||
p->mport = mport;
|
||||
p->dport = dport;
|
||||
p->proto = proto;
|
||||
p->valid = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct portmap_table *
|
||||
ip_portmap_find(u8_t proto, u16_t mport)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ip_portmap_max; i++) {
|
||||
struct portmap_table *p = &ip_portmap_table[i];
|
||||
if (!p->valid)
|
||||
return 0;
|
||||
if (p->proto == proto && p->mport == mport)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct portmap_table *
|
||||
ip_portmap_find_dest(u8_t proto, u16_t dport, u32_t daddr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ip_portmap_max; i++) {
|
||||
struct portmap_table *p = &ip_portmap_table[i];
|
||||
if (!p->valid)
|
||||
return 0;
|
||||
if (p->proto == proto && p->dport == dport && p->daddr == daddr)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8_t
|
||||
ip_portmap_remove(u8_t proto, u16_t mport)
|
||||
{
|
||||
mport = PP_HTONS(mport);
|
||||
struct portmap_table *last = &ip_portmap_table[ip_portmap_max - 1];
|
||||
struct portmap_table *m = ip_portmap_find(proto, mport);
|
||||
if (!m)
|
||||
return 0;
|
||||
for (; m != last; m++)
|
||||
memcpy(m, m + 1, sizeof(*m));
|
||||
last->valid = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
void
|
||||
ip_napt_modify_port_tcp(struct tcp_hdr *tcphdr, u8_t dest, u16_t newval)
|
||||
{
|
||||
if (dest) {
|
||||
checksumadjust((unsigned char *)&tcphdr->chksum, (unsigned char *)&tcphdr->dest, 2, (unsigned char *)&newval, 2);
|
||||
tcphdr->dest = newval;
|
||||
} else {
|
||||
checksumadjust((unsigned char *)&tcphdr->chksum, (unsigned char *)&tcphdr->src, 2, (unsigned char *)&newval, 2);
|
||||
tcphdr->src = newval;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ip_napt_modify_addr_tcp(struct tcp_hdr *tcphdr, ip4_addr_p_t *oldval, u32_t newval)
|
||||
{
|
||||
checksumadjust((unsigned char *)&tcphdr->chksum, (unsigned char *)&oldval->addr, 4, (unsigned char *)&newval, 4);
|
||||
}
|
||||
#endif // LWIP_TCP
|
||||
|
||||
#if LWIP_UDP
|
||||
void
|
||||
ip_napt_modify_port_udp(struct udp_hdr *udphdr, u8_t dest, u16_t newval)
|
||||
{
|
||||
if (dest) {
|
||||
checksumadjust((unsigned char *)&udphdr->chksum, (unsigned char *)&udphdr->dest, 2, (unsigned char *)&newval, 2);
|
||||
udphdr->dest = newval;
|
||||
} else {
|
||||
checksumadjust((unsigned char *)&udphdr->chksum, (unsigned char *)&udphdr->src, 2, (unsigned char *)&newval, 2);
|
||||
udphdr->src = newval;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ip_napt_modify_addr_udp(struct udp_hdr *udphdr, ip4_addr_p_t *oldval, u32_t newval)
|
||||
{
|
||||
checksumadjust( (unsigned char *)&udphdr->chksum, (unsigned char *)&oldval->addr, 4, (unsigned char *)&newval, 4);
|
||||
}
|
||||
#endif // LWIP_UDP
|
||||
|
||||
void
|
||||
ip_napt_modify_addr(struct ip_hdr *iphdr, ip4_addr_p_t *field, u32_t newval)
|
||||
{
|
||||
checksumadjust((unsigned char *)&IPH_CHKSUM(iphdr), (unsigned char *)&field->addr, 4, (unsigned char *)&newval, 4);
|
||||
field->addr = newval;
|
||||
}
|
||||
|
||||
/**
|
||||
* NAPT for an input packet. It checks weather the destination is on NAPT
|
||||
* table and modifythe packet destination address and port if needed.
|
||||
*
|
||||
* @param p the packet to forward (p->payload points to IP header)
|
||||
* @param iphdr the IP header of the input packet
|
||||
* @param inp the netif on which this packet was received
|
||||
*/
|
||||
static void
|
||||
ip_napt_recv(struct pbuf *p, struct ip_hdr *iphdr)
|
||||
{
|
||||
struct portmap_table *m;
|
||||
struct napt_table *t;
|
||||
#if LWIP_ICMP
|
||||
/* NAPT for ICMP Echo Request using identifier */
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_ICMP) {
|
||||
struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
if (iecho->type == ICMP_ER) {
|
||||
t = ip_napt_find(IP_PROTO_ICMP, iphdr->src.addr, iecho->id, iecho->id, 1);
|
||||
if (!t)
|
||||
return;
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif // LWIP_ICMP
|
||||
|
||||
#if LWIP_TCP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_TCP) {
|
||||
struct tcp_hdr *tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_recv\n"));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("src: %"U16_F".%"U16_F".%"U16_F".%"U16_F", dest: %"U16_F".%"U16_F".%"U16_F".%"U16_F", \n",
|
||||
ip4_addr1_16(&iphdr->src), ip4_addr2_16(&iphdr->src),
|
||||
ip4_addr3_16(&iphdr->src), ip4_addr4_16(&iphdr->src),
|
||||
ip4_addr1_16(&iphdr->dest), ip4_addr2_16(&iphdr->dest),
|
||||
ip4_addr3_16(&iphdr->dest), ip4_addr4_16(&iphdr->dest)));
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("sport %u, dport: %u\n",
|
||||
lwip_htons(tcphdr->src),
|
||||
lwip_htons(tcphdr->dest)));
|
||||
|
||||
m = ip_portmap_find(IP_PROTO_TCP, tcphdr->dest);
|
||||
if (m) {
|
||||
/* packet to mapped port: rewrite destination */
|
||||
if (m->dport != tcphdr->dest)
|
||||
ip_napt_modify_port_tcp(tcphdr, 1, m->dport);
|
||||
ip_napt_modify_addr_tcp(tcphdr, &iphdr->dest, m->daddr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, m->daddr);
|
||||
return;
|
||||
}
|
||||
t = ip_napt_find(IP_PROTO_TCP, iphdr->src.addr, tcphdr->src, tcphdr->dest, 1);
|
||||
if (!t)
|
||||
return; /* Unknown TCP session; do nothing */
|
||||
|
||||
if (t->sport != tcphdr->dest)
|
||||
ip_napt_modify_port_tcp(tcphdr, 1, t->sport);
|
||||
ip_napt_modify_addr_tcp(tcphdr, &iphdr->dest, t->src);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
|
||||
|
||||
if ((TCPH_FLAGS(tcphdr) & (TCP_SYN|TCP_ACK)) == (TCP_SYN|TCP_ACK))
|
||||
t->synack = 1;
|
||||
if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
|
||||
t->fin1 = 1;
|
||||
if (t->fin2 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
|
||||
t->finack2 = 1; /* FIXME: Currently ignoring ACK seq... */
|
||||
if (TCPH_FLAGS(tcphdr) & TCP_RST)
|
||||
t->rst = 1;
|
||||
return;
|
||||
}
|
||||
#endif // LWIP_TCP
|
||||
|
||||
#if LWIP_UDP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
|
||||
struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
m = ip_portmap_find(IP_PROTO_UDP, udphdr->dest);
|
||||
if (m) {
|
||||
/* packet to mapped port: rewrite destination */
|
||||
if (m->dport != udphdr->dest)
|
||||
ip_napt_modify_port_udp(udphdr, 1, m->dport);
|
||||
ip_napt_modify_addr_udp(udphdr, &iphdr->dest, m->daddr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, m->daddr);
|
||||
return;
|
||||
}
|
||||
t = ip_napt_find(IP_PROTO_UDP, iphdr->src.addr, udphdr->src, udphdr->dest, 1);
|
||||
if (!t)
|
||||
return; /* Unknown session; do nothing */
|
||||
|
||||
if (t->sport != udphdr->dest)
|
||||
ip_napt_modify_port_udp(udphdr, 1, t->sport);
|
||||
ip_napt_modify_addr_udp(udphdr, &iphdr->dest, t->src);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
|
||||
return;
|
||||
}
|
||||
#endif // LWIP_UDP
|
||||
}
|
||||
|
||||
/**
|
||||
* NAPT for a forwarded packet. It checks weather we need NAPT and modify
|
||||
* the packet source address and port if needed.
|
||||
*
|
||||
* @param p the packet to forward (p->payload points to IP header)
|
||||
* @param iphdr the IP header of the input packet
|
||||
* @param inp the netif on which this packet was received
|
||||
* @param outp the netif on which this packet will be sent
|
||||
* @return ERR_OK if packet should be sent, or ERR_RTE if it should be dropped
|
||||
*/
|
||||
static err_t
|
||||
ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct netif *outp)
|
||||
{
|
||||
if (!inp->napt){
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
#if LWIP_ICMP
|
||||
/* NAPT for ICMP Echo Request using identifier */
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_ICMP) {
|
||||
struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
if (iecho->type == ICMP_ECHO) {
|
||||
/* register src addr and iecho->id and dest info */
|
||||
ip_napt_add(IP_PROTO_ICMP, iphdr->src.addr, iecho->id, iphdr->dest.addr, iecho->id);
|
||||
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_TCP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_TCP) {
|
||||
struct tcp_hdr *tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
u16_t mport;
|
||||
|
||||
struct portmap_table *m = ip_portmap_find_dest(IP_PROTO_TCP, tcphdr->src, iphdr->src.addr);
|
||||
if (m) {
|
||||
/* packet from port-mapped dest addr/port: rewrite source to this node */
|
||||
if (m->mport != tcphdr->src)
|
||||
ip_napt_modify_port_tcp(tcphdr, 0, m->mport);
|
||||
ip_napt_modify_addr_tcp(tcphdr, &iphdr->src, m->maddr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, m->maddr);
|
||||
return ERR_OK;
|
||||
}
|
||||
if ((TCPH_FLAGS(tcphdr) & (TCP_SYN|TCP_ACK)) == TCP_SYN &&
|
||||
PP_NTOHS(tcphdr->src) >= 1024) {
|
||||
/* Register new TCP session to NAPT */
|
||||
mport = ip_napt_add(IP_PROTO_TCP, iphdr->src.addr, tcphdr->src,
|
||||
iphdr->dest.addr, tcphdr->dest);
|
||||
} else {
|
||||
struct napt_table *t = ip_napt_find(IP_PROTO_TCP, iphdr->src.addr, tcphdr->src, 0, 0);
|
||||
if (!t || t->dest != iphdr->dest.addr || t->dport != tcphdr->dest) {
|
||||
#if LWIP_ICMP
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
#endif
|
||||
return ERR_RTE; /* Drop unknown TCP session */
|
||||
}
|
||||
mport = t->mport;
|
||||
if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
|
||||
t->fin2 = 1;
|
||||
if (t->fin1 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
|
||||
t->finack1 = 1; /* FIXME: Currently ignoring ACK seq... */
|
||||
if (TCPH_FLAGS(tcphdr) & TCP_RST)
|
||||
t->rst = 1;
|
||||
}
|
||||
|
||||
if (mport != tcphdr->src)
|
||||
ip_napt_modify_port_tcp(tcphdr, 0, mport);
|
||||
ip_napt_modify_addr_tcp(tcphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_UDP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
|
||||
struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
u16_t mport;
|
||||
|
||||
struct portmap_table *m = ip_portmap_find_dest(IP_PROTO_UDP, udphdr->src, iphdr->src.addr);
|
||||
if (m) {
|
||||
/* packet from port-mapped dest addr/port: rewrite source to this node */
|
||||
if (m->mport != udphdr->src)
|
||||
ip_napt_modify_port_udp(udphdr, 0, m->mport);
|
||||
ip_napt_modify_addr_udp(udphdr, &iphdr->src, m->maddr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, m->maddr);
|
||||
return ERR_OK;
|
||||
}
|
||||
if (PP_NTOHS(udphdr->src) >= 1024) {
|
||||
/* Register new UDP session */
|
||||
mport = ip_napt_add(IP_PROTO_UDP, iphdr->src.addr, udphdr->src,
|
||||
iphdr->dest.addr, udphdr->dest);
|
||||
} else {
|
||||
struct napt_table *t = ip_napt_find(IP_PROTO_UDP, iphdr->src.addr, udphdr->src, 0, 0);
|
||||
if (!t || t->dest != iphdr->dest.addr || t->dport != udphdr->dest) {
|
||||
#if LWIP_ICMP
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
#endif
|
||||
return ERR_RTE; /* Drop unknown UDP session */
|
||||
}
|
||||
mport = t->mport;
|
||||
}
|
||||
|
||||
if (mport != udphdr->src)
|
||||
ip_napt_modify_port_udp(udphdr, 0, mport);
|
||||
ip_napt_modify_addr_udp(udphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif // IP_NAPT
|
||||
|
||||
/**
|
||||
* Determine whether an IP address is in a reserved set of addresses
|
||||
* that may not be forwarded, or whether datagrams to that destination
|
||||
@@ -1075,10 +381,12 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||
return;
|
||||
}
|
||||
|
||||
#if ESP_LWIP
|
||||
#if IP_NAPT
|
||||
if (ip_napt_forward(p, iphdr, inp, netif) != ERR_OK)
|
||||
return;
|
||||
#endif
|
||||
#endif /* ESP_LWIP */
|
||||
|
||||
/* Incrementally update the IP checksum. */
|
||||
if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
|
||||
@@ -1176,7 +484,11 @@ ip4_input_accept(struct netif *netif)
|
||||
err_t
|
||||
ip4_input(struct pbuf *p, struct netif *inp)
|
||||
{
|
||||
#if ESP_LWIP && IP_NAPT
|
||||
struct ip_hdr *iphdr;
|
||||
#else
|
||||
const struct ip_hdr *iphdr;
|
||||
#endif /* IP_NAPT && ESP_LWIP */
|
||||
struct netif *netif;
|
||||
u16_t iphdr_hlen;
|
||||
u16_t iphdr_len;
|
||||
@@ -1262,11 +574,13 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ESP_LWIP
|
||||
#if IP_NAPT
|
||||
/* for unicast packet, check NAPT table and modify dest if needed */
|
||||
if (!inp->napt && ip4_addr_cmp(&iphdr->dest, netif_ip4_addr(inp)))
|
||||
ip_napt_recv(p, iphdr);
|
||||
#endif
|
||||
#endif /* ESP_LWIP */
|
||||
|
||||
/* copy IP addresses to aligned ip_addr_t */
|
||||
ip_addr_copy_from_ip4(ip_data.current_iphdr_dest, iphdr->dest);
|
||||
@@ -1401,7 +715,11 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
if (p == NULL) {
|
||||
return ERR_OK;
|
||||
}
|
||||
#if ESP_LWIP && IP_NAPT
|
||||
iphdr = (struct ip_hdr *)p->payload;
|
||||
#else
|
||||
iphdr = (const struct ip_hdr *)p->payload;
|
||||
#endif
|
||||
#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
|
||||
pbuf_free(p);
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
|
||||
@@ -1737,8 +1055,10 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
|
||||
ip4_debug_print(p);
|
||||
|
||||
#if 0 && ENABLE_LOOPBACK
|
||||
#if ENABLE_LOOPBACK
|
||||
#if ESP_LWIP && IP_NAPT
|
||||
/* doesn't work for external wifi interfaces */
|
||||
#else
|
||||
|
||||
if (ip4_addr_cmp(dest, netif_ip4_addr(netif))
|
||||
#if !LWIP_HAVE_LOOPIF
|
||||
@@ -1754,6 +1074,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
|
||||
netif_loop_output(netif, p);
|
||||
}
|
||||
#endif /* LWIP_MULTICAST_TX_OPTIONS */
|
||||
#endif /* ESP_LWIP && IP_NAPT */
|
||||
#endif /* ENABLE_LOOPBACK */
|
||||
#if IP_FRAG
|
||||
/* don't fragment if interface has mtu set to 0 [loopif] */
|
||||
|
||||
@@ -0,0 +1,796 @@
|
||||
/**
|
||||
* @file
|
||||
* This is the NAPT implementation on IPv4 layer
|
||||
*
|
||||
* @see ip4.c
|
||||
*
|
||||
*/
|
||||
#include "lwip/opt.h"
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* original reassembly code by Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#if ESP_LWIP
|
||||
#if LWIP_IPV4
|
||||
#if IP_NAPT
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/icmp.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/priv/tcp_priv.h"
|
||||
#include "lwip/lwip_napt.h"
|
||||
#include "lwip/ip4_napt.h"
|
||||
#include "string.h"
|
||||
#include "assert.h"
|
||||
|
||||
#define NO_IDX ((u16_t)-1)
|
||||
#define NT(x) ((x) == NO_IDX ? NULL : &ip_napt_table[x])
|
||||
|
||||
struct napt_table {
|
||||
u32_t last;
|
||||
u32_t src;
|
||||
u32_t dest;
|
||||
u16_t sport;
|
||||
u16_t dport;
|
||||
u16_t mport;
|
||||
u8_t proto;
|
||||
unsigned int fin1 : 1;
|
||||
unsigned int fin2 : 1;
|
||||
unsigned int finack1 : 1;
|
||||
unsigned int finack2 : 1;
|
||||
unsigned int synack : 1;
|
||||
unsigned int rst : 1;
|
||||
u16_t next, prev;
|
||||
};
|
||||
|
||||
struct portmap_table {
|
||||
u32_t maddr;
|
||||
u32_t daddr;
|
||||
u16_t mport;
|
||||
u16_t dport;
|
||||
u8_t proto;
|
||||
u8_t valid;
|
||||
};
|
||||
|
||||
static u16_t napt_list = NO_IDX, napt_list_last = NO_IDX, napt_free = 0;
|
||||
|
||||
static struct napt_table *ip_napt_table = NULL;
|
||||
static struct portmap_table *ip_portmap_table = NULL;
|
||||
|
||||
static int nr_active_napt_tcp = 0, nr_active_napt_udp = 0, nr_active_napt_icmp = 0;
|
||||
static uint16_t ip_napt_max = 0;
|
||||
static uint8_t ip_portmap_max = 0;
|
||||
|
||||
#if NAPT_DEBUG
|
||||
/* Print NAPT table using LWIP_DEBUGF
|
||||
*/
|
||||
static void
|
||||
napt_debug_print(void)
|
||||
{
|
||||
int i, next;
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("NAPT table:\n"));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, (" src dest sport dport mport \n"));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("+-----------------------+-----------------------+-------+-------+-------+\n"));
|
||||
|
||||
for (i = napt_list; i != NO_IDX; i = next) {
|
||||
struct napt_table *t = &ip_napt_table[i];
|
||||
next = t->next;
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" |",
|
||||
((const u8_t*) (&t->src))[0],
|
||||
((const u8_t*) (&t->src))[1],
|
||||
((const u8_t*) (&t->src))[2],
|
||||
((const u8_t*) (&t->src))[3]));
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, (" %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" |",
|
||||
((const u8_t*) (&t->dest))[0],
|
||||
((const u8_t*) (&t->dest))[1],
|
||||
((const u8_t*) (&t->dest))[2],
|
||||
((const u8_t*) (&t->dest))[3]));
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, (" %5"U16_F" | %5"U16_F" | %5"U16_F" |\n",
|
||||
lwip_htons(t->sport),
|
||||
lwip_htons(t->dport),
|
||||
lwip_htons(t->mport)));
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* NAPT_DEBUG */
|
||||
|
||||
/**
|
||||
* Deallocates the NAPT tables.
|
||||
*
|
||||
*/
|
||||
static void
|
||||
ip_napt_deinit(void)
|
||||
{
|
||||
mem_free(ip_napt_table);
|
||||
mem_free(ip_portmap_table);
|
||||
ip_portmap_table = NULL;
|
||||
ip_napt_table = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and initializes the NAPT tables.
|
||||
*
|
||||
* @param max_nat max number of enties in the NAPT table (use IP_NAPT_MAX if in doubt)
|
||||
* @param max_portmap max number of enties in the NAPT table (use IP_PORTMAP_MAX if in doubt)
|
||||
*/
|
||||
static void
|
||||
ip_napt_init(uint16_t max_nat, uint8_t max_portmap)
|
||||
{
|
||||
u16_t i;
|
||||
|
||||
if (ip_portmap_table == NULL && ip_napt_table == NULL) {
|
||||
ip_napt_max = max_nat;
|
||||
ip_portmap_max = max_portmap;
|
||||
|
||||
ip_napt_table = (struct napt_table*)mem_calloc(ip_napt_max, sizeof(struct napt_table[1]));
|
||||
ip_portmap_table = (struct portmap_table*)mem_calloc(ip_portmap_max, sizeof(struct portmap_table[1]));
|
||||
assert(ip_portmap_table != NULL && ip_napt_table != NULL);
|
||||
|
||||
for (i = 0; i < ip_napt_max - 1; i++)
|
||||
ip_napt_table[i].next = i + 1;
|
||||
ip_napt_table[i].next = NO_IDX;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ip_napt_enable(u32_t addr, int enable)
|
||||
{
|
||||
struct netif *netif;
|
||||
int napt_in_any_netif = 0;
|
||||
for (netif = netif_list; netif; netif = netif->next) {
|
||||
if (netif->napt)
|
||||
napt_in_any_netif = 1;
|
||||
if (netif_is_up(netif) && !ip_addr_isany(&netif->ip_addr) && netif->ip_addr.u_addr.ip4.addr == addr && enable) {
|
||||
netif->napt = 1;
|
||||
ip_napt_init(IP_NAPT_MAX, IP_PORTMAP_MAX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!enable && !napt_in_any_netif) {
|
||||
for (netif = netif_list; netif; netif = netif->next)
|
||||
netif->napt = 0;
|
||||
ip_napt_deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ip_napt_enable_no(u8_t number, int enable)
|
||||
{
|
||||
struct netif *netif;
|
||||
for (netif = netif_list; netif; netif = netif->next) {
|
||||
if (netif->num == number) {
|
||||
netif->napt = !!enable;
|
||||
if (enable)
|
||||
ip_napt_init(IP_NAPT_MAX, IP_PORTMAP_MAX);
|
||||
else
|
||||
ip_napt_deinit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* adjusts checksum in a packet
|
||||
- chksum points to the chksum in the packet
|
||||
- optr points to the old data in the packet (before)
|
||||
- nptr points to the new data in the packet (after)
|
||||
*/
|
||||
static void
|
||||
checksumadjust(u8_t *chksum, u8_t *optr, int olen, u8_t *nptr, int nlen)
|
||||
{
|
||||
s32_t x, before, after;
|
||||
x=chksum[0]*256+chksum[1];
|
||||
x=~x & 0xFFFFU;
|
||||
while (olen)
|
||||
{
|
||||
before=optr[0]*256+optr[1]; optr+=2;
|
||||
x-=before & 0xFFFFU;
|
||||
if (x<=0) { x--; x&=0xFFFFU; }
|
||||
olen-=2;
|
||||
}
|
||||
while (nlen)
|
||||
{
|
||||
after=nptr[0]*256+nptr[1]; nptr+=2;
|
||||
x+=after & 0xFFFFU;
|
||||
if (x & 0x10000U) { x++; x&=0xFFFFU; }
|
||||
nlen-=2;
|
||||
}
|
||||
x=~x & 0xFFFFU;
|
||||
chksum[0]=x/256; chksum[1]=x & 0xFFU;
|
||||
}
|
||||
|
||||
/* t must be indexed by napt_free */
|
||||
static void
|
||||
ip_napt_insert(struct napt_table *t)
|
||||
{
|
||||
u16_t ti = t - ip_napt_table;
|
||||
assert(ti == napt_free);
|
||||
napt_free = t->next;
|
||||
t->prev = NO_IDX;
|
||||
t->next = napt_list;
|
||||
if (napt_list != NO_IDX)
|
||||
NT(napt_list)->prev = ti;
|
||||
napt_list = ti;
|
||||
if (napt_list_last == NO_IDX)
|
||||
napt_list_last = ti;
|
||||
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP)
|
||||
nr_active_napt_tcp++;
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP)
|
||||
nr_active_napt_udp++;
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP)
|
||||
nr_active_napt_icmp++;
|
||||
#endif
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_insert(): TCP=%d, UDP=%d, ICMP=%d\n", nr_active_napt_tcp, nr_active_napt_udp, nr_active_napt_icmp));
|
||||
}
|
||||
|
||||
static void
|
||||
ip_napt_free(struct napt_table *t)
|
||||
{
|
||||
u16_t ti = t - ip_napt_table;
|
||||
if (ti == napt_list)
|
||||
napt_list = t->next;
|
||||
if (ti == napt_list_last)
|
||||
napt_list_last = t->prev;
|
||||
if (t->next != NO_IDX)
|
||||
NT(t->next)->prev = t->prev;
|
||||
if (t->prev != NO_IDX)
|
||||
NT(t->prev)->next = t->next;
|
||||
t->prev = NO_IDX;
|
||||
t->next = napt_free;
|
||||
napt_free = ti;
|
||||
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP)
|
||||
nr_active_napt_tcp--;
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP)
|
||||
nr_active_napt_udp--;
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP)
|
||||
nr_active_napt_icmp--;
|
||||
#endif
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_free\n"));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
static u8_t
|
||||
ip_napt_find_port(u8_t proto, u16_t port)
|
||||
{
|
||||
int i, next;
|
||||
for (i = napt_list; i != NO_IDX; i = next) {
|
||||
struct napt_table *t = &ip_napt_table[i];
|
||||
next = t->next;
|
||||
if (t->proto == proto && t->mport == port)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct portmap_table *
|
||||
ip_portmap_find(u8_t proto, u16_t mport);
|
||||
|
||||
static u8_t
|
||||
tcp_listening(u16_t port)
|
||||
{
|
||||
struct tcp_pcb_listen *t;
|
||||
for (t = tcp_listen_pcbs.listen_pcbs; t; t = t->next)
|
||||
if (t->local_port == port)
|
||||
return 1;
|
||||
if (ip_portmap_find(IP_PROTO_TCP, port))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
#if LWIP_UDP
|
||||
static u8_t
|
||||
udp_listening(u16_t port)
|
||||
{
|
||||
struct udp_pcb *pcb;
|
||||
for (pcb = udp_pcbs; pcb; pcb = pcb->next)
|
||||
if (pcb->local_port == port)
|
||||
return 1;
|
||||
if (ip_portmap_find(IP_PROTO_UDP, port))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* LWIP_UDP */
|
||||
|
||||
static u16_t
|
||||
ip_napt_new_port(u8_t proto, u16_t port)
|
||||
{
|
||||
if (PP_NTOHS(port) >= IP_NAPT_PORT_RANGE_START && PP_NTOHS(port) <= IP_NAPT_PORT_RANGE_END)
|
||||
if (!ip_napt_find_port(proto, port) && !tcp_listening(port))
|
||||
return port;
|
||||
for (;;) {
|
||||
port = PP_HTONS(IP_NAPT_PORT_RANGE_START +
|
||||
LWIP_RAND() % (IP_NAPT_PORT_RANGE_END - IP_NAPT_PORT_RANGE_START + 1));
|
||||
if (ip_napt_find_port(proto, port))
|
||||
continue;
|
||||
#if LWIP_TCP
|
||||
if (proto == IP_PROTO_TCP && tcp_listening(port))
|
||||
continue;
|
||||
#endif /* LWIP_TCP */
|
||||
#if LWIP_UDP
|
||||
if (proto == IP_PROTO_UDP && udp_listening(port))
|
||||
continue;
|
||||
#endif /* LWIP_UDP */
|
||||
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
static struct napt_table*
|
||||
ip_napt_find(u8_t proto, u32_t addr, u16_t port, u16_t mport, u8_t dest)
|
||||
{
|
||||
u16_t i, next;
|
||||
u32_t now;
|
||||
struct napt_table *t;
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_find\n"));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("looking up in table %s: %"U16_F".%"U16_F".%"U16_F".%"U16_F", port: %u, mport: %u\n",
|
||||
(dest ? "dest" : "src"),
|
||||
((const u8_t*) (&addr))[0], ((const u8_t*) (&addr))[1],
|
||||
((const u8_t*) (&addr))[2], ((const u8_t*) (&addr))[3],
|
||||
PP_HTONS(port),
|
||||
PP_HTONS(mport)));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
|
||||
now = sys_now();
|
||||
for (i = napt_list; i != NO_IDX; i = next) {
|
||||
t = NT(i);
|
||||
next = t->next;
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP &&
|
||||
((((t->finack1 && t->finack2) || !t->synack) &&
|
||||
now - t->last > IP_NAPT_TIMEOUT_MS_TCP_DISCON) ||
|
||||
now - t->last > IP_NAPT_TIMEOUT_MS_TCP)) {
|
||||
ip_napt_free(t);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP && now - t->last > IP_NAPT_TIMEOUT_MS_UDP) {
|
||||
ip_napt_free(t);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP && now - t->last > IP_NAPT_TIMEOUT_MS_ICMP) {
|
||||
ip_napt_free(t);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (dest == 0 && t->proto == proto && t->src == addr && t->sport == port) {
|
||||
t->last = now;
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("found\n"));
|
||||
return t;
|
||||
}
|
||||
if (dest == 1 && t->proto == proto && t->dest == addr && t->dport == port
|
||||
&& t->mport == mport) {
|
||||
t->last = now;
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("found\n"));
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("not found\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u16_t
|
||||
ip_napt_add(u8_t proto, u32_t src, u16_t sport, u32_t dest, u16_t dport)
|
||||
{
|
||||
struct napt_table *t = ip_napt_find(proto, src, sport, 0, 0);
|
||||
if (t) {
|
||||
t->last = sys_now();
|
||||
t->dest = dest;
|
||||
t->dport = dport;
|
||||
/* move this entry to the top of napt_list */
|
||||
ip_napt_free(t);
|
||||
ip_napt_insert(t);
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_add\n"));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
|
||||
return t->mport;
|
||||
}
|
||||
t = NT(napt_free);
|
||||
if (t) {
|
||||
u16_t mport = sport;
|
||||
#if LWIP_TCP
|
||||
if (proto == IP_PROTO_TCP)
|
||||
mport = ip_napt_new_port(IP_PROTO_TCP, sport);
|
||||
#endif
|
||||
#if LWIP_TCP
|
||||
if (proto == IP_PROTO_UDP)
|
||||
mport = ip_napt_new_port(IP_PROTO_UDP, sport);
|
||||
#endif
|
||||
t->last = sys_now();
|
||||
t->src = src;
|
||||
t->dest = dest;
|
||||
t->sport = sport;
|
||||
t->dport = dport;
|
||||
t->mport = mport;
|
||||
t->proto = proto;
|
||||
t->fin1 = t->fin2 = t->finack1 = t->finack2 = t->synack = t->rst = 0;
|
||||
ip_napt_insert(t);
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_add\n"));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
|
||||
return mport;
|
||||
}
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_add() failed to insert\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8_t
|
||||
ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport)
|
||||
{
|
||||
mport = PP_HTONS(mport);
|
||||
dport = PP_HTONS(dport);
|
||||
|
||||
for (int i = 0; i < ip_portmap_max; i++) {
|
||||
struct portmap_table *p = &ip_portmap_table[i];
|
||||
if (p->valid && p->proto == proto && p->mport == mport) {
|
||||
p->dport = dport;
|
||||
p->daddr = daddr;
|
||||
} else if (!p->valid) {
|
||||
p->maddr = maddr;
|
||||
p->daddr = daddr;
|
||||
p->mport = mport;
|
||||
p->dport = dport;
|
||||
p->proto = proto;
|
||||
p->valid = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct portmap_table *
|
||||
ip_portmap_find(u8_t proto, u16_t mport)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ip_portmap_max; i++) {
|
||||
struct portmap_table *p = &ip_portmap_table[i];
|
||||
if (!p->valid)
|
||||
return 0;
|
||||
if (p->proto == proto && p->mport == mport)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct portmap_table *
|
||||
ip_portmap_find_dest(u8_t proto, u16_t dport, u32_t daddr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ip_portmap_max; i++) {
|
||||
struct portmap_table *p = &ip_portmap_table[i];
|
||||
if (!p->valid)
|
||||
return 0;
|
||||
if (p->proto == proto && p->dport == dport && p->daddr == daddr)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8_t
|
||||
ip_portmap_remove(u8_t proto, u16_t mport)
|
||||
{
|
||||
struct portmap_table *last = &ip_portmap_table[ip_portmap_max - 1];
|
||||
struct portmap_table *m = ip_portmap_find(proto, PP_HTONS(mport));
|
||||
if (!m)
|
||||
return 0;
|
||||
for (; m != last; m++)
|
||||
memcpy(m, m + 1, sizeof(*m));
|
||||
last->valid = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
static void
|
||||
ip_napt_modify_port_tcp(struct tcp_hdr *tcphdr, u8_t dest, u16_t newval)
|
||||
{
|
||||
if (dest) {
|
||||
checksumadjust((u8_t *)&tcphdr->chksum, (u8_t *)&tcphdr->dest, 2, (u8_t *)&newval, 2);
|
||||
tcphdr->dest = newval;
|
||||
} else {
|
||||
checksumadjust((u8_t *)&tcphdr->chksum, (u8_t *)&tcphdr->src, 2, (u8_t *)&newval, 2);
|
||||
tcphdr->src = newval;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ip_napt_modify_addr_tcp(struct tcp_hdr *tcphdr, ip4_addr_p_t *oldval, u32_t newval)
|
||||
{
|
||||
checksumadjust((u8_t *)&tcphdr->chksum, (u8_t *)&oldval->addr, 4, (u8_t *)&newval, 4);
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
#if LWIP_UDP
|
||||
static void
|
||||
ip_napt_modify_port_udp(struct udp_hdr *udphdr, u8_t dest, u16_t newval)
|
||||
{
|
||||
if (dest) {
|
||||
checksumadjust((u8_t *)&udphdr->chksum, (u8_t *)&udphdr->dest, 2, (u8_t *)&newval, 2);
|
||||
udphdr->dest = newval;
|
||||
} else {
|
||||
checksumadjust((u8_t *)&udphdr->chksum, (u8_t *)&udphdr->src, 2, (u8_t *)&newval, 2);
|
||||
udphdr->src = newval;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ip_napt_modify_addr_udp(struct udp_hdr *udphdr, ip4_addr_p_t *oldval, u32_t newval)
|
||||
{
|
||||
checksumadjust( (u8_t *)&udphdr->chksum, (u8_t *)&oldval->addr, 4, (u8_t *)&newval, 4);
|
||||
}
|
||||
#endif /* LWIP_UDP */
|
||||
|
||||
static void
|
||||
ip_napt_modify_addr(struct ip_hdr *iphdr, ip4_addr_p_t *field, u32_t newval)
|
||||
{
|
||||
checksumadjust((u8_t *)&IPH_CHKSUM(iphdr), (u8_t *)&field->addr, 4, (u8_t *)&newval, 4);
|
||||
field->addr = newval;
|
||||
}
|
||||
|
||||
void
|
||||
ip_napt_recv(struct pbuf *p, struct ip_hdr *iphdr)
|
||||
{
|
||||
struct portmap_table *m;
|
||||
struct napt_table *t;
|
||||
#if LWIP_ICMP
|
||||
/* NAPT for ICMP Echo Request using identifier */
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_ICMP) {
|
||||
struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
if (iecho->type == ICMP_ER) {
|
||||
t = ip_napt_find(IP_PROTO_ICMP, iphdr->src.addr, iecho->id, iecho->id, 1);
|
||||
if (!t)
|
||||
return;
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* LWIP_ICMP */
|
||||
|
||||
#if LWIP_TCP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_TCP) {
|
||||
struct tcp_hdr *tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_recv\n"));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("src: %"U16_F".%"U16_F".%"U16_F".%"U16_F", dest: %"U16_F".%"U16_F".%"U16_F".%"U16_F", \n",
|
||||
ip4_addr1_16(&iphdr->src), ip4_addr2_16(&iphdr->src),
|
||||
ip4_addr3_16(&iphdr->src), ip4_addr4_16(&iphdr->src),
|
||||
ip4_addr1_16(&iphdr->dest), ip4_addr2_16(&iphdr->dest),
|
||||
ip4_addr3_16(&iphdr->dest), ip4_addr4_16(&iphdr->dest)));
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("sport %u, dport: %u\n",
|
||||
lwip_htons(tcphdr->src),
|
||||
lwip_htons(tcphdr->dest)));
|
||||
|
||||
m = ip_portmap_find(IP_PROTO_TCP, tcphdr->dest);
|
||||
if (m) {
|
||||
/* packet to mapped port: rewrite destination */
|
||||
if (m->dport != tcphdr->dest)
|
||||
ip_napt_modify_port_tcp(tcphdr, 1, m->dport);
|
||||
ip_napt_modify_addr_tcp(tcphdr, &iphdr->dest, m->daddr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, m->daddr);
|
||||
return;
|
||||
}
|
||||
t = ip_napt_find(IP_PROTO_TCP, iphdr->src.addr, tcphdr->src, tcphdr->dest, 1);
|
||||
if (!t)
|
||||
return; /* Unknown TCP session; do nothing */
|
||||
|
||||
if (t->sport != tcphdr->dest)
|
||||
ip_napt_modify_port_tcp(tcphdr, 1, t->sport);
|
||||
ip_napt_modify_addr_tcp(tcphdr, &iphdr->dest, t->src);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
|
||||
|
||||
if ((TCPH_FLAGS(tcphdr) & (TCP_SYN|TCP_ACK)) == (TCP_SYN|TCP_ACK))
|
||||
t->synack = 1;
|
||||
if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
|
||||
t->fin1 = 1;
|
||||
if (t->fin2 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
|
||||
t->finack2 = 1; /* FIXME: Currently ignoring ACK seq... */
|
||||
if (TCPH_FLAGS(tcphdr) & TCP_RST)
|
||||
t->rst = 1;
|
||||
return;
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
#if LWIP_UDP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
|
||||
struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
m = ip_portmap_find(IP_PROTO_UDP, udphdr->dest);
|
||||
if (m) {
|
||||
/* packet to mapped port: rewrite destination */
|
||||
if (m->dport != udphdr->dest)
|
||||
ip_napt_modify_port_udp(udphdr, 1, m->dport);
|
||||
ip_napt_modify_addr_udp(udphdr, &iphdr->dest, m->daddr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, m->daddr);
|
||||
return;
|
||||
}
|
||||
t = ip_napt_find(IP_PROTO_UDP, iphdr->src.addr, udphdr->src, udphdr->dest, 1);
|
||||
if (!t)
|
||||
return; /* Unknown session; do nothing */
|
||||
|
||||
if (t->sport != udphdr->dest)
|
||||
ip_napt_modify_port_udp(udphdr, 1, t->sport);
|
||||
ip_napt_modify_addr_udp(udphdr, &iphdr->dest, t->src);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
|
||||
return;
|
||||
}
|
||||
#endif /* LWIP_UDP */
|
||||
}
|
||||
|
||||
err_t
|
||||
ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct netif *outp)
|
||||
{
|
||||
if (!inp->napt)
|
||||
return ERR_OK;
|
||||
|
||||
#if LWIP_ICMP
|
||||
/* NAPT for ICMP Echo Request using identifier */
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_ICMP) {
|
||||
struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
if (iecho->type == ICMP_ECHO) {
|
||||
/* register src addr and iecho->id and dest info */
|
||||
ip_napt_add(IP_PROTO_ICMP, iphdr->src.addr, iecho->id, iphdr->dest.addr, iecho->id);
|
||||
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_TCP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_TCP) {
|
||||
struct tcp_hdr *tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
u16_t mport;
|
||||
|
||||
struct portmap_table *m = ip_portmap_find_dest(IP_PROTO_TCP, tcphdr->src, iphdr->src.addr);
|
||||
if (m) {
|
||||
/* packet from port-mapped dest addr/port: rewrite source to this node */
|
||||
if (m->mport != tcphdr->src)
|
||||
ip_napt_modify_port_tcp(tcphdr, 0, m->mport);
|
||||
ip_napt_modify_addr_tcp(tcphdr, &iphdr->src, m->maddr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, m->maddr);
|
||||
return ERR_OK;
|
||||
}
|
||||
if ((TCPH_FLAGS(tcphdr) & (TCP_SYN|TCP_ACK)) == TCP_SYN &&
|
||||
PP_NTOHS(tcphdr->src) >= 1024) {
|
||||
/* Register new TCP session to NAPT */
|
||||
mport = ip_napt_add(IP_PROTO_TCP, iphdr->src.addr, tcphdr->src,
|
||||
iphdr->dest.addr, tcphdr->dest);
|
||||
if (mport == 0)
|
||||
return ERR_RTE; /* routing err if add entry failed */
|
||||
} else {
|
||||
struct napt_table *t = ip_napt_find(IP_PROTO_TCP, iphdr->src.addr, tcphdr->src, 0, 0);
|
||||
if (!t || t->dest != iphdr->dest.addr || t->dport != tcphdr->dest) {
|
||||
#if LWIP_ICMP
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
#endif
|
||||
return ERR_RTE; /* Drop unknown TCP session */
|
||||
}
|
||||
mport = t->mport;
|
||||
if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
|
||||
t->fin2 = 1;
|
||||
if (t->fin1 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
|
||||
t->finack1 = 1; /* FIXME: Currently ignoring ACK seq... */
|
||||
if (TCPH_FLAGS(tcphdr) & TCP_RST)
|
||||
t->rst = 1;
|
||||
}
|
||||
|
||||
if (mport != tcphdr->src)
|
||||
ip_napt_modify_port_tcp(tcphdr, 0, mport);
|
||||
ip_napt_modify_addr_tcp(tcphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_UDP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
|
||||
struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||
u16_t mport;
|
||||
|
||||
struct portmap_table *m = ip_portmap_find_dest(IP_PROTO_UDP, udphdr->src, iphdr->src.addr);
|
||||
if (m) {
|
||||
/* packet from port-mapped dest addr/port: rewrite source to this node */
|
||||
if (m->mport != udphdr->src)
|
||||
ip_napt_modify_port_udp(udphdr, 0, m->mport);
|
||||
ip_napt_modify_addr_udp(udphdr, &iphdr->src, m->maddr);
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("Modify UDP addr %x %x", iphdr->src.addr, m->maddr));
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, m->maddr);
|
||||
return ERR_OK;
|
||||
}
|
||||
if (PP_NTOHS(udphdr->src) >= 1024) {
|
||||
/* Register new UDP session */
|
||||
mport = ip_napt_add(IP_PROTO_UDP, iphdr->src.addr, udphdr->src,
|
||||
iphdr->dest.addr, udphdr->dest);
|
||||
if (mport == 0)
|
||||
return ERR_RTE; /* routing err if add entry failed */
|
||||
} else {
|
||||
struct napt_table *t = ip_napt_find(IP_PROTO_UDP, iphdr->src.addr, udphdr->src, 0, 0);
|
||||
if (!t || t->dest != iphdr->dest.addr || t->dport != udphdr->dest) {
|
||||
#if LWIP_ICMP
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
#endif
|
||||
return ERR_RTE; /* Drop unknown UDP session */
|
||||
}
|
||||
mport = t->mport;
|
||||
}
|
||||
|
||||
if (mport != udphdr->src)
|
||||
ip_napt_modify_port_udp(udphdr, 0, mport);
|
||||
ip_napt_modify_addr_udp(udphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, outp->ip_addr.u_addr.ip4.addr);
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* IP_NAPT */
|
||||
#endif /* LWIP_IPV4 */
|
||||
#endif /* ESP_LWIP */
|
||||
@@ -367,9 +367,11 @@ netif_add(struct netif *netif,
|
||||
netif->loop_cnt_current = 0;
|
||||
#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
|
||||
|
||||
#if ESP_LWIP
|
||||
#if IP_NAPT
|
||||
netif->napt = 0;
|
||||
#endif /* IP_NAPT */
|
||||
#endif /* ESP_LWIP */
|
||||
|
||||
#if LWIP_IPV4
|
||||
netif_set_addr(netif, ipaddr, netmask, gw);
|
||||
|
||||
@@ -172,12 +172,6 @@ extern struct ip_globals ip_data;
|
||||
/** Destination IP4 address of current_header */
|
||||
#define ip4_current_dest_addr() (ip_2_ip4(&ip_data.current_iphdr_dest))
|
||||
|
||||
#if NAPT_DEBUG
|
||||
void napt_debug_print()ICACHE_FLASH_ATTR;
|
||||
#else
|
||||
#define napt_debug_print(p)
|
||||
#endif /* NAPT_DEBUG */
|
||||
|
||||
#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
|
||||
/** Get the IPv4 header of the current packet.
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file ip4_napt.h
|
||||
* This is a private interface of ip4_napt used from ip4.c
|
||||
*
|
||||
* @see ip4_napt.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* original reassembly code by Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LWIP_HDR_IP4_NAPT_H
|
||||
#define LWIP_HDR_IP4_NAPT_H
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if ESP_LWIP
|
||||
#if IP_FORWARD
|
||||
#if IP_NAPT
|
||||
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/ip4_addr.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/prot/ip4.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/ip4.h"
|
||||
|
||||
/**
|
||||
* NAPT for a forwarded packet. It checks weather we need NAPT and modify
|
||||
* the packet source address and port if needed.
|
||||
*
|
||||
* @param p the packet to forward (p->payload points to IP header)
|
||||
* @param iphdr the IP header of the input packet
|
||||
* @param inp the netif on which this packet was received
|
||||
* @param outp the netif on which this packet will be sent
|
||||
* @return ERR_OK if packet should be sent, or ERR_RTE if it should be dropped
|
||||
*/
|
||||
err_t
|
||||
ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct netif *outp);
|
||||
|
||||
/**
|
||||
* NAPT for an input packet. It checks weather the destination is on NAPT
|
||||
* table and modify the packet destination address and port if needed.
|
||||
*
|
||||
* @param p the packet to forward (p->payload points to IP header)
|
||||
* @param iphdr the IP header of the input packet
|
||||
* @param inp the netif on which this packet was received
|
||||
*/
|
||||
void
|
||||
ip_napt_recv(struct pbuf *p, struct ip_hdr *iphdr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* IP_NAPT */
|
||||
#endif /* IP_FORWARD */
|
||||
#endif /* ESP_LWIP */
|
||||
|
||||
#endif /* LWIP_HDR_IP4_NAPT_H */
|
||||
|
||||
@@ -1,3 +1,42 @@
|
||||
/**
|
||||
* @file lwip_napt.h
|
||||
* public API of ip4_napt
|
||||
*
|
||||
* @see ip4_napt.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* original reassembly code by Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LWIP_NAPT_H__
|
||||
#define __LWIP_NAPT_H__
|
||||
|
||||
@@ -7,12 +46,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if ESP_LWIP
|
||||
#if IP_FORWARD
|
||||
#if IP_NAPT
|
||||
|
||||
/* Default size of the tables used for NAPT */
|
||||
#ifndef IP_NAPT_MAX
|
||||
#define IP_NAPT_MAX 512
|
||||
#endif
|
||||
#ifndef IP_PORTMAP_MAX
|
||||
#define IP_PORTMAP_MAX 32
|
||||
#endif
|
||||
|
||||
/* Timeouts in sec for the various protocol types */
|
||||
#define IP_NAPT_TIMEOUT_MS_TCP (30*60*1000)
|
||||
@@ -23,43 +67,6 @@ extern "C" {
|
||||
#define IP_NAPT_PORT_RANGE_START 49152
|
||||
#define IP_NAPT_PORT_RANGE_END 61439
|
||||
|
||||
struct napt_table {
|
||||
u32_t last;
|
||||
u32_t src;
|
||||
u32_t dest;
|
||||
u16_t sport;
|
||||
u16_t dport;
|
||||
u16_t mport;
|
||||
u8_t proto;
|
||||
u8_t fin1 : 1;
|
||||
u8_t fin2 : 1;
|
||||
u8_t finack1 : 1;
|
||||
u8_t finack2 : 1;
|
||||
u8_t synack : 1;
|
||||
u8_t rst : 1;
|
||||
u16_t next, prev;
|
||||
};
|
||||
|
||||
struct portmap_table {
|
||||
u32_t maddr;
|
||||
u32_t daddr;
|
||||
u16_t mport;
|
||||
u16_t dport;
|
||||
u8_t proto;
|
||||
u8_t valid;
|
||||
};
|
||||
|
||||
extern struct portmap_table *ip_portmap_table;
|
||||
|
||||
/**
|
||||
* Allocates and initializes the NAPT tables.
|
||||
*
|
||||
* @param max_nat max number of enties in the NAPT table (use IP_NAPT_MAX if in doubt)
|
||||
* @param max_portmap max number of enties in the NAPT table (use IP_PORTMAP_MAX if in doubt)
|
||||
*/
|
||||
void ip_napt_init(uint16_t max_nat, uint8_t max_portmap);
|
||||
|
||||
|
||||
/**
|
||||
* Enable/Disable NAPT for a specified interface.
|
||||
*
|
||||
@@ -91,7 +98,7 @@ ip_napt_enable_no(u8_t number, int enable);
|
||||
* @param daddr destination ip address
|
||||
* @param dport destination port, in host byte order.
|
||||
*/
|
||||
u8_t
|
||||
u8_t
|
||||
ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport);
|
||||
|
||||
|
||||
@@ -101,11 +108,12 @@ ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport);
|
||||
* @param proto target protocol
|
||||
* @param maddr ip address of the external interface
|
||||
*/
|
||||
u8_t
|
||||
u8_t
|
||||
ip_portmap_remove(u8_t proto, u16_t mport);
|
||||
|
||||
#endif /* IP_NAPT */
|
||||
#endif /* IP_FORWARD */
|
||||
#endif /* ESP_LWIP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -410,9 +410,11 @@ struct netif {
|
||||
void (*l2_buffer_free_notify)(struct netif *lwip_netif, void *user_buf); /* Allows LWIP to notify driver when a L2-supplied pbuf can be freed */
|
||||
ip_addr_t last_ip_addr; /* Store last non-zero ip address */
|
||||
#endif
|
||||
#if ESP_LWIP
|
||||
#if LWIP_IPV4 && IP_NAPT
|
||||
u8_t napt;
|
||||
#endif
|
||||
#endif /* ESP_LWIP */
|
||||
};
|
||||
#if LWIP_CHECKSUM_CTRL_PER_NETIF
|
||||
#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) do { \
|
||||
|
||||
@@ -736,7 +736,7 @@
|
||||
* interface, define this to 0.
|
||||
*/
|
||||
#if !defined IP_FORWARD || defined __DOXYGEN__
|
||||
#define IP_FORWARD 1
|
||||
#define IP_FORWARD 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -767,8 +767,12 @@
|
||||
#define IP_FRAG 0
|
||||
#endif /* !LWIP_IPV4 */
|
||||
|
||||
#ifndef IP_NAPT
|
||||
#define IP_NAPT 1
|
||||
/**
|
||||
* IP_NAPT==1: Enables IPv4 Network Address and Port Translation
|
||||
* Note that IP_FORWARD needs to be enabled for NAPT to work
|
||||
*/
|
||||
#if !defined IP_NAPT || defined __DOXYGEN__
|
||||
#define IP_NAPT 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -1118,7 +1122,7 @@
|
||||
* transport.
|
||||
*/
|
||||
#if !defined LWIP_DNS || defined __DOXYGEN__
|
||||
#define LWIP_DNS 1
|
||||
#define LWIP_DNS 0
|
||||
#endif
|
||||
|
||||
/** DNS maximum number of entries to maintain locally. */
|
||||
|
||||
Reference in New Issue
Block a user