使用libpcap过滤arp

上一篇博客简单讲述了libpcap的工作流程及简单使用,今天我们需要做的是继续使用libpcap抓取我们感兴趣的流量,并进行简单的解析:

测试环境是centos 7

下面贴一张arp帧结构图:

下面我们实现的是通过pcap过滤抓取arp报文,解析其中的Ethernet address 和proctocal address并打印出来

分析是arp request还是reply,前面就不做过多解释,代码比较简单,直接贴:

 1 #include <stdio.h>  
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <stdint.h>
 5 #include <pcap.h>
 6 #include <arpa/inet.h>
 7 
 8 #define MAXBYTES2CAPTURE 2048
 9 #define ARP_REQUEST     1
10 #define ARP_REPLY       2
11 
12 typedef struct arphdr {
13     u_int16_t htype;        //hardware type
14     u_int16_t ptype;        //protocol type
15     u_char hlen;            //hardware address length
16     u_char plen;            //protocol address length
17     u_int16_t oper;         //operation code
18     u_char sha[6];          //sendHardware address
19     u_char spa[4];          //sender ip address
20     u_char tha[6];          //target hardware address
21     u_char tpa[4];          //target ip address
22 } arphdr_t;
23 
24 int main(int argc, char **argv)
25 {
26     int i = 0;
27     bpf_u_int32 net = 0;
28     bpf_u_int32 mask = 0;
29     struct bpf_program filter; /*place to store the filter program*/
30     char errbuf[PCAP_ERRBUF_SIZE];
31     pcap_t *handle = NULL;   /*interface handle*/
32     struct pcap_pkthdr pkthdr; /**/
33     const unsigned char *packet = NULL; /*received raw data*/
34     arphdr_t *arpheader = NULL; /*point to arp header*/
35     
36     if (argc != 2) {
37         printf("USAGE: arpsniffer <interface>
");
38         exit(1);
39     }
40     
41     memset(errbuf, 0, PCAP_ERRBUF_SIZE);
42     /*open network device for packet capture*/
43     handle = pcap_open_live(argv[1], MAXBYTES2CAPTURE, 0, 512, errbuf);
44     if (handle == NULL) {
45         fprintf(stderr, "Couldn't open device %s: %s
", argv[1], errbuf);
46         exit(1);
47     }
48 
49     /*look up device network addr and mask*/
50     if (pcap_lookupnet(argv[1], &net, &mask, errbuf) == -1) {
51         fprintf(stderr, "Couldn't get netmask for device %s: %s
", argv[1], errbuf);
52         exit(1);
53     }
54     
55     /*complie the filter expression of filter program*/
56     pcap_compile(handle, &filter, "arp", 0, mask);
57 
58     pcap_setfilter(handle, &filter);
59 
60     while(1) {
61         /*Get one packet if null continue wait*/
62         if ((packet = pcap_next(handle, &pkthdr)) == NULL) {
63             continue;
64         }
65 
66         arpheader = (struct arphdr *)(packet + 14); /*Point to the ARP header*/
67         printf("
------------- ARP --------------
");
68         printf("Received Packet Size: %d bytes
", pkthdr.len);
69         printf("Hardware type: %s
", (ntohs(arpheader->htype) == 1)?"Ethernet":"Unknown");
70         printf("Protocol type: %s
", (ntohs(arpheader->ptype) == 0x0800)?"IPv4":"Unknown");
71         printf("Operation : %s
", (ntohs(arpheader->oper) == ARP_REQUEST)?"ARP_REQUEST":"ARP_REPLY");
72 
73         /*If is Ethernet and IPv4 print packet contents*/
74         if (ntohs(arpheader->htype) == 1 && ntohs(arpheader->ptype) == 0x0800) {
75             printf("
Soucre MAC:%02x:%02x:%02X:%02x:%02x:%02x
", 
76                             arpheader->sha[0], arpheader->sha[1], 
77                             arpheader->sha[2], arpheader->sha[3], 
78                             arpheader->sha[4], arpheader->sha[5]);
79             printf("Soucre IP:%d.%d.%d.%d
", 
80                             arpheader->spa[0], arpheader->spa[1], 
81                             arpheader->spa[2], arpheader->spa[3]);
82             printf("
Destination MAC:%02x:%02x:%02X:%02x:%02x:%02x
", 
83                             arpheader->tha[0], arpheader->tha[1], 
84                             arpheader->tha[2], arpheader->tha[3], 
85                             arpheader->tha[4], arpheader->tha[5]);
86             printf("Destination IP:%d.%d.%d.%d
", 
87                             arpheader->tpa[0], arpheader->tpa[1], 
88                             arpheader->tpa[2], arpheader->tpa[3]);
89         }    
90     }
91     return 0;
92 } 

下面是运行结果:

 1 [root@localhost pcap_arp]# ./pcap enp0s3
 2 
 3 ------------- ARP --------------
 4 Received Packet Size: 60 bytes
 5 Hardware type: Ethernet
 6 Ptotocol type: IPv4
 7 Operation : ARP_REQUEST
 8 
 9 Soucre MAC:b0:83:FE:99:5a:5b
10 Soucre IP:192.168.16.139
11 
12 Destination MAC:08:00:27:25:e7:52
13 Destination IP:192.168.16.125
14 
15 ------------- ARP --------------
16 Received Packet Size: 42 bytes
17 Hardware type: Ethernet
18 Ptotocol type: IPv4
19 Operation : ARP_REPLY
20 
21 Soucre MAC:08:00:27:25:e7:52
22 Soucre IP:192.168.16.125
23 
24 Destination MAC:b0:83:FE:99:5a:5b
25 Destination IP:192.168.16.139

Makefile:

 1 #
 2 #design of ARP sniffer
 3 #
 4 
 5 CFLAGS = -g
 6 LDFLAGS = -lpcap
 7 
 8 OBJS = test.o
 9 TARGET = pcap
10 
11 RM = rm -f  
12 
13 $(TARGET):$(OBJS)
14     $(CC) $(LDFLAGS) -o $@ $^
15 
16 %.o:%.c
17     $(CC) $(CFLAGS) -c -o $@ $<
18 
19 .PHONY:clean
20 
21 clean:
22     $(RM) $(TARGET) $(OBJS)
原文地址:https://www.cnblogs.com/wenqiang/p/5718006.html