diff --git a/src/Filelists.cmake b/src/Filelists.cmake index bb6f2b3a..7cbac9a7 100644 --- a/src/Filelists.cmake +++ b/src/Filelists.cmake @@ -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 diff --git a/src/Filelists.mk b/src/Filelists.mk index 828b9f2a..88e8baab 100644 --- a/src/Filelists.mk +++ b/src/Filelists.mk @@ -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 \ diff --git a/src/core/init.c b/src/core/init.c index f35344d5..b3737a35 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -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 */ } diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c index 04930aca..e3fc1dc9 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -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 @@ -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] */ diff --git a/src/core/ipv4/ip4_napt.c b/src/core/ipv4/ip4_napt.c new file mode 100644 index 00000000..a2272632 --- /dev/null +++ b/src/core/ipv4/ip4_napt.c @@ -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 + * + */ + +#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 */ \ No newline at end of file diff --git a/src/core/netif.c b/src/core/netif.c index 7df65e40..45f8e34f 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -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); diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h index 5cf4d8a4..653c3b2f 100644 --- a/src/include/lwip/ip.h +++ b/src/include/lwip/ip.h @@ -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. diff --git a/src/include/lwip/ip4_napt.h b/src/include/lwip/ip4_napt.h new file mode 100644 index 00000000..8d98e120 --- /dev/null +++ b/src/include/lwip/ip4_napt.h @@ -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 + * + */ + +#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 */ + diff --git a/src/include/lwip/lwip_napt.h b/src/include/lwip/lwip_napt.h index 0cde2949..a1816d42 100644 --- a/src/include/lwip/lwip_napt.h +++ b/src/include/lwip/lwip_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 + * + */ + #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 } diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index 89747829..dd1c0d31 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -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 { \ diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index cb0e5890..3a338d5a 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -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. */