mirror of
https://github.com/espressif/esp-lwip.git
synced 2026-06-05 21:04:45 +00:00
napt: Fixes and improvements (2.2.0)
2.1.3-esp:fadb9109napt: Fixes and improvements (2.1.3) 2.1.3-esp:5c4f899fnapt: restore to the initial state in deinit 2.1.3-esp:d65ad241napt: Fix ip_portmap_add() to keep only one port mapping 2.1.3-esp:7033e26fnapt: Fix clean compilation 2.1.3-esp:bc78df87napt: Fix IP forwarding when forward netif enable NAPT 2.1.3-esp:b55e64aenapt/stats: Move some napt counters to stats module 2.1.3-esp:a7e0a50cip_napt_maint: Fix timestamp overflow handling (2.1.3) 2.1.3-esp: partiallyf5c43549lwip_debug: Fixed string format error in ip6 and napt
This commit is contained in:
committed by
David Cermak
parent
faa7ff4f43
commit
3462f21a38
+5
-2
@@ -332,8 +332,11 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||
|
||||
#if ESP_LWIP
|
||||
#if IP_NAPT
|
||||
if (ip_napt_forward(p, iphdr, inp, netif) != ERR_OK)
|
||||
return;
|
||||
/* If the output netif uses NAPT, we will not perform NAPT forwarding (because NAPT netif will not search the NAPT table on ip4_input) */
|
||||
if (!netif->napt) {
|
||||
if (ip_napt_forward(p, iphdr, inp, netif) != ERR_OK)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif /* ESP_LWIP */
|
||||
|
||||
|
||||
+365
-152
@@ -39,9 +39,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if ESP_LWIP
|
||||
#if LWIP_IPV4
|
||||
#if IP_NAPT
|
||||
#if ESP_LWIP && LWIP_IPV4 && IP_NAPT
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ip.h"
|
||||
@@ -53,31 +55,39 @@
|
||||
#include "lwip/priv/tcp_priv.h"
|
||||
#include "lwip/lwip_napt.h"
|
||||
#include "lwip/ip4_napt.h"
|
||||
#include "string.h"
|
||||
#include "assert.h"
|
||||
#include "lwip/timeouts.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#define NO_IDX ((u16_t)-1)
|
||||
#define NT(x) ((x) == NO_IDX ? NULL : &ip_napt_table[x])
|
||||
|
||||
struct napt_table {
|
||||
#pragma GCC diagnostic push
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic ignored "-Wc90-c99-compat" /* To allow u8_t bit fields */
|
||||
#endif
|
||||
struct ip_napt_entry {
|
||||
u32_t last;
|
||||
u32_t src;
|
||||
u32_t dest;
|
||||
u16_t sport;
|
||||
u16_t dport;
|
||||
u16_t mport;
|
||||
u32_t src; /* net */
|
||||
u32_t dest; /* net */
|
||||
u16_t sport; /* net */
|
||||
u16_t dport; /* net */
|
||||
u16_t mport; /* net */
|
||||
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;
|
||||
u8_t fin1 : 1;
|
||||
u8_t fin2 : 1;
|
||||
u8_t finack1 : 1;
|
||||
u8_t finack2 : 1;
|
||||
u8_t synack : 1;
|
||||
u8_t rst : 1;
|
||||
u8_t _unused : 2;
|
||||
u32_t src_seqno; /* host */
|
||||
u32_t dest_seqno; /* host */
|
||||
u16_t next, prev;
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#if IP_NAPT_PORTMAP
|
||||
struct portmap_table {
|
||||
struct ip_portmap_entry {
|
||||
u32_t maddr;
|
||||
u32_t daddr;
|
||||
u16_t mport;
|
||||
@@ -88,51 +98,72 @@ struct portmap_table {
|
||||
#endif
|
||||
|
||||
static u16_t napt_list = NO_IDX, napt_list_last = NO_IDX, napt_free = 0;
|
||||
|
||||
static struct napt_table *ip_napt_table = NULL;
|
||||
#if IP_NAPT_PORTMAP
|
||||
static struct portmap_table *ip_portmap_table = NULL;
|
||||
#endif
|
||||
|
||||
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 u16_t ip_napt_max = 0;
|
||||
#if IP_NAPT_PORTMAP
|
||||
static uint8_t ip_portmap_max = 0;
|
||||
#endif
|
||||
|
||||
static struct ip_napt_entry *ip_napt_table = NULL;
|
||||
#if IP_NAPT_PORTMAP
|
||||
static struct ip_portmap_entry *ip_portmap_table = NULL;
|
||||
#endif
|
||||
|
||||
static void ip_napt_gc(uint32_t now, bool force);
|
||||
static void ip_napt_tmr(void *arg);
|
||||
|
||||
#define WRAPPED_AROUND(a, b) ((((a) ^ (b)) & (1UL << 31)) != 0)
|
||||
|
||||
#if NAPT_DEBUG
|
||||
/* Print NAPT table using LWIP_DEBUGF
|
||||
*/
|
||||
/* Print NAPT table using LWIP_DEBUGF */
|
||||
#define DPRINTF(m) LWIP_DEBUGF(NAPT_DEBUG, m)
|
||||
/* #define DPRINTF(m) printf m */
|
||||
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"));
|
||||
int i, next, p;
|
||||
u32_t now = sys_now();
|
||||
#if LWIP_STATS
|
||||
u32_t nr_total = STATS_GET(ip_napt.nr_active_tcp) + STATS_GET(ip_napt.nr_active_udp) + STATS_GET(ip_napt.nr_active_icmp);
|
||||
DPRINTF(("NAPT table (%"STAT_COUNTER_F"+%"STAT_COUNTER_F"+%"STAT_COUNTER_F"=%"U32_F" / %"U16_F"):\n",
|
||||
STATS_GET(ip_napt.nr_active_tcp), STATS_GET(ip_napt.nr_active_udp), STATS_GET(ip_napt.nr_active_icmp), nr_total, ip_napt_max));
|
||||
if (nr_total == 0) return;
|
||||
#endif
|
||||
|
||||
DPRINTF(("+-----------------------+-----------------------+-------+---------+----------+\n"));
|
||||
DPRINTF(("| src | dest | mport | flags | age |\n"));
|
||||
DPRINTF(("+-----------------------+-----------------------+-------+---------+----------+\n"));
|
||||
for (i = napt_list; i != NO_IDX; i = next) {
|
||||
struct napt_table *t = &ip_napt_table[i];
|
||||
struct ip_napt_entry *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]));
|
||||
DPRINTF(("| %3"U16_F".%3"U16_F".%3"U16_F".%3"U16_F":%5"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_ntohs(t->sport)));
|
||||
|
||||
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]));
|
||||
DPRINTF(("| %3"U16_F".%3"U16_F".%3"U16_F".%3"U16_F":%5"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_ntohs(t->dport)));
|
||||
|
||||
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)));
|
||||
p = t->proto;
|
||||
DPRINTF(("| %5"U16_F" | %c%c%c%c%c%c%c | %8"U32_F" |\n",
|
||||
lwip_ntohs(t->mport),
|
||||
(p == IP_PROTO_TCP ? 'T' : (p == IP_PROTO_UDP ? 'U' : (p == IP_PROTO_ICMP ? 'I' : '?'))),
|
||||
(t->fin1 ? 'f' : '.'),
|
||||
(t->fin2 ? 'F' : '.'),
|
||||
(t->finack1 ? 'a' : '.'),
|
||||
(t->finack2 ? 'A' : '.'),
|
||||
(t->synack ? 'S' : '.'),
|
||||
(t->rst ? 'R' : '.'),
|
||||
now - t->last));
|
||||
|
||||
}
|
||||
DPRINTF(("+-----------------------+-----------------------+-------+---------+----------+\n"));
|
||||
}
|
||||
#endif /* NAPT_DEBUG */
|
||||
|
||||
@@ -144,12 +175,20 @@ napt_debug_print(void)
|
||||
static void
|
||||
ip_napt_deinit(void)
|
||||
{
|
||||
napt_list = NO_IDX;
|
||||
napt_list_last = NO_IDX;
|
||||
napt_free = 0;
|
||||
ip_napt_max = 0;
|
||||
#if IP_NAPT_PORTMAP
|
||||
ip_portmap_max = 0;
|
||||
#endif
|
||||
mem_free(ip_napt_table);
|
||||
ip_napt_table = NULL;
|
||||
#if IP_NAPT_PORTMAP
|
||||
mem_free(ip_portmap_table);
|
||||
ip_portmap_table = NULL;
|
||||
#endif
|
||||
ip_napt_table = NULL;
|
||||
sys_untimeout(ip_napt_tmr, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,7 +198,11 @@ ip_napt_deinit(void)
|
||||
* @param max_portmap max number of enties in the NAPT table (use IP_PORTMAP_MAX if in doubt)
|
||||
*/
|
||||
static void
|
||||
#if IP_NAPT_PORTMAP
|
||||
ip_napt_init(uint16_t max_nat, uint8_t max_portmap)
|
||||
#else
|
||||
ip_napt_init(uint16_t max_nat)
|
||||
#endif
|
||||
{
|
||||
u16_t i;
|
||||
|
||||
@@ -171,17 +214,19 @@ ip_napt_init(uint16_t max_nat, uint8_t max_portmap)
|
||||
#endif
|
||||
ip_napt_max = max_nat;
|
||||
|
||||
ip_napt_table = (struct napt_table*)mem_calloc(ip_napt_max, sizeof(struct napt_table[1]));
|
||||
ip_napt_table = (struct ip_napt_entry *) mem_calloc(max_nat, sizeof(*ip_napt_table));
|
||||
#if IP_NAPT_PORTMAP
|
||||
ip_portmap_table = (struct portmap_table*)mem_calloc(ip_portmap_max, sizeof(struct portmap_table[1]));
|
||||
ip_portmap_table = (struct ip_portmap_entry *) mem_calloc(max_portmap, sizeof(*ip_portmap_table));
|
||||
assert(ip_portmap_table != NULL && ip_napt_table != NULL);
|
||||
#else
|
||||
assert(ip_napt_table != NULL);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ip_napt_max - 1; i++)
|
||||
for (i = 0; i < max_nat - 1; i++)
|
||||
ip_napt_table[i].next = i + 1;
|
||||
ip_napt_table[i].next = NO_IDX;
|
||||
|
||||
sys_timeout(NAPT_TMR_INTERVAL, ip_napt_tmr, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,17 +236,20 @@ 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)
|
||||
if (netif_is_up(netif) && !ip_addr_isany(&netif->ip_addr) && (ip_2_ip4(&netif->ip_addr)->addr) == addr) {
|
||||
netif->napt = enable;
|
||||
}
|
||||
if (netif->napt) {
|
||||
napt_in_any_netif = 1;
|
||||
if (netif_is_up(netif) && !ip_addr_isany(&netif->ip_addr) && (ip_2_ip4(&netif->ip_addr)->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;
|
||||
if (napt_in_any_netif) {
|
||||
#if IP_NAPT_PORTMAP
|
||||
ip_napt_init(IP_NAPT_MAX, IP_PORTMAP_MAX);
|
||||
#else
|
||||
ip_napt_init(IP_NAPT_MAX);
|
||||
#endif
|
||||
} else {
|
||||
ip_napt_deinit();
|
||||
}
|
||||
}
|
||||
@@ -214,7 +262,11 @@ ip_napt_enable_no(u8_t number, int enable)
|
||||
if (netif->num == number) {
|
||||
netif->napt = !!enable;
|
||||
if (enable)
|
||||
#if IP_NAPT_PORTMAP
|
||||
ip_napt_init(IP_NAPT_MAX, IP_PORTMAP_MAX);
|
||||
#else
|
||||
ip_napt_init(IP_NAPT_MAX);
|
||||
#endif
|
||||
else
|
||||
ip_napt_deinit();
|
||||
break;
|
||||
@@ -234,7 +286,11 @@ ip_napt_enable_netif(struct netif *netif, int enable)
|
||||
if (!netif->napt && enable) {
|
||||
/* Enable napt */
|
||||
netif->napt = 1;
|
||||
#if IP_NAPT_PORTMAP
|
||||
ip_napt_init(IP_NAPT_MAX, IP_PORTMAP_MAX);
|
||||
#else
|
||||
ip_napt_init(IP_NAPT_MAX);
|
||||
#endif
|
||||
|
||||
} else if (netif->napt && !enable) {
|
||||
/* Disable napt */
|
||||
@@ -282,9 +338,41 @@ checksumadjust(u8_t *chksum, u8_t *optr, int olen, u8_t *nptr, int nlen)
|
||||
chksum[0]=x/256; chksum[1]=x & 0xFFU;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ip_napt_send_rst(u32_t src_be, u16_t sport_be, u32_t dst_be, u16_t dport_be, u32_t seqno_le, u32_t ackno_le)
|
||||
{
|
||||
struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
|
||||
struct tcp_hdr *tcphdr;
|
||||
struct netif *netif;
|
||||
ip_addr_t src, dst;
|
||||
if (p == NULL) return;
|
||||
tcphdr = (struct tcp_hdr *)p->payload;
|
||||
tcphdr->src = sport_be;
|
||||
tcphdr->dest = dport_be;
|
||||
tcphdr->seqno = lwip_htonl(seqno_le);
|
||||
tcphdr->ackno = lwip_htonl(ackno_le);
|
||||
TCPH_HDRLEN_FLAGS_SET(tcphdr, 5, (TCP_RST | TCP_ACK));
|
||||
tcphdr->wnd = lwip_htons(512);
|
||||
tcphdr->urgp = 0;
|
||||
tcphdr->chksum = 0;
|
||||
ip_addr_set_ip4_u32_val(src, src_be);
|
||||
ip_addr_set_ip4_u32_val(dst, dst_be);
|
||||
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, &src, &dst);
|
||||
netif = ip4_route(ip_2_ip4(&dst));
|
||||
if (netif != NULL) {
|
||||
err_t res = ip4_output_if(p, ip_2_ip4(&src), ip_2_ip4(&dst), ICMP_TTL, 0, IP_PROTO_TCP, netif);
|
||||
LWIP_UNUSED_ARG(res); /* might be unused if debugging off */
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("SEND RST to %#"X32_F":%"U16_F" from %#"X32_F":%"U16_F" seq %"U32_F" ack %"U32_F" res %d\n",
|
||||
lwip_ntohl(src_be), lwip_ntohs(sport_be), lwip_ntohl(dst_be), lwip_ntohs(dport_be),
|
||||
seqno_le, ackno_le, res));
|
||||
}
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
/* t must be indexed by napt_free */
|
||||
static void
|
||||
ip_napt_insert(struct napt_table *t)
|
||||
ip_napt_insert(struct ip_napt_entry *t)
|
||||
{
|
||||
u16_t ti = t - ip_napt_table;
|
||||
assert(ti == napt_free);
|
||||
@@ -297,23 +385,26 @@ ip_napt_insert(struct napt_table *t)
|
||||
if (napt_list_last == NO_IDX)
|
||||
napt_list_last = ti;
|
||||
|
||||
#if LWIP_STATS
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP)
|
||||
nr_active_napt_tcp++;
|
||||
STATS_INC(ip_napt.nr_active_tcp);
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP)
|
||||
nr_active_napt_udp++;
|
||||
STATS_INC(ip_napt.nr_active_udp);
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP)
|
||||
nr_active_napt_icmp++;
|
||||
STATS_INC(ip_napt.nr_active_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));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_insert(): TCP=%"STAT_COUNTER_F", UDP=%"STAT_COUNTER_F", ICMP=%"STAT_COUNTER_F"\n",
|
||||
STATS_GET(ip_napt.nr_active_tcp), STATS_GET(ip_napt.nr_active_udp), STATS_GET(ip_napt.nr_active_icmp)));
|
||||
#endif /* LWIP_STATS */
|
||||
}
|
||||
|
||||
static void
|
||||
ip_napt_free(struct napt_table *t)
|
||||
ip_napt_free(struct ip_napt_entry *t)
|
||||
{
|
||||
u16_t ti = t - ip_napt_table;
|
||||
if (ti == napt_list)
|
||||
@@ -328,22 +419,31 @@ ip_napt_free(struct napt_table *t)
|
||||
t->next = napt_free;
|
||||
napt_free = ti;
|
||||
|
||||
#if LWIP_STATS
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP)
|
||||
nr_active_napt_tcp--;
|
||||
STATS_DEC(ip_napt.nr_active_tcp);
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP)
|
||||
nr_active_napt_udp--;
|
||||
STATS_DEC(ip_napt.nr_active_udp);
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP)
|
||||
nr_active_napt_icmp--;
|
||||
STATS_DEC(ip_napt.nr_active_icmp);
|
||||
#endif
|
||||
#endif /* LWIP_STATS */
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_free\n"));
|
||||
#if NAPT_DEBUG
|
||||
napt_debug_print();
|
||||
#endif
|
||||
/* Send RST to both sides to let them know connection is being evicted */
|
||||
if (t->proto == IP_PROTO_TCP && t->synack && !(t->fin1 || t->fin2 || t-> rst)) {
|
||||
/* Send RST both ways. */
|
||||
ip_napt_send_rst(t->dest, t->dport, t->src, t->sport, t->dest_seqno, t->src_seqno);
|
||||
ip_napt_send_rst(t->src, t->sport, t->dest, t->dport, t->src_seqno, t->dest_seqno);
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
@@ -352,15 +452,16 @@ 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];
|
||||
struct ip_napt_entry *t = &ip_napt_table[i];
|
||||
next = t->next;
|
||||
if (t->proto == proto && t->mport == port)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if IP_NAPT_PORTMAP
|
||||
static struct portmap_table *
|
||||
static struct ip_portmap_entry *
|
||||
ip_portmap_find(u8_t proto, u16_t mport);
|
||||
#endif
|
||||
|
||||
@@ -419,20 +520,20 @@ ip_napt_new_port(u8_t proto, u16_t port)
|
||||
}
|
||||
}
|
||||
|
||||
static struct napt_table*
|
||||
static struct ip_napt_entry*
|
||||
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;
|
||||
struct ip_napt_entry *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)));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("looking up in table %s: %"U16_F".%"U16_F".%"U16_F".%"U16_F", port: %"U16_F", mport: %"U16_F"\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
|
||||
@@ -441,33 +542,12 @@ ip_napt_find(u8_t proto, u32_t addr, u16_t port, u16_t mport, u8_t dest)
|
||||
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) {
|
||||
if (!dest && 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
|
||||
if (dest && t->proto == proto && t->dest == addr && t->dport == port
|
||||
&& t->mport == mport) {
|
||||
t->last = now;
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("found\n"));
|
||||
@@ -480,9 +560,9 @@ ip_napt_find(u8_t proto, u32_t addr, u16_t port, u16_t mport, u8_t dest)
|
||||
}
|
||||
|
||||
static u16_t
|
||||
ip_napt_add(u8_t proto, u32_t src, u16_t sport, u32_t dest, u16_t dport)
|
||||
ip_napt_add(u8_t proto, u32_t src, u16_t sport, u32_t dest, u16_t dport, u32_t seqno)
|
||||
{
|
||||
struct napt_table *t = ip_napt_find(proto, src, sport, 0, 0);
|
||||
struct ip_napt_entry *t = ip_napt_find(proto, src, sport, 0, 0);
|
||||
if (t) {
|
||||
t->last = sys_now();
|
||||
t->dest = dest;
|
||||
@@ -499,6 +579,10 @@ ip_napt_add(u8_t proto, u32_t src, u16_t sport, u32_t dest, u16_t dport)
|
||||
return t->mport;
|
||||
}
|
||||
t = NT(napt_free);
|
||||
if (!t) {
|
||||
ip_napt_gc(sys_now(), true /* make_room */);
|
||||
t = NT(napt_free);
|
||||
}
|
||||
if (t) {
|
||||
u16_t mport = sport;
|
||||
#if LWIP_TCP
|
||||
@@ -517,6 +601,8 @@ ip_napt_add(u8_t proto, u32_t src, u16_t sport, u32_t dest, u16_t dport)
|
||||
t->mport = mport;
|
||||
t->proto = proto;
|
||||
t->fin1 = t->fin2 = t->finack1 = t->finack2 = t->synack = t->rst = 0;
|
||||
t->src_seqno = ntohl(seqno);
|
||||
t->dest_seqno = 0;
|
||||
ip_napt_insert(t);
|
||||
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_add\n"));
|
||||
@@ -539,10 +625,11 @@ ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport)
|
||||
dport = PP_HTONS(dport);
|
||||
|
||||
for (i = 0; i < ip_portmap_max; i++) {
|
||||
struct portmap_table *p = &ip_portmap_table[i];
|
||||
struct ip_portmap_entry *p = &ip_portmap_table[i];
|
||||
if (p->valid && p->proto == proto && p->mport == mport) {
|
||||
p->dport = dport;
|
||||
p->daddr = daddr;
|
||||
p->maddr = maddr;
|
||||
} else if (!p->valid) {
|
||||
p->maddr = maddr;
|
||||
p->daddr = daddr;
|
||||
@@ -556,12 +643,12 @@ ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct portmap_table *
|
||||
static struct ip_portmap_entry *
|
||||
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];
|
||||
struct ip_portmap_entry *p = &ip_portmap_table[i];
|
||||
if (!p->valid)
|
||||
return 0;
|
||||
if (p->proto == proto && p->mport == mport)
|
||||
@@ -570,12 +657,12 @@ ip_portmap_find(u8_t proto, u16_t mport)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct portmap_table *
|
||||
static struct ip_portmap_entry *
|
||||
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];
|
||||
struct ip_portmap_entry *p = &ip_portmap_table[i];
|
||||
if (!p->valid)
|
||||
return 0;
|
||||
if (p->proto == proto && p->dport == dport && p->daddr == daddr)
|
||||
@@ -584,11 +671,23 @@ ip_portmap_find_dest(u8_t proto, u16_t dport, u32_t daddr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8_t
|
||||
ip_portmap_get(u8_t proto, u16_t mport, u32_t *maddr, u32_t *daddr, u16_t *dport)
|
||||
{
|
||||
struct ip_portmap_entry *m = ip_portmap_find(proto, PP_HTONS(mport));
|
||||
if (!m)
|
||||
return 0;
|
||||
*maddr = m->maddr;
|
||||
*daddr = m->daddr;
|
||||
*dport = PP_NTOHS(m->dport);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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));
|
||||
struct ip_portmap_entry *last = &ip_portmap_table[ip_portmap_max - 1];
|
||||
struct ip_portmap_entry *m = ip_portmap_find(proto, PP_HTONS(mport));
|
||||
if (!m)
|
||||
return 0;
|
||||
for (; m != last; m++)
|
||||
@@ -652,9 +751,12 @@ void
|
||||
ip_napt_recv(struct pbuf *p, struct ip_hdr *iphdr)
|
||||
{
|
||||
#if IP_NAPT_PORTMAP
|
||||
struct portmap_table *m;
|
||||
struct ip_portmap_entry *m;
|
||||
#endif
|
||||
struct napt_table *t;
|
||||
struct ip_napt_entry *t;
|
||||
|
||||
if (ip_napt_max == 0) return;
|
||||
|
||||
#if LWIP_ICMP
|
||||
/* NAPT for ICMP Echo Request using identifier */
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_ICMP) {
|
||||
@@ -673,18 +775,19 @@ ip_napt_recv(struct pbuf *p, struct ip_hdr *iphdr)
|
||||
|
||||
#if LWIP_TCP
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_TCP) {
|
||||
uint32_t seqno, dest_seqno;
|
||||
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)));
|
||||
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)));
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("sport %"U16_F", dport: %"U16_F"\n",
|
||||
lwip_htons(tcphdr->src),
|
||||
lwip_htons(tcphdr->dest)));
|
||||
|
||||
#if IP_NAPT_PORTMAP
|
||||
m = ip_portmap_find(IP_PROTO_TCP, tcphdr->dest);
|
||||
@@ -698,23 +801,28 @@ ip_napt_recv(struct pbuf *p, struct ip_hdr *iphdr)
|
||||
}
|
||||
#endif
|
||||
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)
|
||||
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 (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;
|
||||
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;
|
||||
seqno = ntohl(tcphdr->seqno);
|
||||
dest_seqno = t->dest_seqno;
|
||||
if (seqno >= dest_seqno || WRAPPED_AROUND(seqno, dest_seqno)) {
|
||||
t->dest_seqno = seqno + (p->tot_len - IPH_HL(iphdr) * 4 - TCPH_HDRLEN_BYTES(tcphdr));
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
@@ -758,7 +866,7 @@ ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct
|
||||
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_add(IP_PROTO_ICMP, iphdr->src.addr, iecho->id, iphdr->dest.addr, iecho->id, 0);
|
||||
|
||||
ip_napt_modify_addr(iphdr, &iphdr->src, ip_2_ip4(&outp->ip_addr)->addr);
|
||||
}
|
||||
@@ -773,7 +881,7 @@ ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct
|
||||
u16_t mport;
|
||||
|
||||
#if IP_NAPT_PORTMAP
|
||||
struct portmap_table *m = ip_portmap_find_dest(IP_PROTO_TCP, tcphdr->src, iphdr->src.addr);
|
||||
struct ip_portmap_entry *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)
|
||||
@@ -787,24 +895,34 @@ ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct
|
||||
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)
|
||||
iphdr->dest.addr, tcphdr->dest, tcphdr->seqno);
|
||||
if (mport == 0) {
|
||||
#if LWIP_ICMP
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
#endif
|
||||
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);
|
||||
uint32_t seqno, src_seqno;
|
||||
struct ip_napt_entry *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);
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
#endif
|
||||
return ERR_RTE; /* Drop unknown TCP session */
|
||||
}
|
||||
mport = t->mport;
|
||||
if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
|
||||
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))
|
||||
if (t->fin1 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
|
||||
t->finack1 = 1; /* FIXME: Currently ignoring ACK seq... */
|
||||
if (TCPH_FLAGS(tcphdr) & TCP_RST)
|
||||
if (TCPH_FLAGS(tcphdr) & TCP_RST)
|
||||
t->rst = 1;
|
||||
seqno = ntohl(tcphdr->seqno);
|
||||
src_seqno = t->src_seqno;
|
||||
if (seqno >= t->src_seqno || WRAPPED_AROUND(seqno, src_seqno)) {
|
||||
t->src_seqno = seqno + (p->tot_len - IPH_HL(iphdr) * 4 - TCPH_HDRLEN_BYTES(tcphdr));
|
||||
}
|
||||
}
|
||||
|
||||
if (mport != tcphdr->src)
|
||||
@@ -822,7 +940,7 @@ ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct
|
||||
u16_t mport;
|
||||
|
||||
#if IP_NAPT_PORTMAP
|
||||
struct portmap_table *m = ip_portmap_find_dest(IP_PROTO_UDP, udphdr->src, iphdr->src.addr);
|
||||
struct ip_portmap_entry *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)
|
||||
@@ -836,11 +954,11 @@ ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct
|
||||
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);
|
||||
iphdr->dest.addr, udphdr->dest, 0);
|
||||
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);
|
||||
struct ip_napt_entry *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);
|
||||
@@ -860,6 +978,101 @@ ip_napt_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp, struct
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* IP_NAPT */
|
||||
#endif /* LWIP_IPV4 */
|
||||
#endif /* ESP_LWIP */
|
||||
|
||||
static void
|
||||
ip_napt_gc(uint32_t now, bool force)
|
||||
{
|
||||
u16_t i, next, oldest = NO_IDX;
|
||||
u32_t age = 0, oldest_age = 0;
|
||||
int checked = 0, evicted = 0, forced = 0;
|
||||
for (i = napt_list; i != NO_IDX; i = next) {
|
||||
struct ip_napt_entry *t = &ip_napt_table[i];
|
||||
checked++;
|
||||
next = t->next;
|
||||
age = now - t->last;
|
||||
if (age > oldest_age) {
|
||||
oldest = i;
|
||||
oldest_age = age;
|
||||
}
|
||||
#if LWIP_TCP
|
||||
if (t->proto == IP_PROTO_TCP) {
|
||||
if (age > IP_NAPT_TIMEOUT_MS_TCP_DISCON) {
|
||||
if ((t->finack1 || t->finack2 || !t->synack || t->rst) ||
|
||||
age > IP_NAPT_TIMEOUT_MS_TCP) {
|
||||
ip_napt_free(t);
|
||||
evicted++;
|
||||
if (force) break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
if (t->proto == IP_PROTO_UDP) {
|
||||
if (age > IP_NAPT_TIMEOUT_MS_UDP) {
|
||||
ip_napt_free(t);
|
||||
evicted++;
|
||||
if (force) break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
if (t->proto == IP_PROTO_ICMP) {
|
||||
if (age > IP_NAPT_TIMEOUT_MS_ICMP) {
|
||||
ip_napt_free(t);
|
||||
evicted++;
|
||||
if (force) break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (napt_free == NO_IDX && force && oldest != NO_IDX) {
|
||||
ip_napt_free(&ip_napt_table[oldest]);
|
||||
evicted++;
|
||||
forced++;
|
||||
STATS_INC(ip_napt.nr_forced_evictions);
|
||||
}
|
||||
LWIP_DEBUGF(NAPT_DEBUG, ("ip_napt_gc(%d): chk %d evict %d (forced %d), oldest %"U32_F"\n",
|
||||
force, checked, evicted, forced, oldest_age));
|
||||
}
|
||||
|
||||
static void
|
||||
ip_napt_maint(void)
|
||||
{
|
||||
static uint32_t s_last_now = 0;
|
||||
uint32_t now;
|
||||
if (napt_list == NO_IDX) return;
|
||||
now = sys_now();
|
||||
/* Check for timestamp wraparound (happens every ~49.7 days). */
|
||||
if (WRAPPED_AROUND(s_last_now, now)) {
|
||||
u16_t i;
|
||||
struct ip_napt_entry *t;
|
||||
for (i = napt_list; i != NO_IDX; i = t->next) {
|
||||
t = &ip_napt_table[i];
|
||||
/* It's a very simplistic way of dealing with it
|
||||
* but it's fine for our purposes. */
|
||||
t->last = now;
|
||||
}
|
||||
}
|
||||
ip_napt_gc(now, false /* make_room */);
|
||||
s_last_now = now;
|
||||
}
|
||||
|
||||
static void
|
||||
ip_napt_tmr(void *arg)
|
||||
{
|
||||
ip_napt_maint();
|
||||
sys_timeout(NAPT_TMR_INTERVAL, ip_napt_tmr, arg);
|
||||
}
|
||||
|
||||
#if LWIP_STATS
|
||||
void
|
||||
ip_napt_get_stats(struct stats_ip_napt *stats)
|
||||
{
|
||||
*stats = STATS_GET(ip_napt);
|
||||
}
|
||||
#endif /* LWIP_STATS */
|
||||
|
||||
#endif /* ESP_LWIP && LWIP_IPV4 && IP_NAPT */
|
||||
|
||||
@@ -139,6 +139,17 @@ stats_display_sys(struct stats_sys *sys)
|
||||
}
|
||||
#endif /* SYS_STATS */
|
||||
|
||||
#if IP_NAPT_STATS
|
||||
void stats_display_ip_napt(struct stats_ip_napt *napt)
|
||||
{
|
||||
LWIP_PLATFORM_DIAG(("\nIP NAPT\n\t"));
|
||||
LWIP_PLATFORM_DIAG(("nr_active_tcp: %"STAT_COUNTER_F"\n\t", napt->nr_active_tcp));
|
||||
LWIP_PLATFORM_DIAG(("nr_active_udp: %"STAT_COUNTER_F"\n\t", napt->nr_active_udp));
|
||||
LWIP_PLATFORM_DIAG(("nr_active_icmp: %"STAT_COUNTER_F"\n\t", napt->nr_active_icmp));
|
||||
LWIP_PLATFORM_DIAG(("nr_forced_evictions: %"STAT_COUNTER_F"\n\t", napt->nr_forced_evictions));
|
||||
}
|
||||
#endif /* IP_NAPT_STATS */
|
||||
|
||||
void
|
||||
stats_display(void)
|
||||
{
|
||||
@@ -162,6 +173,7 @@ stats_display(void)
|
||||
MEMP_STATS_DISPLAY(i);
|
||||
}
|
||||
SYS_STATS_DISPLAY();
|
||||
IP_NAPT_STATS_DISPLAY();
|
||||
}
|
||||
#endif /* LWIP_STATS_DISPLAY */
|
||||
|
||||
|
||||
@@ -60,16 +60,21 @@ extern "C" {
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/ip4.h"
|
||||
|
||||
|
||||
#ifndef NAPT_TMR_INTERVAL
|
||||
#define NAPT_TMR_INTERVAL 2000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
* 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);
|
||||
|
||||
|
||||
@@ -60,13 +60,24 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Timeouts in sec for the various protocol types */
|
||||
#ifndef IP_NAPT_TIMEOUT_MS_TCP
|
||||
#define IP_NAPT_TIMEOUT_MS_TCP (30*60*1000)
|
||||
#define IP_NAPT_TIMEOUT_MS_TCP_DISCON (20*1000)
|
||||
#endif
|
||||
#ifndef IP_NAPT_TIMEOUT_MS_TCP_DISCON
|
||||
#define IP_NAPT_TIMEOUT_MS_TCP_DISCON (TCP_MSL)
|
||||
#endif
|
||||
#ifndef IP_NAPT_TIMEOUT_MS_UDP
|
||||
#define IP_NAPT_TIMEOUT_MS_UDP (2*1000)
|
||||
#endif
|
||||
#ifndef IP_NAPT_TIMEOUT_MS_ICMP
|
||||
#define IP_NAPT_TIMEOUT_MS_ICMP (2*1000)
|
||||
|
||||
#endif
|
||||
#ifndef IP_NAPT_PORT_RANGE_START
|
||||
#define IP_NAPT_PORT_RANGE_START 49152
|
||||
#endif
|
||||
#ifndef IP_NAPT_PORT_RANGE_END
|
||||
#define IP_NAPT_PORT_RANGE_END 61439
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@@ -82,13 +93,12 @@ ip_napt_enable(u32_t addr, int enable);
|
||||
/**
|
||||
* Enable/Disable NAPT for a specified interface.
|
||||
*
|
||||
* @param number netif number of the interface
|
||||
* @param number number of the interface
|
||||
* @param enable non-zero to enable NAPT, or 0 to disable.
|
||||
*/
|
||||
void
|
||||
ip_napt_enable_no(u8_t number, int enable);
|
||||
|
||||
|
||||
/**
|
||||
* Enable/Disable NAPT for a specified interface.
|
||||
*
|
||||
@@ -117,16 +127,31 @@ ip_napt_enable_netif(struct netif *netif, int enable);
|
||||
u8_t
|
||||
ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport);
|
||||
|
||||
u8_t
|
||||
ip_portmap_get(u8_t proto, u16_t mport, u32_t *maddr, u32_t *daddr, u16_t *dport);
|
||||
|
||||
|
||||
/**
|
||||
* Unregister port mapping on the external interface to internal interface.
|
||||
*
|
||||
* @param proto target protocol
|
||||
* @param mport mapped port
|
||||
* @param mport mapped port on the external interface, in host byte order.
|
||||
*/
|
||||
u8_t
|
||||
ip_portmap_remove(u8_t proto, u16_t mport);
|
||||
|
||||
|
||||
|
||||
#if LWIP_STATS
|
||||
/**
|
||||
* Get statistics.
|
||||
*
|
||||
* @param stats struct to receive current stats
|
||||
*/
|
||||
void
|
||||
ip_napt_get_stats(struct stats_ip_napt *stats);
|
||||
#endif
|
||||
|
||||
#endif /* IP_NAPT */
|
||||
#endif /* IP_FORWARD */
|
||||
#endif /* ESP_LWIP */
|
||||
|
||||
@@ -2305,6 +2305,14 @@
|
||||
#define MIB2_STATS 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IP_NAPT_STATS==1: Stats for IP NAPT.
|
||||
*/
|
||||
#if !defined IP_NAPT_STATS || defined __DOXYGEN__
|
||||
#define IP_NAPT_STATS (IP_NAPT)
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define LINK_STATS 0
|
||||
@@ -2325,6 +2333,7 @@
|
||||
#define MLD6_STATS 0
|
||||
#define ND6_STATS 0
|
||||
#define MIB2_STATS 0
|
||||
#define IP_NAPT_STATS 0
|
||||
|
||||
#endif /* LWIP_STATS */
|
||||
/**
|
||||
|
||||
@@ -228,6 +228,18 @@ struct stats_mib2_netif_ctrs {
|
||||
u32_t ifouterrors;
|
||||
};
|
||||
|
||||
#if ESP_LWIP && IP_NAPT_STATS
|
||||
/**
|
||||
* IP NAPT stats
|
||||
*/
|
||||
struct stats_ip_napt {
|
||||
STAT_COUNTER nr_active_tcp;
|
||||
STAT_COUNTER nr_active_udp;
|
||||
STAT_COUNTER nr_active_icmp;
|
||||
STAT_COUNTER nr_forced_evictions;
|
||||
};
|
||||
#endif /* ESP_LWIP && IP_NAPT */
|
||||
|
||||
/** lwIP stats container */
|
||||
struct stats_ {
|
||||
#if LINK_STATS
|
||||
@@ -298,6 +310,11 @@ struct stats_ {
|
||||
/** SNMP MIB2 */
|
||||
struct stats_mib2 mib2;
|
||||
#endif
|
||||
#if ESP_LWIP && IP_NAPT_STATS
|
||||
/** IP NAPT */
|
||||
struct stats_ip_napt ip_napt;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/** Global variable containing lwIP internal statistics. Add this to your debugger's watchlist. */
|
||||
@@ -467,6 +484,19 @@ void stats_init(void);
|
||||
#define MIB2_STATS_INC(x)
|
||||
#endif
|
||||
|
||||
#if IP_NAPT_STATS
|
||||
#define IP_NAPT_STATS_INC(x) STATS_INC(x)
|
||||
#else
|
||||
#define IP_NAPT_STATS_INC(x)
|
||||
#endif
|
||||
|
||||
#if LWIP_STATS_DISPLAY && IP_NAPT_STATS
|
||||
void stats_display_ip_napt(struct stats_ip_napt *napt);
|
||||
#define IP_NAPT_STATS_DISPLAY() stats_display_ip_napt(&lwip_stats.ip_napt)
|
||||
#else
|
||||
#define IP_NAPT_STATS_DISPLAY()
|
||||
#endif
|
||||
|
||||
/* Display of statistics */
|
||||
#if LWIP_STATS_DISPLAY
|
||||
void stats_display(void);
|
||||
|
||||
Reference in New Issue
Block a user