亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ip_frag.c

?? STM32F107_ETH_LwIP_V1.0.0.rar
?? C
?? 第 1 頁 / 共 2 頁
字號:
      iprh_prev->next_pbuf = new_p;
      if (iprh_prev->end != iprh->start) {
        valid = 0;
      }
    } else {
#if IP_REASS_CHECK_OVERLAP
      LWIP_ASSERT("no previous fragment, this must be the first fragment!",
        ipr->p == NULL);
#endif /* IP_REASS_CHECK_OVERLAP */
      /* this is the first fragment we ever received for this ip datagram */
      ipr->p = new_p;
    }
  }

  /* At this point, the validation part begins: */
  /* If we already received the last fragment */
  if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) {
    /* and had no wholes so far */
    if (valid) {
      /* then check if the rest of the fragments is here */
      /* Check if the queue starts with the first datagram */
      if (((struct ip_reass_helper*)ipr->p->payload)->start != 0) {
        valid = 0;
      } else {
        /* and check that there are no wholes after this datagram */
        iprh_prev = iprh;
        q = iprh->next_pbuf;
        while (q != NULL) {
          iprh = (struct ip_reass_helper*)q->payload;
          if (iprh_prev->end != iprh->start) {
            valid = 0;
            break;
          }
          iprh_prev = iprh;
          q = iprh->next_pbuf;
        }
        /* if still valid, all fragments are received
         * (because to the MF==0 already arrived */
        if (valid) {
          LWIP_ASSERT("sanity check", ipr->p != NULL);
          LWIP_ASSERT("sanity check",
            ((struct ip_reass_helper*)ipr->p->payload) != iprh);
          LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
            iprh->next_pbuf == NULL);
          LWIP_ASSERT("validate_datagram:datagram end!=datagram len",
            iprh->end == ipr->datagram_len);
        }
      }
    }
    /* If valid is 0 here, there are some fragments missing in the middle
     * (since MF == 0 has already arrived). Such datagrams simply time out if
     * no more fragments are received... */
    return valid;
  }
  /* If we come here, not all fragments were received, yet! */
  return 0; /* not yet valid! */
#if IP_REASS_CHECK_OVERLAP
freepbuf:
  ip_reass_pbufcount -= pbuf_clen(new_p);
  pbuf_free(new_p);
  return 0;
#endif /* IP_REASS_CHECK_OVERLAP */
}

/**
 * Reassembles incoming IP fragments into an IP datagram.
 *
 * @param p points to a pbuf chain of the fragment
 * @return NULL if reassembly is incomplete, ? otherwise
 */
