最近在学习以太网和uip协议,有新的理解就会在这里更新,这些仅是个人见解,若有错误欢迎批评指正,希望大家多发言,和大家一起讨论
我的邮箱: 1024549573@qq.com
这是我的另一篇关于以太网的贴子:ARP是怎么映IP地址和MAC地址的 ,帖子链接 http://www.openedv.com/posts/list/28828.htm
在讨论的过程中,是以uip协议栈为基础的,接下来阐述一下我对以太网接收、处理数据的过程的理解。
简述以太网数据接收、处理过程:
首先硬件驱动从网络读取一帧的数据到uip_buff 并把数据的长度赋给uip_len , 当uip_len 大于0的时候说明收到了数据。
但收到的数据可能是IP数据包也可能是ARP包。
fficeffice" />
然后判断数据包的类型:
if 收到的是IP数据包,
调用函数uip_arp_ipin()进行IP包Arp部分的处理(更新ARP缓冲表),然后调用uip_input()处理缓存uip_buf中的IP数据,
如果uip_len 的长度大于零说明有IP的确定号要发送(我觉得应该是IP数据包的确认号),硬件发送数据之前要调用函数uip_arp_out( )
该函数查看ARP表中是否有目标IP对应的MAC地址的历史记录如果有填入以太网帧头,发送数据,注意:这里的发送
数据调用的是硬件的驱动函数tapdev_send(),而不是uip_send()该函数只在当有uip应用事件发生时有数据要发送才调用uip_send();
如果没有则发送ARP请求,同时丢弃这帧数据。
测试函数用于区别不同的应用事件。
else 收到的的ARP包
调用函数uip_arp_arpin( )函数,这个函数会判断ARP包的类型是响应包还是请求包,如果是响应包,那么更新ARP表。
如果是请求包,那么发送ARP回复帧包括本机的IP地址和MAC地址。
处理数据过程代码:
uip_len = tapdev_read(); /* 读取以太网数据包,返回数据长度 */
if(uip_len > 0) /* 收到数据 */
{
if(BUF->type == htons(UIP_ETHTYPE_IP)) /* 收到IP数据包 */
{
uip_arp_ipin();
uip_input();
if (uip_len > 0)
{
uip_arp_out();
tapdev_send();
}
}
else if (BUF->type == htons(UIP_ETHTYPE_ARP)) /* 收到ARP数据包 */
{
uip_arp_arpin();
if (uip_len > 0)
{
tapdev_send();
}
}
更新时间:2014.03.22
|