Skip to content

new network feature: NAPT (widely known as NAT) #6360

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Aug 28, 2019
Original file line number Diff line number Diff line change
@@ -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 <ESP8266WiFi.h>
#include <lwip/napt.h>
#include <lwip/dns.h>
#include <dhcpserver.h>

#define NAPT 1000
#define NAPT_PORT 10

#if HAVE_NETDUMP

#include <NetDump.h>

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() {
}

1 change: 0 additions & 1 deletion libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
*
*/

#include <arch/cc.h>
#include <sys/time.h>
#include <IPAddress.h>
#include <AddrList.h>
Expand Down
Binary file modified tools/sdk/lib/liblwip2-1460-feat.a
Binary file not shown.
Binary file modified tools/sdk/lib/liblwip2-1460.a
Binary file not shown.
Binary file modified tools/sdk/lib/liblwip2-536-feat.a
Binary file not shown.
Binary file modified tools/sdk/lib/liblwip2-536.a
Binary file not shown.
Binary file modified tools/sdk/lib/liblwip6-1460-feat.a
Binary file not shown.
Binary file modified tools/sdk/lib/liblwip6-536-feat.a
Binary file not shown.
10 changes: 6 additions & 4 deletions tools/sdk/lwip2/include/arch/cc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

///////////////////////////////
Expand Down
130 changes: 130 additions & 0 deletions tools/sdk/lwip2/include/dhcpserver.h
Original file line number Diff line number Diff line change
@@ -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
113 changes: 113 additions & 0 deletions tools/sdk/lwip2/include/glue.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion tools/sdk/lwip2/include/lwip-git-hash.h
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions tools/sdk/lwip2/include/lwip/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading