搜索
bottom↓
回复: 1

嵌入式TCP/IP学习笔记-IP协议【恢复】

[复制链接]

出0入0汤圆

发表于 2008-12-19 10:30:17 | 显示全部楼层 |阅读模式
IP.C 

//=========================================================================== 

//  嵌入式 TCP/IP 协议栈 MSC51 专用版 

// IP.C 

//  作     者:南开大学-李章林 

//  注     释:李清林 

//  日     期:2008 年3 月 

//  声     明:英文注释由作者李章林添加,中文注释由■李清林添加。 

//        转载时请保留上述信息。 

//  成都理工学院/应用数字系/应用数字专业 

//=========================================================================== 

#include "..\GloblDef\GloblDef.h" 

#include "..\TCPIP\TCPIPmem.h" 

#include "..\TCPIP\IP.h" 

#include "..\TCPIP\icmp.h" 

#include "..\TCPIP\Netif.h" 

#include "..\TCPIP\TCP.h" 

 

//=========================================================================== 

/* Check sum calulation. data in buff, size, InSum is initial sum */ 

//  嵌入式 TCP/IP 协议栈 MSC51 专用版 

// IP.C 

//  作     者:南开大学-李章林 

//  注     释:李清林 

//  日     期:2008 年3 月 

//  声     明:英文注释由作者李章林添加,中文注释由■李清林添加。 

//        转载时请保留上述信息。 

//  成都理工学院/应用数字系/应用数字专业 

//--------------------------------------------------------------------------- 

//  程序名称:CheckSum=计算IP 首部检验和 

//  入口参数: 

//       *buff=缓冲区 

//     size=长度 

//     InSum=检验和初始值 

//  出口参数: 

//      检验和(检验和只覆盖IP 首部) 

//=========================================================================== 

WORD CheckSum(WORD DT_XDATA * buff,WORD size,DWORD InSum) REENTRANT_SIG 

{ 

  /* TO DO:in packet memory high part of short is in low memory. add all data in 

  form of 16 bits get a result of 32 bits, add high 16 bits to low 16 bits two 

  times.  get a 16 bits result then complement it. */ 

  DWORD cksum = InSum; 

  /* sum all word except the last odd byte(if size is a odd num) */ 

  WORD DT_XDATA * EndBuf = buff + size/2; 

 IP.C 

  while (buff < EndBuf) 

  { 

    /* net order is equeal as host order in mirochip, so no need to change */ 

    cksum += *(buff++); 

  } 

  /**((WORD xdata *)CheckSumInParam) = size; 

  *((WORD xdata *)(CheckSumInParam+2)) = buff; 

  asmAddCheckSum(); 

  cksum = CheckSumOutParm; 

  */ 

  /* if has last odd byte. use this byte as the high part of 16 bits, and add. */ 

  //  如果缓冲区长度=奇数 

  if ((size & 0x0001) != 0) 

    cksum += (*buff) & 0xff00; 

  cksum = (cksum>> 16) + (cksum & 0xffff); 

  cksum += (cksum>>16); 

  return (WORD)(~cksum); 

} 

 

//=========================================================================== 

/* IP input process */ 

//  作     者:南开大学-李章林 

//  注     释:李清林 

//  日     期:2008 年3 月 

//  声     明:英文注释由作者李章林添加,中文注释由■李清林添加。 

//        转载时请保留上述信息。 

//  成都理工学院/应用数字系/应用数字专业 

//--------------------------------------------------------------------------- 

//  程序名称:IPInput=IP 接收子程序 

//  功     能:接收到回显请求报文后发送 ICMP 回显应答报文 

//  入口参数: 

//       *MemHead=缓存控制块指针 

//  出口参数: 

//      无 

//=========================================================================== 

void IPInput(struct SMemHead DT_XDATA *MemHead) REENTRANT_MUL 

