c++ winpcap开发(9)
收集網絡流量統計
本課程展示了WinPcap的另一個高級功能:收集網絡流量統計信息的能力。統計引擎利用內核級包過濾器對傳入的數據包進行有效的分類。如果您想了解更多詳細信息,可以參考NPF驅動程序內部手冊。
為了使用此功能,程序員必須打開適配器并將其置于統計?模式。這可以用pcap_setmode()完成。特別地,MODE_STAT必須用作該函數的模式參數。
通過統計模式,監控TCP流量負載的應用程序是幾行代碼。以下示例顯示如何執行此操作。
#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); }在啟用統計模式之前,用戶可以選擇設置一個過濾器,該過濾器定義要監視的網絡流量子集。有關詳細信息,請參閱過濾表達式語法中的段落。如果沒有設置過濾器,將監視所有流量。
一旦
- 過濾器設置
- pcap_setmode()被調用
- 使用pcap_loop()啟用回調調用
接口描述符在統計模式下開始工作。注意pcap_open()的第四個參數(to_ms):它定義統計樣本之間的間隔。回調函數接收由驅動程序計算的樣本每至幾毫秒。這些樣本被封裝在回調函數的第二和第三個參數中,如下圖所示:
提供兩個64位計數器:最后一個間隔期間的數據包數量和字節數。
在該示例中,適配器打開超時1000 ms。這意味著dispatcher_handler()每秒調用一次。此時,只保存tcp數據包的過濾器被編譯和設置。然后調用pcap_setmode()和pcap_loop()。請注意,struct timeval指針作為用戶參數傳遞給pcap_loop()。該結構將用于存儲時間戳以計算兩個樣本之間的間隔。dispatcher_handler()使用此間隔來獲取每秒的位數和每秒的數據包,然后在屏幕上打印這些值。
最后要注意的是,這個例子比傳統方式捕獲數據包的程序要高得多,并且在用戶級別上計算統計信息。統計模式需要最小數量的數據副本和上下文切換,因此CPU被優化。此外,需要非常少量的內存。
總結
以上是生活随笔為你收集整理的c++ winpcap开发(9)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git 使用篇一:初步使用GitHub,
- 下一篇: s3c2440移植MQTT