ARP协议是网络层协议,但并不同于IP协议。可以说,ARP协议是IP协议的底层协议,同时又是数据链路层的上层协议,每次发送IP数据包时,需要使用IP协议,而IP协议首先使用ARP模块查询目的地物理地址。ARP协议具体作用是进行IP和物理地址之间的转换。

 

 

  之所以进行IP与物理地址的转换,是因为IP层以IP地址作为通信双方的地址,而数据链路层是以物理地址(mac)作为通信双方的地址,传输时,发送方需要同时知道接收者的IP地址以及物理地址。IP层协议处理过后的数据,最终需要通过数据链路层来传输。一般应用中,我们往往只知道对方的IP地址,而对物理地址一概不知。假设没有ARP协议,那么就会出现无法传输的情况。在ARP协议出现以前,人们为了解决这个问题,使用一种叫做“静态映射”的办法,它在本机电脑建立一个表格,记录对应的ip地址与mac地址。每次发送时,查询该表格,得到mac地址,从而完成传输。这种方法有局限性,因为IP地址与物理地址的对应并非一成不变的。某些时候,物理地址也会变化。比如一个机器可能会更换其网卡,结果得到一个新的物理地址。静态映射就失效了。

 

 

  没有什么可以阻挡人类前进的步伐。在静态映射失效之后,互联网从业者发明了ARP协议。它有另外一个名字,叫做“动态映射”,也是一种IP地址与物理地址的映射,但不是“静态”的映射。主机只要在发送时知道IP地址或物理地址两者中的一个。在ARP协议中,当一台主机A知道对方的IP地址时,就可按照ARP协议生成一个ARP请求分组,然后A主机发送该请求分组,向局域网内所有其他主机发送该分组。

 

 

  ARP协议分组的具体工作原理是:既然知道了对方IP地址,想得到局域网内与该IP地址对应的物理地址,而局域网内不止一台电脑,发送方只好通过发送一个ARP请求分组,该分组包含自己的IP地址以及MAC地址,以及对方的IP地址,对方的物理地址不知道,空着。有了这三样,其他主机接收到该分组之后,可以读取其中的目的IP地址,拿自己的IP地址进行比对,如果两者一致,则在该ARP分组中写入自己的物理地址,再发送回去,这个过程统称为应答;如果不一样,那么直接丢弃该包裹,不应答。

 

  除了上述这四样最重要的东西,ARP分组还有许多内容。下图是完整的ARP分组格式。

 

 

  有一个地方值得注意,ARP分组并非通过IP协议传输,而是,本身就作为数据被封装在数据链路帧,通过数据链路帧传输,在该帧的类型字段中,将指出此帧所携带的数据是ARP分组,帧中源地址使用发送端的物理地址,目的地址使用物理广播地址,即向局域网内所有其他主机发送该分组。这个帧,也称为请求帧。相应地,是应答帧,应答帧即上文中ARP应答包,根据上文的介绍,应答帧只是单播帧,只是一对一传输,而不是向请求帧那样一对多。

 

 

   ARP协议大致过程就是这样了,有大侠在github上发布了一个arp_joke代码,是arp报文的一种应用。感兴趣者可以杀过去看一看(https://github.com/Joinhack/arp_joke)。代码中还有arp分组的结构体,我抄录在下面。

struct ARP_HEADER{

                unsigned short arp_hdr;   /*ARP分组中的硬件类型,2字节,定义运行ARP的网络的类型,以太网是类型1*/

                unsigned short arp_pro;  /*协议类型,2字节,定义上层协议类型,对于IPV4协议,该字段值为0800*/

                unsigned char arp_hln;  /*硬件长度,8位字段,定义对应物理地址长度,以太网中这个值为6*/

                unsigned char apr_pln; /*协议长度,8位字段,定义以字节为单位的逻辑地址长度,对IPV4协议这个值为4*/

                unsigned  short arp_opt;  /*16位字段,定义分组类型,是ARP请求(值为1),或者ARP应答(值为2)*/

                unsigned char arp_sha[6]; /*发送端硬件地址,可变长度字段,对以太网这个字段是6字节长*/

                unsigned char arp_spa[4]; /*发送端协议地址,可变长度字段,对IP协议,这个字段是4字节长*/

                unsigned char arp_tha[6]; /*接受端硬件地址*/

                unsigned long arp_tpa[4];/*接收端协议地址*/

};

  具体的代码实施过程,每一个IP分组,都要先经过ARP协议,查询ARP模块中高速缓存表,表中存有许多临时的IP地址以及对应的物理地址,若找到相应接受端的物理地址,那么直接发送该IP分组;否则,将发送ARP分组广播报文,查找目的地址物理地址。最后再发送该IP分组。

 

 

  如果不知道自己的IP地址,则可以使用RARP协议查询,在网络上,必然有一台机器(路由器)知道该网络内所有的IP地址,请求的机器上运行着RARP客户程序,响应的机器运行着RARP服务器程序,借助两者,就可以查到自己的IP地址了。RARP分组格式完全与ARP协议相同。除了操作字段或者是3(请求标记),或者是4(回答标记)。此外,还有许多扩展协议,如BOOTP,DHCP协议,功能类似于ARP与RARP协议,只是它们能够查询到更多的信息,比如子网掩码,路由器的IP地址,以及名字服务器的IP地址等等。