C++直接获取ARP报文实战

一 点睛

1 以太网帧头结构定义

#define ETH_ALEN 6  //定义了以太网接口的MAC地址的长度为6个字节
#define ETH_HLAN 14  //定义了以太网帧的头长度为14个字节
#define ETH_ZLEN 60  //定义了以太网帧的最小长度为 ETH_ZLEN + ETH_FCS_LEN = 64个字节
#define ETH_DATA_LEN 1500  //定义了以太网帧的最大负载为1500个字节
#define ETH_FRAME_LEN 1514  //定义了以太网正的最大长度为ETH_DATA_LEN + ETH_FCS_LEN = 1518个字节
#define ETH_FCS_LEN 4   //定义了以太网帧的CRC值占4个字节
struct ethhdr
{
    unsigned char h_dest[ETH_ALEN]; //目的MAC地址
     
    unsigned char h_source[ETH_ALEN]; //源MAC地址
     
    __u16 h_proto ; //网络层所使用的协议类型
}__attribute__((packed))  //用于告诉编译器不要对这个结构体中的缝隙部分进行填充操作;

二 实战前准备

1 准备两台虚拟机A和B。

A的IP:192.168.0.110       A的MAC:08:00:27:60:7b:7f

B的IP:192.168.0.120       B的MAC:08:00:27:0c:3b:d3

2 步骤

程序部署在A机上,B给A发送一些ARP包,然后看A是否收到并判断出来。

三 代码

#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include    //for ethhdr
int main(int argc, char *argv [])  
{  
    int i = 0;  
    unsigned char buf[1024] = "";  
    struct ethhdr *eth;      //以太网头结构体指针
    // 使用ETH_P_ARP协议号,这样这个套接字就只会去接收ARP报文了。
    int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));  
    while (1)  
    {  
        recvfrom(sock_raw_fd, buf, sizeof(buf), 0, NULL, NULL);  //获取链路层的数据帧  
        eth = (struct ethhdr*)buf;  //指向接收到的数据缓冲区,就能通过结构体字段获得目的、源MAC和协议号
        //从eth里提取目的mac、源mac、协议号
        printf("proto=0x%04x,dst mac addr:%02x:%02x:%02x:%02x:%02x:%02x\n", ntohs(eth->h_proto), eth->h_dest[0], eth->h_dest[1], eth->h_dest[2], eth->h_dest[3], eth->h_dest[4], eth->h_dest[5]);
        printf("proto=0x%04x,src mac addr:%02x:%02x:%02x:%02x:%02x:%02x\n", ntohs(eth->h_proto), eth->h_source[0], eth->h_source[1], eth->h_source[2], eth->h_source[3], eth->h_source[4], eth->h_source[5]);

    }  
    return 0;  
}

四 在A机上编译并运行

[root@localhost test]# g++ test.cpp -o test
[root@localhost test]# ./test

五 捕获ARP包

1 在B机上发送2个ARP探测包,输入如下命令

[root@localhost ~]# arping -I enp0s3 192.168.0.110 -c 2
ARPING 192.168.0.110 from 192.168.0.120 enp0s3
Unicast reply from 192.168.0.110 [08:00:27:60:7B:7F]  0.869ms
Unicast reply from 192.168.0.110 [08:00:27:60:7B:7F]  0.813ms
Sent 2 probes (1 broadcast(s))
Received 2 response(s)

2 A端捕获4个ARP包

[root@localhost test]# ./test
proto=0x0806,dst mac addr:ff:ff:ff:ff:ff:ff
proto=0x0806,src mac addr:08:00:27:0c:3b:d3
proto=0x0806,dst mac addr:08:00:27:60:7b:7f
proto=0x0806,src mac addr:08:00:27:0c:3b:d3

 

你可能感兴趣的:(C++)