利用libpcap抓包(四)----------抓包主函數的實現

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個字節)

這裏的網絡設備默認取第一個設備,也可以自己硬編碼爲指定的設備名稱

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章