专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

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

作者:刘温电   来源:本站原创   点击数:  更新时间:2013年11月24日   【字体:

简介
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);
}

关闭窗口

相关文章