本篇,我们就进入数据链路层的上层,网络层,看看我们在网络层需要做哪些事情。 在网路层,我们实现的协议有ARP协议,IPv4协议,ICMP协议。 学习网络协议栈的伙伴相信对于协议的内容及功能都已经有了一定的掌握,我在此不再赘述。 ARP协议处在网络层协议的最底层,为网络层其他协议服务的。按照我们自底向上的设计顺序,我们本篇,就给大家先带来ARP协议的设计。
地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。
发送方目的: (1)发送ARP请求报文。 (2)接收ARP应答报文。 (3)根据接收到的ARP应答报文维护发送方ARP表。
我们将以上目的分为三部分设计,本篇介绍ARP请求报文的发送。
协议数据单元结构: 以太网首部不再介绍,其余各个字段含义如下: 1.硬件类型:占2个字节,表明ARP实现在何种类型的网络上。 Ø 值为1:表示以太网。 2.协议类型:占2个字节表示要映射的协议地址类型。 Ø IP:0X0800 3.硬件地址长度:占1个字节,表示 MAC地址长度,其值为6个字节。 4.协议地址长度:占1个字节,表示IP地址长度,此处值4个字节 5.操作类型 :占2个字节,表示ARP数据包类型。 Ø 值为1表示ARP请求。 Ø 值为2表示ARP应答。 Ø 值为3表示RARP请求。 Ø 值为4表示RARP应答。 6.源MAC地址:占6个字节,表示发送端MAC地址 7.源IP地址:占4个字节,表示发送端IP地址 8.目的MAC地址:占6个字节,表示目标设备的MAC物理地址。若为请求报文则为空。 9.目的IP地址:占4个字节,表示目标设备的IP地址. 注意:在ARP操作中,有效数据的长度为28个字节,不足以太网的最小长度46字节长度,需要填充字节,填充字节最小长度为18个字节
有了以上的介绍,我们将ARP数据包设计为一个结构体:
struct arp_pkt { u_int16_t hardware_type; u_int16_t protocol_type; u_int8_t hardware_addr_length; u_int8_t protocol_addr_length; u_int16_t op_code; u_int8_t source_mac[6]; u_int8_t source_ip[4]; u_int8_t destination_mac[6]; u_int8_t destination_ip[4]; };根据以太网数据包发送设计的经验,我们将加载数据单独设计为一个函数。 ARP请求根据上层所给的IP地址解析MAC地址,所以我们只需要一个目的IP地址,其他字段基本固定。
void load_arp_packet(u_int8_t *destination_ip);至此,我们提供一个发送ARP请求数据包的函数接口:
//这里的参数u_int8_t *ethernet_dest_mac是因为我们设计时与接收方共用一个函数模板。 //接收方向我们发送ARP应答报文时是单播发送,所以需要提供一个目的MAC地址,我们在调用时提供一个广播MAC地址即可 void network_arp_send(u_int8_t *destination_ip, u_int8_t *ethernet_dest_mac); { 加载ARP请求数据包; 计算数据包长度; 调用以太网发送函数发送; }下一篇为大家带来ARP请求报文发送的代码实现。