libpcap可以讀取一些數據供讀取,像是封包掉的資訊。
一樣開啟預設的device,然後隨意抓個封包,timeout訂在5000毫秒,過濾器用"tcp or udp"。
char errbuf[PCAP_ERRBUF_SIZE];
char *device = NULL;
//get default interface name
device = pcap_lookupdev(errbuf);
if(!device) {
fprintf(stderr, "pcap_lookupdev(): %s\n", errbuf);
exit(1);
}//end if
printf("Sniffing: %s\n", device);
//open interface
pcap_t *handle = pcap_open_live(device, 65535, 1, 5000, errbuf);
if(!handle) {
fprintf(stderr, "pcap_open_live(): %s\n", errbuf);
exit(1);
}//end if
//generate bpf filter
bpf_u_int32 net, mask;
struct bpf_program fcode;
//get network and mask
if(-1 == pcap_lookupnet(device, &net, &mask, errbuf)) {
fprintf(stderr, "pcap_lookupnet(): %s\n", errbuf);
mask = PCAP_NETMASK_UNKNOWN;
}//end if
//compile filter
if(-1 == pcap_compile(handle, &fcode, "tcp or udp", 1, mask)) {
fprintf(stderr, "pcap_compile(): %s\n", pcap_geterr(handle));
pcap_close(handle);
exit(1);
}//end if
//set filter
if(-1 == pcap_setfilter(handle, &fcode)) {
fprintf(stderr, "pcap_pcap_setfilter(): %s\n", pcap_geterr(handle));
pcap_freecode(&fcode);
pcap_close(handle);
exit(1);
}//end if
//free bpf code
pcap_freecode(&fcode);
//start capture
int capture = 0;
pcap_dispatch(handle, -1, pcap_callback, (u_char *)&capture);
其中變數capture是用來記錄目前抓到幾個封包了。
而callback只是單純紀錄抓到幾個封包了,要小心指標轉型。
static void pcap_callback(u_char *arg, const struct pcap_pkthdr *header, const u_char *content) {
int *capture = (int *)arg;
(*capture)++;
return;
}//end pcap_callback
函數
pcap_stats()可以抓取一些數據出來。
//get stat
struct pcap_stat ps;
if(pcap_stats(handle, &ps) != 0) {
fprintf(stderr, "pcap_stats(): %s\n", pcap_geterr(handle));
}//end if
else {
printf("Receive: %d\n", capture);
printf("Receive by filter: %d\n", ps.ps_recv);
printf("Drop by kernel: %d\n", ps.ps_drop);
printf("Drop by interface: %d\n", ps.ps_ifdrop);
}//end else
要注意的是成員
ps_recv是原本的封包數量,變數capture則是被過濾後命中條件的封包數量。函數
pcap_stats()原型:int pcap_stats(pcap_t *p, struct pcap_stat *ps);
- 回傳值:成功傳回0,失敗傳回-1,錯誤訊息從pcap_geterr()取得。
- 參數:p一個libpcap handle。ps數據結果指標。
- 功能:取得目前數據,不能用在檔案。
結構
struct stat宣告:
/*
* As returned by the pcap_stats()
*/
struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */
#ifdef WIN32
u_int bs_capt; /* number of packets that reach the application */
#endif /* WIN32 */
};
編譯:
libpcap % gcc -I/usr/local/opt/libpcap/include -Wall -std=gnu99 -L/usr/local/opt/libpcap/lib -lpcap get-stat.c -o get-stat
執行結果:
libpcap % ./get-stat Sniffing: en0 Receive: 343 Receive by filter: 358 Drop by kernel: 0 Drop by interface: 0
在這timeout前總共358個封包接收到,343個封包符合"tcp or udp"條件,0個被丟棄。
Source code on Github
沒有留言:
張貼留言