libpcap/capture_pcap_next_ex.c
前面兩種方法pcap_loop()
和pcap_dispatch()
都是利用callback的方式抓封包,在物件導向語言使用上比較不方便,在這裡介紹第三種方法:pcap_next_ex()
(pcap_next()
就不介紹了,跟pcap_next_ex()
用法差不多)。
Source Code
//
// capture_pcap_next_ex.c
// 功能:使用pcap_next_ex抓取封包。
// Created by 聲華 陳 on 2015/12/30.
//
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
int main(int argc, const char * argv[]) {
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *handle = NULL;
struct pcap_pkthdr *header = NULL;
const u_char *content = NULL;
//open interface
handle = pcap_open_live("en0", 65535, 1, 1000, errbuf);
if(!handle) {
fprintf(stderr, "pcap_open_live: %s\n", errbuf);
exit(1);
}//end if
//start capture
int ret =
pcap_next_ex(handle, &header, &content);
if(ret == 1) {
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
local_tv_sec = header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);
//print header
printf("Time: %s.%.6d\n", timestr, header->ts.tv_usec);
printf("Length: %d bytes\n", header->len);
printf("Capture length: %d bytes\n", header->caplen);
//print packet in hex dump
for(int i = 0 ; i < header->caplen ; i++) {
printf("%02x ", content[i]);
}//end for
printf("\n\n");
}//end if success
else if(ret == 0) {
printf("Timeout\n");
}//end if timeout
else if(ret == -1) {
fprintf(stderr, "pcap_next_ex: %s\n", pcap_geterr(handle));
}//end if fail
else if(ret == -2) {
printf("No more packet from file\n");
}//end if read no more packet
//free
pcap_close(handle);
return 0;
}
結果
libpcap % ./capture_pcap_next_ex
Time: 23:48:03.256262
Length: 66 bytes
Capture length: 66 bytes
f8 1a 67 53 f5 dc 6c 40 08 bc ae 98 08 00 45 00 00 34 b6 ec 40 00 40 06 a9 29 c0 a8 01 64 6c a0 ac 01 dd 15 01 bb a4 3a 46 c0 e8 c0 ea c1 80 11 10 00 7a 10 00 00 01 01 08 0a 41 75 56 1f 86 73 56 a7
分析
//open interface
handle = pcap_open_live("en0", 65535, 1, 1000, errbuf);
if(!handle) {
fprintf(stderr, "pcap_open_live: %s\n", errbuf);
exit(1);
}//end if
這次就不分割封包,直接第二個參數給65535
,to_ms
設置1000
毫秒。
//start capture
int ret =
pcap_next_ex(handle, &header, &content);
if(ret == 1) {
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
local_tv_sec = header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);
//print header
printf("Time: %s.%.6d\n", timestr, header->ts.tv_usec);
printf("Length: %d bytes\n", header->len);
printf("Capture length: %d bytes\n", header->caplen);
//print packet in hex dump
for(int i = 0 ; i < header->caplen ; i++) {
printf("%02x ", content[i]);
}//end for
printf("\n\n");
}//end if success
else if(ret == 0) {
printf("Timeout\n");
}//end if timeout
else if(ret == -1) {
fprintf(stderr, "pcap_next_ex: %s\n", pcap_geterr(handle));
}//end if fail
else if(ret == -2) {
printf("No more packet from file\n");
}//end if read no more packet
函數pcap_next()
只會抓取一個封包而已,如果要一直抓封包可以利用迴圈。這裡一樣把封包的時間資訊、長度以及封包內容給顯示出來。
//free
pcap_close(handle);
結束後記得釋放。
結語
這個函數不同於pcap_loop()
和pcap_dispatch()
在於它不使用callback方式處理封包,在物件導向語言使用上比較方便,Wireshark也是用此函數來抓取封包。至於什麼時候要用什麼函數,就看需求來使用。