diff --git a/libraries/ESP8266WiFi/examples/RangeExtender-NAPT/RangeExtender-NAPT.ino b/libraries/ESP8266WiFi/examples/RangeExtender-NAPT/RangeExtender-NAPT.ino new file mode 100644 index 000000000..9676857b1 --- /dev/null +++ b/libraries/ESP8266WiFi/examples/RangeExtender-NAPT/RangeExtender-NAPT.ino @@ -0,0 +1,97 @@ + +// NAPT example released to public domain + +#if LWIP_FEATURES && !LWIP_IPV6 + +#define HAVE_NETDUMP 0 + +#ifndef STASSID +#define STASSID "mynetwork" +#define STAPSK "mynetworkpassword" +#endif + +#include +#include +#include +#include + +#define NAPT 1000 +#define NAPT_PORT 10 + +#if HAVE_NETDUMP + +#include + +void dump(int netif_idx, const char* data, size_t len, int out, int success) { + (void)success; + Serial.print(out ? F("out ") : F(" in ")); + Serial.printf("%d ", netif_idx); + + // optional filter example: if (netDump_is_ARP(data)) + { + netDump(Serial, data, len); + //netDumpHex(Serial, data, len); + } +} +#endif + +void setup() { + Serial.begin(115200); + Serial.printf("\n\nNAPT Range extender\n"); + Serial.printf("Heap on start: %d\n", ESP.getFreeHeap()); + +#if HAVE_NETDUMP + phy_capture = dump; +#endif + + // first, connect to STA so we can get a proper local DNS server + WiFi.mode(WIFI_STA); + WiFi.begin(STASSID, STAPSK); + while (WiFi.status() != WL_CONNECTED) { + Serial.print('.'); + delay(500); + } + Serial.printf("\nSTA: %s (dns: %s / %s)\n", + WiFi.localIP().toString().c_str(), + WiFi.dnsIP(0).toString().c_str(), + WiFi.dnsIP(1).toString().c_str()); + + // give DNS servers to AP side + dhcps_set_dns(0, WiFi.dnsIP(0)); + dhcps_set_dns(1, WiFi.dnsIP(1)); + + WiFi.softAPConfig( // enable AP, with android-compatible google domain + IPAddress(172, 217, 28, 254), + IPAddress(172, 217, 28, 254), + IPAddress(255, 255, 255, 0)); + WiFi.softAP(STASSID "extender", STAPSK); + Serial.printf("AP: %s\n", WiFi.softAPIP().toString().c_str()); + + Serial.printf("Heap before: %d\n", ESP.getFreeHeap()); + err_t ret = ip_napt_init(NAPT, NAPT_PORT); + Serial.printf("ip_napt_init(%d,%d): ret=%d (OK=%d)\n", NAPT, NAPT_PORT, (int)ret, (int)ERR_OK); + if (ret == ERR_OK) { + ret = ip_napt_enable_no(SOFTAP_IF, 1); + Serial.printf("ip_napt_enable_no(SOFTAP_IF): ret=%d (OK=%d)\n", (int)ret, (int)ERR_OK); + if (ret == ERR_OK) { + Serial.printf("WiFi Network '%s' with same password is now NATed behind '%s'\n", STASSID "extender", STASSID); + } + } + Serial.printf("Heap after napt init: %d\n", ESP.getFreeHeap()); + if (ret != ERR_OK) { + Serial.printf("NAPT initialization failed\n"); + } +} + +#else + +void setup() { + Serial.begin(115200); + Serial.printf("\n\nNAPT not supported in this configuration\n"); +} + +#endif + +void loop() { +} + diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp index b00a84f73..53e93b24f 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp @@ -22,7 +22,6 @@ * */ -#include #include #include #include diff --git a/tools/sdk/lib/liblwip2-1460-feat.a b/tools/sdk/lib/liblwip2-1460-feat.a index 5732de9cd..2194496de 100644 Binary files a/tools/sdk/lib/liblwip2-1460-feat.a and b/tools/sdk/lib/liblwip2-1460-feat.a differ diff --git a/tools/sdk/lib/liblwip2-1460.a b/tools/sdk/lib/liblwip2-1460.a index be9966fa6..5acb4f95e 100644 Binary files a/tools/sdk/lib/liblwip2-1460.a and b/tools/sdk/lib/liblwip2-1460.a differ diff --git a/tools/sdk/lib/liblwip2-536-feat.a b/tools/sdk/lib/liblwip2-536-feat.a index bc679a5a6..10cc2a01e 100644 Binary files a/tools/sdk/lib/liblwip2-536-feat.a and b/tools/sdk/lib/liblwip2-536-feat.a differ diff --git a/tools/sdk/lib/liblwip2-536.a b/tools/sdk/lib/liblwip2-536.a index 193d2d439..69e5e881d 100644 Binary files a/tools/sdk/lib/liblwip2-536.a and b/tools/sdk/lib/liblwip2-536.a differ diff --git a/tools/sdk/lib/liblwip6-1460-feat.a b/tools/sdk/lib/liblwip6-1460-feat.a index e4dd8b8fc..51db390d0 100644 Binary files a/tools/sdk/lib/liblwip6-1460-feat.a and b/tools/sdk/lib/liblwip6-1460-feat.a differ diff --git a/tools/sdk/lib/liblwip6-536-feat.a b/tools/sdk/lib/liblwip6-536-feat.a index 5cb1db04e..d16ec2be8 100644 Binary files a/tools/sdk/lib/liblwip6-536-feat.a and b/tools/sdk/lib/liblwip6-536-feat.a differ diff --git a/tools/sdk/lwip2/builder b/tools/sdk/lwip2/builder index 2314329c8..ffa962483 160000 --- a/tools/sdk/lwip2/builder +++ b/tools/sdk/lwip2/builder @@ -1 +1 @@ -Subproject commit 2314329c86cb7eb9670e3adf7632bd52001f45cd +Subproject commit ffa962483cc1c5d874b11bec13080359619c4cb2 diff --git a/tools/sdk/lwip2/include/arch/cc.h b/tools/sdk/lwip2/include/arch/cc.h index 2ec8fe5a5..961c51aa3 100644 --- a/tools/sdk/lwip2/include/arch/cc.h +++ b/tools/sdk/lwip2/include/arch/cc.h @@ -58,10 +58,12 @@ void sntp_set_system_time (uint32_t t); #include "mem.h" // useful for os_malloc used in esp-arduino's mDNS -typedef uint32_t sys_prot_t; // not really used -#define SYS_ARCH_DECL_PROTECT(lev) -#define SYS_ARCH_PROTECT(lev) os_intr_lock() -#define SYS_ARCH_UNPROTECT(lev) os_intr_unlock() +#include "glue.h" // include assembly locking macro used below +typedef uint32_t sys_prot_t; +#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev +#define SYS_ARCH_PROTECT(lev) lev = lwip_xt_rsil(15) +#define SYS_ARCH_UNPROTECT(lev) lwip_xt_wsr_ps(lev) + #define LWIP_NO_CTYPE_H 1 /////////////////////////////// diff --git a/tools/sdk/lwip2/include/dhcpserver.h b/tools/sdk/lwip2/include/dhcpserver.h new file mode 100644 index 000000000..0f8f9c1e6 --- /dev/null +++ b/tools/sdk/lwip2/include/dhcpserver.h @@ -0,0 +1,130 @@ + +// adapted from dhcpserver.c distributed in esp8266 sdk 2.0.0 +// same license may apply + +#ifndef __DHCPS_H__ +#define __DHCPS_H__ + +#include "glue.h" // for UDEBUG + +#define USE_DNS + +typedef struct dhcps_state{ + sint16_t state; +} dhcps_state; + +typedef struct dhcps_msg { + uint8_t op, htype, hlen, hops; + uint8_t xid[4]; + uint16_t secs, flags; + uint8_t ciaddr[4]; + uint8_t yiaddr[4]; + uint8_t siaddr[4]; + uint8_t giaddr[4]; + uint8_t chaddr[16]; + uint8_t sname[64]; + uint8_t file[128]; + uint8_t options[312]; +}dhcps_msg; + +#ifndef LWIP_OPEN_SRC +struct dhcps_lease { + bool enable; + struct ipv4_addr start_ip; + struct ipv4_addr end_ip; +}; + +enum dhcps_offer_option{ + OFFER_START = 0x00, + OFFER_ROUTER = 0x01, + OFFER_END +}; +#endif + +typedef enum { + DHCPS_TYPE_DYNAMIC, + DHCPS_TYPE_STATIC +} dhcps_type_t; + +typedef enum { + DHCPS_STATE_ONLINE, + DHCPS_STATE_OFFLINE +} dhcps_state_t; + +struct dhcps_pool{ + struct ipv4_addr ip; + uint8 mac[6]; + uint32 lease_timer; + dhcps_type_t type; + dhcps_state_t state; + +}; + +typedef struct _list_node{ + void *pnode; + struct _list_node *pnext; +}list_node; + +extern uint32 dhcps_lease_time; +#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 +#define DHCPS_MAX_LEASE 0x64 +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPS_SERVER_PORT 67 +#define DHCPS_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_INTERFACE_MTU 26 +#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31 +#define DHCP_OPTION_BROADCAST_ADDRESS 28 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +//#define USE_CLASS_B_NET 1 +#define DHCPS_DEBUG UDEBUG +#define MAX_STATION_NUM 8 + +#define DHCPS_STATE_OFFER 1 +#define DHCPS_STATE_DECLINE 2 +#define DHCPS_STATE_ACK 3 +#define DHCPS_STATE_NAK 4 +#define DHCPS_STATE_IDLE 5 +#define DHCPS_STATE_RELEASE 6 + +#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) + +#ifdef __cplusplus +extern "C" +{ +#endif + +void dhcps_set_dns (int num, const ipv4_addr_t* dns); + +void dhcps_start(struct ip_info *info); +void dhcps_stop(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/sdk/lwip2/include/glue.h b/tools/sdk/lwip2/include/glue.h new file mode 100644 index 000000000..06ef36bdf --- /dev/null +++ b/tools/sdk/lwip2/include/glue.h @@ -0,0 +1,113 @@ + +/* + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +author: d. gauchard + +*/ + +#ifndef GLUE_H +#define GLUE_H + +#ifndef ARDUINO +#define ARDUINO 0 +#endif + +#ifndef OPENSDK +#define OPENSDK 0 +#endif + +#if !ARDUINO && !OPENSDK +#error Must defined ARDUINO or OPENSDK +#endif + +#include "gluedebug.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "ets_sys.h" +#include "osapi.h" +#include "user_interface.h" +#ifdef __cplusplus +} +#endif + +typedef enum +{ + GLUE_ERR_OK = 0, + GLUE_ERR_MEM = -1, + GLUE_ERR_BUF = -2, + GLUE_ERR_TIMEOUT = -3, + GLUE_ERR_RTE = -4, + GLUE_ERR_INPROGRESS = -5, + GLUE_ERR_VAL = -6, + GLUE_ERR_WOULDBLOCK = -7, + GLUE_ERR_USE = -8, + GLUE_ERR_ALREADY = -9, + GLUE_ERR_ISCONN = -10, + GLUE_ERR_CONN = -11, + GLUE_ERR_IF = -12, + GLUE_ERR_ABRT = -13, + GLUE_ERR_RST = -14, + GLUE_ERR_CLSD = -15, + GLUE_ERR_ARG = -16 +} err_glue_t; + +typedef enum +{ + GLUE_NETIF_FLAG_BROADCAST = 1, + GLUE_NETIF_FLAG_UP = 2, + GLUE_NETIF_FLAG_ETHARP = 4, + GLUE_NETIF_FLAG_IGMP = 8, + GLUE_NETIF_FLAG_LINK_UP = 16, +} glue_netif_flags_t; + +void esp2glue_lwip_init (void); +void esp2glue_espconn_init (void); +void esp2glue_dhcps_start (struct ip_info* info); +err_glue_t esp2glue_dhcp_start (int netif_idx); +void esp2glue_dhcp_stop (int netif_idx); +void esp2glue_netif_updated (int netif_idx, uint32_t ip, uint32_t mask, uint32_t gw, glue_netif_flags_t flags, size_t hwlen, const uint8_t* hw /*, void* state*/); +err_glue_t esp2glue_ethernet_input (int netif_idx, void* glue_pbuf); +void esp2glue_alloc_for_recv (size_t len, void** glue_pbuf, void** glue_data); +void esp2glue_pbuf_freed (void* ref_saved); +void esp2glue_netif_set_default (int netif_idx); +void esp2glue_netif_update (int netif_idx, uint32_t ip, uint32_t mask, uint32_t gw, size_t hwlen, const uint8_t* hwaddr, uint16_t mtu); +void esp2glue_netif_set_up1down0 (int netif_idx, int up1_or_down0); + +void glue2esp_ifupdown (int netif_idx, uint32_t ip, uint32_t mask, uint32_t gw); +err_glue_t glue2esp_linkoutput (int netif_idx, void* ref2save, void* data, size_t size); + +// fixed definitions from esp8266/arduino +// renamed with lwip_ to avoid name collision +// reference and credits: https://github.com/esp8266/Arduino/pull/6301 +#ifndef __STRINGIFY +#define __STRINGIFY(a) #a +#endif +#define lwip_xt_rsil(level) (__extension__({uint32_t state; __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state) :: "memory"); state;})) +#define lwip_xt_wsr_ps(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory") + +#endif // GLUE_H diff --git a/tools/sdk/lwip2/include/lwip-git-hash.h b/tools/sdk/lwip2/include/lwip-git-hash.h index bf1fbda76..ffcef8ec4 100644 --- a/tools/sdk/lwip2/include/lwip-git-hash.h +++ b/tools/sdk/lwip2/include/lwip-git-hash.h @@ -1,5 +1,5 @@ // generated by makefiles/make-lwip2-hash #ifndef LWIP_HASH_H #define LWIP_HASH_H -#define LWIP_HASH_STR "STABLE-2_1_2_RELEASE/glue:1.1-8-g2314329" +#define LWIP_HASH_STR "STABLE-2_1_2_RELEASE/glue:1.2-8-g7958710" #endif // LWIP_HASH_H diff --git a/tools/sdk/lwip2/include/lwip/ip.h b/tools/sdk/lwip2/include/lwip/ip.h index 653c3b2f4..230bfdcf9 100644 --- a/tools/sdk/lwip2/include/lwip/ip.h +++ b/tools/sdk/lwip2/include/lwip/ip.h @@ -189,6 +189,12 @@ extern struct ip_globals ip_data; /** Destination IP4 address of current_header */ #define ip4_current_dest_addr() (&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_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ /** Get the IPv6 header of the current packet. diff --git a/tools/sdk/lwip2/include/lwip/napt.h b/tools/sdk/lwip2/include/lwip/napt.h new file mode 100644 index 000000000..b25e03941 --- /dev/null +++ b/tools/sdk/lwip2/include/lwip/napt.h @@ -0,0 +1,116 @@ +#ifndef __LWIP_NAPT_H__ +#define __LWIP_NAPT_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if IP_FORWARD +#if IP_NAPT + +/* Default size of the tables used for NAPT */ +#define IP_NAPT_MAX 512 +#define IP_PORTMAP_MAX 32 + +/* Timeouts in sec for the various protocol types */ +#define IP_NAPT_TIMEOUT_MS_TCP (30*60*1000) +#define IP_NAPT_TIMEOUT_MS_TCP_DISCON (20*1000) +#define IP_NAPT_TIMEOUT_MS_UDP (2*1000) +#define IP_NAPT_TIMEOUT_MS_ICMP (2*1000) + +#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) + */ +err_t +ip_napt_init(u16_t max_nat, u8_t max_portmap); + + +/** + * Enable/Disable NAPT for a specified interface. + * + * @param addr ip address of the interface + * @param enable non-zero to enable NAPT, or 0 to disable. + */ +err_t +ip_napt_enable(u32_t addr, int enable); + + +/** + * Enable/Disable NAPT for a specified interface. + * + * @param netif number of the interface + * @param enable non-zero to enable NAPT, or 0 to disable. + */ +err_t +ip_napt_enable_no(u8_t number, int enable); + + +/** + * Register port mapping on the external interface to internal interface. + * When the same port mapping is registered again, the old mapping is overwritten. + * In this implementation, only 1 unique port mapping can be defined for each target address/port. + * + * @param proto target protocol + * @param maddr ip address of the external interface + * @param mport mapped port on the external interface, in host byte order. + * @param daddr destination ip address + * @param dport destination port, in host byte order. + */ +u8_t +ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport); + + +/** + * Unregister port mapping on the external interface to internal interface. + * + * @param proto target protocol + * @param maddr ip address of the external interface + */ +u8_t +ip_portmap_remove(u8_t proto, u16_t mport); + +#endif /* IP_NAPT */ +#endif /* IP_FORWARD */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NAPT_H__ */ diff --git a/tools/sdk/lwip2/include/lwip/netif.h b/tools/sdk/lwip2/include/lwip/netif.h index 911196ab3..c29a98761 100644 --- a/tools/sdk/lwip2/include/lwip/netif.h +++ b/tools/sdk/lwip2/include/lwip/netif.h @@ -387,6 +387,9 @@ struct netif { u16_t loop_cnt_current; #endif /* LWIP_LOOPBACK_MAX_PBUFS */ #endif /* ENABLE_LOOPBACK */ +#if LWIP_IPV4 && IP_NAPT + u8_t napt; +#endif }; #if LWIP_CHECKSUM_CTRL_PER_NETIF diff --git a/tools/sdk/lwip2/include/lwip/opt.h b/tools/sdk/lwip2/include/lwip/opt.h index 82c420c16..371286b6a 100644 --- a/tools/sdk/lwip2/include/lwip/opt.h +++ b/tools/sdk/lwip2/include/lwip/opt.h @@ -764,6 +764,10 @@ #define IP_FRAG 0 #endif /* !LWIP_IPV4 */ +#ifndef IP_NAPT +#define IP_NAPT 0 +#endif + /** * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. @@ -3484,6 +3488,14 @@ #if !defined DHCP6_DEBUG || defined __DOXYGEN__ #define DHCP6_DEBUG LWIP_DBG_OFF #endif + +/** + * NAPT_DEBUG: Enable debugging for NAPT. + */ +#ifndef NAPT_DEBUG +#define NAPT_DEBUG LWIP_DBG_OFF +#endif + /** * @} */ diff --git a/tools/sdk/lwip2/include/lwipopts.h b/tools/sdk/lwip2/include/lwipopts.h index f54208806..f5197795e 100644 --- a/tools/sdk/lwip2/include/lwipopts.h +++ b/tools/sdk/lwip2/include/lwipopts.h @@ -741,7 +741,7 @@ * interface, define this to 0. */ #if !defined IP_FORWARD || defined __DOXYGEN__ -#define IP_FORWARD 0 +#define IP_FORWARD LWIP_FEATURES #endif /** @@ -772,6 +772,10 @@ #define IP_FRAG 0 #endif /* !LWIP_IPV4 */ +#ifndef IP_NAPT +#define IP_NAPT (LWIP_FEATURES && !LWIP_IPV6) +#endif + /** * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. @@ -3496,6 +3500,13 @@ * @} */ +/** + * NAPT_DEBUG: Enable debugging for NAPT. + */ +#ifndef NAPT_DEBUG +#define NAPT_DEBUG LWIP_DBG_OFF +#endif + /** * LWIP_TESTMODE: Changes to make unit test possible */