66 #ifndef IP_REASS_CHECK_OVERLAP 67 #define IP_REASS_CHECK_OVERLAP 1 74 #ifndef IP_REASS_FREE_OLDEST 75 #define IP_REASS_FREE_OLDEST 1 78 #define IP_REASS_FLAG_LASTFRAG 0x01 88 #ifdef PACK_STRUCT_USE_INCLUDES 89 # include "arch/bpstruct.h" 92 struct ip_reass_helper {
98 #ifdef PACK_STRUCT_USE_INCLUDES 99 # include "arch/epstruct.h" 102 #define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ 103 (ip_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \ 104 ip_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ 105 IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 108 static struct ip_reassdata *reassdatagrams;
109 static u16_t ip_reass_pbufcount;
112 static void ip_reass_dequeue_datagram(
struct ip_reassdata *ipr,
struct ip_reassdata *prev)
ICACHE_FLASH_ATTR;
113 static int ip_reass_free_complete_datagram(
struct ip_reassdata *ipr,
struct ip_reassdata *prev)
ICACHE_FLASH_ATTR;
124 struct ip_reassdata *r, *prev =
NULL;
137 struct ip_reassdata *tmp;
143 ip_reass_free_complete_datagram(tmp, prev);
158 ip_reass_free_complete_datagram(
struct ip_reassdata *ipr,
struct ip_reassdata *prev)
160 u16_t pbufs_freed = 0;
163 struct ip_reass_helper *iprh;
167 LWIP_ASSERT(
"prev->next == ipr", prev->next == ipr);
172 iprh = (
struct ip_reass_helper *)ipr->p->payload;
173 if (iprh->start == 0) {
177 ipr->p = iprh->next_pbuf;
182 LWIP_ASSERT(
"pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
193 iprh = (
struct ip_reass_helper *)p->
payload;
198 LWIP_ASSERT(
"pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
203 ip_reass_dequeue_datagram(ipr, prev);
204 LWIP_ASSERT(
"ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed);
205 ip_reass_pbufcount -= pbufs_freed;
210 #if IP_REASS_FREE_OLDEST 221 ip_reass_remove_oldest_datagram(
struct ip_hdr *fraghdr,
int pbufs_needed)
226 struct ip_reassdata *r, *oldest, *prev;
227 int pbufs_freed = 0, pbufs_freed_current;
238 if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) {
241 if (oldest ==
NULL) {
243 }
else if (r->timer <= oldest->timer) {
248 if (r->next !=
NULL) {
253 if (oldest !=
NULL) {
254 pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev);
255 pbufs_freed += pbufs_freed_current;
257 }
while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1));
269 ip_reass_enqueue_new_datagram(
struct ip_hdr *fraghdr,
int clen)
271 struct ip_reassdata* ipr;
273 ipr = (
struct ip_reassdata *)
memp_malloc(MEMP_REASSDATA);
275 #if IP_REASS_FREE_OLDEST 276 if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) {
277 ipr = (
struct ip_reassdata *)
memp_malloc(MEMP_REASSDATA);
287 os_memset(ipr, 0,
sizeof(
struct ip_reassdata));
291 ipr->next = reassdatagrams;
292 reassdatagrams = ipr;
304 ip_reass_dequeue_datagram(
struct ip_reassdata *ipr,
struct ip_reassdata *prev)
308 if (reassdatagrams == ipr) {
310 reassdatagrams = ipr->next;
314 prev->next = ipr->next;
331 ip_reass_chain_frag_into_datagram_and_validate(
struct ip_reassdata *ipr,
struct pbuf *new_p)
333 struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=
NULL;
347 LWIP_ASSERT(
"sizeof(struct ip_reass_helper) <= IP_HLEN",
348 sizeof(
struct ip_reass_helper) <=
IP_HLEN);
349 iprh = (
struct ip_reass_helper*)new_p->
payload;
350 iprh->next_pbuf =
NULL;
351 iprh->start = offset;
352 iprh->end = offset + len;
356 for (q = ipr->p; q !=
NULL;) {
357 iprh_tmp = (
struct ip_reass_helper*)q->
payload;
358 if (iprh->start < iprh_tmp->start) {
361 if (iprh_prev !=
NULL) {
363 #if IP_REASS_CHECK_OVERLAP 364 if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) {
369 iprh_prev->next_pbuf = new_p;
375 }
else if(iprh->start == iprh_tmp->start) {
378 #if IP_REASS_CHECK_OVERLAP 379 }
else if(iprh->start < iprh_tmp->end) {
385 if (iprh_prev !=
NULL) {
386 if (iprh_prev->end != iprh_tmp->start) {
393 q = iprh_tmp->next_pbuf;
394 iprh_prev = iprh_tmp;
399 if (iprh_prev !=
NULL) {
402 #if IP_REASS_CHECK_OVERLAP 403 LWIP_ASSERT(
"check fragments don't overlap", iprh_prev->end <= iprh->start);
405 iprh_prev->next_pbuf = new_p;
406 if (iprh_prev->end != iprh->start) {
410 #if IP_REASS_CHECK_OVERLAP 411 LWIP_ASSERT(
"no previous fragment, this must be the first fragment!",
421 if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) {
426 if (((
struct ip_reass_helper*)ipr->p->payload)->start != 0) {
433 iprh = (
struct ip_reass_helper*)q->
payload;
434 if (iprh_prev->end != iprh->start) {
446 ((
struct ip_reass_helper*)ipr->p->payload) != iprh);
448 iprh->next_pbuf ==
NULL);
449 LWIP_ASSERT(
"validate_datagram:datagram end!=datagram len",
450 iprh->end == ipr->datagram_len);
461 #if IP_REASS_CHECK_OVERLAP 476 ip_reass(
struct pbuf *p)
480 struct ip_reassdata *ipr;
481 struct ip_reass_helper *iprh;
484 struct ip_reassdata *ipr_prev =
NULL;
503 #if IP_REASS_FREE_OLDEST 504 if (!ip_reass_remove_oldest_datagram(fraghdr, clen) ||
520 for (ipr = reassdatagrams; ipr !=
NULL; ipr = ipr->next) {
524 if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
535 ipr = ip_reass_enqueue_new_datagram(fraghdr, clen);
552 ip_reass_pbufcount += clen;
559 ipr->flags |= IP_REASS_FLAG_LASTFRAG;
560 ipr->datagram_len = offset + len;
562 (
"ip_reass: last fragment seen, total len %"S16_F"\n",
567 if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) {
573 r = ((
struct ip_reass_helper*)ipr->p->payload)->next_pbuf;
576 fraghdr = (
struct ip_hdr*)(ipr->p->payload);
588 iprh = (
struct ip_reass_helper*)r->
payload;
596 ip_reass_dequeue_datagram(ipr, ipr_prev);
617 #if IP_FRAG_USES_STATIC_BUF 621 #if !LWIP_NETIF_TX_SINGLE_PBUF 624 ip_frag_alloc_pbuf_custom_ref(
void)
626 return (
struct pbuf_custom_ref*)
memp_malloc(MEMP_FRAG_PBUF);
631 ip_frag_free_pbuf_custom_ref(
struct pbuf_custom_ref* p)
640 ipfrag_free_pbuf_custom(
struct pbuf *p)
642 struct pbuf_custom_ref *pcr = (
struct pbuf_custom_ref*)p;
645 if (pcr->original !=
NULL) {
648 ip_frag_free_pbuf_custom_ref(pcr);
670 #if IP_FRAG_USES_STATIC_BUF 673 #if !LWIP_NETIF_TX_SINGLE_PBUF 674 struct pbuf *newpbuf;
676 struct ip_hdr *original_iphdr;
686 #if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF 687 u16_t newpbuflen = 0;
692 #if IP_FRAG_USES_STATIC_BUF 698 if (rambuf ==
NULL) {
710 iphdr = original_iphdr;
723 last = (left <= mtu -
IP_HLEN);
726 tmp = omf | (IP_OFFMASK & (ofo));
732 cop = last ? left : nfb * 8;
734 #if IP_FRAG_USES_STATIC_BUF 737 #if LWIP_NETIF_TX_SINGLE_PBUF 739 if (rambuf ==
NULL) {
760 if (rambuf ==
NULL) {
773 while (left_to_copy) {
774 struct pbuf_custom_ref *pcr;
775 newpbuflen = (left_to_copy < p->
len) ? left_to_copy : p->
len;
781 pcr = ip_frag_alloc_pbuf_custom_ref();
788 if (newpbuf ==
NULL) {
789 ip_frag_free_pbuf_custom_ref(pcr);
795 pcr->pc.custom_free_function = ipfrag_free_pbuf_custom;
801 left_to_copy -= newpbuflen;
816 #if IP_FRAG_USES_STATIC_BUF 827 if (header !=
NULL) {
829 netif->
output(netif, header, dest);
842 netif->
output(netif, rambuf, dest);
857 #if IP_FRAG_USES_STATIC_BUF
#define snmp_inc_ipreasmreqds()
void memp_free(memp_t type, void *mem) ICACHE_FLASH_ATTR
#define SMEMCPY(dst, src, len)
u16_t inet_chksum(void *dataptr, u16_t len) ICACHE_FLASH_ATTR
#define ICACHE_FLASH_ATTR
void * memp_malloc(memp_t type) ICACHE_FLASH_ATTR
void pbuf_cat(struct pbuf *head, struct pbuf *tail) ICACHE_FLASH_ATTR
#define snmp_inc_ipfragoks()
#define IP_REASS_MAX_PBUFS
#define LWIP_MEM_ALIGN_SIZE(size)
#define LWIP_DEBUGF(debug, message)
#define IPH_OFFSET_SET(hdr, off)
#define snmp_inc_ipreasmfails()
#define PACK_STRUCT_STRUCT
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
#define snmp_inc_ipfragcreates()
void pbuf_chain(struct pbuf *head, struct pbuf *tail) ICACHE_FLASH_ATTR
#define IPH_CHKSUM_SET(hdr, chksum)
u8_t pbuf_free(struct pbuf *p) ICACHE_FLASH_ATTR
void pbuf_ref(struct pbuf *p) ICACHE_FLASH_ATTR
#define PACK_STRUCT_BEGIN
u8_t pbuf_header(struct pbuf *p, s16_t header_size) ICACHE_FLASH_ATTR
#define LWIP_ASSERT(message, assertion)
#define IPFRAG_STATS_INC(x)
u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset) ICACHE_FLASH_ATTR
#define IPH_LEN_SET(hdr, len)
void pbuf_realloc(struct pbuf *p, u16_t size) ICACHE_FLASH_ATTR
#define LWIP_MEM_ALIGN(addr)
struct pbuf * pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type) ICACHE_FLASH_ATTR
u8_t pbuf_clen(struct pbuf *p) ICACHE_FLASH_ATTR
#define PACK_STRUCT_FIELD(x)