搜索
bottom↓
回复: 1

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

[复制链接]

出0入0汤圆

发表于 2008-12-19 10:28:18 | 显示全部楼层 |阅读模式
ETHERIF.C 

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

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

// ETHERIF.C =  以太网数据链路层 

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

//  注     释:李清林 

//  日     期:2008 年3 月 

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

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

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

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

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

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

#include "..\Netif\etherif.h" 

#include "..\Netif\ARP.h" 

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

 

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

/* call output to put a packet from IP layer to device. After 

  Ip layer selected a device, it use output to send this packet. 

  MemHead contain a packet and Netif tell dirver which netif it 

  is. NOTE:MemHead->pStart point to pIPHead 

return: 

  TRUE: send successfuly.*/ 

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

//  注     释:李清林 

//  日     期:2008 年3 月 

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

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

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

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

//  程序名称:EtherOutput=以太网数据链路层发送子程序 

//  入口参数: 

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

//        *NetIf=网络接口设备队列指针 

//    DestIP=目的IP 地址 

//  出口参数: 

//    BOOL=TRUE (发送成功) FALSE (发送失败) 

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

BOOL EtherOutput(struct SMemHead DT_XDATA *MemHead, 

   struct SNetIf DT_XDATA* NetIf,IP_ADDR DestIP) REENTRANT_SIG 

{ 

  /* next host to receive the packet in rout */ 

  DWORD NextIP; 

  //  以太网数据链路层首部结构体指针 

  struct SEtherHead DT_XDATA * pEtherHead; ETHERIF.C 

  //  缓存控制块指针 

  struct SMemHead DT_XDATA *p; 

 

  //  缓存控制块中得到以太网数据链路层指针位置 

  //   入口时 MemHead  的.pStart 域指向 IP 数据报文位置 

  pEtherHead = (struct SEtherHead DT_XDATA *) 

    (MemHead->pStart - sizeof(struct SEtherHead)); 

  /* if DestIP in this subnet ... */ 

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

  if ((NetIf->NetMask & NetIf->IPAddr) == (NetIf->NetMask & DestIP)) 

    NextIP = DestIP; 

  else 

    NextIP = NetIf->GateWay; 

  /* find Ether addr of NextIP */ 

  //  查找 NextIP 对应的网卡物理地址 

  if (ARPFind(pEtherHead->DestAddr,NextIP) == FALSE) 

  { 

    /* send a arp query */ 

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

//  如果 ARP  高速缓存表中未找到 NextIP,则调用 ARPQuery  发送程序发送一条 

// ARP  广播。其中在 ARPQuery  程序中已经填写好以太网数据链路层报文和 ARP 

//  报文。 ARPQuery  如果申请内存成功,则返回缓存控制块指针,否则返回 NULL。 

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

    if ((p = ARPQuery(NetIf,NextIP)) != NULL) 

    {   //  如果发送 ARP  广播时申请内存成功 

      //  调用网络接口设备队列的发送指针函数,发送 ARP 数据包 

      ((struct SEtherDevice DT_XDATA *) 

      (NetIf->Info))->send(p->pStart,sizeof(struct SARPPacket) + 

      sizeof(struct SEtherHead)); 

      MemFree(p);    //  释放缓存控制块 

    } 

  } 

  else 

  { 

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

//  如果 ARP  高速缓存表中找到 NextIP,则 pEtherHead->DestAddr  中存储 

//  NextIP 对应的以太网物理地址。 

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

    /*  fill ehter header, DestAddr already filled in ARPFind */ 

    //   填写以太网数据链路层首部.ScrAddr 域=以太网源物理地址 

    //   网络接口设备队列指针中获取以太网源物理地址 

    MemCopy(pEtherHead->ScrAddr,  

    ((struct SEtherDevice DT_XDATA *)(NetIf->Info))->Addr,ETHER_ADDR_LEN); 

    //   填写以太网数据链路层首部.type 域=数据帧类型 

    //   以太网帧类型=IP 数据包 ETHERIF.C 

    pEtherHead->type = htons(ETHER_TYPE_IP); 

    //   注:以太网目的物理地址已经在调用 ARPFind  程序时填写到 

    //  pEtherHead->DestAddr 中。 

    /* send the packet. packet lenth is less than MemHead size */ 

    //  调用网络接口设备队列的发送指针函数,发送 IP 数据包 

    return ((struct SEtherDevice DT_XDATA *)(NetIf->Info))->send( 

      pEtherHead,(WORD)(MemHead->pEnd - (BYTE DT_XDATA *)pEtherHead)); 

  } 

  return FALSE; 

  /* free MemHead when it is acked in tcp model */ 

} 

 

 

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

/* this function is called periodically.Get a packet from specific  

device. If there is a packet, call NetIf->Input to do more */ 

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

//  注     释:李清林 

//  日     期:2008 年3 月 

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

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

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

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

//  程序名称:EtherInput=以太网数据链路层接收子程序 

//  入口参数: 

//     *NetIf=网络接口设备队列指针 

//  出口参数: 

//      无 

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

void EtherInput(struct SNetIf DT_XDATA * NetIf) REENTRANT_SIG 

{ 

  struct SMemHead DT_XDATA *MemHead;    //  缓存控制块指针 

  struct SEtherHead DT_XDATA *pEtherHead;   //  以太网数据链路层指针 

  struct SMemHead DT_XDATA *p;           //  临时缓存控制块指针 

 

  /* if there is a packet to deal with */ 

  //  如果以太网网络接口设备接收到数据包 

  while ((MemHead = ((struct SEtherDevice DT_XDATA *)(NetIf->Info))->recv()) 

    != NULL) 

  { 

    /* Note, pStart point to EtherHead */ 

    //  以太网数据链路层指针 EetherHead  指向数据包数据链路层位置 

    pEtherHead = (struct SEtherHead DT_XDATA *)(MemHead->pStart); 

    /* which packet type */ 

    switch(ntohs(pEtherHead->type))    //  分析数据包帧类型 ETHERIF.C 

    { 

      case ETHER_TYPE_IP:        //  IP 数据包 

      /* before pass to IP layer, let MemHead->pStart point 

      to IP header */ 

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

      /* pass to IP layer for more dealing */ 

      //  将缓存控制块指针的 pStart 域指针指向IP 首部 

        IPInput(MemHead);           //   调用 IP 数据包接收子程序, 

        break; 

      case ETHER_TYPE_ARP:            //  ARP 数据包 

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

// ARPInput  程序中如果接收到 ARP 请求报文,填写以太网数据链路层首部信息,然后 

//  填写 ARP 应答报文,并返回 MemHead;如果接收到 ARP 应答报文,填写 ARP 高速缓存表, 

//  然后返回 NULL。据此通过返回值可确定是接收到 ARP 请求报文还是 ARP 应答报文。 

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

        if ((p = ARPInput(MemHead,NetIf)) != NULL) 

        { 

          /* a arp reply need to be send */ 

          //  接收到 ARP 请求报文后,发送 ARP 应答报文 

          //  调用网络接口设备发送函数指针发送 ARP 应答报文 

          ((struct SEtherDevice DT_XDATA *)(NetIf->Info))->send( 

          p->pStart,sizeof(struct SARPPacket) 

          + sizeof(struct SEtherHead)); 

          MemFree(p); 

        } 

        /* 'MemHead' is freed in ARPInput() */ 

        break; 

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

//   以太网数据链路层支持三种数据包。而一般嵌入式 TCP/IP 协议栈只支持IP 数据包和 

//  ARP 数据包,不支持 RARP 数据包(RARP 数据包针对无盘网络工作)。 

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

      default:  

        /* unknown packet type free */ 

        MemFree(MemHead); 

    } 

  } 

} 

 

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

/* ethernet device init */ 

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

//  注     释:李清林 

//  日     期:2008 年3 月 

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

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

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

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

//  程序名称:EtherDevInit=以太网数据链路层网络接口设备队列初始化子程序 

//  入口参数: 

//      *pDevice=以太网数据链路层设备指针 

//       EtherAddr[]=网卡物理地址 

//        以太网数据链路层发送指针函数 

//     BOOL (DT_CODE * send)(void DT_XDATA *buf, WORD size) 

//        以太网数据链路层接收指针函数 

//     struct SMemHead DT_XDATA *(DT_CODE * recv)() 

//  出口参数: 

//      无 

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

void EtherDevInit(struct SEtherDevice DT_XDATA * pDevice,  

  BYTE EtherAddr[], 

  BOOL (DT_CODE * send)(void DT_XDATA *buf, WORD size) REENTRANT_SIG,  

  struct SMemHead DT_XDATA *(DT_CODE * recv)() REENTRANT_SIG) REENTRANT_MUL 

{ 

  //  网卡物理地址拷贝到以太网数据链路层设备驱动结构体指针.Addr 域 

  MemCopy(pDevice->Addr,EtherAddr,ETHER_ADDR_LEN); 

  //  填写以太网数据链路层设备驱动结构体指针.recv 域 

  pDevice->recv = recv; 

  //  填写以太网数据链路层设备驱动结构体指针.send 域 

  pDevice->send = send; 

} 

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

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

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-20 21:27

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

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