QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1758|回复: 2

ucosii4skyeye中网卡驱动ne2kif.c的问题

[复制链接]
发表于 2007-3-16 23:56:02 | 显示全部楼层 |阅读模式
ne2kif.c网卡驱动中的接收数据驱动部分代码如下:

static struct pbuf *
low_level_receive(struct RTL8019if *rtl8019if)
{
u16_t  packetLength,len;
u8_t PDHeader[18];   // Temp storage for ethernet headers
struct pbuf * p;
struct pbuf * q;
u8_t * payload;


outb(ISR_RDC, NE_ISR);
outb(0x0f, NE_RBCR1);  /* See controller manual , use send packet command */
outb(CMD_PAGE0 | CMD_SEND | CMD_RUN, NE_CR);

//get the first 18 bytes from nic
ne2k_copyin(18,PDHeader);

//  Store real length, set len to packet length - header
packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 ));

   //verify if the packet is an IP packet or ARP packet
if((PDHeader[3]>0x06)||(PDHeader[16] != ||(PDHeader[17] != 0 && PDHeader[17] != 6))
       {
     ne2k_discard(packetLength-14);
            return NULL;
       }  
我的思路是这样的:

  先申明一个18字节的数组u8_t PDHeader[18];   然后通过驱动程序从NIC接收18个字节的数据放入上面所申明的数组中!我猜测这个18个字节是指以太网头部的14个字节加上IP头部的前4个字节,取ip头部前四个字节,我的想法是为了取出IP数据报的长度,但是在packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 ))中为什么要用PDHeadr[2]和PDHeader[3]来取IP报长度呢?

如果说PDHeader[2]和PDHeader[3]是存储了IP头中的“总长度”字段,也就是IP头部的第3,4个字节;那为什么IP头部储存到了PDHeader[18]数组的前面而不是在该数组的最后面呢???

如果我以上的猜想是正确的!!那么为什么从NIC读出来的18数据字节中以太网头部14个字节放到了数组的后面而IP头部前4个字节放到了数组的最前面呢?????



我也考虑了是否是因为 以太II 和802.3帧封装的问题,但是我查阅了它们的资料还是想不通!在此小弟向各位大师请教!不胜感激!!!!!
发表于 2007-3-17 09:24:36 | 显示全部楼层

Re: ucosii4skyeye中网卡驱动ne2kif.c

[quote:fe9ff835a8="swordzq"]
  先申明一个18字节的数组u8_t PDHeader[18];   然后通过驱动程序从NIC接收18个字节的数据放入上面所申明的数组中!我猜测这个18个字节是指以太网头部的14个字节加上IP头部的前4个字节,取ip头部前四个字节,我的想法是为了取出IP数据报的长度,但是在packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 ))中为什么要用PDHeadr[2]和PDHeader[3]来取IP报长度呢?

如果说PDHeader[2]和PDHeader[3]是存储了IP头中的“总长度”字段,也就是IP头部的第3,4个字节;那为什么IP头部储存到了PDHeader[18]数组的前面而不是在该数组的最后面呢???

如果我以上的猜想是正确的!!那么为什么从NIC读出来的18数据字节中以太网头部14个字节放到了数组的后面而IP头部前4个字节放到了数组的最前面呢?????



我也考虑了是否是因为 以太II 和802.3帧封装的问题,但是我查阅了它们的资料还是想不通!在此小弟向各位大师请教!不胜感激!!!!![/quote]

在 ne2000 卡中每个读取的 page 前 4 个字节为专用字节
第一个:接收状态
第二个:下一页起始地址
第三个:(包长度+4)的低位
第四个:(包长度+4)的高位

所以 PacketLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 ))

其实 IP 报应从读入的 Packet 的第五个字节开始:
unsigned char *ethPacket = &PDHeader[4];
unsigned int ethPacketLength =  ((unsigned int) PDHeader[2] | (PDHeader[3] << 8 )) - 4;
回复

使用道具 举报

 楼主| 发表于 2007-3-19 12:25:27 | 显示全部楼层
谢谢AnthonyLee的解释!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-23 05:34 , Processed in 0.039250 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

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