45 |
#include "lwip/ip_frag.h" |
#include "lwip/ip_frag.h" |
46 |
#include "lwip/netif.h" |
#include "lwip/netif.h" |
47 |
|
|
48 |
|
#include "lwip/stats.h" |
49 |
|
|
50 |
|
|
51 |
/* |
/* |
75 |
} |
} |
76 |
|
|
77 |
#define IP_REASS_BUFSIZE 5760 |
#define IP_REASS_BUFSIZE 5760 |
78 |
#define IP_REASS_MAXAGE 10 |
#define IP_REASS_MAXAGE 30 |
79 |
#define IP_REASS_TMO 100 |
#define IP_REASS_TMO 1000 |
80 |
|
|
81 |
static u8_t ip_reassbuf[IP_HLEN + IP_REASS_BUFSIZE]; |
static u8_t ip_reassbuf[IP_HLEN + IP_REASS_BUFSIZE]; |
82 |
static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8)]; |
static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8)]; |
93 |
static void |
static void |
94 |
ip_reass_timer(void *arg) |
ip_reass_timer(void *arg) |
95 |
{ |
{ |
96 |
if(ip_reasstmr) |
if(ip_reasstmr > 1) { |
97 |
ip_reasstmr--; |
ip_reasstmr--; |
98 |
sys_timeout(IP_REASS_TMO, (sys_timeout_handler) ip_reass_timer, NULL); |
sys_timeout(IP_REASS_TMO, (sys_timeout_handler) ip_reass_timer, NULL); |
99 |
|
} else if(ip_reasstmr == 1) |
100 |
|
ip_reasstmr = 0; |
101 |
} |
} |
102 |
|
|
103 |
struct pbuf * |
struct pbuf * |
108 |
u16_t offset, len; |
u16_t offset, len; |
109 |
u16_t i; |
u16_t i; |
110 |
|
|
111 |
|
#ifdef IP_STATS |
112 |
|
++lwip_stats.ip_frag.recv; |
113 |
|
#endif /* IP_STATS */ |
114 |
|
|
115 |
iphdr = (struct ip_hdr *) ip_reassbuf; |
iphdr = (struct ip_hdr *) ip_reassbuf; |
116 |
fraghdr = (struct ip_hdr *) p->payload; |
fraghdr = (struct ip_hdr *) p->payload; |
117 |
/* If ip_reasstmr is zero, no packet is present in the buffer, so we |
/* If ip_reasstmr is zero, no packet is present in the buffer, so we |
134 |
ip_addr_cmp(&iphdr->dest, &fraghdr->dest) && |
ip_addr_cmp(&iphdr->dest, &fraghdr->dest) && |
135 |
IPH_ID(iphdr) == IPH_ID(fraghdr)) { |
IPH_ID(iphdr) == IPH_ID(fraghdr)) { |
136 |
DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching old packet\n")); |
DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching old packet\n")); |
137 |
|
#ifdef IP_STATS |
138 |
|
++lwip_stats.ip_frag.cachehit; |
139 |
|
#endif /* IP_STATS */ |
140 |
/* Find out the offset in the reassembly buffer where we should |
/* Find out the offset in the reassembly buffer where we should |
141 |
copy the fragment. */ |
copy the fragment. */ |
142 |
len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; |
len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; |
148 |
DEBUGF(IP_REASS_DEBUG, |
DEBUGF(IP_REASS_DEBUG, |
149 |
("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset, |
("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset, |
150 |
offset + len, IP_REASS_BUFSIZE)); |
offset + len, IP_REASS_BUFSIZE)); |
151 |
|
sys_timeout_remove((sys_timeout_handler) ip_reass_timer, NULL); |
152 |
ip_reasstmr = 0; |
ip_reasstmr = 0; |
153 |
goto nullreturn; |
goto nullreturn; |
154 |
} |
} |
236 |
/* If we have come this far, we have a full packet in the |
/* If we have come this far, we have a full packet in the |
237 |
buffer, so we allocate a pbuf and copy the packet into it. We |
buffer, so we allocate a pbuf and copy the packet into it. We |
238 |
also reset the timer. */ |
also reset the timer. */ |
239 |
|
sys_timeout_remove((sys_timeout_handler) ip_reass_timer, NULL); |
240 |
ip_reasstmr = 0; |
ip_reasstmr = 0; |
241 |
pbuf_free(p); |
pbuf_free(p); |
242 |
p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL); |
p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL); |
254 |
q->len > ip_reasslen - i ? ip_reasslen - i : q->len); |
q->len > ip_reasslen - i ? ip_reasslen - i : q->len); |
255 |
i += q->len; |
i += q->len; |
256 |
} |
} |
257 |
|
#ifdef IP_STATS |
258 |
|
++lwip_stats.ip_frag.fw; |
259 |
|
#endif /* IP_STATS */ |
260 |
|
} else { |
261 |
|
#ifdef IP_STATS |
262 |
|
++lwip_stats.ip_frag.memerr; |
263 |
|
#endif /* IP_STATS */ |
264 |
} |
} |
265 |
DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p)); |
DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p)); |
266 |
return p; |
return p; |
268 |
} |
} |
269 |
|
|
270 |
nullreturn: |
nullreturn: |
271 |
|
#ifdef IP_STATS |
272 |
|
++lwip_stats.ip_frag.drop; |
273 |
|
#endif /* IP_STATS */ |
274 |
pbuf_free(p); |
pbuf_free(p); |
275 |
return NULL; |
return NULL; |
276 |
} |
} |
346 |
header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM); |
header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM); |
347 |
pbuf_chain(header, rambuf); |
pbuf_chain(header, rambuf); |
348 |
netif->output(netif, header, dest); |
netif->output(netif, header, dest); |
349 |
|
#ifdef IP_STATS |
350 |
|
++lwip_stats.ip_frag.xmit; |
351 |
|
#endif /* IP_STATS */ |
352 |
pbuf_dechain(header); |
pbuf_dechain(header); |
353 |
pbuf_free(header); |
pbuf_free(header); |
354 |
|
|