51单片机ARP协议实现原理
ARP_request(目的IP地址) //ARP请求
{
//判断IP地址是否属于同一子网的任务交给上层软件处理
//(由它决定请求网卡IP地址还是默认网关IP地址),
//这有利于减少代码量。
//申请小号内存
pARP=OSMemGet();
//填以太网帧
以太网协议=0x0806;//ARP协议
目的MAC地址=0xffff;//广播地址
源MAC地址=自己的MAC地址;
//填ARP表
硬件类型=0x0001;
协议类型=0x0800;
硬件地址长度=0x06;
协议长度=0x04;
操作=0x0001;//请求
发送方首部=自己的MAC地址;
发送方IP地址=源IP地址;
目标首部=0x0000;
目标IP地址=目的IP地址;
//填充PAD
没有内容处填充0;
//发送ARP包至TxQFIFO缓存
OSQSend(QID,*pARP);
}
ARP_answer(*pARP) //ARP应答
{
学习/更新ARP缓存表;
//修改收到的ARP包,形成ARP应答
//填以太网帧
目的MAC地址=对方(网卡/网关)发来的源MAC地址;
源MAC地址=自己的MAC地址;
//填ARP表
目标首部=发送方首部;发送方首部=自己的MAC地址;
交换发送方IP地址和目标IP地址;
操作=0x0002;//ARP应答
//发送ARP包至TxQFIFO缓存
OSQSend(QID,*pARP);
}
ARP_process(*pARP) //ARP应答处理
{
//更新
for(i=0;iARPTabSize;i++){
if(ARPTab[i].status==1){
if(ARPTab[i].IPAdr==收到的ARP应答包源IP地址){
ARPTab[i].ttl=最大寿命;
ARPTab[i].IPAdr=收到的包的源IP地址;
ARPTab[i].MACAdr=收到的包的源MAC地址;
return;
}
}
}
//学习
for(i=0;iARPTabSize;i++){
if(ARPTab[i].status==0){
ARPTab[i].status=1;
ARPTab[i].ttl=最大寿命;
ARPTab[i].IPAdr=收到的包的源IP地址;
ARPTab[i].MACAdr=收到的包的源MAC地址;
return;
}
}
//表满处理,有损性能的快速算法
ARPTab[index].status=1; //注:index为全局变量,保存ARP缓存表项索引。每次处理加1取模。
ARPTab[index].ttl=最大寿命;
index++;
if(index>=ARPTabSize) index=0;
}
IP_in(*pIP) //IP包过滤(ARP地址学习) 注:这里处理的是IP包,伪代码与上面程序相似,但源代码差别很大。
{
//更新
for(i=0;iARPTabSize;i++){
if(ARPTab[i].status==1){
if(ARPTab[i].IPAdr==收到的IP包源IP地址){
ARPTab[i].ttl=最大寿命;
ARPTab[i].IPAdr=收到的包的源IP地址;
ARPTab[i].MACAdr=收到的包的源MAC地址;
return;
}
}
}
//学习
for(i=0;iARPTabSize;i++){
if(ARPTab[i].status==0){
ARPTab[i].status=1;
ARPTab[i].ttl=最大寿命;
ARPTab[i].IPAdr=收到的包的源IP地址;
ARPTab[i].MACAdr=收到的包的源MAC地址;
return;
}
}
//表满处理,有损性能的快速算法
ARPTab[index].status=1; //注:index为全局变量,保存ARP缓存表项索引。每次处理加1取模。
ARPTab[index].ttl=最大寿命;
index++;
if(index>=ARPTabSize) index=0;
}
timer() //软定时器任务,用于ARP老化
{
for(;;){
taskDelay(1秒);
for(i=0;iARPTabSize;i++){
if(ARPTab[i].status==1){
if(ARPTab[i].ttl==0)
ARPTab[i].status=0;
else
ARPTab[i].ttl--;
}
}
}
主程序框架:
initNIC //初始化网卡
//创建资源
TxSem和RxSem信号量
TxQFIFO队列
大中小内存设立
//创建任务
收
发
。
。
。
参考文献:
1。《用TCP/IP进行网际互连》(第3版)第一、二、三卷 DOUGLAS E.COMER著 电子工业出版社
- 关于RTX51 TINY的分析与探讨(05-30)
- 浅析8051模块化编程技巧(05-28)
- 基于DSP和单片机通信的液晶显示设计方案(07-20)
- 锁相环控制及初始化简析(08-27)
- 基于MSP430自动胀管控制器的研究(09-07)
- 嵌入式C实现延时程序的不同变量的区别(03-01)