libpcap/capture_pcap_loop.c
接著就開要開始講怎麼抓封包了,在libpcap裡有幾種抓封包的方式:
pcap_loop()
pcap_dispatch()
pcap_next()
(最好別使用)pcap\_next\_ex()
而這篇會示範如何用pcap_loop()
抓封包。
Source Code
//
// capture_pcap_loop.c
// 功能:使用pcap_loop抓取封包。
// Created by 聲華 陳 on 2015/12/28.
//
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
void pcap_callback(u_char *arg, const struct pcap_pkthdr *header, const u_char *content);
int main(int argc, const char * argv[]) {
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *handle = NULL;
//open interface
handle = pcap_open_live("en0", 65535, 1, 1, errbuf);
if(!handle) {
fprintf(stderr, "pcap_open_live: %s\n", errbuf);
exit(1);
}//end if
//start capture loop
if(0 != pcap_loop(handle, 10, pcap_callback, NULL)) {
fprintf(stderr, "pcap_loop: %s\n", pcap_geterr(handle));
}//end if
//free
pcap_close(handle);
return 0;
}
void pcap_callback(u_char *arg, const struct pcap_pkthdr *header, const u_char *content) {
static int d = 0;
printf("%d: captured\n", ++d);
}//end pcap_callback
結果
libpcap % ./capture_pcap_loop
1: captured
2: captured
3: captured
4: captured
5: captured
6: captured
7: captured
8: captured
9: captured
10: captured
當有封包進出時,就會列印出目前抓到第幾個封包。
分析
//open interface
handle = pcap_open_live("en0", 65535, 1, 1, errbuf);
if(!handle) {
fprintf(stderr, "pcap_open_live: %s\n", errbuf);
exit(1);
}//end if
在抓封包的時候要先指定該從哪個Interface抓取封包,先使用pcap_open_live()
打開一個Interface,這邊因為我是要抓Wi-Fi所以第一個參數選擇en0
,第二個參數指定封包最大值表示說不切割封包。然後使用混雜模式以及設置to_ms
表示每毫秒處理封包。
//start capture loop
if(0 != pcap_loop(handle, 10, pcap_callback, NULL)) {
fprintf(stderr, "pcap_loop: %s\n", pcap_geterr(handle));
}//end if
如果沒有要設定過濾器就可以馬上抓封包了,這裡抓取十個封包後就停止,當有封包經過的時候會呼叫第三個參數所給的callback:pcap_callback()
,第四個參數是要傳給pcap_callback()
哪個變數。
//free
pcap_close(handle);
結束後記得要釋放pcap_open_live()
傳回的pcap_t *
結構指標。
void pcap_callback(u_char *arg, const struct pcap_pkthdr *header, const u_char *content) {
static int d = 0;
printf("%d: captured\n", ++d);
}//end pcap_callback
當有封包進出的時候,pcap_loop()
會呼叫這個callback,這個callback會記錄目前有幾個封包並列印出來。當pcap_loop()
的第四個參數有給參數的話,會傳給arg
變數,在這個程式裡pcap_loop()
第四個參數為NULL,所以這裡的arg
就是NULL囉。
結語
抓取封包最簡單只要兩個函數就可以完成,libpcap簡化了很多步驟讓開發者專心在封包分析上。但是這個方法使用callback方式,在一些物件導向語言會不好開發,例如Objective-C
,可以使用pcap_next_ex()
代替。