#define _XKEYCHECK_H #define HAVE_REMOTE #include "pcap.h" #include "remote-ext.h" #include <winsock2.h> #include <string.h> #include <iostream> #pragma comment(lib, "wpcap.lib") #pragma comment(lib, "Ws2_32.lib") using namespace std; void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *); int main(int argc, char **argv) { pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE]; struct timeval st_ts; u_int netmask; struct bpf_program fcode; pcap_if_t *alldevs; pcap_if_t *d; int inum; int i=0; pcap_t *adhandle; char packet_filter[] = "ip and udp"; /* 得到設備列表 */ if (pcap_findalldevs(&alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); exit(1); } /* 打印列表 */ for(d=alldevs; d; d=d->next) { printf("%d. %s", ++i, d->name); if (d->description) printf(" (%s)\n", d->description); else printf(" (No description available)\n"); } if(i==0) { printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); return -1; } printf("Enter the interface number (1-%d):",i); scanf("%d", &inum); if(inum < 1 || inum > i) { printf("\nInterface number out of range.\n"); /* 釋放設備列表 */ pcap_freealldevs(alldevs); return -1; } /* 跳轉到已選設備 */ for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); /* 打開輸出適配器 */ if ( (fp= pcap_open(d->name, 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL) { fprintf(stderr,"\nUnable to open adapter %s.\n", errbuf); return 0; } /* 不用關心掩碼,在這個過濾器中,它不會被使用 */ netmask=0xffffff; // 編譯過濾器 if (pcap_compile(fp, &fcode, "ip and udp", 1, netmask) <0 ) { fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); /* 釋放設備列表 */ return 0; } //設置過濾器 if (pcap_setfilter(fp, &fcode)<0) { fprintf(stderr,"\nError setting the filter.\n"); pcap_close(fp); /* 釋放設備列表 */ return 0; } /* 將接口設置爲統計模式 */ if (pcap_setmode(fp, MODE_STAT)<0) { fprintf(stderr,"\nError setting the mode.\n"); pcap_close(fp); /* 釋放設備列表 */ return 0; } printf("TCP traffic summary:\n"); /* 開始主循環 */ pcap_loop(fp, 0, dispatcher_handler, (PUCHAR)&st_ts); pcap_close(fp); return 0; } 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; /* 以毫秒計算上一次採樣的延遲時間 */ /* 這個值經過採樣到的時間戳得到 */ delay=(header->ts.tv_sec - old_ts->tv_sec) * 1000000 - old_ts->tv_usec + header->ts.tv_usec; /* 獲取每秒的比特數b/s */ Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay)); /* ^ ^ | | | | | | 將字節轉換成比特 -- | | 延時是以毫秒錶示的 -- */ /* 獲得每秒的數據包數量 */ Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay)); /* 將時間戳轉化爲可識別的格式 */ local_tv_sec = header->ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); /* 打印時間戳*/ printf("%s ", timestr); /* 打印採樣結果 */ printf("BPS=%I64u ", Bps.QuadPart); printf("PPS=%I64u\n", Pps.QuadPart); //存儲當前的時間戳 old_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); }