{ 

  struct SIPHead DT_XDATA *pIPHead;  //  IP 首部指针 

  /* for search netif list */ 

  struct SNetIf  DT_XDATA *pNetIf;    //   网络接口链表指针 

 

  // IP 首部指针指向缓存控制块IP 首部 

  pIPHead = (struct SIPHead DT_XDATA *)(MemHead->pStart); 

  /* check ip version */ 

  if (IP_VERSION(pIPHead) != IP_VERSION_4) IP.C 

  {   //  如果 IP 报文版本号不等于IPV4.5 

    MemFree(MemHead);               //   释放缓存控制块占用空间 

    return;                         //   返回 

  } 

  /* if checksum is ok */ 

  if (CheckSum((WORD DT_XDATA *)pIPHead,(WORD)IP_HEAD_LEN(pIPHead),0) != 0) 

  {  //  如果 IP 报文首部检验和错误 

    MemFree(MemHead);               //   释放缓存控制块占用空间 

    return;                         //   返回 

  } 

  /* ip packet with options is not supported */ 

  if(IP_HEAD_LEN(pIPHead) != IP_HEAD_MIN_LEN) 

  {  //  如果 IP 报文首部长度不等于 20 字节 

    MemFree(MemHead);               //   释放缓存控制块占用空间 

    return;                         //   嵌入式TCP/IP 协议栈不支持选项 

  } 

  /* ip packet fragmented is not supported */ 

  if  ((pIPHead->FragmentFlag_Offset & IP_FRAGMENT_OFFSET_MASK)!= 0) 

  { 

    MemFree(MemHead);               //   释放缓存控制块占用空间 

    return;                         //    嵌入式 TCP/IP 协议栈不支持分片 

  } 

  /* if this packet for us. check all the netif. if a host 

  has tow device(tow ip). This packet may come from one device 

  but send for the IP of the other deviec. In this case we should 

  not drop or forward this packet */ 

  /* if this packet is not for us. forward it */ 

  //  如果已使用网络接口设备中未找到 IP 报文中规定的 IP 地址 

  if ((pNetIf = NetIfFindIP(pIPHead->IPDest)) == NULL) 

  { 

    #ifdef IP_ENABLE_FORWARD 

    /* if act as a router */ 

    /* We should decrease the IPHead->ttl */ 

    //  已就是说该 IP 报文仅仅为了通过本机传输,则递减 

    // IP 报文的生存时间TTL。 

    if (pIPHead->LifeLength != 0) 

    { 

      pIPHead->LifeLength--;  //  递减 IP 报文的生存时间 TTL 

      /* recaculate IP head checksum. there is a easy method 

      to recaculate, leave for later version improvment */ 

      //  重新计算 IP 报文首部的检验和 

      CheckSum((WORD DT_XDATA *)pIPHead,(WORD)IP_HEAD_LEN(pIPHead),0); 

      /* find a rout( a interface ) */ 

      // ?????????????????????????????????????????????????? 

      if ((pNetIf = NetIfFindRout(pIPHead->IPDest)) != NULL) IP.C 

      { 

        /* forward. send it through this interface. if return FALSE, we 

        do not care, the soure of the packet will deel with it. */ 

        pNetIf->output(MemHead,pNetIf,pIPHead->IPDest); 

      } 

    } 

    #endif 

    MemFree(MemHead); 

    return; 

  } 

  //  如果已使用网络接口设备中找到 IP 报文中规定的 IP 地址 

  else 

  { 

    /* MemHead->pStart set to point uper layer */ 

    //  调整缓存控制块指针指向报文的上层首部 

    // IP 报文中上层协议数据可能是ICMP,IGMP,TCP,UDP 

    MemHead->pStart += sizeof(struct SIPHead); 

    /* pass to the uper layer */ 

    switch (pIPHead->Protocol) 

    { 

      case IP_PROTOCOL_TCP:      //  上层协议是 TCP 报文 

        TCPInput(MemHead);      //  调用 TCP 接收子程序 

        break; 

    #if   ICMP_EN 

      case IP_PROTOCOL_ICMP:      //  上层协议是 ICMP 报文 

        ICMPInput(MemHead);     //   调用 ICMP 接收子程序 

        break; 

    #endif 

      default:        //  嵌入式 TCP/IP 协议栈不支持IGMP 

        MemFree(MemHead); 

    } 

  } 

} 

 

//=========================================================================== 

/* out put a ip packet,NOTE:MemHead->pStart point to IPHead. 

IPScr IPDest Protocol TotalLen is already filled at uper layer. 

To do so TCPCheckSum is easy to generate and pass augument to 

IPOutput is easyer.  

return : 

TURE: send the packt successful. */ 

//  作     者:南开大学-李章林 

//  注     释:李清林 

//  日     期:2008 年3 月 

//  声     明:英文注释由作者李章林添加,中文注释由■李清林添加。 IP.C 

//        转载时请保留上述信息。 

//  成都理工学院/应用数字系/应用数字专业 

//--------------------------------------------------------------------------- 

//  程序名称:IPOutput=IP 发送子程序 

//  入口参数: 

//       *MemHead=缓存控制块指针 

//  出口参数: 

//     BOOL=TRUE   发送成功 

//        =FALSE  发送失败 

//=========================================================================== 

 

BOOL IPOutput(struct SMemHead DT_XDATA * MemHead) REENTRANT_SIG 

{ 

  struct SNetIf  DT_XDATA *pNetIf;  //  网络接口设备指针 

  struct SIPHead DT_XDATA *pIPHead;   //  IP 报文指针 

  WORD tCheckSum;                     //  检验和局部变量 

 

  // IP 报文指针指向缓存控制块IP 报文 

  pIPHead = (struct SIPHead DT_XDATA *)(MemHead->pStart); 

  /* found a rout */ 

  // ???????????????????????????? 

  if ((pNetIf = NetIfFindRout(pIPHead->IPDest)) != NULL) 

  { 

    /* fill IP head */ 

    //  填写 4 位版本号和 4位 IP 首部长度/4 

    pIPHead->Ver_HeadLen = (IP_VERSION_4 << 4) + IP_HEAD_MIN_LEN/4; 

    //  填写 8 位服务类型 TOS 

    pIPHead->ServeType       = 0; 

    //  填写标识符 

    pIPHead->FragmentID       = 0; 

    //  填写 3 位标志及 13 位分片偏移 

    pIPHead->FragmentFlag_Offset = 0; 

    //  填写 8 位生存时间 TTL 

    pIPHead->LifeLength       = IP_INITIAL_LIFE; 

    //  填写 IP 首部检验和初始值 

    pIPHead->CheckSum       = 0; 

    /* checksum */ 

    //  重新计算 IP 首部检验和 

    tCheckSum = CheckSum((WORD DT_XDATA *)pIPHead,(WORD)IP_HEAD_LEN(pIPHead),0); 

    //  填写更新后的 IP 首部检验和 

    pIPHead->CheckSum = htons(tCheckSum); 

    /* output it */ 

    //  调用网络接口设备发送程序发送 IP 报文 

    return pNetIf->output(MemHead,pNetIf,pIPHead->IPDest); 

  } IP.C 

  else 

    return FALSE; 

  /* 'MemHead' freeing is at tcp model when it is acked */ 

} 

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
头像被屏蔽

出0入0汤圆

发表于 2010-2-14 21:23:09 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 23:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表