微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARP的组成与解析及单片机程序

ARP的组成与解析及单片机程序

时间:11-30 来源:互联网 点击:
简介

arp:地址解析协议,简单的来说,对于底层的以太网通讯,有两个地址需要了解,一个地址叫ip地址,第二个地址叫mac地址,只有知道了这两个地址,才可以进行点对点的通讯,那么有的时候,系统只知道IP地址,不知道mac地址,那么这个时候,怎么办呢?就用arp协议,arp协议属于网络层,和ip协议平级,他是以广播形式发出的,发出时,带有一个目标ip,符合目标ip的主机收到这个信息后,就会把自己的mac地址按照arp协议告诉询问主机。这就是arp。

关于arp的组成
arp分为问包和答包,一般有42个字节组成,发送接收一般都是42个字节。
arp包由以太网帧,arp报文组成,帧数据为,目标地址以广播形式,即6个0xff。源地址则是自己的mac地址。类型则为0x0806,这样,以广播的形式发送给所有机器。(疑问,这个广播是如何传递到目标ip的呢?通过路由器,那么这个arp是如何选择目的地的呢?在局域网内还好点,但在广域网内,就不知道了),以上是以太网帧类型,以太网帧后面则是,arp帧,arp帧首先包含着2位硬件类型,2位协议类型,一般是0x8000,后面跟的是mac长度和ip长度,一般是6和4,就是mac地址和ip的字节数。最后是一个问答字节,0001代表问,0002代表答

解析
解析的时候,首先判断以太网帧类型是否为arp,若为arp,则判断是否为问命令,若为问命令则继续判断ip字节,一般的情况下,mac就是6个字节,但ip则由于版本不一样,ip地址字节数也不一样,所以判断ip字节数即可,若全部通过,则进行arp应答。

应答
应答过程:1、首先装入mac地址
2、然后将自己的mac地址填入源地址,
3、改变问答包
4、装入ip数据
5、发送

下面是51单片机驱动enc28j60的驱动
//目标mac地址
#define ETH_DST_MAC 0
//源mac地址
#define ETH_SRC_MAC 6
#define ETH_DST_MAC 0
#define ARP_SRC_MAC 0x16 //arp包中的发端mac
#define ARP_SRC_IP 0x1c //arp包中的发端ip
#define ARP_DST_MAC 0x20 //arp包中的收端mac
#define ARP_DST_IP 0x26 //arp包中的目标ip
#define ARP_DST_IP_0 0x26
#define ARP_DST_IP_1 0x27
#define ARP_DST_IP_2 0x28
#define ARP_DST_IP_3 0x29
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//arp解析语句
if(eth_ip_type == ETH_TYPE_ARP) //arp类型
{
if(buf[ARP_PLEN] == ARP_PLEN_VALUE) //判断协议字节是否为4,若为4,则是ipv4,进行ip比较
{
//检测IP地址,如果是本机ip则进行返回处理,如果不是ip则不处理
if((buf[ARP_DST_IP_0] == myip[0]) && (buf[ARP_DST_IP_1] == myip[1]) && (buf[ARP_DST_IP_2] == myip[2]) && (buf[ARP_DST_IP_3] == myip[3]))
{
//判断是否为问数据
if(buf[ARP_OP] == 0x01)
{
//进行返回数据处理
eth_arp_ack(buf);
return 0;
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
arp应答函数
void eth_arp_ack(u8 *buf)
{
u8 i = 0;
//制作目标地址,源地址,发端地址,收端地址
while(i < 6)
{
buf[ETH_DST_MAC + i] = buf[ETH_SRC_MAC + i]; //目标地址
buf[ARP_DST_MAC + i] = buf[ETH_SRC_MAC + i]; //收端地址

buf[ETH_SRC_MAC + i] = mymac[i]; //源地址
buf[ARP_SRC_MAC + i] = mymac[i]; //发端地址

i++;
}

buf[ARP_OP] = ARP_OP_ACK;

i = 0;

while(i<4)
{
buf[ARP_DST_IP + i] = buf[ARP_SRC_IP + i];
buf[ARP_SRC_IP + i] = myip[i];
i++;
}
// eth+arp is 42 bytes:
enc28j60PacketSend(42,buf);
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top