使用 libpcap 实现网络转包
概述
libpcap 是一個網(wǎng)絡(luò)數(shù)據(jù)包捕獲函數(shù)庫,功能非常強(qiáng)大,Linux 下著名的 tcpdump 就是以它為基礎(chǔ)的。
libpcap主要的作用
1)捕獲各種數(shù)據(jù)包,列如:網(wǎng)絡(luò)流量統(tǒng)計(jì)。
2)過濾網(wǎng)絡(luò)數(shù)據(jù)包,列如:過濾掉本地上的一些數(shù)據(jù),類似防火墻。
3)分析網(wǎng)絡(luò)數(shù)據(jù)包,列如:分析網(wǎng)絡(luò)協(xié)議,數(shù)據(jù)的采集。
4)存儲網(wǎng)絡(luò)數(shù)據(jù)包,列如:保存捕獲的數(shù)據(jù)以為將來進(jìn)行分析。
libpcap 的安裝
libpcap 的抓包框架
pcap_lookupdev():函數(shù)用于查找網(wǎng)絡(luò)設(shè)備,返回可被 pcap_open_live() 函數(shù)調(diào)用的網(wǎng)絡(luò)設(shè)備名指針。
pcap_lookupnet():函數(shù)獲得指定網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號和掩碼。
pcap_open_live(): 函數(shù)用于打開網(wǎng)絡(luò)設(shè)備,并且返回用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包的數(shù)據(jù)包捕獲描述字。對于此網(wǎng)絡(luò)設(shè)備的操作都要基于此網(wǎng)絡(luò)設(shè)備描述字。
pcap_compile(): 函數(shù)用于將用戶制定的過濾策略編譯到過濾程序中。
pcap_setfilter():函數(shù)用于設(shè)置過濾器。
pcap_loop():函數(shù) pcap_dispatch() 函數(shù)用于捕獲數(shù)據(jù)包,捕獲后還可以進(jìn)行處理,此外 pcap_next() 和 pcap_next_ex() 兩個函數(shù)也可以用來捕獲數(shù)據(jù)包。
pcap_close():函數(shù)用于關(guān)閉網(wǎng)絡(luò)設(shè)備,釋放資源。
利用 libpcap 函數(shù)庫開發(fā)應(yīng)用程序的基本步驟:
1、打開網(wǎng)絡(luò)設(shè)備
2、設(shè)置過濾規(guī)則
3、捕獲數(shù)據(jù)
4、關(guān)閉網(wǎng)絡(luò)設(shè)備
抓包詳細(xì)步驟
首先要使用 libpcap,我們必須包含 pcap.h 頭文件,可以在 /usr/local/include/pcap/pcap.h 找到,其中包含了每個類型定義的詳細(xì)說明。
1、獲取網(wǎng)絡(luò)接口設(shè)備名
char *pcap_lookupdev(char *errbuf);
功能:
得到可用的網(wǎng)絡(luò)設(shè)備名指針
參數(shù):
errbuf:存放出錯信息字符串,里面有個宏定義:PCAP_ERRBUF_SIZE,為錯誤緩沖區(qū)大小
返回值:
成功返回設(shè)備名指針(第一個合適的網(wǎng)絡(luò)接口的字符串指針);
失敗返回 NULL,同時,errbuf 存放出錯信息字符串。
實(shí)例如下:
char error_content[PCAP_ERRBUF_SIZE] = {0}; // 出錯信息
char *dev = pcap_lookupdev(error_content);
if(NULL == dev)
{
printf(error_content);
exit(-1);
}
2、獲取網(wǎng)絡(luò)號(ip 地址)和掩碼
int pcap_lookupnet( ? ?char *device, ? ? ? ? ? ? ? ? ? ?
bpf_u_int32 *netp,?
bpf_u_int32 *maskp, ? ??
char *errbuf ?);功能:
獲取指定網(wǎng)卡的 ip 地址,子網(wǎng)掩碼
參數(shù):
device:網(wǎng)絡(luò)設(shè)備名,為第一步獲取的網(wǎng)絡(luò)接口字符串(pcap_lookupdev() 的返回值 ),也可人為指定,如“eth0”。
netp:存放 ip 地址的指針,bpf_u_int32 為 32 位無符號整型
maskp:存放子網(wǎng)掩碼的指針,bpf_u_int32 為 32 位無符號整型
errbuf:存放出錯信息
返回值:
成功返回 0,失敗返回 -1
實(shí)例如下:
char error_content[PCAP_ERRBUF_SIZE] = {0}; // 出錯信息
char *dev = pcap_lookupdev(error_content);
if(NULL == dev)
{
printf(error_content);
exit(-1);
}
bpf_u_int32 netp = 0, maskp = 0;
pcap_t * pcap_handle = NULL;
int ret = 0;
//獲得網(wǎng)絡(luò)號和掩碼
ret = pcap_lookupnet(dev, &netp, &maskp, error_content);
if(ret == -1)
{
printf(error_content);
exit(-1);
}
3、打開網(wǎng)絡(luò)接口
pcap_t *pcap_open_live( ?const char *device,
int snaplen,
int promisc,
int to_ms,
char *ebuf );
功能:
打開一個用于捕獲數(shù)據(jù)的網(wǎng)絡(luò)接口
參數(shù):
device:網(wǎng)絡(luò)接口的名字,為第一步獲取的網(wǎng)絡(luò)接口字符串(pcap_lookupdev() 的返回值 ),也可人為指定,如“eth0”。
snaplen:捕獲數(shù)據(jù)包的長度,長度不能大于 65535 個字節(jié)。
promise:“1” 代表混雜模式,其它非混雜模式。什么為混雜模式,請看《原始套接字編程》。
to_ms:指定需要等待的毫秒數(shù),超過這個數(shù)值后,獲取數(shù)據(jù)包的函數(shù)就會立即返回(這個函數(shù)不會阻塞,后面的抓包函數(shù)才會阻塞)。0 表示一直等待直到有數(shù)據(jù)包到來。
ebuf:存儲錯誤信息。
返回值:
返回 pcap_t 類型指針,后面的所有操作都要使用這個指針。
實(shí)例如下:
char?error_content[PCAP_ERRBUF_SIZE]?=?{0}; //?出錯信息 char?*dev?=?pcap_lookupdev(error_content); //?獲取網(wǎng)絡(luò)接口 if(NULL?==?dev) {printf(error_content);exit(-1); }//?打開網(wǎng)絡(luò)接口 pcap_t?*?pcap_handle?=?pcap_open_live(dev,?1024,?1,?0,?error_content); if(NULL?==?pcap_handle) {printf(error_content);exit(-1); }4、獲取數(shù)據(jù)包
a)
const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h);
功能:
捕獲一個網(wǎng)絡(luò)數(shù)據(jù)包,收到一個數(shù)據(jù)包立即返回
參數(shù):
p:pcap_open_live()返回的?pcap_t?類型的指針
h:數(shù)據(jù)包頭
pcap_pkthdr 類型的定義如下:
struct?pcap_pkthdr {struct?timeval?ts;?//?抓到包的時間bpf_u_int32?caplen;?//?表示抓到的數(shù)據(jù)長度bpf_u_int32?len;?//?表示數(shù)據(jù)包的實(shí)際長度 }len 和 caplen的區(qū)別:
返回值:
成功返回捕獲數(shù)據(jù)包的地址,失敗返回 NULL
實(shí)例如下:
[cpp]
const?unsigned?char?*p_packet_content?=?NULL;?//?保存接收到的數(shù)據(jù)包的起始地址 pcap_t?*pcap_handle?=?NULL; struct?pcap_pkthdr?protocol_header;pcap_handle?=?pcap_open_live("eth0",?1024,?1,?0,NULL);p_packet_content?=?pcap_next(pcap_handle,?&protocol_header);? //p_packet_content??所捕獲數(shù)據(jù)包的地址printf("Capture?Time?is?:%s",ctime((const?time_t?*)&protocol_header.ts.tv_sec));?//?時間 printf("Packet?Lenght?is?:%d\n",protocol_header.len); //?數(shù)據(jù)包的實(shí)際長度//?分析以太網(wǎng)中的?源mac、目的mac struct?ether_header?*ethernet_protocol?=?NULL; unsigned?char?*p_mac_string?=?NULL; //?保存mac的地址,臨時變量ethernet_protocol?=?(struct?ether_header?*)p_packet_content;??//struct?ether_header?以太網(wǎng)幀頭部p_mac_string?=?(unsigned?char?*)ethernet_protocol->ether_shost;//獲取源mac printf("Mac?Source?Address?is?%02x:%02x:%02x:%02x:%02x:%02x\n",*(p_mac_string+0),*(p_mac_string+1),*(p_mac_string+2),*(p_mac_string+3),*(p_mac_string+4),*(p_mac_string+5));p_mac_string?=?(unsigned?char?*)ethernet_protocol->ether_dhost;//獲取目的mac printf("Mac?Destination?Address?is?%02x:%02x:%02x:%02x:%02x:%02x\n",*(p_mac_string+0),*(p_mac_string+1),*(p_mac_string+2),*(p_mac_string+3),*(p_mac_string+4),*(p_mac_string+5));b)
int pcap_loop( ? ? pcap_t *p,
int cnt,
pcap_handler callback,
u_char *user );
功能:
循環(huán)捕獲網(wǎng)絡(luò)數(shù)據(jù)包,直到遇到錯誤或者滿足退出條件。每次捕獲一個數(shù)據(jù)包就會調(diào)用 callback 指定的回調(diào)函數(shù),所以,可以在回調(diào)函數(shù)中進(jìn)行數(shù)據(jù)包的處理操作。
參數(shù):
p:pcap_open_live()返回的?pcap_t?類型的指針。
cnt:指定捕獲數(shù)據(jù)包的個數(shù),一旦抓到了 cnt 個數(shù)據(jù)包,pcap_loop 立即返回。如果是 -1,就會永無休止的捕獲,直到出現(xiàn)錯誤。
callback:回調(diào)函數(shù),名字任意,根據(jù)需要自行起名。
user:向回調(diào)函數(shù)中傳遞的參數(shù)。
callback?回調(diào)函數(shù)的定義:
void callback( ?u_char *userarg,?
const struct pcap_pkthdr * pkthdr,?
const u_char * packet )
userarg:pcap_loop() 的最后一個參數(shù),當(dāng)收到足夠數(shù)量的包后 pcap_loop 會調(diào)用callback 回調(diào)函數(shù),同時將pcap_loop()的user參數(shù)傳遞給它
pkthdr:是收到數(shù)據(jù)包的 pcap_pkthdr 類型的指針,和?pcap_next() 第二個參數(shù)是一樣的。
packet?:收到的數(shù)據(jù)包數(shù)據(jù)
返回值:
成功返回0,失敗返回負(fù)數(shù)
實(shí)例如下:
[cpp]
if(?pcap_loop(pcap_handle,?-1,?ethernet_protocol_callback,?NULL)?<?0?) {perror("pcap_loop"); }/*******************************回調(diào)函數(shù)************************************/ void?ethernet_protocol_callback(unsigned?char?*argument,const?struct?pcap_pkthdr?*packet_heaher,const?unsigned?char?*packet_content) {unsigned?char?*mac_string; //struct?ether_header?*ethernet_protocol;unsigned?short?ethernet_type; //以太網(wǎng)類型printf("----------------------------------------------------\n");printf("%s\n",?ctime((time_t?*)&(packet_heaher->ts.tv_sec)));?//轉(zhuǎn)換時間ethernet_protocol?=?(struct?ether_header?*)packet_content;mac_string?=?(unsigned?char?*)ethernet_protocol->ether_shost;//獲取源mac地址printf("Mac?Source?Address?is?%02x:%02x:%02x:%02x:%02x:%02x\n",*(mac_string+0),*(mac_string+1),*(mac_string+2),*(mac_string+3),*(mac_string+4),*(mac_string+5));mac_string?=?(unsigned?char?*)ethernet_protocol->ether_dhost;//獲取目的macprintf("Mac?Destination?Address?is?%02x:%02x:%02x:%02x:%02x:%02x\n",*(mac_string+0),*(mac_string+1),*(mac_string+2),*(mac_string+3),*(mac_string+4),*(mac_string+5));ethernet_type?=?ntohs(ethernet_protocol->ether_type);//獲得以太網(wǎng)的類型printf("Ethernet?type?is?:%04x\n",ethernet_type);switch(ethernet_type){case?0x0800:printf("The?network?layer?is?IP?protocol\n");break;//ipcase?0x0806:printf("The?network?layer?is?ARP?protocol\n");break;//arpcase?0x0835:printf("The?network?layer?is?RARP?protocol\n");break;//rarpdefault:break;}usleep(800*1000); }c)
int pcap_dispatch(pcap_t * p, int cnt, pcap_handler callback, u_char * user);
這個函數(shù)和 pcap_loop() 非常類似,只是在超過 to_ms 毫秒后就會返回( to_ms 是pcap_open_live() 的第4個參數(shù) )
5、釋放網(wǎng)絡(luò)接口
void pcap_close(pcap_t *p);
功能:
關(guān)閉 pcap_open_live() 打開的網(wǎng)絡(luò)接口(即其返回值,pcap_t 類型指針),并釋放相關(guān)資源。注意,操作完網(wǎng)絡(luò)接口,應(yīng)該釋放其資源。
參數(shù):
p:需要關(guān)閉的網(wǎng)絡(luò)接口,pcap_open_live()?的返回值(pcap_t 類型指針)
返回值:
無
實(shí)例如下:
//?打開網(wǎng)絡(luò)接口 pcap_t?*?pcap_handle?=?pcap_open_live("eth0",?1024,?1,?0,?error_content); if(NULL?==?pcap_handle) {printf(error_content);exit(-1); }…………pcap_close(pcap_handle);?//釋放網(wǎng)絡(luò)接口
例子1(接收一個數(shù)據(jù)包):
#include?<stdio.h> #include?<pcap.h> #include?<arpa/inet.h> #include?<time.h> #include?<stdlib.h> struct?ether_header {unsigned?char?ether_dhost[6]; //目的macunsigned?char?ether_shost[6]; //源macunsigned?short?ether_type; //以太網(wǎng)類型 }; #define?BUFSIZE?1514int?main(int?argc,char?*argv[]) {pcap_t?*?pcap_handle?=?NULL;char?error_content[100]?=?""; //?出錯信息const?unsigned?char?*p_packet_content?=?NULL; //?保存接收到的數(shù)據(jù)包的起始地址unsigned?char?*p_mac_string?=?NULL; //?保存mac的地址,臨時變量unsigned?short?ethernet_type?=?0; //?以太網(wǎng)類型char?*p_net_interface_name?=?NULL; //?接口名字struct?pcap_pkthdr?protocol_header;struct?ether_header?*ethernet_protocol;//獲得接口名p_net_interface_name?=?pcap_lookupdev(error_content);if(NULL?==?p_net_interface_name){perror("pcap_lookupdev");exit(-1);}//打開網(wǎng)絡(luò)接口pcap_handle?=?pcap_open_live(p_net_interface_name,BUFSIZE,1,0,error_content);p_packet_content?=?pcap_next(pcap_handle,&protocol_header);printf("------------------------------------------------------------------------\n");printf("capture?a?Packet?from?p_net_interface_name?:%s\n",p_net_interface_name);printf("Capture?Time?is?:%s",ctime((const?time_t?*)&protocol_header.ts.tv_sec));printf("Packet?Lenght?is?:%d\n",protocol_header.len);/**分析以太網(wǎng)中的?源mac、目的mac*/ethernet_protocol?=?(struct?ether_header?*)p_packet_content;p_mac_string?=?(unsigned?char?*)ethernet_protocol->ether_shost;//獲取源macprintf("Mac?Source?Address?is?%02x:%02x:%02x:%02x:%02x:%02x\n",*(p_mac_string+0),*(p_mac_string+1),*(p_mac_string+2),*(p_mac_string+3),*(p_mac_string+4),*(p_mac_string+5));p_mac_string?=?(unsigned?char?*)ethernet_protocol->ether_dhost;//獲取目的macprintf("Mac?Destination?Address?is?%02x:%02x:%02x:%02x:%02x:%02x\n",*(p_mac_string+0),*(p_mac_string+1),*(p_mac_string+2),*(p_mac_string+3),*(p_mac_string+4),*(p_mac_string+5));/**獲得以太網(wǎng)的數(shù)據(jù)包的地址,然后分析出上層網(wǎng)絡(luò)協(xié)議的類型*/ethernet_type?=?ntohs(ethernet_protocol->ether_type);printf("Ethernet?type?is?:%04x\t",ethernet_type);switch(ethernet_type){case?0x0800:printf("The?network?layer?is?IP?protocol\n");break;//ipcase?0x0806:printf("The?network?layer?is?ARP?protocol\n");break;//arpcase?0x0835:printf("The?network?layer?is?RARP?protocol\n");break;//rarpdefault:printf("The?network?layer?unknow!\n");break;}pcap_close(pcap_handle);return?0; }注意:gcc 編譯時需要加上 -lpcap,運(yùn)行時需要使用超級權(quán)限
例子2(接收多個數(shù)據(jù)包):
[cpp] #include?<stdio.h> #include?<pcap.h> #include?<arpa/inet.h> #include?<time.h> #include?<stdlib.h>#define?BUFSIZE?1514struct?ether_header {unsigned?char?ether_dhost[6]; //目的macunsigned?char?ether_shost[6]; //源macunsigned?short?ether_type; //以太網(wǎng)類型 };/*******************************回調(diào)函數(shù)************************************/ void?ethernet_protocol_callback(unsigned?char?*argument,const?struct?pcap_pkthdr?*packet_heaher,const?unsigned?char?*packet_content) {unsigned?char?*mac_string; //struct?ether_header?*ethernet_protocol;unsigned?short?ethernet_type; //以太網(wǎng)類型printf("----------------------------------------------------\n");printf("%s\n",?ctime((time_t?*)&(packet_heaher->ts.tv_sec)));?//轉(zhuǎn)換時間ethernet_protocol?=?(struct?ether_header?*)packet_content;mac_string?=?(unsigned?char?*)ethernet_protocol->ether_shost;//獲取源mac地址printf("Mac?Source?Address?is?%02x:%02x:%02x:%02x:%02x:%02x\n",*(mac_string+0),*(mac_string+1),*(mac_string+2),*(mac_string+3),*(mac_string+4),*(mac_string+5));mac_string?=?(unsigned?char?*)ethernet_protocol->ether_dhost;//獲取目的macprintf("Mac?Destination?Address?is?%02x:%02x:%02x:%02x:%02x:%02x\n",*(mac_string+0),*(mac_string+1),*(mac_string+2),*(mac_string+3),*(mac_string+4),*(mac_string+5));ethernet_type?=?ntohs(ethernet_protocol->ether_type);//獲得以太網(wǎng)的類型printf("Ethernet?type?is?:%04x\n",ethernet_type);switch(ethernet_type){case?0x0800:printf("The?network?layer?is?IP?protocol\n");break;//ipcase?0x0806:printf("The?network?layer?is?ARP?protocol\n");break;//arpcase?0x0835:printf("The?network?layer?is?RARP?protocol\n");break;//rarpdefault:break;}usleep(800*1000); }int?main(int?argc,?char?*argv[]) {char?error_content[100]; //出錯信息pcap_t?*?pcap_handle;unsigned?char?*mac_string; unsigned?short?ethernet_type; //以太網(wǎng)類型char?*net_interface?=?NULL; //接口名字struct?pcap_pkthdr?protocol_header;struct?ether_header?*ethernet_protocol;//獲取網(wǎng)絡(luò)接口net_interface?=?pcap_lookupdev(error_content);if(NULL?==?net_interface){perror("pcap_lookupdev");exit(-1);}pcap_handle?=?pcap_open_live(net_interface,BUFSIZE,1,0,error_content);//打開網(wǎng)絡(luò)接口if(pcap_loop(pcap_handle,-1,ethernet_protocol_callback,NULL)?<?0){perror("pcap_loop");}pcap_close(pcap_handle);return?0; }
運(yùn)行情況如下:
過濾數(shù)據(jù)包
我們抓到的數(shù)據(jù)包往往很多,如何過濾掉我們不感興趣的數(shù)據(jù)包呢?
幾乎所有的操作系統(tǒng)( BSD, AIX, Mac OS, Linux 等)都會在內(nèi)核中提供過濾數(shù)據(jù)包的方法,主要都是基于 BSD Packet Filter( BPF ) 結(jié)構(gòu)的。libpcap 利用 BPF 來過濾數(shù)據(jù)包。
1)設(shè)置過濾條件
BPF 使用一種類似于匯編語言的語法書寫過濾表達(dá)式,不過 libpcap 和 tcpdump 都把它封裝成更高級且更容易的語法了,具體可以通過 man tcpdump查看:
以下是一些例子:
src host 192.168.1.177
只接收源 ip 地址是 192.168.1.177 的數(shù)據(jù)包
dst port 80
只接收 tcp/udp 的目的端口是 80 的數(shù)據(jù)包
not tcp
只接收不使用 tcp 協(xié)議的數(shù)據(jù)包
tcp[13] == 0x02 and (dst port 22 or dst port 23)
只接收 SYN 標(biāo)志位置位且目標(biāo)端口是 22 或 23 的數(shù)據(jù)包( tcp 首部開始的第 13 個字節(jié))
icmp[icmptype] == icmp-echoreply or icmp[icmptype] == icmp-echo
只接收 icmp 的 ping 請求和 ping 響應(yīng)的數(shù)據(jù)包
ehter dst 00:e0:09:c1:0e:82
只接收以太網(wǎng) mac 地址是 00:e0:09:c1:0e:82 的數(shù)據(jù)包
ip[8] == 5
只接收 ip 的 ttl=5 的數(shù)據(jù)包(ip首部開始的第8個字節(jié))
2)編譯 BPF 過濾規(guī)則
int pcap_compile( ?pcap_t *p,
struct bpf_program *fp,
char *buf,int optimize,
bpf_u_int32 mask );
功能:
編譯 BPF 過濾規(guī)則
參數(shù):
p:pcap_open_live()?返回的 pcap_t 類型的指針
fp:存放編譯后的 bpf,應(yīng)用過濾規(guī)則時需要用到這個指針
buf:過濾條件
optimize:是否需要優(yōu)化過濾表達(dá)式
mask:指定本地網(wǎng)絡(luò)的網(wǎng)絡(luò)掩碼,不需要時可寫 0
返回值:
成功返回 0,失敗返回 -1
3)應(yīng)用?BPF 過濾規(guī)則
int pcap_setfilter( pcap_t * p, ?struct bpf_program * fp );
功能:
應(yīng)用 BPF 過濾規(guī)則,簡單理解為讓過濾生效
參數(shù):
p:pcap_open_live()?返回的 pcap_t 類型的指針
fp:pcap_compile() 的第二個參數(shù)
返回值:
成功返回 0,失敗返回 -1
這個編譯應(yīng)用過程,有點(diǎn)類似于,我們寫一個 C 程序,先編譯,后運(yùn)行的過程。
應(yīng)用完過濾表達(dá)式之后我們便可以使用 pcap_loop() 或 pcap_next() 等抓包函數(shù)來抓包了。
下面的程序演示了如何過濾數(shù)據(jù)包,我們只接收目的端口是 80 的數(shù)據(jù)包:
?[cpp]
#include?<pcap.h> #include?<time.h> #include?<stdlib.h> #include?<stdio.h>void?getPacket(u_char?*?arg,?const?struct?pcap_pkthdr?*?pkthdr,?const?u_char?*?packet) {int?*?id?=?(int?*)arg;printf("id:?%d\n",?++(*id));printf("Packet?length:?%d\n",?pkthdr->len);printf("Number?of?bytes:?%d\n",?pkthdr->caplen);printf("Recieved?time:?%s",?ctime((const?time_t?*)&pkthdr->ts.tv_sec));?int?i;for(i=0;?i<pkthdr->len;?++i){printf("?%02x",?packet[i]);if(?(i?+?1)?%?16?==?0?){printf("\n");}}printf("\n\n"); }int?main() {char?errBuf[PCAP_ERRBUF_SIZE],?*?devStr;/*?get?a?device?*/devStr?=?pcap_lookupdev(errBuf);if(devStr){printf("success:?device:?%s\n",?devStr);}else{printf("error:?%s\n",?errBuf);exit(1);}/*?open?a?device,?wait?until?a?packet?arrives?*/pcap_t?*?device?=?pcap_open_live(devStr,?65535,?1,?0,?errBuf);if(!device){printf("error:?pcap_open_live():?%s\n",?errBuf);exit(1);}/*?construct?a?filter?*/struct?bpf_program?filter;pcap_compile(device,?&filter,?"dst?port?80",?1,?0);pcap_setfilter(device,?&filter);/*?wait?loop?forever?*/int?id?=?0;pcap_loop(device,?-1,?getPacket,?(u_char*)&id);pcap_close(device);return?0; }轉(zhuǎn)載出處:http://blog.csdn.net/tennysonsky/article/details/44811899
轉(zhuǎn)載于:https://blog.51cto.com/aaroncao/1840193
總結(jié)
以上是生活随笔為你收集整理的使用 libpcap 实现网络转包的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android隐藏状态栏、导航栏
- 下一篇: android的m、mm、mmm编译命令