struct pbuf *
ip_reass(struct pbuf *p)
{
  struct pbuf *r;
  struct ip_hdr *fraghdr;
  struct ip_reassdata *ipr;
  struct ip_reass_helper *iprh;
  u16_t offset, len;
  u8_t clen;
  struct ip_reassdata *ipr_prev = NULL;

  IPFRAG_STATS_INC(ip_frag.recv);
  snmp_inc_ipreasmreqds();

  fraghdr = (struct ip_hdr*)p->payload;

  if ((IPH_HL(fraghdr) * 4) != IP_HLEN) {
    LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n"));
    IPFRAG_STATS_INC(ip_frag.err);
    goto nullreturn;
  }

  offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
  len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;

  /* Check if we are allowed to enqueue more datagrams. */
  clen = pbuf_clen(p);
  if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
#if IP_REASS_FREE_OLDEST
    if (!ip_reass_remove_oldest_datagram(fraghdr, clen) ||
        ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
#endif /* IP_REASS_FREE_OLDEST */
    {
      /* No datagram could be freed and still too many pbufs enqueued */
      LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n",
        ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
      IPFRAG_STATS_INC(ip_frag.memerr);
      /* @todo: send ICMP time exceeded here? */
      /* drop this pbuf */
      goto nullreturn;
    }
  }

  /* Look for the datagram the fragment belongs to in the current datagram queue,
   * remembering the previous in the queue for later dequeueing. */
  for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) {
    /* Check if the incoming fragment matches the one currently present
       in the reassembly buffer. If so, we proceed with copying the
       fragment into the buffer. */
    if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n",
        ntohs(IPH_ID(fraghdr))));
      IPFRAG_STATS_INC(ip_frag.cachehit);
      break;
    }
    ipr_prev = ipr;
  }

  if (ipr == NULL) {
  /* Enqueue a new datagram into the datagram queue */
    ipr = ip_reass_enqueue_new_datagram(fraghdr, clen);
    /* Bail if unable to enqueue */
    if(ipr == NULL) {
      goto nullreturn;
    }
  } else {
    if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && 
      ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
      /* ipr->iphdr is not the header from the first fragment, but fraghdr is
       * -> copy fraghdr into ipr->iphdr since we want to have the header
       * of the first fragment (for ICMP time exceeded and later, for copying
       * all options, if supported)*/
      SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN);
    }
  }
  /* Track the current number of pbufs current 'in-flight', in order to limit 
  the number of fragments that may be enqueued at any one time */
  ip_reass_pbufcount += clen;

  /* At this point, we have either created a new entry or pointing 
   * to an existing one */

  /* check for 'no more fragments', and update queue entry*/
  if ((ntohs(IPH_OFFSET(fraghdr)) & IP_MF) == 0) {
    ipr->flags |= IP_REASS_FLAG_LASTFRAG;
    ipr->datagram_len = offset + len;
    LWIP_DEBUGF(IP_REASS_DEBUG,
     ("ip_reass: last fragment seen, total len %"S16_F"\n",
      ipr->datagram_len));
  }
  /* find the right place to insert this pbuf */
  /* @todo: trim pbufs if fragments are overlapping */
  if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) {
    /* the totally last fragment (flag more fragments = 0) was received at least
     * once AND all fragments are received */
    ipr->datagram_len += IP_HLEN;

    /* save the second pbuf before copying the header over the pointer */
    r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf;

    /* copy the original ip header back to the first pbuf */
    fraghdr = (struct ip_hdr*)(ipr->p->payload);
    SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN);
    IPH_LEN_SET(fraghdr, htons(ipr->datagram_len));
    IPH_OFFSET_SET(fraghdr, 0);
    IPH_CHKSUM_SET(fraghdr, 0);
    /* @todo: do we need to set calculate the correct checksum? */
    IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));

    p = ipr->p;

    /* chain together the pbufs contained within the reass_data list. */
    while(r != NULL) {
      iprh = (struct ip_reass_helper*)r->payload;

      /* hide the ip header for every succeding fragment */
      pbuf_header(r, -IP_HLEN);
      pbuf_cat(p, r);
      r = iprh->next_pbuf;
    }
    /* release the sources allocate for the fragment queue entry */
    ip_reass_dequeue_datagram(ipr, ipr_prev);

    /* and adjust the number of pbufs currently queued for reassembly. */
    ip_reass_pbufcount -= pbuf_clen(p);

    /* Return the pbuf chain */
    return p;
  }
  /* the datagram is not (yet?) reassembled completely */
  LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount));
  return NULL;

nullreturn:
  LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n"));
  IPFRAG_STATS_INC(ip_frag.drop);
  pbuf_free(p);
  return NULL;
}
#endif /* IP_REASSEMBLY */

#if IP_FRAG
#if IP_FRAG_USES_STATIC_BUF
static u8_t buf[LWIP_MEM_ALIGN_SIZE(IP_FRAG_MAX_MTU + MEM_ALIGNMENT - 1)];
#endif /* IP_FRAG_USES_STATIC_BUF */

/**
 * Fragment an IP datagram if too large for the netif.
 *
 * Chop the datagram in MTU sized chunks and send them in order
 * by using a fixed size static memory buffer (PBUF_REF) or
 * point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF).
 *
 * @param p ip packet to send
 * @param netif the netif on which to send
 * @param dest destination ip address to which to send
 *
 * @return ERR_OK if sent successfully, err_t otherwise
 */
