?? ppp.c
字號:
/*本程序是通過libpcap來對數據鏈路層直接訪問。這里面用到的函數都是來自包:libpcap下面主要是介紹它的函數的使用情況及如何對包進行過濾,它的整個流程如下: ********************* *查找有效的網絡設備** * ******************* * * * ******************** 獲得網絡地址及網絡掩碼 ******************** * * * ******************** 打開網絡設備 ******************** * * * ******************** 將用戶輸入的字串符編譯到過濾程序中 ******************** * * * ******************** 設置過濾器 ******************* * *工 * * * ****************** * * * * * * ********************* * 捕獲包 * ********************* * * * * * * * *********************** * 緩沖滿? * *********************** * * * * * *Y N ********* ***************顯示包*** ************************ * ********************* 退出 ******************** */ #include<pcap.h>#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#define PCAP_ERRBUF_SIZE 200void Display(const u_char *packet, const size_t length);void my_callback(u_char *none, const struct pcap_pkthdr *pkthdr, const u_char *packet){ Display((u_char *)packet, (size_t)(pkthdr->caplen)); return;}int main(int argc, char **argv){ int i; char *dev; char errbuf[PCAP_ERRBUF_SIZE]; //程序中的錯誤信息放在這里 /*網絡設備符結構: pcap_t { int fd; int snapshort; int linktype; int tzoff; int offset; struct pcap_sf sf; struct pcap_md md; int bufsize; u_char *buffer; u_char bp; int cc; u_char pkt; struct bpf_programe fcode; char errbuf[PCAP_ERRBUF_SIZE]; } 結構pcap_pkthdr struct pcap_pkthdr { struct timeval ts; bpf_u_int32 caplen; bpf_u_int32 len; }; */ pcap_t *descr; //網絡設備描述符 const u_char *packet; struct pcap_pkthdr hdr; struct ether_header *eptr; struct bpf_program fp; bpf_u_int32 maskp; //子網掩 碼 bpf_u_int32 netp; //網絡號 if (argc != 2) { fprintf(stdout, "Usage:%s\"filter program\"\n", argv[0]); return 0; } dev = pcap_lookupdev(errbuf); //調用它返回網絡設備名指針,如果出錯則把 printf("用到的網絡設備是:%s\n", dev); //錯誤放在errbuf中 if (dev == NULL) { fprintf(stderr, "%s\n", errbuf); exit(1); } pcap_lookupnet(dev, &netp, &maskp, errbuf); //獲得指定網絡設備名的網絡號 和掩碼 /*char *netnum; char *masknum; itoa(netp, netnum, 2); itoa(netp, masknum, 2);*/ printf("網絡號及掩碼:%x\n%x\n", netp, maskp); descr = pcap_open_live(dev, BUFSIZ, 1, 5, errbuf); //獲得捕獲數據包的描 //述符BUFSIZ是定接收包的最大長度,5是指超時時間(毫秒) if (descr == NULL) { printf("pcap_open_live():%s\n", errbuf); exit(1); } /*將指定的argv[1]編譯到過濾程序中,netp是網絡掩碼*/ if (pcap_compile(descr, &fp, argv[1], 0, netp) == -1) { fprintf(stderr, "Error calling pcap_compile\n"); exit(1); } if (pcap_setfilter(descr, &fp) == -1) //對指定的網絡設備指定一個過濾程序 { fprintf(stderr, "Error setting filter\n"); exit(1); } /*捕獲數據包,并進行處理。-1表是函數返回前所處理數據包的最大值,為-1表示 * 在一個緩沖區中處理所有的數據包,為0時表示處理所有數據包,直到遇到以下錯誤(EOF, 超時讀?。?,my_callback是一個帶有三個參數的回調函數, NULL傳遞給回調 * 函數的參數額,在回調函數時對捕獲的數所包進行處理*/ pcap_loop(descr, -1, my_callback, NULL); return 0;}void Display(const u_char *packet, const size_t length)//用于顯示捕獲到的包的數據{ u_long offset; int i, j, k; printf("packet[%d] bytes:\n", (long unsigned int)length); if (length <= 0) { return; } i = 0; offset = 0; for (k = length/16; k>0; k--, offset += 16)//顯示時排列成K排,每行有16個16進制數 { printf("%08X\n", (unsigned int)offset); for (j=0; j<16; j++, i++) { if (j == 8) { printf("-%02X", packet[i]); } else { printf("%02X", packet[i]); } } printf(" "); i -= 16; for (j=0; j<16; j++, i++) { if ((packet[i] >= ' ') && (packet[i] <= 128)) { printf("%c", packet[i]); } else { printf("."); } } printf("\n"); } k = length - i; if (k <= 0) { return; } printf("%08X", (unsigned int)offset); for (j=0; j<k; j++, i++) { if (j == 8) { printf("-%02X", packet[i]); } else { printf("%02X", packet[i]); } } i -= k; for (j=16-k; j>0; j--) { printf(" "); } printf(" "); for (j=0; j<k; j++, i++) { if ((packet[i] >= ' ') && (packet[i] <= 128)) { printf("%c", packet[i]); } else { printf("."); } } printf("\n"); return;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -