• 使用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)
  • 相关阅读:
    putty的复制 技巧
    linux下的yum命令详解
    mysql修改密码
    我的阅读编程书籍的好方法
    WINDOWS下VIM配置
    Debian下VSFTPD配置
    一个远程访问MySQL的错误(2003, 10061)的解决
    auto_increment
    hello,world!
    scss文件中使用深度选择器/deep/报错 Expected selector Jim
  • 原文地址:https://www.cnblogs.com/wenqiang/p/5718006.html
Copyright © 2020-2023  润新知