err_t 
ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest)
{
  struct pbuf *rambuf;
#if IP_FRAG_USES_STATIC_BUF
  struct pbuf *header;
#else
  struct pbuf *newpbuf;
  struct ip_hdr *original_iphdr;
#endif
  struct ip_hdr *iphdr;
  u16_t nfb;
  u16_t left, cop;
  u16_t mtu = netif->mtu;
  u16_t ofo, omf;
  u16_t last;
  u16_t poff = IP_HLEN;
  u16_t tmp;
#if !IP_FRAG_USES_STATIC_BUF
  u16_t newpbuflen = 0;
  u16_t left_to_copy;
#endif

  /* Get a RAM based MTU sized pbuf */
#if IP_FRAG_USES_STATIC_BUF
  /* When using a static buffer, we use a PBUF_REF, which we will
   * use to reference the packet (without link header).
   * Layer and length is irrelevant.
   */
  rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF);
  if (rambuf == NULL) {
    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n"));
    return ERR_MEM;
  }
  rambuf->tot_len = rambuf->len = mtu;
  rambuf->payload = LWIP_MEM_ALIGN((void *)buf);

  /* Copy the IP header in it */
  iphdr = rambuf->payload;
  SMEMCPY(iphdr, p->payload, IP_HLEN);
#else /* IP_FRAG_USES_STATIC_BUF */
  original_iphdr = p->payload;
  iphdr = original_iphdr;
#endif /* IP_FRAG_USES_STATIC_BUF */

  /* Save original offset */
  tmp = ntohs(IPH_OFFSET(iphdr));
  ofo = tmp & IP_OFFMASK;
  omf = tmp & IP_MF;

  left = p->tot_len - IP_HLEN;

  nfb = (mtu - IP_HLEN) / 8;

  while (left) {
    last = (left <= mtu - IP_HLEN);

    /* Set new offset and MF flag */
    tmp = omf | (IP_OFFMASK & (ofo));
    if (!last)
      tmp = tmp | IP_MF;

    /* Fill this fragment */
    cop = last ? left : nfb * 8;

#if IP_FRAG_USES_STATIC_BUF
    poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff);
#else /* IP_FRAG_USES_STATIC_BUF */
    /* When not using a static buffer, create a chain of pbufs.
     * The first will be a PBUF_RAM holding the link and IP header.
     * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
     * but limited to the size of an mtu.
     */
    rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM);
    if (rambuf == NULL) {
      return ERR_MEM;
    }
    LWIP_ASSERT("this needs a pbuf in one piece!",
                (p->len >= (IP_HLEN)));
    SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
    iphdr = rambuf->payload;

    /* Can just adjust p directly for needed offset. */
    p->payload = (u8_t *)p->payload + poff;
    p->len -= poff;

    left_to_copy = cop;
    while (left_to_copy) {
      newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len;
      /* Is this pbuf already empty? */
      if (!newpbuflen) {
        p = p->next;
        continue;
      }
      newpbuf = pbuf_alloc(PBUF_RAW, 0, PBUF_REF);
      if (newpbuf == NULL) {
        pbuf_free(rambuf);
        return ERR_MEM;
      }
      /* Mirror this pbuf, although we might not need all of it. */
      newpbuf->payload = p->payload;
      newpbuf->len = newpbuf->tot_len = newpbuflen;
      /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain
       * so that it is removed when pbuf_dechain is later called on rambuf.
       */
      pbuf_cat(rambuf, newpbuf);
      left_to_copy -= newpbuflen;
      if (left_to_copy)
        p = p->next;
    }
    poff = newpbuflen;
#endif /* IP_FRAG_USES_STATIC_BUF */

    /* Correct header */
    IPH_OFFSET_SET(iphdr, htons(tmp));
    IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));
    IPH_CHKSUM_SET(iphdr, 0);
    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));

