ARP协议DPI深度解析

项目需要采用DPI对ARP报文进行解析(也可以借鉴open dpi?),整理ARP报文结构如下:

结构ether_header定义了以太网帧首部;结构arphdr定义了其后的5个字段,其信息用于在任何类型的介质上传送ARP请求和回答;ether_arp结构除了包含arphdr结构外,还包含源主机和目的主机的地址。

定义以太网首部:

typedef struct ehhdr 
{
    unsigned char eh_dst[6];   /* destination ethernet addrress */
    unsigned char eh_src[6];   /* source ethernet addresss */
    unsigned short eh_type;   /* ethernet pachet type */
}EHHDR, *PEHHDR;

定义以太网arp字段:

typedef struct arphdr
{
   /* arp 头 */
unsigned short arp_hrd;    /* format of hardware address */
unsigned short arp_pro;    /* format of protocol address */
unsigned char arp_hln;    /* length of hardware address */
unsigned char arp_pln;    /* length of protocol address */
unsigned short arp_op;     /* ARP/RARP operation */

/* 发送端信息(mac + ip) */
unsigned char arp_sha[6];  /* sender hardware address */
unsigned long arp_spa;    /* sender protocol address */

/* 目的端信息(mac + ip) */
unsigned char arp_tha[6];   /* target hardware address */
unsigned long arp_tpa;    /* target protocol address */
}ARPHDR, *PARPHDR;

ARP应答报文会将自己的 mac + ip 填在发送端信息中;将请求端的 mac + ip 填在目的端信息中;即对调ARP请求报文中的信息。

根据以上结构可以定义整个arp报文包,总长度42字节:

typedef struct arpPacket
{
   EHHDR ehhdr;
   ARPHDR arphdr;
} ARPPACKET, *PARPPACKET;

根据定义,头6个字节是以太网目的地址 ff ff ff ff ff ff 这是一个广播地址,全网下的所有终端都能接收到,紧跟着的6个字节是以太网源地址,即发送者的MAC地址( 00 0c f1 d4 d9 60 是我的MAC地址)。帧类型0806占两个字节,到这里以太网帧头就结束了。0806指的是后面的数据是属于arp包的。

接着分析ARP包头。头两个字节是硬件类型 00 01,接着两个字节是协议类型,即ARP使用的是IP协议代号08 00。硬件地址长度和协议地址长度分别是6和4。这与ARP报文格式是对应的。后面的2个字节OP指示当前包是请求包还是应答包,对应的值分别是0x0001和0x0002。原始数据里是00 01所以这是一个请求包,然后6个字节又是发送者MAC地址00 0c f1 d4 d9 60 ,后面4个字节是发送者IP地址c0 a8 01 0f ,转换成点分十进制格式即192.168.1.15,这是我的IP,接下来的6个字节留空,00 00 00 00 00 00 在arp请求包里也可以是其他数据,因为稍后IP地址为c0 a8 01 02 (192.168.1.2)会把自己的MAC地址填充进这6个字节中。

填充完后,arp包里的发送者硬件地址|目标硬件地址和以太网首部的以太网目的地址|以太网源地址正好对调。最后把这个封装好的ARP包发送出去,这样一个来回就可以让两台终端互相知道对方的IP和MAC。

利用wireShark抓包如下:


Linux 定义ARP协议报文结构如下:


猜你喜欢

转载自blog.csdn.net/u014279330/article/details/80225875