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