#if IP_FRAG_USES_STATIC_BUF
    if (last)
      pbuf_realloc(rambuf, left + IP_HLEN);

    /* This part is ugly: we alloc a RAM based pbuf for 
     * the link level header for each chunk and then 
     * free it.A PBUF_ROM style pbuf for which pbuf_header
     * worked would make things simpler.
     */
    header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM);
    if (header != NULL) {
      pbuf_chain(header, rambuf);
      netif->output(netif, header, dest);
      IPFRAG_STATS_INC(ip_frag.xmit);
      snmp_inc_ipfragcreates();
      pbuf_free(header);
    } else {
      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc() for header failed\n"));
      pbuf_free(rambuf);
      return ERR_MEM;
    }
#else /* IP_FRAG_USES_STATIC_BUF */
    /* No need for separate header pbuf - we allowed room for it in rambuf
     * when allocated.
     */
    netif->output(netif, rambuf, dest);
    IPFRAG_STATS_INC(ip_frag.xmit);

    /* Unfortunately we can't reuse rambuf - the hardware may still be
     * using the buffer. Instead we free it (and the ensuing chain) and
     * recreate it next time round the loop. If we're lucky the hardware
     * will have already sent the packet, the free will really free, and
     * there will be zero memory penalty.
     */
    
    pbuf_free(rambuf);
#endif /* IP_FRAG_USES_STATIC_BUF */
    left -= cop;
    ofo += nfb;
  }
#if IP_FRAG_USES_STATIC_BUF
  pbuf_free(rambuf);
