<Kxing 原創(chuàng),水平有限、歡迎批評和指正。如需轉(zhuǎn)載請注明作者與出處>
一
libpcap是一個C語言庫,其功能是通過網(wǎng)卡抓取網(wǎng)絡(luò)以太網(wǎng)中的數(shù)據(jù)包,在windows系統(tǒng)下有相應(yīng)的winpcap庫。
要想使用這個庫自然先要知道它在哪里,怎么安裝就不廢話了。在/usr/local/lib下有l(wèi)ibpcap.a和libpcao.so,在/usr/local/include下有pcap.h,打開手冊的命令是man pcap,而不是man libpcap,如果覺得在字符模式下查看man太麻煩也可以baidu或者google一下"man pcap"會又可讀性更高的手冊。要寫一個使用libpcap的程序只需要在代碼中加上#i nclude <pcap.h>,然后在編譯時使用-lpcap選項就可以了,例如:
$>gcc -o test1 test1.c -lpcap
二
如果能正確的編譯通過使用libpcap的代碼,那么便可以進(jìn)入第二步了,寫一個最簡單的抓包程序。
先來介紹第一個類型:pcap_t。要抓包就要首先生成一個抓包的描述符(或稱句柄),后來的很多操作都需要用這個描述符做參數(shù)。pcap_t就是由pcap.h定義的抓包描述符的類型,函數(shù)pcap_open_live返回指向該類型的指針:
pcap_t *pd = pcap_open_live ("eth0", 68, 0, 1000, ebuf);
其中第一個參數(shù)表示用來抓包的設(shè)備;第二個參數(shù)定義了抓包的最大字節(jié)數(shù),如果這個值小于包的大小(如定義為68,包大于68),那么則只抓這個包的前68個字節(jié);第三個參數(shù)把網(wǎng)卡設(shè)置為混雜模式,以便抓取以太網(wǎng)中的數(shù)據(jù)包;第四個參數(shù)是一個以毫秒為單位的讀取超時時間,如果設(shè)置為0則超時時間為無限大;第五個參數(shù)為出錯信息,需要這樣聲明(第一個簡單的程序不需要出錯處理,只知道這樣聲明就夠了):
char ebuf[PCAP_ERRBUF_SIZE];
好了,現(xiàn)在生成了一個描述符了,現(xiàn)在我們可以用它來做一點什么事情了。開始一個抓包的循環(huán),然后關(guān)閉抓包過程(釋放描述符):
pcap_loop (pd, 7, printer, NULL);
pcap_close (pd);
這里的pd就是我們剛剛生成的描述符;pcap_loop的第二個參數(shù)表示抓多少個包,設(shè)置為-1表示不定義數(shù)量,抓取所有的包;第三個參數(shù)是一個回調(diào)函數(shù),每當(dāng)抓到一個數(shù)據(jù)包之后程序?qū)⒆詣诱{(diào)用這個函數(shù);第四個參數(shù)是一個指針,可以為空,將在下面詳細(xì)講解。
下面我們來詳細(xì)的實現(xiàn)這個回調(diào)函數(shù),使其每抓到一個包則打印一次:
void printer()
{
printf("A packet is captured! ");
printf(" \n");
return;
}
當(dāng)程序成功編譯以后執(zhí)行,則每抓到一個包后輸出一行"A packet is captured! ",輸出7行以后退出程序。
參考源碼:
/**
libpcap test program
compile command:"$>gcc -o exe_file_name this_file_name -lpcap"
written by Kxing <S.Kxing@gmail.com>
Last Modified 2006-03-02
*/
#i nclude <stdio.h>
#i nclude <pcap.h>
int main (int argc, char* argv[])
{
/*the printer running when packet have captured*/
void printer()
{
printf("A packet is captured!");
printf(" \n");
return;
}
/*the error code buf of libpcap*/
char ebuf[PCAP_ERRBUF_SIZE];
/*create capture handler of libpcap*/
pcap_t *pd = pcap_open_live ("eth0", 68, 0, 1000, ebuf);
/*start the loop of capture, loop 7 times, enter printer when capted*/
pcap_loop (pd, 7, printer, NULL);
pcap_close (pd);
return 0;
}