日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络抓包工具wireshark and tcpdump 及其实现基于的libpcap

發(fā)布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络抓包工具wireshark and tcpdump 及其实现基于的libpcap 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近無意中看到博客園中一篇介紹wireshark的文章,寫得不錯,它簡單清楚介紹了wireshark的使用

簡介

wireshark以前叫做Ethereal, 在大學時候的網絡課程中就常看到它,它是世界上最流行的網絡抓包分析工具(world's most popular network protocol analyzer),它是基于圖形界面的,官網有介紹wireshark是1998年的一個項目衍生出來的,它有比較強大的特性,可以用來分析數百種網絡協(xié)議。wireshark是在GNU General Public Lisence下發(fā)布的。

以下是我自己使用wireshark的一個截圖, 照著上面的博客中去抓取和查看一次http請求前的tcp三次握手,下面詳細顯示的那行及其上下行就是我從本機瀏覽器訪問自己博客園博客的時候產生的tcp三次握手,可以看到是先握手成功才傳輸的http報文

可以看到wireshark提供了一個非常友好和詳細的界面,可以看到一個包從鏈路層ethernet,網絡層ip,傳輸層tcp的包信息。詳細的使用參加上面提到的博客

tcpdump其實和wireshark很像,區(qū)別只是tcpdump是命令行界面的,wireshark和tcpdump都共同使用 libpcap作為其底層抓包的庫, ?tcpdump最早是由?Van Jacobson于1987年開發(fā)的,后來在1999年http://www.tcpdump.org/創(chuàng)立,這上面有關于tcpdump和pcap詳細的文檔。

?

tcpdump的輸出

tcpdump的輸出格式是和協(xié)議相關的,在協(xié)議棧的同一層會有不同的協(xié)議,比如在Transport Layer會有TCP,UDP協(xié)議。下圖摘自wikipedia

對于tcpdump,-e表示輸出link level header,以下是一個例子 ? tcpdump -i eth2 -e -n?

要以看到用了-e打印出了網卡MAC地址,鏈路層的協(xié)議(ethertype), 網絡層的協(xié)議(IPv4), 第一個length是表示鏈路層包的長度。然后打出的是里面的tcp packet的信息,發(fā)送端和接收端的ip地址,tcp中的Flags等,可以看到后三個包都是廣播的包。最后一個是一個ARP查詢的包

用tcpdump來看一下三次握手

用這樣的命令形式,sudo tcpdump -i eth2 -n '(tcp[13] & 2 == 2 or tcp[13] & 16 ==16)' ?, 注意tcpdump是需要superviser的權限的,?輸出很多,從中提了一個三次握手

上面的 -n 表示輸出結果全用數字表示而不用域名和端口代表的服務名,而后面那個是傳遞給tcpdump中的libpcap模塊的過濾expression, 關于這個過濾expression的語法,在man pcap-filter中有詳細的說明,上面這個表達式的意思是 , tcp[13]是包中的tcp子包的第13個字節(jié)的值,字節(jié)數是從第0個字節(jié)開始的。而這個字節(jié)正好是Flags這個字節(jié)。 而上面Flags的字段中 S表示SYN, ? .(一個點)表示ACK

上圖是TCP的結構,從圖中可以看出,對于Flags這個字節(jié),2表示只有SYN這一位為1, 16則是只有ACK那一位為1, 而上面的tcp[13] & 2 == 2表示SYN這一位為1, 其他位不管。在tcp協(xié)議中,只有建立連接的兩個端口發(fā)的第一個包才會設置SYN位,表示起始的sequence number。從上面可以看到起始的seq num是一個隨機值。

?

libpcap , 以及基于libpcap實現一個簡單的抓包程序

安裝

libpcap是一個c庫,用于網絡抓包和過濾,源于tcpdump項目,是從最開始tcpdump中剝離出來的一個庫, tcpdump中抓包,過濾,capture file的讀寫的代碼被提取出來成了libpcap。現在也是由tcpdump項目的開發(fā)者維護。

從tcpdump的官網上下載下來后,包里面有一個INSTALL.txt文件,也就是三步的內容,./configure; ? make; ? make install;在這個過程中我安裝了flex(一個lexical analyzer generator)和yacc才成功了

寫的一個簡單程序

pcap實際上是從鏈路層抓包的,所以可以從中提出取出從鏈路層開始的包信息,官網里(這里)有詳細的基于pcap的編程文檔。這個文檔中有提到基于libpcap編程的基本步驟, 如何應用過濾條件,如何拿到一個包后回調,以及在回調函數中(下面的call_back)怎樣提取包的詳細信息,因為是得到這個鏈路層包的實際內容的(以字串的形式),所以是可以提取出從鏈路層開始,網絡程ip, 傳輸層如tcp的所有信息的, ?基本上不同的基于libpcap的軟件也就是這里不同了,怎樣提取和展示包的信息。基于這個文檔我寫了一個簡單的程序

1 #include<stdio.h>2 #include<pcap.h>3 #include<string>4 5 using namespace std;6 7 static const unsigned int ETHER_ADDR_LEN = 6; 8 void call_back(u_char * args, const struct pcap_pkthdr * header, const u_char * packet);9 string generate_mac_address(char macChars[ETHER_ADDR_LEN]); 10 11 int main(){ 12 pcap_t * handle; // Sesion handle 13 char dev[] = "eth2"; //device to sniff on 14 char errbuf[PCAP_ERRBUF_SIZE]; // error string 15 char filter_exp[] = ""; //filter expression 16 bpf_u_int32 mask; //The netmask of our sniffing device 17 bpf_u_int32 net; //The IP of our sniffing device 18 19 struct bpf_program fp; //the compiled filter expression 20 21 //查詢device的mask和ip 22 if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1){ 23 fprintf(stderr, "Can't get netmask for device %s\n", dev); 24 net = 0; 25 mask = 0; 26 } 27 28 //obtaining packet capture descriptor 29 handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); 30 if(handle == NULL){ 31 fprintf(stderr, "Can't open device %s\n", dev); 32 return 2; 33 } 34 35 // before apply filter exp, compile it 36 if(pcap_compile(handle, &fp, filter_exp, 0, net) == -1){ 37 fprintf(stderr, "can't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); 38 return 2; 39 } 40 //apply filter to this session 41 if(pcap_setfilter(handle, &fp) == -1){ 42 fprintf(stderr, "can't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); 43 return 2; 44 } 45 46 // now the device is prepared to sniff under the filter condition 47 struct pcap_pkthdr header; // packet header struct 48 const u_char * packet; // actual packet 49 50 //5表示積累5個包pcap_loop才返回,但每個包都會調一次call_back 51 while(!pcap_loop(handle, 5, call_back, NULL)){ 52 printf("-------\n"); //每8行才會輸出一次這個 53 } 54 pcap_close(handle); 55 } 56 57 struct sniff_ethernet { 58 char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */ 59 char ether_shost[ETHER_ADDR_LEN]; /* Source host address */ 60 u_short ether_type; /* IP? ARP? RARP? etc */ 61 }; 62 63 // call_back function的統(tǒng)一原型 64 void call_back(u_char * args, const struct pcap_pkthdr * header, const u_char * packet){ 65 static int count = 0; 66 struct sniff_ethernet * ethernet; //ethernet header 67 ethernet = (struct sniff_ethernet*)(packet); 68 69 //把6字節(jié)的字符串轉換成mac地址的表示形式 70 std::string source_mac_address = generate_mac_address(ethernet->ether_shost); 71 std::string dst_mac_address = generate_mac_address(ethernet->ether_dhost); 72 73 printf("wy: call_back called %d, %s->%s, packet length:%d\n", count++, source_mac_address.c_str(), dst_mac_address.c_str(), header->len); 74 } 75 76 //由字節(jié)為單位字符串生成mac地址,16進制數的字串 77 string generate_mac_address(char macChars[ETHER_ADDR_LEN]){ 78 string macAddr; 79 char temp[2]; 80 for(int i = 0; i < ETHER_ADDR_LEN; i++){ 81 //把一個字節(jié)轉化成16進制表示形式 82 sprintf(temp, "%x", macChars[i]); 83 if(i != 0){ 84 macAddr.append(":"); 85 } 86 macAddr.append(temp, 2); 87 } 88 return macAddr; 89 }

?

這個程序上面有比較詳細的注釋,就是把通用的基于libpcap編程的流程走了一遍,最后打印出每個包鏈路層from和to的MAC地址,以及每個包的長度.

對于call_back的第二個參數 struct pcap_pkthdr, 這是pcap.h中定義的一個結構體,包含了這個包的一些信息,捕獲時間,包長度, 可以看到程序中的包長度就是從中提取的,定義如下

1 struct pcap_pkthdr { 2 struct timeval ts; /* time stamp */ 3 bpf_u_int32 caplen; /* length of portion present */ 4 bpf_u_int32 len; /* length this packet (off wire) */ 5 };

?

上面的參數char * packet實際上是整個包在內存在的地址,為了從這當中提取出信息,必須要自己定義相應的數據結構從這個純字符串中去提, 可以看到我照著文檔中去定義了一個 struct ?sniff_ethernet,這個是需要自己定義的,pcap.h中是沒有的,然后可以看到我如何寫了一個函數 generate_mac_address把這個6字節(jié)的字符串轉換成mac地址標準的表達形式。以下是程序運行輸出

比較奇怪的是,我本機網卡 eth2的MAC地址是 ?bc:30:5b:a4:40:40, 但是程序的輸出是 ff:30:5b:ff:40:40

本來想選擇就用c來寫這個程序,但是寫到字串轉換那里,對字符串的操作用c確實比較麻煩和難看,所以我還是用的c++, 我想到了陳皓的一篇文章,他感慨c的編譯器gcc已經開始用c++來實現了,他列舉出了c++比c優(yōu)雅的地方,就我的感覺是很贊同的。

一個鏈接錯誤

很奇怪的是我編譯程序遇到了一個錯誤,?g++ -o test_pcap test_pcap.cpp -L/usr/local/lib -lpcap

錯誤提示是?

/usr/local/lib/libpcap.so: undefined reference to `pcap_parse'
collect2: ld returned 1 exit status

google了一下,發(fā)現這個問題很普遍卻都沒給出一個明確的原因解釋,有篇文章提到把libpcap重裝也一遍,也就是cd到下載下來的包目錄,make clean ; ./configure; make ; make install ; ?我這樣試了之后竟然好了,沒有明白是為什么,網上也沒有找到,在這里做一個記錄吧

轉載于:https://www.cnblogs.com/livingintruth/archive/2012/10/17/2721877.html

總結

以上是生活随笔為你收集整理的网络抓包工具wireshark and tcpdump 及其实现基于的libpcap的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲无色 | 日本精品视频网站 | 喷潮在线 | 好吊操视频这里只有精品 | 欧美综合激情 | 三级亚洲 | 婷婷六月天 | 天堂中文在线8 | 成人天堂av | 91视频一区二区三区 | 久久精品屋 | 天堂а√在线中文在线鲁大师 | 超碰人人人人人人 | 国产成人av免费观看 | 中文字幕日韩精品一区 | 日韩免费网 | 国产真实夫妇交换视频 | 日韩一级淫片 | 精品人妻一区二区三区三区四区 | 天天av天天| 九九九九色| 91干干干 | 国产精品久久一区 | 免费成人在线看 | a毛片 | 精品一卡二卡三卡 | 91视频日本| 天堂在线视频免费 | 精品人妻午夜一区二区三区四区 | 中文字幕免费高清在线 | 日日操狠狠操 | 亚洲精品国产一区二 | 日韩一区二区a片免费观看 伊人网综合在线 | 日日躁夜夜躁狠狠躁 | 久久丫精品国产亚洲av不卡 | 国产精品伦子伦免费视频 | 蜜桃av免费在线观看 | 成人免费看片 | www亚洲| 大肉大捧一进一出好爽视频动漫 | 最近最新中文字幕 | 911成人网 | 国产丝袜美腿一区二区三区 | 一区视频在线免费观看 | 可以免费看污视频的网站 | 国产欧美成人 | 黑人巨大精品欧美黑白配亚洲 | 欧美日韩视频一区二区三区 | 嫩草视频免费观看 | av色资源 | 国产白丝精品91爽爽久久 | 色综合久久网 | 亚洲久视频 | 成人在线观看国产 | 亚洲成熟毛多妇女av毛片 | 青青草国内自拍 | 好看的中文字幕电影 | 天天影视插插插 | 日韩欧美视频在线 | 在线a| 国产片淫乱18一级毛片动态图 | 中文字幕在线天堂 | 中文字幕一级二级三级 | 王者后宫yin肉h文催眠 | 乱熟女高潮一区二区在线 | 亚洲在线电影 | 永久久久久久 | 日韩国产综合 | 国产级毛片 | 亚洲三级黄 | 成人无高清96免费 | 亚洲一片| av色吧| 91视频在线免费 | 中文字幕123区 | 九九九国产视频 | 亚洲男女一区二区三区 | 户外露出一区二区三区 | 日韩在线看片 | 韩国19主播内部福利vip | 91av网址| 亚洲色图 一区二区 | 外国电影免费观看高清完整版 | 成年人视频网站 | 国产高清视频一区二区 | 国产微拍精品 | 成人毛片a | 91蝌蚪视频在线 | 少妇免费毛片久久久久久久久 | 日韩福利片在线观看 | 一级日韩一级欧美 | 久久成人免费网站 | 男女毛片视频 | 中文字幕69页 | 香蕉av一区二区三区 | 26uuu精品一区二区 | 欧美疯狂做受xxxxx高潮 | 99热国| 在线免费看av |