#endif /* IP_FRAG_USES_STATIC_BUF */
  snmp_inc_ipfragoks();
  return ERR_OK;
}
#endif /* IP_FRAG */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久精品免费观看| 国产精品国产三级国产有无不卡| 夜夜夜精品看看| 在线观看91视频| 亚洲少妇中出一区| 欧美午夜精品一区| 日韩av一二三| 久久综合久久综合久久综合| 国产成人免费视频| 国产精品无人区| 日本韩国一区二区三区视频| 亚洲综合网站在线观看| 91精品中文字幕一区二区三区| 久久99精品久久久久久动态图| 久久久久久97三级| 日本久久电影网| 久久成人久久鬼色| 国产精品国产自产拍高清av王其 | 亚洲欧洲av一区二区三区久久| 99热国产精品| 午夜久久福利影院| 精品成人一区二区| 成人97人人超碰人人99| 午夜一区二区三区视频| 欧美大片一区二区三区| 成人福利视频网站| 日韩国产在线一| 国产嫩草影院久久久久| 欧美亚洲综合在线| 国产一区二区三区黄视频 | 一本到三区不卡视频| 午夜激情久久久| 国产偷国产偷精品高清尤物| 欧美三级电影在线看| 国产精品1区2区3区| 亚洲国产乱码最新视频| 国产拍欧美日韩视频二区| 日本精品视频一区二区| 国产精品一区久久久久| 亚洲午夜精品17c| 久久精品在线免费观看| 欧美精品一级二级三级| 97久久超碰国产精品| 精品一二三四区| 亚洲亚洲人成综合网络| 国产欧美日韩另类视频免费观看| 欧美男人的天堂一二区| 99久久777色| 国产精品一区在线| 日本特黄久久久高潮| 一区二区三区欧美激情| 欧美激情一区在线| 精品免费视频一区二区| 欧美剧情片在线观看| 91在线云播放| 国产传媒日韩欧美成人| 麻豆国产精品视频| 亚洲va韩国va欧美va精品| 亚洲欧美福利一区二区| 国产精品女同一区二区三区| 精品国产第一区二区三区观看体验| 欧美主播一区二区三区美女| 91丨国产丨九色丨pron| 福利一区二区在线| 国产精品原创巨作av| 裸体一区二区三区| 亚洲成a人片在线观看中文| 亚洲免费av在线| 国产精品国产自产拍高清av王其| 国产亚洲欧洲一区高清在线观看| 日韩三级在线观看| 日韩一二三区不卡| 51午夜精品国产| 欧美日韩国产另类不卡| 欧美日韩在线播放三区四区| 欧美在线|欧美| 在线观看视频一区二区| 欧美三级乱人伦电影| 欧美日韩激情一区二区三区| 欧美日韩一区中文字幕| 3d动漫精品啪啪一区二区竹菊| 欧美亚洲综合另类| 欧美日韩精品一区二区| 欧美精品久久99久久在免费线 | 99精品热视频| 色综合婷婷久久| 欧美性色综合网| 欧美精品777| 日韩欧美国产综合| 久久亚区不卡日本| 国产精品毛片大码女人| 亚洲视频一区二区在线观看| 一区av在线播放| 欧美aⅴ一区二区三区视频| 久久成人免费电影| 高清不卡在线观看| 在线欧美小视频| 欧美日韩在线播放| 26uuu欧美| 最新日韩在线视频| 亚洲高清视频在线| 久久99精品久久久久久动态图| 国产精品1024| 91黄色免费网站| 欧美一区二区精品在线| 久久精品夜夜夜夜久久| 一区二区三区影院| 美女视频黄频大全不卡视频在线播放| 国产一区二区中文字幕| 91视视频在线观看入口直接观看www | 亚洲国产精品精华液网站| 免费看欧美美女黄的网站| 国产精品一区久久久久| 91极品美女在线| 精品99999| 悠悠色在线精品| 精品一区二区三区欧美| 91在线小视频| 日韩一级免费观看| 亚洲精品中文在线| 激情国产一区二区| 91国偷自产一区二区三区成为亚洲经典| 日韩一区二区在线观看视频播放| 亚洲国产精品v| 天天综合色天天综合色h| 成人免费观看av| 91精品国产色综合久久久蜜香臀| 国产精品毛片大码女人| 久久精品国产999大香线蕉| 91美女福利视频| 亚洲精品一区二区三区精华液| 亚洲激情综合网| 国产成人午夜视频| 欧美一卡2卡三卡4卡5免费| 亚洲人快播电影网| 国产一区二区三区综合| 欧美电影在哪看比较好| 亚洲天堂a在线| 国产在线视频不卡二| 欧美麻豆精品久久久久久| 亚洲私人黄色宅男| 国产成+人+日韩+欧美+亚洲| 日韩午夜在线观看视频| 亚洲第一激情av| 91麻豆自制传媒国产之光| 欧美—级在线免费片| 韩国毛片一区二区三区| 日韩视频永久免费| 五月婷婷欧美视频| 91久久精品一区二区| 中文字幕一区二区5566日韩| 国产一区二区剧情av在线| 日韩亚洲国产中文字幕欧美| 午夜欧美视频在线观看| 欧洲视频一区二区| 亚洲精品欧美激情| 91麻豆免费观看| 中文字幕亚洲欧美在线不卡| 成人自拍视频在线观看| 久久人人超碰精品| 国产高清精品久久久久| 久久久蜜臀国产一区二区| 精品无人码麻豆乱码1区2区| 日韩亚洲欧美在线观看| 麻豆91精品91久久久的内涵| 日韩精品一区二区三区蜜臀| 蓝色福利精品导航| 日韩免费高清视频| 九九在线精品视频| 久久久综合精品| 国产不卡免费视频| 国产精品久久久久9999吃药| 成人av午夜电影| 亚洲婷婷综合久久一本伊一区| 99国产精品一区| 亚洲最大色网站| 欧美日韩一区二区在线观看| 亚洲成av人片在www色猫咪| 欧美日韩激情一区二区| 日日摸夜夜添夜夜添精品视频| 欧美人妇做爰xxxⅹ性高电影| 人禽交欧美网站| 欧美精品一区二区不卡| 国产精品亚洲а∨天堂免在线| 国产人久久人人人人爽| av成人免费在线观看| 亚洲激情av在线| 欧美精品123区| 国产剧情一区二区| 国产精品国产精品国产专区不蜜 | 国产精品888| 亚洲婷婷在线视频| 欧美亚洲动漫另类| 蜜臀久久99精品久久久久宅男| 精品少妇一区二区三区免费观看 | 日韩精品一区二区三区视频播放| 精品亚洲国内自在自线福利| 日本一区二区免费在线| 91亚洲精品久久久蜜桃网站| 首页国产欧美久久|