64 #ifndef LWIP_INLINE_IP_CHKSUM 65 #define LWIP_INLINE_IP_CHKSUM 1 67 #if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP 68 #define CHECKSUM_GEN_IP_INLINE 1 70 #define CHECKSUM_GEN_IP_INLINE 0 73 #if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) 74 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 81 #if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) 83 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \ 84 || (LWIP_IP_ACCEPT_UDP_PORT(port))) 85 #elif defined(LWIP_IP_ACCEPT_UDP_PORT) 87 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(dst_port)) 90 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) 94 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 207 #define NO_IDX ((u16_t)-1) 208 #define NT(x) ((x) == NO_IDX ? NULL : &ip_napt_table[x]) 210 u16_t napt_list = NO_IDX, napt_list_last = NO_IDX, napt_free = 0;
212 static struct napt_table *ip_napt_table;
213 struct portmap_table *ip_portmap_table;
215 int nr_active_napt_tcp = 0, nr_active_napt_udp = 0, nr_active_napt_icmp = 0;
216 uint16_t ip_napt_max = 0;
217 uint8_t ip_portmap_max = 0;
220 ip_napt_init(uint16_t max_nat, uint8_t max_portmap)
224 ip_napt_max = max_nat;
225 ip_portmap_max = max_portmap;
227 ip_napt_table = (
struct napt_table*)
os_zalloc(
sizeof(
struct napt_table[ip_napt_max]));
228 ip_portmap_table = (
struct portmap_table*)
os_zalloc(
sizeof(
struct portmap_table[ip_portmap_max]));
230 for (i = 0; i < ip_napt_max - 1; i++)
231 ip_napt_table[i].next = i + 1;
232 ip_napt_table[i].next = NO_IDX;
236 ip_napt_enable(
u32_t addr,
int enable)
241 netif->napt = !!enable;
248 ip_napt_enable_no(
u8_t number,
int enable)
252 if (netif->
num == number) {
253 netif->napt = !!enable;
259 void ICACHE_FLASH_ATTR checksumadjust(
unsigned char *chksum,
unsigned char *optr,
260 int olen,
unsigned char *nptr,
int nlen)
268 x=chksum[0]*256+chksum[1];
272 old=optr[0]*256+optr[1]; optr+=2;
274 if (x<=0) { x--; x&=0xffff; }
279 new=nptr[0]*256+nptr[1]; nptr+=2;
281 if (x & 0x10000) { x++; x&=0xffff; }
285 chksum[0]=x/256; chksum[1]=x & 0xff;
291 ip_napt_insert(
struct napt_table *t)
293 u16_t ti = t - ip_napt_table;
294 if (ti != napt_free) *((
int*)1)=1;
298 if (napt_list != NO_IDX)
299 NT(napt_list)->prev = ti;
301 if (napt_list_last == NO_IDX)
306 nr_active_napt_tcp++;
310 nr_active_napt_udp++;
314 nr_active_napt_icmp++;
320 ip_napt_free(
struct napt_table *t)
322 u16_t ti = t - ip_napt_table;
325 if (ti == napt_list_last)
326 napt_list_last = t->prev;
327 if (t->next != NO_IDX)
328 NT(t->next)->prev = t->prev;
329 if (t->prev != NO_IDX)
330 NT(t->prev)->next = t->next;
337 nr_active_napt_tcp--;
341 nr_active_napt_udp--;
345 nr_active_napt_icmp--;
351 ip_napt_find_port(
u8_t proto,
u16_t port)
354 for (i = napt_list; i != NO_IDX; i =
next) {
355 struct napt_table *t = &ip_napt_table[i];
357 if (t->proto == proto && t->mport == port)
364 ip_portmap_find(
u8_t proto,
u16_t mport);
367 tcp_listening(
u16_t port)
369 struct tcp_pcb_listen *t;
370 for (t = tcp_listen_pcbs.listen_pcbs; t; t = t->next)
371 if (t->local_port == port)
381 udp_listening(
u16_t port)
384 for (pcb = udp_pcbs; pcb; pcb = pcb->next)
385 if (pcb->local_port == port)
396 if (
PP_NTOHS(port) >= IP_NAPT_PORT_RANGE_START &&
PP_NTOHS(port) <= IP_NAPT_PORT_RANGE_END)
397 if (!ip_napt_find_port(proto, port) && !tcp_listening(port))
400 port =
PP_HTONS(IP_NAPT_PORT_RANGE_START +
401 os_random() % (IP_NAPT_PORT_RANGE_END - IP_NAPT_PORT_RANGE_START + 1));
402 if (ip_napt_find_port(proto, port))
421 struct napt_table *t;
423 for (i = napt_list; i != NO_IDX; i = next) {
428 (((t->finack1 && t->finack2 || !t->synack) &&
429 now - t->last > IP_NAPT_TIMEOUT_MS_TCP_DISCON) ||
430 now - t->last > IP_NAPT_TIMEOUT_MS_TCP)) {
436 if (t->proto ==
IP_PROTO_UDP && now - t->last > IP_NAPT_TIMEOUT_MS_UDP) {
442 if (t->proto ==
IP_PROTO_ICMP && now - t->last > IP_NAPT_TIMEOUT_MS_ICMP) {
447 if (dest == 0 && t->proto == proto && t->src == addr && t->sport == port) {
451 if (dest == 1 && t->proto == proto && t->dest == addr && t->dport == port
452 && t->mport == mport) {
464 struct napt_table *t = ip_napt_find(proto, src, sport, 0, 0);
492 t->fin1 = t->fin2 = t->finack1 = t->finack2 = t->synack = t->rst = 0;
507 for (i = 0; i < ip_portmap_max; i++) {
508 struct portmap_table *p = &ip_portmap_table[i];
509 if (p->valid && p->proto == proto && p->mport == mport) {
512 }
else if (!p->valid) {
529 for (i = 0; i < ip_portmap_max; i++) {
530 struct portmap_table *p = &ip_portmap_table[i];
533 if (p->proto == proto && p->mport == mport)
543 for (i = 0; i < ip_portmap_max; i++) {
544 struct portmap_table *p = &ip_portmap_table[i];
547 if (p->proto == proto && p->dport == dport && p->daddr == daddr)
555 ip_portmap_remove(
u8_t proto,
u16_t mport)
558 struct portmap_table *last = &ip_portmap_table[ip_portmap_max - 1];
559 struct portmap_table *m = ip_portmap_find(proto, mport);
562 for (; m != last; m++)
563 memcpy(m, m + 1,
sizeof(*m));
570 ip_napt_modify_port_tcp(
struct tcp_hdr *tcphdr,
u8_t dest,
u16_t newval)
573 checksumadjust((
char *)&tcphdr->chksum, (
char *)&tcphdr->dest, 2, (
char *)&newval, 2);
574 tcphdr->dest = newval;
576 checksumadjust((
char *)&tcphdr->chksum, (
char *)&tcphdr->src, 2, (
char *)&newval, 2);
577 tcphdr->src = newval;
583 ip_napt_modify_addr_tcp(
struct tcp_hdr *tcphdr,
ip_addr_p_t *oldval,
u32_t newval)
585 checksumadjust((
char *)&tcphdr->chksum, (
char *)&oldval->addr, 4, (
char *)&newval, 4);
591 ip_napt_modify_port_udp(
struct udp_hdr *udphdr,
u8_t dest,
u16_t newval)
594 checksumadjust((
char *)&udphdr->chksum, (
char *)&udphdr->dest, 2, (
char *)&newval, 2);
595 udphdr->dest = newval;
597 checksumadjust((
char *)&udphdr->chksum, (
char *)&udphdr->src, 2, (
char *)&newval, 2);
598 udphdr->src = newval;
603 ip_napt_modify_addr_udp(
struct udp_hdr *udphdr,
ip_addr_p_t *oldval,
u32_t newval)
605 checksumadjust((
char *)&udphdr->chksum, (
char *)&oldval->addr, 4, (
char *)&newval, 4);
612 checksumadjust((
char *)&
IPH_CHKSUM(iphdr), (
char *)&field->addr, 4, (
char *)&newval, 4);
613 field->addr = newval;
628 struct portmap_table *m;
629 struct napt_table *t;
636 t = ip_napt_find(
IP_PROTO_ICMP, iphdr->src.addr, iecho->id, iecho->id, 1);
639 ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
649 struct tcp_hdr *tcphdr = (
struct tcp_hdr *)((
u8_t *)p->
payload +
IPH_HL(iphdr) * 4);
653 if (m->dport != tcphdr->dest)
654 ip_napt_modify_port_tcp(tcphdr, 1, m->dport);
655 ip_napt_modify_addr_tcp(tcphdr, &iphdr->dest, m->daddr);
656 ip_napt_modify_addr(iphdr, &iphdr->dest, m->daddr);
659 t = ip_napt_find(
IP_PROTO_TCP, iphdr->src.addr, tcphdr->src, tcphdr->dest, 1);
663 if (t->sport != tcphdr->dest)
664 ip_napt_modify_port_tcp(tcphdr, 1, t->sport);
665 ip_napt_modify_addr_tcp(tcphdr, &iphdr->dest, t->src);
666 ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
668 if ((TCPH_FLAGS(tcphdr) & (TCP_SYN|TCP_ACK)) == (TCP_SYN|TCP_ACK))
670 if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
672 if (t->fin2 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
674 if (TCPH_FLAGS(tcphdr) & TCP_RST)
682 struct udp_hdr *udphdr = (
struct udp_hdr *)((
u8_t *)p->
payload +
IPH_HL(iphdr) * 4);
686 if (m->dport != udphdr->dest)
687 ip_napt_modify_port_udp(udphdr, 1, m->dport);
688 ip_napt_modify_addr_udp(udphdr, &iphdr->dest, m->daddr);
689 ip_napt_modify_addr(iphdr, &iphdr->dest, m->daddr);
692 t = ip_napt_find(
IP_PROTO_UDP, iphdr->src.addr, udphdr->src, udphdr->dest, 1);
696 if (t->sport != udphdr->dest)
697 ip_napt_modify_port_udp(udphdr, 1, t->sport);
698 ip_napt_modify_addr_udp(udphdr, &iphdr->dest, t->src);
699 ip_napt_modify_addr(iphdr, &iphdr->dest, t->src);
727 ip_napt_add(
IP_PROTO_ICMP, iphdr->src.addr, iecho->id, iphdr->dest.addr, iecho->id);
729 ip_napt_modify_addr(iphdr, &iphdr->src, outp->
ip_addr.addr);
737 struct tcp_hdr *tcphdr = (
struct tcp_hdr *)((
u8_t *)p->
payload +
IPH_HL(iphdr) * 4);
740 struct portmap_table *m = ip_portmap_find_dest(
IP_PROTO_TCP, tcphdr->src, iphdr->src.addr);
743 if (m->mport != tcphdr->src)
744 ip_napt_modify_port_tcp(tcphdr, 0, m->mport);
745 ip_napt_modify_addr_tcp(tcphdr, &iphdr->src, m->maddr);
746 ip_napt_modify_addr(iphdr, &iphdr->src, m->maddr);
749 if ((TCPH_FLAGS(tcphdr) & (TCP_SYN|TCP_ACK)) == TCP_SYN &&
752 mport = ip_napt_add(
IP_PROTO_TCP, iphdr->src.addr, tcphdr->src,
753 iphdr->dest.addr, tcphdr->dest);
755 struct napt_table *t = ip_napt_find(
IP_PROTO_TCP, iphdr->src.addr, tcphdr->src, 0, 0);
756 if (!t || t->dest != iphdr->dest.addr || t->dport != tcphdr->dest) {
763 if ((TCPH_FLAGS(tcphdr) & TCP_FIN))
765 if (t->fin1 && (TCPH_FLAGS(tcphdr) & TCP_ACK))
767 if (TCPH_FLAGS(tcphdr) & TCP_RST)
771 if (mport != tcphdr->src)
772 ip_napt_modify_port_tcp(tcphdr, 0, mport);
773 ip_napt_modify_addr_tcp(tcphdr, &iphdr->src, outp->
ip_addr.addr);
774 ip_napt_modify_addr(iphdr, &iphdr->src, outp->
ip_addr.addr);
781 struct udp_hdr *udphdr = (
struct udp_hdr *)((
u8_t *)p->
payload +
IPH_HL(iphdr) * 4);
784 struct portmap_table *m = ip_portmap_find_dest(
IP_PROTO_UDP, udphdr->src, iphdr->src.addr);
787 if (m->mport != udphdr->src)
788 ip_napt_modify_port_udp(udphdr, 0, m->mport);
789 ip_napt_modify_addr_udp(udphdr, &iphdr->src, m->maddr);
790 ip_napt_modify_addr(iphdr, &iphdr->src, m->maddr);
793 if (
PP_NTOHS(udphdr->src) >= 1024) {
795 mport = ip_napt_add(
IP_PROTO_UDP, iphdr->src.addr, udphdr->src,
796 iphdr->dest.addr, udphdr->dest);
798 struct napt_table *t = ip_napt_find(
IP_PROTO_UDP, iphdr->src.addr, udphdr->src, 0, 0);
799 if (!t || t->dest != iphdr->dest.addr || t->dport != udphdr->dest) {
808 if (mport != udphdr->src)
809 ip_napt_modify_port_udp(udphdr, 0, mport);
810 ip_napt_modify_addr_udp(udphdr, &iphdr->src, outp->
ip_addr.addr);
811 ip_napt_modify_addr(iphdr, &iphdr->src, outp->
ip_addr.addr);
874 if (ip_napt_forward(p, iphdr, inp, netif) !=
ERR_OK)
929 #if IP_ACCEPT_LINK_LAYER_ADDRESSING 938 if (
IPH_V(iphdr) != 4) {
949 iphdr_hlen =
IPH_HL(iphdr);
956 if ((iphdr_hlen > p->
len) || (iphdr_len > p->
tot_len)) {
957 if (iphdr_hlen > p->
len) {
959 (
"IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
960 iphdr_hlen, p->
len));
964 (
"IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
976 #if CHECKSUM_CHECK_IP 980 (
"Checksum (0x%"X16_F") failed, IP packet dropped.\n",
inet_chksum(iphdr, iphdr_hlen)));
993 ip_napt_recv(p, iphdr, netif);
1041 if ((netif->autoip !=
NULL) &&
1054 netif = netif->
next;
1057 netif = netif->
next;
1059 }
while(netif !=
NULL);
1062 #if IP_ACCEPT_LINK_LAYER_ADDRESSING 1072 if (netif ==
NULL) {
1075 struct udp_hdr *udphdr = (
struct udp_hdr *)((
u8_t *)iphdr + iphdr_hlen);
1077 ntohs(udphdr->dest)));
1078 if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
1088 #if IP_ACCEPT_LINK_LAYER_ADDRESSING 1106 if (netif ==
NULL) {
1113 ip_forward(p, iphdr, inp);
1147 #if IP_OPTIONS_ALLOWED == 0 1170 current_netif = inp;
1171 current_header = iphdr;
1175 if (raw_input(p, inp) == 0)
1225 current_netif =
NULL;
1226 current_header =
NULL;
1261 u8_t proto,
struct netif *netif)
1264 return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif,
NULL, 0);
1274 u8_t ttl,
u8_t tos,
u8_t proto,
struct netif *netif,
void *ip_options,
1280 #if CHECKSUM_GEN_IP_INLINE 1294 u16_t optlen_aligned = 0;
1296 #if CHECKSUM_GEN_IP_INLINE 1300 optlen_aligned = ((optlen + 3) & ~3);
1301 ip_hlen += optlen_aligned;
1310 if (optlen < optlen_aligned) {
1314 #if CHECKSUM_GEN_IP_INLINE 1315 for (i = 0; i < optlen_aligned/2; i++) {
1331 LWIP_ASSERT(
"check that first pbuf can hold struct ip_hdr",
1336 #if CHECKSUM_GEN_IP_INLINE 1342 #if CHECKSUM_GEN_IP_INLINE 1348 #if CHECKSUM_GEN_IP_INLINE 1349 chk_sum += iphdr->_v_hl_tos;
1352 #if CHECKSUM_GEN_IP_INLINE 1353 chk_sum += iphdr->_len;
1357 #if CHECKSUM_GEN_IP_INLINE 1358 chk_sum += iphdr->_id;
1369 #if CHECKSUM_GEN_IP_INLINE 1372 chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
1373 chk_sum = (chk_sum >> 16) + chk_sum;
1375 iphdr->_chksum = chk_sum;
1398 return netif_loop_output(netif, p, dest);
1402 netif_loop_output(netif, p, dest);
1409 return ip_frag(p, netif, dest);
1414 return netif->
output(netif, p, dest);
1438 struct netif *netif;
1451 return ip_output_if(p, src, dest, ttl, tos, proto, netif);
1454 #if LWIP_NETIF_HWADDRHINT 1477 struct netif *netif;
1491 netif->addr_hint = addr_hint;
1492 err =
ip_output_if(p, src, dest, ttl, tos, proto, netif);
1493 netif->addr_hint =
NULL;
1519 LWIP_DEBUGF(
IP_DEBUG, (
"| %5"U16_F
" |%"U16_F
"%"U16_F
"%"U16_F
"| %4"U16_F
" | (id, flags, offset)\n",
#define ip4_addr_get_u32(src_ipaddr)
#define ip4_addr3_16(ipaddr)
err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto, struct netif *netif)
struct netif * current_netif
u16_t inet_chksum(void *dataptr, u16_t len) ICACHE_FLASH_ATTR
#define ip_addr_netcmp(addr1, addr2, mask)
struct netif * netif_list
err_t ip_input(struct pbuf *p, struct netif *inp)
#define IPH_VHLTOS_SET(hdr, v, hl, tos)
#define snmp_inc_ipoutdiscards()
#define ICACHE_FLASH_ATTR
#define IPH_PROTO_SET(hdr, proto)
struct netif * eagle_lwip_getif(uint8 index)
#define snmp_inc_ipinreceives()
static u32_t sys_now(void) ICACHE_FLASH_ATTR
#define PBUF_FLAG_MCASTLOOP
#define snmp_inc_ipoutnoroutes()
#define snmp_inc_ipindelivers()
#define ip_addr_islinklocal(addr1)
#define LWIP_DEBUGF(debug, message)
#define ip_addr_cmp(addr1, addr2)
#define IPH_OFFSET_SET(hdr, off)
#define ip_addr_copy(dest, src)
#define LWIP_DBG_LEVEL_SERIOUS
#define snmp_inc_ipforwdatagrams()
unsigned long os_random(void)
struct netif * netif_default
#define snmp_inc_ipinhdrerrors()
#define ip_debug_print(p)
#define ip_addr_set_any(ipaddr)
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
struct netif * ip_route(ip_addr_t *dest)
#define LWIP_DBG_LEVEL_WARNING
#define ip4_addr4_16(ipaddr)
#define snmp_inc_ipindiscards()
#define ip_addr_isany(addr1)
#define snmp_inc_ipinunknownprotos()
err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto)
#define IPH_CHKSUM_SET(hdr, chksum)
u8_t pbuf_free(struct pbuf *p) ICACHE_FLASH_ATTR
ip_addr_t current_iphdr_src
#define IPH_TTL_SET(hdr, ttl)
#define snmp_inc_ipinaddrerrors()
ip_addr_t current_iphdr_dest
#define ip_addr_isbroadcast(ipaddr, netif)
u8_t pbuf_header(struct pbuf *p, s16_t header_size) ICACHE_FLASH_ATTR
#define ip4_addr1_16(ipaddr)
#define MEMCPY(dst, src, len)
#define IPH_ID_SET(hdr, id)
#define LWIP_ASSERT(message, assertion)
#define ip4_addr2_16(ipaddr)
#define netif_is_up(netif)
#define IPH_LEN_SET(hdr, len)
void pbuf_realloc(struct pbuf *p, u16_t size) ICACHE_FLASH_ATTR
#define ip_addr_ismulticast(addr1)
#define LWIP_MAKE_U16(a, b)
const struct ip_hdr * current_header
struct netif *ICACHE_FLASH_ATTR ip_router(ip_addr_t *dest, ip_addr_t *source)
#define snmp_inc_ipoutrequests()