Skip to content

Commit 06f1865

Browse files
authored
new network feature: NAPT (widely known as NAT) (#6360)
* lwIP: napt patches (enabled with lwip2 w/o IPv6 w/ features)
1 parent 7436f38 commit 06f1865

File tree

18 files changed

+497
-8
lines changed

18 files changed

+497
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
// NAPT example released to public domain
3+
4+
#if LWIP_FEATURES && !LWIP_IPV6
5+
6+
#define HAVE_NETDUMP 0
7+
8+
#ifndef STASSID
9+
#define STASSID "mynetwork"
10+
#define STAPSK "mynetworkpassword"
11+
#endif
12+
13+
#include <ESP8266WiFi.h>
14+
#include <lwip/napt.h>
15+
#include <lwip/dns.h>
16+
#include <dhcpserver.h>
17+
18+
#define NAPT 1000
19+
#define NAPT_PORT 10
20+
21+
#if HAVE_NETDUMP
22+
23+
#include <NetDump.h>
24+
25+
void dump(int netif_idx, const char* data, size_t len, int out, int success) {
26+
(void)success;
27+
Serial.print(out ? F("out ") : F(" in "));
28+
Serial.printf("%d ", netif_idx);
29+
30+
// optional filter example: if (netDump_is_ARP(data))
31+
{
32+
netDump(Serial, data, len);
33+
//netDumpHex(Serial, data, len);
34+
}
35+
}
36+
#endif
37+
38+
void setup() {
39+
Serial.begin(115200);
40+
Serial.printf("\n\nNAPT Range extender\n");
41+
Serial.printf("Heap on start: %d\n", ESP.getFreeHeap());
42+
43+
#if HAVE_NETDUMP
44+
phy_capture = dump;
45+
#endif
46+
47+
// first, connect to STA so we can get a proper local DNS server
48+
WiFi.mode(WIFI_STA);
49+
WiFi.begin(STASSID, STAPSK);
50+
while (WiFi.status() != WL_CONNECTED) {
51+
Serial.print('.');
52+
delay(500);
53+
}
54+
Serial.printf("\nSTA: %s (dns: %s / %s)\n",
55+
WiFi.localIP().toString().c_str(),
56+
WiFi.dnsIP(0).toString().c_str(),
57+
WiFi.dnsIP(1).toString().c_str());
58+
59+
// give DNS servers to AP side
60+
dhcps_set_dns(0, WiFi.dnsIP(0));
61+
dhcps_set_dns(1, WiFi.dnsIP(1));
62+
63+
WiFi.softAPConfig( // enable AP, with android-compatible google domain
64+
IPAddress(172, 217, 28, 254),
65+
IPAddress(172, 217, 28, 254),
66+
IPAddress(255, 255, 255, 0));
67+
WiFi.softAP(STASSID "extender", STAPSK);
68+
Serial.printf("AP: %s\n", WiFi.softAPIP().toString().c_str());
69+
70+
Serial.printf("Heap before: %d\n", ESP.getFreeHeap());
71+
err_t ret = ip_napt_init(NAPT, NAPT_PORT);
72+
Serial.printf("ip_napt_init(%d,%d): ret=%d (OK=%d)\n", NAPT, NAPT_PORT, (int)ret, (int)ERR_OK);
73+
if (ret == ERR_OK) {
74+
ret = ip_napt_enable_no(SOFTAP_IF, 1);
75+
Serial.printf("ip_napt_enable_no(SOFTAP_IF): ret=%d (OK=%d)\n", (int)ret, (int)ERR_OK);
76+
if (ret == ERR_OK) {
77+
Serial.printf("WiFi Network '%s' with same password is now NATed behind '%s'\n", STASSID "extender", STASSID);
78+
}
79+
}
80+
Serial.printf("Heap after napt init: %d\n", ESP.getFreeHeap());
81+
if (ret != ERR_OK) {
82+
Serial.printf("NAPT initialization failed\n");
83+
}
84+
}
85+
86+
#else
87+
88+
void setup() {
89+
Serial.begin(115200);
90+
Serial.printf("\n\nNAPT not supported in this configuration\n");
91+
}
92+
93+
#endif
94+
95+
void loop() {
96+
}
97+

libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
*
2323
*/
2424

25-
#include <arch/cc.h>
2625
#include <sys/time.h>
2726
#include <IPAddress.h>
2827
#include <AddrList.h>

tools/sdk/lib/liblwip2-1460-feat.a

66.6 KB
Binary file not shown.

tools/sdk/lib/liblwip2-1460.a

4.38 KB
Binary file not shown.

tools/sdk/lib/liblwip2-536-feat.a

66.6 KB
Binary file not shown.

tools/sdk/lib/liblwip2-536.a

4.38 KB
Binary file not shown.

tools/sdk/lib/liblwip6-1460-feat.a

8.83 KB
Binary file not shown.

tools/sdk/lib/liblwip6-536-feat.a

8.83 KB
Binary file not shown.

tools/sdk/lwip2/include/arch/cc.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@ void sntp_set_system_time (uint32_t t);
5858

5959
#include "mem.h" // useful for os_malloc used in esp-arduino's mDNS
6060

61-
typedef uint32_t sys_prot_t; // not really used
62-
#define SYS_ARCH_DECL_PROTECT(lev)
63-
#define SYS_ARCH_PROTECT(lev) os_intr_lock()
64-
#define SYS_ARCH_UNPROTECT(lev) os_intr_unlock()
61+
#include "glue.h" // include assembly locking macro used below
62+
typedef uint32_t sys_prot_t;
63+
#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev
64+
#define SYS_ARCH_PROTECT(lev) lev = lwip_xt_rsil(15)
65+
#define SYS_ARCH_UNPROTECT(lev) lwip_xt_wsr_ps(lev)
66+
6567
#define LWIP_NO_CTYPE_H 1
6668

6769
///////////////////////////////

tools/sdk/lwip2/include/dhcpserver.h

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
2+
// adapted from dhcpserver.c distributed in esp8266 sdk 2.0.0
3+
// same license may apply
4+
5+
#ifndef __DHCPS_H__
6+
#define __DHCPS_H__
7+
8+
#include "glue.h" // for UDEBUG
9+
10+
#define USE_DNS
11+
12+
typedef struct dhcps_state{
13+
sint16_t state;
14+
} dhcps_state;
15+
16+
typedef struct dhcps_msg {
17+
uint8_t op, htype, hlen, hops;
18+
uint8_t xid[4];
19+
uint16_t secs, flags;
20+
uint8_t ciaddr[4];
21+
uint8_t yiaddr[4];
22+
uint8_t siaddr[4];
23+
uint8_t giaddr[4];
24+
uint8_t chaddr[16];
25+
uint8_t sname[64];
26+
uint8_t file[128];
27+
uint8_t options[312];
28+
}dhcps_msg;
29+
30+
#ifndef LWIP_OPEN_SRC
31+
struct dhcps_lease {
32+
bool enable;
33+
struct ipv4_addr start_ip;
34+
struct ipv4_addr end_ip;
35+
};
36+
37+
enum dhcps_offer_option{
38+
OFFER_START = 0x00,
39+
OFFER_ROUTER = 0x01,
40+
OFFER_END
41+
};
42+
#endif
43+
44+
typedef enum {
45+
DHCPS_TYPE_DYNAMIC,
46+
DHCPS_TYPE_STATIC
47+
} dhcps_type_t;
48+
49+
typedef enum {
50+
DHCPS_STATE_ONLINE,
51+
DHCPS_STATE_OFFLINE
52+
} dhcps_state_t;
53+
54+
struct dhcps_pool{
55+
struct ipv4_addr ip;
56+
uint8 mac[6];
57+
uint32 lease_timer;
58+
dhcps_type_t type;
59+
dhcps_state_t state;
60+
61+
};
62+
63+
typedef struct _list_node{
64+
void *pnode;
65+
struct _list_node *pnext;
66+
}list_node;
67+
68+
extern uint32 dhcps_lease_time;
69+
#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0
70+
#define DHCPS_MAX_LEASE 0x64
71+
#define BOOTP_BROADCAST 0x8000
72+
73+
#define DHCP_REQUEST 1
74+
#define DHCP_REPLY 2
75+
#define DHCP_HTYPE_ETHERNET 1
76+
#define DHCP_HLEN_ETHERNET 6
77+
#define DHCP_MSG_LEN 236
78+
79+
#define DHCPS_SERVER_PORT 67
80+
#define DHCPS_CLIENT_PORT 68
81+
82+
#define DHCPDISCOVER 1
83+
#define DHCPOFFER 2
84+
#define DHCPREQUEST 3
85+
#define DHCPDECLINE 4
86+
#define DHCPACK 5
87+
#define DHCPNAK 6
88+
#define DHCPRELEASE 7
89+
90+
#define DHCP_OPTION_SUBNET_MASK 1
91+
#define DHCP_OPTION_ROUTER 3
92+
#define DHCP_OPTION_DNS_SERVER 6
93+
#define DHCP_OPTION_REQ_IPADDR 50
94+
#define DHCP_OPTION_LEASE_TIME 51
95+
#define DHCP_OPTION_MSG_TYPE 53
96+
#define DHCP_OPTION_SERVER_ID 54
97+
#define DHCP_OPTION_INTERFACE_MTU 26
98+
#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31
99+
#define DHCP_OPTION_BROADCAST_ADDRESS 28
100+
#define DHCP_OPTION_REQ_LIST 55
101+
#define DHCP_OPTION_END 255
102+
103+
//#define USE_CLASS_B_NET 1
104+
#define DHCPS_DEBUG UDEBUG
105+
#define MAX_STATION_NUM 8
106+
107+
#define DHCPS_STATE_OFFER 1
108+
#define DHCPS_STATE_DECLINE 2
109+
#define DHCPS_STATE_ACK 3
110+
#define DHCPS_STATE_NAK 4
111+
#define DHCPS_STATE_IDLE 5
112+
#define DHCPS_STATE_RELEASE 6
113+
114+
#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0)
115+
116+
#ifdef __cplusplus
117+
extern "C"
118+
{
119+
#endif
120+
121+
void dhcps_set_dns (int num, const ipv4_addr_t* dns);
122+
123+
void dhcps_start(struct ip_info *info);
124+
void dhcps_stop(void);
125+
126+
#ifdef __cplusplus
127+
}
128+
#endif
129+
130+
#endif

tools/sdk/lwip2/include/glue.h

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
2+
/*
3+
4+
Redistribution and use in source and binary forms, with or without modification,
5+
are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice,
8+
this list of conditions and the following disclaimer.
9+
2. Redistributions in binary form must reproduce the above copyright notice,
10+
this list of conditions and the following disclaimer in the documentation
11+
and/or other materials provided with the distribution.
12+
3. The name of the author may not be used to endorse or promote products
13+
derived from this software without specific prior written permission.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED
16+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
18+
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
20+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
24+
OF SUCH DAMAGE.
25+
26+
author: d. gauchard
27+
28+
*/
29+
30+
#ifndef GLUE_H
31+
#define GLUE_H
32+
33+
#ifndef ARDUINO
34+
#define ARDUINO 0
35+
#endif
36+
37+
#ifndef OPENSDK
38+
#define OPENSDK 0
39+
#endif
40+
41+
#if !ARDUINO && !OPENSDK
42+
#error Must defined ARDUINO or OPENSDK
43+
#endif
44+
45+
#include "gluedebug.h"
46+
47+
#ifdef __cplusplus
48+
extern "C"
49+
{
50+
#endif
51+
#include "ets_sys.h"
52+
#include "osapi.h"
53+
#include "user_interface.h"
54+
#ifdef __cplusplus
55+
}
56+
#endif
57+
58+
typedef enum
59+
{
60+
GLUE_ERR_OK = 0,
61+
GLUE_ERR_MEM = -1,
62+
GLUE_ERR_BUF = -2,
63+
GLUE_ERR_TIMEOUT = -3,
64+
GLUE_ERR_RTE = -4,
65+
GLUE_ERR_INPROGRESS = -5,
66+
GLUE_ERR_VAL = -6,
67+
GLUE_ERR_WOULDBLOCK = -7,
68+
GLUE_ERR_USE = -8,
69+
GLUE_ERR_ALREADY = -9,
70+
GLUE_ERR_ISCONN = -10,
71+
GLUE_ERR_CONN = -11,
72+
GLUE_ERR_IF = -12,
73+
GLUE_ERR_ABRT = -13,
74+
GLUE_ERR_RST = -14,
75+
GLUE_ERR_CLSD = -15,
76+
GLUE_ERR_ARG = -16
77+
} err_glue_t;
78+
79+
typedef enum
80+
{
81+
GLUE_NETIF_FLAG_BROADCAST = 1,
82+
GLUE_NETIF_FLAG_UP = 2,
83+
GLUE_NETIF_FLAG_ETHARP = 4,
84+
GLUE_NETIF_FLAG_IGMP = 8,
85+
GLUE_NETIF_FLAG_LINK_UP = 16,
86+
} glue_netif_flags_t;
87+
88+
void esp2glue_lwip_init (void);
89+
void esp2glue_espconn_init (void);
90+
void esp2glue_dhcps_start (struct ip_info* info);
91+
err_glue_t esp2glue_dhcp_start (int netif_idx);
92+
void esp2glue_dhcp_stop (int netif_idx);
93+
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*/);
94+
err_glue_t esp2glue_ethernet_input (int netif_idx, void* glue_pbuf);
95+
void esp2glue_alloc_for_recv (size_t len, void** glue_pbuf, void** glue_data);
96+
void esp2glue_pbuf_freed (void* ref_saved);
97+
void esp2glue_netif_set_default (int netif_idx);
98+
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);
99+
void esp2glue_netif_set_up1down0 (int netif_idx, int up1_or_down0);
100+
101+
void glue2esp_ifupdown (int netif_idx, uint32_t ip, uint32_t mask, uint32_t gw);
102+
err_glue_t glue2esp_linkoutput (int netif_idx, void* ref2save, void* data, size_t size);
103+
104+
// fixed definitions from esp8266/arduino
105+
// renamed with lwip_ to avoid name collision
106+
// reference and credits: https://github.com/esp8266/Arduino/pull/6301
107+
#ifndef __STRINGIFY
108+
#define __STRINGIFY(a) #a
109+
#endif
110+
#define lwip_xt_rsil(level) (__extension__({uint32_t state; __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state) :: "memory"); state;}))
111+
#define lwip_xt_wsr_ps(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory")
112+
113+
#endif // GLUE_H
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// generated by makefiles/make-lwip2-hash
22
#ifndef LWIP_HASH_H
33
#define LWIP_HASH_H
4-
#define LWIP_HASH_STR "STABLE-2_1_2_RELEASE/glue:1.1-8-g2314329"
4+
#define LWIP_HASH_STR "STABLE-2_1_2_RELEASE/glue:1.2-8-g7958710"
55
#endif // LWIP_HASH_H

tools/sdk/lwip2/include/lwip/ip.h

+6
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ extern struct ip_globals ip_data;
189189
/** Destination IP4 address of current_header */
190190
#define ip4_current_dest_addr() (&ip_data.current_iphdr_dest)
191191

192+
#if NAPT_DEBUG
193+
void napt_debug_print()ICACHE_FLASH_ATTR;
194+
#else
195+
#define napt_debug_print(p)
196+
#endif /* NAPT_DEBUG */
197+
192198
#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */
193199

194200
/** Get the IPv6 header of the current packet.

0 commit comments

Comments
 (0)