55 #if LWIP_IPV6 && LWIP_IPV6_REASS   
   61 #ifndef IP_REASS_CHECK_OVERLAP 
   62 #define IP_REASS_CHECK_OVERLAP 1 
   69 #ifndef IP_REASS_FREE_OLDEST 
   70 #define IP_REASS_FREE_OLDEST 1 
   73 #if IPV6_FRAG_COPYHEADER 
   74 #define IPV6_FRAG_REQROOM ((s16_t)(sizeof(struct ip6_reass_helper) - IP6_FRAG_HLEN)) 
   77 #define IP_REASS_FLAG_LASTFRAG 0x01 
   86 #ifdef PACK_STRUCT_USE_INCLUDES 
   87 #  include "arch/bpstruct.h" 
   90 struct ip6_reass_helper {
 
   96 #ifdef PACK_STRUCT_USE_INCLUDES 
   97 #  include "arch/epstruct.h" 
  101 static struct ip6_reassdata *reassdatagrams;
 
  102 static u16_t ip6_reass_pbufcount;
 
  105 static void ip6_reass_free_complete_datagram(
struct ip6_reassdata *ipr);
 
  106 #if IP_REASS_FREE_OLDEST 
  107 static void ip6_reass_remove_oldest_datagram(
struct ip6_reassdata *ipr, 
int pbufs_needed);
 
  113   struct ip6_reassdata *r, *tmp;
 
  115 #if !IPV6_FRAG_COPYHEADER 
  116   LWIP_ASSERT(
"sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
 
  133       ip6_reass_free_complete_datagram(tmp);
 
  146 ip6_reass_free_complete_datagram(
struct ip6_reassdata *ipr)
 
  148   struct ip6_reassdata *prev;
 
  149   u16_t pbufs_freed = 0;
 
  152   struct ip6_reass_helper *iprh;
 
  155   iprh = (
struct ip6_reass_helper *)ipr->p->payload;
 
  156   if (iprh->start == 0) {
 
  160     ipr->p = iprh->next_pbuf;
 
  164       LWIP_ASSERT(
"ip6_reass_free: moving p->payload to ip6 header failed\n", 0);
 
  170     LWIP_ASSERT(
"pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
 
  181     iprh = (
struct ip6_reass_helper *)p->
payload;
 
  186     LWIP_ASSERT(
"pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
 
  192   if (ipr == reassdatagrams) {
 
  193     reassdatagrams = ipr->next;
 
  195     prev = reassdatagrams;
 
  196     while (prev != 
NULL) {
 
  197       if (prev->next == ipr) {
 
  203       prev->next = ipr->next;
 
  209   LWIP_ASSERT(
"ip_reass_pbufcount >= clen", ip6_reass_pbufcount >= pbufs_freed);
 
  210   ip6_reass_pbufcount -= pbufs_freed;
 
  213 #if IP_REASS_FREE_OLDEST 
  223 ip6_reass_remove_oldest_datagram(
struct ip6_reassdata *ipr, 
int pbufs_needed)
 
  225   struct ip6_reassdata *r, *oldest;
 
  230     r = oldest = reassdatagrams;
 
  233         if (r->timer <= oldest->timer) {
 
  244     if (oldest != 
NULL) {
 
  245       ip6_reass_free_complete_datagram(oldest);
 
  259 ip6_reass(
struct pbuf *p)
 
  261   struct ip6_reassdata *ipr, *ipr_prev;
 
  262   struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=
NULL;
 
  282   offset = 
lwip_ntohs(frag_hdr->_fragment_offset);
 
  287   len = 
lwip_ntohs(ip6_current_header()->_plen);
 
  293   for (ipr = reassdatagrams, ipr_prev = 
NULL; ipr != 
NULL; ipr = ipr->next) {
 
  297     if ((frag_hdr->_identification == ipr->identification) &&
 
  298         ip6_addr_cmp(ip6_current_src_addr(), &(IPV6_FRAG_HDRREF(ipr->iphdr)->src)) &&
 
  299         ip6_addr_cmp(ip6_current_dest_addr(), &(IPV6_FRAG_HDRREF(ipr->iphdr)->dest))) {
 
  308     ipr = (
struct ip6_reassdata *)
memp_malloc(MEMP_IP6_REASSDATA);
 
  310 #if IP_REASS_FREE_OLDEST 
  312       ip6_reass_remove_oldest_datagram(ipr, clen);
 
  313       ipr = (
struct ip6_reassdata *)
memp_malloc(MEMP_IP6_REASSDATA);
 
  316         for (ipr_prev = reassdatagrams; ipr_prev != 
NULL; ipr_prev = ipr_prev->next) {
 
  317           if (ipr_prev->next == ipr) {
 
  330     memset(ipr, 0, 
sizeof(
struct ip6_reassdata));
 
  334     ipr->next = reassdatagrams;
 
  335     reassdatagrams = ipr;
 
  340 #if IPV6_FRAG_COPYHEADER 
  344     ipr->iphdr = 
ip_data.current_ip6_header;
 
  348     ipr->identification = frag_hdr->_identification;
 
  351     ipr->nexth = frag_hdr->_nexth;
 
  356 #if IP_REASS_FREE_OLDEST 
  357     ip6_reass_remove_oldest_datagram(ipr, clen);
 
  360       for (ipr_prev = reassdatagrams; ipr_prev != 
NULL; ipr_prev = ipr_prev->next) {
 
  361         if (ipr_prev->next == ipr) {
 
  377 #if IPV6_FRAG_COPYHEADER 
  378   if (IPV6_FRAG_REQROOM > 0) {
 
  383     LWIP_ASSERT(
"no room for struct ip6_reass_helper", hdrerr == 0);
 
  386   LWIP_ASSERT(
"sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
 
  389   iprh = (
struct ip6_reass_helper *)p->
payload;
 
  390   iprh->next_pbuf = 
NULL;
 
  397   for (q = ipr->p; q != 
NULL;) {
 
  398     iprh_tmp = (
struct ip6_reass_helper*)q->
payload;
 
  399     if (iprh->start < iprh_tmp->start) {
 
  400 #if IP_REASS_CHECK_OVERLAP 
  401       if (iprh->end > iprh_tmp->start) {
 
  407       if (iprh_prev != 
NULL) {
 
  408         if (iprh->start < iprh_prev->end) {
 
  418       if (iprh_prev != 
NULL) {
 
  420         iprh_prev->next_pbuf = p;
 
  426     } 
else if (iprh->start == iprh_tmp->start) {
 
  430 #if IP_REASS_CHECK_OVERLAP 
  431     } 
else if (iprh->start < iprh_tmp->end) {
 
  439       if (iprh_prev != 
NULL) {
 
  440         if (iprh_prev->end != iprh_tmp->start) {
 
  447     q = iprh_tmp->next_pbuf;
 
  448     iprh_prev = iprh_tmp;
 
  453     if (iprh_prev != 
NULL) {
 
  456 #if IP_REASS_CHECK_OVERLAP 
  457       LWIP_ASSERT(
"check fragments don't overlap", iprh_prev->end <= iprh->start);
 
  459       iprh_prev->next_pbuf = p;
 
  460       if (iprh_prev->end != iprh->start) {
 
  464 #if IP_REASS_CHECK_OVERLAP 
  465       LWIP_ASSERT(
"no previous fragment, this must be the first fragment!",
 
  475   ip6_reass_pbufcount += clen;
 
  478   if (iprh->start == 0) {
 
  479 #if IPV6_FRAG_COPYHEADER 
  480     if (iprh->next_pbuf != 
NULL) {
 
  485     ipr->iphdr = 
ip_data.current_ip6_header;
 
  491     ipr->datagram_len = iprh->end;
 
  495   iprh_tmp = (
struct ip6_reass_helper*)ipr->p->payload;
 
  496   if (iprh_tmp->start != 0) {
 
  499   if (ipr->datagram_len == 0) {
 
  506   while ((q != 
NULL) && valid) {
 
  507     iprh = (
struct ip6_reass_helper*)q->
payload;
 
  508     if (iprh_prev->end != iprh->start) {
 
  521     iprh = (
struct ip6_reass_helper*) ipr->p->payload;
 
  522     while (iprh != 
NULL) {
 
  523       struct pbuf* next_pbuf = iprh->next_pbuf;
 
  524       if (next_pbuf != 
NULL) {
 
  526         iprh_tmp = (
struct ip6_reass_helper*)next_pbuf->
payload;
 
  530 #if IPV6_FRAG_COPYHEADER 
  531         if (IPV6_FRAG_REQROOM > 0) {
 
  535           LWIP_ASSERT(
"no room for struct ip6_reass_helper", hdrerr == 0);
 
  547 #if IPV6_FRAG_COPYHEADER 
  548     if (IPV6_FRAG_REQROOM > 0) {
 
  552       LWIP_ASSERT(
"no room for struct ip6_reass_helper", hdrerr == 0);
 
  557     iphdr_ptr = ipr->iphdr;
 
  561     ipr->datagram_len += (
u16_t)(((
u8_t*)ipr->p->payload - (
u8_t*)iphdr_ptr)
 
  566     iphdr_ptr->_plen = 
lwip_htons(ipr->datagram_len);
 
  574     frag_hdr->_nexth = ipr->nexth;
 
  575     frag_hdr->reserved = 0;
 
  576     frag_hdr->_fragment_offset = 0;
 
  577     frag_hdr->_identification = 0;
 
  580     if (reassdatagrams == ipr) {
 
  582       reassdatagrams = ipr->next;
 
  586       ipr_prev->next = ipr->next;
 
  596       LWIP_ASSERT(
"ip6_reass: moving p->payload to ip6 header failed\n", 0);
 
  614 #if LWIP_IPV6 && LWIP_IPV6_FRAG 
  616 #if !LWIP_NETIF_TX_SINGLE_PBUF 
  618 static struct pbuf_custom_ref*
 
  619 ip6_frag_alloc_pbuf_custom_ref(
void)
 
  621   return (
struct pbuf_custom_ref*)
memp_malloc(MEMP_FRAG_PBUF);
 
  626 ip6_frag_free_pbuf_custom_ref(
struct pbuf_custom_ref* p)
 
  635 ip6_frag_free_pbuf_custom(
struct pbuf *p)
 
  637   struct pbuf_custom_ref *pcr = (
struct pbuf_custom_ref*)p;
 
  640   if (pcr->original != 
NULL) {
 
  643   ip6_frag_free_pbuf_custom_ref(pcr);
 
  660 ip6_frag(
struct pbuf *p, 
struct netif *
netif, 
const ip6_addr_t *dest)
 
  662   struct ip6_hdr *original_ip6hdr;
 
  666 #if !LWIP_NETIF_TX_SINGLE_PBUF 
  667   struct pbuf *newpbuf;
 
  668   u16_t newpbuflen = 0;
 
  671   static u32_t identification;
 
  675   u16_t fragment_offset = 0;
 
  683   mtu = nd6_get_destination_mtu(dest, 
netif);
 
  691     last = (left <= nfb);
 
  694     cop = last ? left : nfb;
 
  696 #if LWIP_NETIF_TX_SINGLE_PBUF 
  698     if (rambuf == 
NULL) {
 
  722     if (rambuf == 
NULL) {
 
  738     while (left_to_copy) {
 
  739       struct pbuf_custom_ref *pcr;
 
  740       newpbuflen = (left_to_copy < p->
len) ? left_to_copy : p->
len;
 
  746       pcr = ip6_frag_alloc_pbuf_custom_ref();
 
  754       if (newpbuf == 
NULL) {
 
  755         ip6_frag_free_pbuf_custom_ref(pcr);
 
  762       pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom;
 
  768       left_to_copy -= newpbuflen;
 
  777     frag_hdr->_nexth = original_ip6hdr->_nexth;
 
  778     frag_hdr->reserved = 0;
 
  780     frag_hdr->_identification = 
lwip_htonl(identification);
 
  800     fragment_offset += cop;