利用libpcap抓包(四)----------抓包主函数的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Sophisticated_/article/details/83339797

main函数的实现,调用libpcap提供的库函数,抓取数据包,然后交给回调函数进行对数据包的解析

/******************************************************************************
  文 件 名   : packetAnalyze.c
  版 本 号   : V1.1
  负 责 人   : Sophisticated
  生成日期   : 2018年9月27日
  最近修改   :
  文件描述   : 使用libpcap抓取数据包
  函数列表   :
              main
  修改历史   :
  1.日    期   : 2018年9月27日
    作    者   : Sophisticated
    修改内容   : 创建文件

******************************************************************************/

#include<stdio.h>
#include<sys/types.h>
#include<pcap.h>
#include"head.h"
#include"callback.h"


#define PROMISC 1

/*过滤条件*/
char filter_exp[128];

/*抓包设备名称*/
char *dev;

/*****************************************************************************
 函 数 名  : main
 功能描述  : 抓取数据包主函数
 输入参数  : 无
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2018年9月27日
    作    者   : Sophisticated
    审 核 人   : #
    修改内容   : 新生成函数

*****************************************************************************/
int main(int argc, int *argv[])
{
	pcap_t *pcap;
	char errbuf[PCAP_ERRBUF_SIZE];
	struct pcap_pkthdr hdr;
	pcap_if_t *alldevs;

	struct bpf_program bpf_p;
	bpf_u_int32 net;
	bpf_u_int32 mask;

	/*find the device to capture packet*/
	if (pcap_findalldevs(&alldevs, errbuf) == -1)
	{
		print("no device !\n");
	}
	
	/*默认取第一个网络设备*/
	dev = alldevs->name;

    //dev = "br0";  
    
	/*open the device*/
	pcap = pcap_open_live(dev, SNAP_LEN, PROMISC, 0, errbuf);
	if (pcap == NULL)
	{
		print("open error!\n");
		return;
	}

	if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1)
	{
        print("Could not get netmask for device!\n");
        net = 0;
        mask = 0;
	}

    if (argc > 1)
    {
        int i;
        for (i = 1; i < argc; i++)
        {
            strncat(filter_exp, argv[i], 100);
            strncat(filter_exp, " ", 100);
        }
    }
        
    if (pcap_compile(pcap, &bpf_p, filter_exp, 0,net) == -1)
    {
        print("Could not parse filter\n");
        return;
    }
    if(pcap_setfilter(pcap, &bpf_p) == -1)
    {
        print("Could not install filter\n");
        return;
    }
    
	int id = 0;
	
	/*capture the packet until occure error*/
	pcap_loop(pcap, -1, ethernet_callback, (u_char *)&id);

	pcap_close(pcap);

	return 0;
}

将过滤条件通过main函数参数的方式传递进来,此时的过滤条件格式必须遵守libpcap的格式
可用的过滤格式例子:
src host 192.168.1.177
只接收源ip地址是192.168.1.177的数据包

dst port 80
只接收tcp/udp的目的端口是80的数据包

not tcp
只接收不使用tcp协议的数据包

tcp[13] == 0x02 and (dst port 22 or dst port 23)
只接收SYN标志位置位且目标端口是22或23的数据包(tcp首部开始的第13个字节)

icmp[icmptype] == icmp-echoreply or icmp[icmptype] == icmp-echo
只接收icmp的ping请求和ping响应的数据包

ehter dst 00:e0:09:c1:0e:82
只接收以太网mac地址是00:e0:09:c1:0e:82的数据包

ip[8] == 5
只接收ip的ttl=5的数据包(ip首部开始的第8个字节)

这里的网络设备默认取第一个设备,也可以自己硬编码为指定的设备名称

猜你喜欢

转载自blog.csdn.net/Sophisticated_/article/details/83339797