⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fragment.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
    ip = (Ip *)buf->ip_pkt;    packoff = (ip->frag_off & IP_FRAGOFF) << 3;    /*-----------------------------------------------------------------*/    /* Fail if this fragment's offset is not expected.                 */    /*-----------------------------------------------------------------*/    if (offset != packoff)      return FALSE;    /*-----------------------------------------------------------------*/    /* Get fragment data length. If not last, trim to 8-byte multiple. */    /*-----------------------------------------------------------------*/    dlen = buf->length;    if (buf->next)      dlen &= ~7;    /*-----------------------------------------------------------------*/    /* Add this fragment's IP data to total offset count.              */    /*-----------------------------------------------------------------*/    offset += dlen;    /*-----------------------------------------------------------------*/    /* Advance to next buffer and break if end of queue.               */    /*-----------------------------------------------------------------*/    buf = buf->next;  } while (buf);  /*-------------------------------------------------------------------*/  /* Return FALSE if MF flag set in last fragment received.            */  /*-------------------------------------------------------------------*/  if (ip->frag_off & IP_MF)    return FALSE;  /*-------------------------------------------------------------------*/  /* Get pointers to first fragment buffer and IP packet.              */  /*-------------------------------------------------------------------*/  fbuf = queue->head;  ip = (Ip *)fbuf->ip_pkt;  /*-------------------------------------------------------------------*/  /* Get large buffer for fragment reassembly or free fragment queue.  */  /*-------------------------------------------------------------------*/  hlen = IP_HLEN(ip);  buf = tcpGetBuf(NIMHLEN + hlen + offset);  if (buf == NULL)  {    free_queue(fbuf);    NetTimerStop(&queue->timer);    queue->state = IPFF_FREE;    return FALSE;  }  /*-------------------------------------------------------------------*/  /* Copy entire IP header from first fragment.                        */  /*-------------------------------------------------------------------*/  memcpy(buf->ip_pkt, ip, hlen);  /*-------------------------------------------------------------------*/  /* Initialize data length and pointer to recontructed IP packet.     */  /*-------------------------------------------------------------------*/  dst = buf->ip_data = buf->ip_pkt + hlen;  dlen = fbuf->length & ~7;  /*-------------------------------------------------------------------*/  /* Convert buffer length to length of region starting at ip_data.    */  /*-------------------------------------------------------------------*/  fbuf->length -= (fbuf->app_len + fbuf->app_len2);  /*-------------------------------------------------------------------*/  /* Copy IP data from first fragment.                                 */  /*-------------------------------------------------------------------*/  copy_ip_data(dst, fbuf, dlen);  dst += dlen;  /*-------------------------------------------------------------------*/  /* Copy data from remaining fragments.                               */  /*-------------------------------------------------------------------*/  for (;;)  {    NetBuf *tmp;    /*-----------------------------------------------------------------*/    /* Free head of fragment queue and advance to next queued buffer.  */    /*-----------------------------------------------------------------*/    tmp = fbuf;    fbuf = fbuf->next;    tcpRetBuf(&tmp);    /*-----------------------------------------------------------------*/    /* Break on reaching end of queue.                                 */    /*-----------------------------------------------------------------*/    if (fbuf == NULL)      break;    /*-----------------------------------------------------------------*/    /* Get fragment data length. If not last, trim to 8-byte multiple. */    /*-----------------------------------------------------------------*/    dlen = fbuf->length;    if (fbuf->next)      dlen &= ~7;    /*-----------------------------------------------------------------*/    /* Convert length of first region and copy IP data.                */    /*-----------------------------------------------------------------*/    hlen = IP_HLEN(fbuf->ip_pkt);    fbuf->length -= (fbuf->app_len + fbuf->app_len2);    copy_ip_data(dst, fbuf, dlen);    dst += dlen;  }  /*-------------------------------------------------------------------*/  /* Fix the large packet header.                                      */  /*-------------------------------------------------------------------*/  Net.Ip = (Ip *)buf->ip_pkt;  Net.Ip->length = dst - buf->ip_pkt;  Net.Ip->frag_off = 0;  /*-------------------------------------------------------------------*/  /* Release fragment queue.                                           */  /*-------------------------------------------------------------------*/  NetTimerStop(&queue->timer);  queue->state = IPFF_FREE;  /*-------------------------------------------------------------------*/  /* Initialize buffer length and use re-assembled buffer.             */  /*-------------------------------------------------------------------*/  buf->length = dst - (ui8 *)buf->ip_data;  RxBuf = buf;  return TRUE;}/***********************************************************************//* copy_frag_hdr: copy IP header and options for a fragment            *//*                                                                     *//*      Inputs: ipto = pointer to buffer containing fragment           *//*              ipfrom = pointer to original buffer                    *//*              offindg = offset from original fragment                *//*                                                                     *//*     Returns: header length in bytes                                 *//*                                                                     *//***********************************************************************/static int copy_frag_hdr(Ip *ipto, const Ip *ipfrom, int offindg){  int ito, ifrom;  int opt_size;  /*-------------------------------------------------------------------*/  /* If first fragment, copy all options and return header size.       */  /*-------------------------------------------------------------------*/  if (offindg == 0)  {    memcpy(ipto, ipfrom, IP_HLEN(ipfrom));    return IP_HLEN(ipfrom);  }  /*-------------------------------------------------------------------*/  /* Else start with fixed header from first fragment (no options).    */  /*-------------------------------------------------------------------*/  memcpy(ipto, ipfrom, IPMHLEN);  /*-------------------------------------------------------------------*/  /* Only options with COPY bit set are copied to remaining fragments. */  /*-------------------------------------------------------------------*/  opt_size = IP_HLEN(ipfrom) - IPMHLEN;  ifrom = ito = 0;  while (ifrom < opt_size)  {    ui8 otype, olen;    /*-----------------------------------------------------------------*/    /* Read option type and tentative length from source datagram.     */    /*-----------------------------------------------------------------*/    otype = ipfrom->options[ifrom];    olen = ipfrom->options[ifrom + 1];    /*-----------------------------------------------------------------*/    /* If copy bit is set, copy using variable length field.           */    /*-----------------------------------------------------------------*/    if (otype & IPO_COPY)    {      memcpy(&ipto->options[ito], &ipfrom->options[ifrom], olen);      ito += olen;    }    /*-----------------------------------------------------------------*/    /* Nop and "end of option list" tokens are copied with length 1.   */    /*-----------------------------------------------------------------*/    else if ((otype == IPO_NOP) || (otype == IPO_EOOP))    {      ipto->options[ito++] = otype;      olen = 1;    }    /*-----------------------------------------------------------------*/    /* Finished processing this option, advance to next.               */    /*-----------------------------------------------------------------*/    ifrom += olen;    /*-----------------------------------------------------------------*/    /* Exit loop if "end of list" token is found.                      */    /*-----------------------------------------------------------------*/    if (otype == IPO_EOOP)      break;  }  /*-------------------------------------------------------------------*/  /* Pad to a multiple of 4 bytes using nop options.                   */  /*-------------------------------------------------------------------*/  while (ito & 3)    ipto->options[ito++] = IPO_NOP;  /*-------------------------------------------------------------------*/  /* Return header length (option list size plus fixed header size).   */  /*-------------------------------------------------------------------*/  return ito + IPMHLEN;}/***********************************************************************//*  frag_timeo: Process IP fragment timeout                            *//*                                                                     *//*       Input: timer = pointer to expired fragment timer              *//*                                                                     *//***********************************************************************/static void frag_timeo(void *object){  IpFragQ *queue = object;  Ip *ip = (Ip *)queue->head->ip_pkt;  /*-------------------------------------------------------------------*/  /* If fragment queue was valid, release the pending buffers.         */  /*-------------------------------------------------------------------*/  if (queue->state == IPFF_VALID)  {    /*-----------------------------------------------------------------*/    /* Send ICMP time expired error message.                           */    /*-----------------------------------------------------------------*/    IcmpTimeEx(ICC_FTIMEX, queue->head, ip->src_ip, ip->dst_ip);    /*-----------------------------------------------------------------*/    /* Free queued fragment buffers.                                   */    /*-----------------------------------------------------------------*/    free_queue(queue->head);  }  /*-------------------------------------------------------------------*/  /* Declare expired entry to be free.                                 */  /*-------------------------------------------------------------------*/  queue->state = IPFF_FREE;}/***********************************************************************//* Global Function Definitions                                         *//***********************************************************************//***********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -