c++ winpcap开发(9)
收集網(wǎng)絡(luò)流量統(tǒng)計(jì)
本課程展示了WinPcap的另一個(gè)高級(jí)功能:收集網(wǎng)絡(luò)流量統(tǒng)計(jì)信息的能力。統(tǒng)計(jì)引擎利用內(nèi)核級(jí)包過濾器對(duì)傳入的數(shù)據(jù)包進(jìn)行有效的分類。如果您想了解更多詳細(xì)信息,可以參考NPF驅(qū)動(dòng)程序內(nèi)部手冊(cè)。
為了使用此功能,程序員必須打開適配器并將其置于統(tǒng)計(jì)?模式。這可以用pcap_setmode()完成。特別地,MODE_STAT必須用作該函數(shù)的模式參數(shù)。
通過統(tǒng)計(jì)模式,監(jiān)控TCP流量負(fù)載的應(yīng)用程序是幾行代碼。以下示例顯示如何執(zhí)行此操作。
#include <stdlib.h> #include <stdio.h>#include <pcap.h>void usage();void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);void main(int argc, char **argv) { pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE]; struct timeval st_ts; u_int netmask; struct bpf_program fcode;/* Check the validity of the command line */if (argc != 2){usage();return;}/* Open the output adapter */if ( (fp= pcap_open(argv[1], 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL){fprintf(stderr,"\nUnable to open adapter %s.\n", errbuf);return;}/* Don't care about netmask, it won't be used for this filter */netmask=0xffffff; //compile the filterif (pcap_compile(fp, &fcode, "tcp", 1, netmask) <0 ){fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");/* Free the device list */return;}//set the filterif (pcap_setfilter(fp, &fcode)<0){fprintf(stderr,"\nError setting the filter.\n");pcap_close(fp);/* Free the device list */return;}/* Put the interface in statstics mode */if (pcap_setmode(fp, MODE_STAT)<0){fprintf(stderr,"\nError setting the mode.\n");pcap_close(fp);/* Free the device list */return;}printf("TCP traffic summary:\n");/* Start the main loop */pcap_loop(fp, 0, dispatcher_handler, (PUCHAR)&st_ts);pcap_close(fp);return; }void dispatcher_handler(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data) {struct timeval *old_ts = (struct timeval *)state;u_int delay;LARGE_INTEGER Bps,Pps;struct tm ltime;char timestr[16];time_t local_tv_sec;/* Calculate the delay in microseconds from the last sample. *//* This value is obtained from the timestamp that the associated with the sample. */delay=(header->ts.tv_sec - old_ts->tv_sec) * 1000000 - old_ts->tv_usec + header->ts.tv_usec;/* Get the number of Bits per second */Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay));/* ^ ^| || | | |converts bytes in bits -- ||delay is expressed in microseconds --*//* Get the number of Packets per second */Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay));/* Convert the timestamp to readable format */local_tv_sec = header->ts.tv_sec;localtime_s(<ime, &local_tv_sec);strftime( timestr, sizeof timestr, "%H:%M:%S", <ime);/* Print timestamp*/printf("%s ", timestr);/* Print the samples */printf("BPS=%I64u ", Bps.QuadPart);printf("PPS=%I64u\n", Pps.QuadPart);//store current timestampold_ts->tv_sec=header->ts.tv_sec;old_ts->tv_usec=header->ts.tv_usec; }void usage() {printf("\nShows the TCP traffic load, in bits per second and packets per second.\nCopyright (C) 2002 Loris Degioanni.\n");printf("\nUsage:\n");printf("\t tcptop adapter\n");printf("\t You can use \"WinDump -D\" if you don't know the name of your adapters.\n");exit(0); }在啟用統(tǒng)計(jì)模式之前,用戶可以選擇設(shè)置一個(gè)過濾器,該過濾器定義要監(jiān)視的網(wǎng)絡(luò)流量子集。有關(guān)詳細(xì)信息,請(qǐng)參閱過濾表達(dá)式語(yǔ)法中的段落。如果沒有設(shè)置過濾器,將監(jiān)視所有流量。
一旦
- 過濾器設(shè)置
- pcap_setmode()被調(diào)用
- 使用pcap_loop()啟用回調(diào)調(diào)用
接口描述符在統(tǒng)計(jì)模式下開始工作。注意pcap_open()的第四個(gè)參數(shù)(to_ms):它定義統(tǒng)計(jì)樣本之間的間隔?;卣{(diào)函數(shù)接收由驅(qū)動(dòng)程序計(jì)算的樣本每至幾毫秒。這些樣本被封裝在回調(diào)函數(shù)的第二和第三個(gè)參數(shù)中,如下圖所示:
提供兩個(gè)64位計(jì)數(shù)器:最后一個(gè)間隔期間的數(shù)據(jù)包數(shù)量和字節(jié)數(shù)。
在該示例中,適配器打開超時(shí)1000 ms。這意味著dispatcher_handler()每秒調(diào)用一次。此時(shí),只保存tcp數(shù)據(jù)包的過濾器被編譯和設(shè)置。然后調(diào)用pcap_setmode()和pcap_loop()。請(qǐng)注意,struct timeval指針作為用戶參數(shù)傳遞給pcap_loop()。該結(jié)構(gòu)將用于存儲(chǔ)時(shí)間戳以計(jì)算兩個(gè)樣本之間的間隔。dispatcher_handler()使用此間隔來(lái)獲取每秒的位數(shù)和每秒的數(shù)據(jù)包,然后在屏幕上打印這些值。
最后要注意的是,這個(gè)例子比傳統(tǒng)方式捕獲數(shù)據(jù)包的程序要高得多,并且在用戶級(jí)別上計(jì)算統(tǒng)計(jì)信息。統(tǒng)計(jì)模式需要最小數(shù)量的數(shù)據(jù)副本和上下文切換,因此CPU被優(yōu)化。此外,需要非常少量的內(nèi)存。
總結(jié)
以上是生活随笔為你收集整理的c++ winpcap开发(9)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git 使用篇一:初步使用GitHub,
- 下一篇: 异步杂记