winshark重要数据结构
說起來有一些慚愧,研究wireshark有一段時間了,但是對源代碼的分析卻至今沒有什么進(jìn)展。。。
最初想要研究wireshark是因為我的開題是基于wireshark來做的。
現(xiàn)在有很多抓包工具,wireshark的優(yōu)勢在于完全開源,分析功能強(qiáng)大,但其缺點也很明顯,即捕獲的數(shù)據(jù)包存儲過于分散,大數(shù)據(jù)背景下,不能有效的對海量的數(shù)據(jù)包進(jìn)行存儲分析,因此將wireshark捕獲到的數(shù)據(jù)存儲到專門的數(shù)據(jù)庫中是非常必要的。(當(dāng)然,存儲數(shù)據(jù)只是第一步,接下來還要進(jìn)行對數(shù)據(jù)的分析工作)
真正開始分析wireshark了,首先是編譯。unbutu下很順利就編譯通過了,但是在windows下卻出現(xiàn)各種問題,至今沒有編譯通過。。。,分析wireshark源代碼,在windows下編譯通過有必要嗎?
后來看關(guān)于wireshark的論文,接觸到了兩個東西。即winpcap、libpcap。
winpcap是底層的,在windows上wireshark是依賴于winpcap來截包的,在linux上則是依賴于libpcap。而winpcap又是基于libpcap的設(shè)計基礎(chǔ)上開發(fā)設(shè)計的,使用方法也和libpcap基本相同。
那么,我在分析wireshark存儲部分源代碼的時候有必要看winpcap和libpcap的函數(shù)庫嗎?
到真正看wireshark源代碼了,200多M,算上子文件共2000多個,對于一個不是計算機(jī)科班出身的我來說,不得不說,有點困難。。 從百度文庫上下載了些資料,主要是分析wireshark邏輯功能模塊,最有價值的應(yīng)該是這篇了,如下:
a) GTK1/2 處理用戶的輸入輸出顯示,源碼在gtk目錄.b) Core 核心模塊,通過函數(shù)調(diào)用將其他模塊連接在一起,源碼在根目錄c) Epan wireshark Packetage Analyzing,包分析引擎,源碼在epan目錄Protocol-Tree:保存數(shù)據(jù)包的協(xié)議信息,wireshark的協(xié)議結(jié)構(gòu)采用樹形結(jié)構(gòu),解析協(xié)議報文時只需要從根節(jié)點通過函數(shù)句柄依次調(diào)用各層解析函數(shù)即可。Dissectors:在epan/dissector目錄下,各種協(xié)議解碼器,支持700+種協(xié)議解析,對于每種協(xié)議,解碼器都能識別出協(xié)議字段(field),并顯示出字段值(field value)由于網(wǎng)絡(luò)協(xié)議種類很多,為了使協(xié)議和協(xié)議間層次關(guān)系明顯,對數(shù)據(jù)流里的各個層次的協(xié)議能夠逐層處理,wireshark系統(tǒng)采用了協(xié)議樹的方式。Plugins:一些協(xié)議解碼器以插件形式實現(xiàn),源碼在plugins目錄Display-Filters:顯示過濾引擎,源碼在epan/dfilter目錄d) Capture 捕包引擎,利用libpcap/WinPcap從底層抓取網(wǎng)絡(luò)數(shù)據(jù)包,libpcap/WinPcap提供了通用的抓包接口,能從不同類型的網(wǎng)絡(luò)接口(包括以太網(wǎng),令牌環(huán)網(wǎng),ATM網(wǎng)等)獲取數(shù)據(jù)包。e) Wiretap 從文件中讀取數(shù)據(jù)包,支持多種文件格式,源碼在wiretap目錄f) Win-/libpcap Wireshark抓包時依賴的庫文件wireshark功能模塊3. wireshark流程分析 1) 初始化 Wireshark的初始化包括一些全局變量的初始化、協(xié)議分析引擎的初始化和Gtk相關(guān)初始化,顯示Ethereal主窗口,等待用戶進(jìn)一步操作。重點就是Epan模塊的初始化。 Epan初始化:tvbuff初始化:全局變量tvbuff_mem_chunk指向用memchunk分配的固定大小的空閑內(nèi)存塊,每個內(nèi)存塊是tvbuff_t結(jié)構(gòu),從空閑內(nèi)存塊中取出后,用來保存原始數(shù)據(jù)包。協(xié)議初始化:全局變量:proto_names proto_short_names proto_filter_names 以上三個全局變量主要用來判斷新注冊的協(xié)議名是否重復(fù),如果重復(fù),給出提示信息,在協(xié)議解析過程中并沒有使用。 ? 協(xié)議注冊: ? 注冊協(xié)議:將三個參數(shù)分別注冊給proto_names、proto_short_names、proto_filter_names三個全局變量中, ? 注冊字段,需要在wireshark協(xié)議樹顯示的報文內(nèi)容字段。 ? 協(xié)議解析表 ? Handoff注冊 ? 將協(xié)議與父協(xié)議節(jié)點關(guān)聯(lián)起來 ? Packet(包)初始化 ? 全局變量: ? frame_handle:協(xié)議解析從frame開始,層層解析,直到所有的協(xié)議都解析完為止。frame_handle保存了frame協(xié)議的handle。 ? data_handle:有的協(xié)議無法從frame開始,那么就從data開始。原理同frame。 ? 讀配置文件preference ? 讀capture filter和display filter文件,分別保存在全局變量capture_filter和display_filter中。 ? 讀disabled protocols文件,保存全局變量global_disabled_protos和disabled_protos中 ? 初始化全局變量cfile ? Cfile是個重要的變量,數(shù)據(jù)類型為capture file,它保存了數(shù)據(jù)包的所有信息, ? 取得命令行啟動時,參數(shù)列表,并進(jìn)行相應(yīng)的處理2) 處理流程 Wireshark初始化完成以后進(jìn)入實際處理階段,主程序創(chuàng)建抓包進(jìn)程,捕包進(jìn)程和主程序是通過PIPE進(jìn)行傳遞數(shù)據(jù)的,主程序把抓取的數(shù)據(jù)寫入臨時文件,通過函數(shù)add_packet_to_packet_list將數(shù)據(jù)包加入包列表。處理時,主程序從列表中選取一個數(shù)據(jù)包,提取該數(shù)據(jù)包中的數(shù)據(jù)填寫在數(shù)據(jù)結(jié)構(gòu)中,最后調(diào)用協(xié)議解析函數(shù)epan_dissect_run進(jìn)行處理,從epan_dissect_run開始,是實際的協(xié)議解析過程, 下面以HTTP協(xié)議報文為例,流程如下: a) 解析frame層 調(diào)用函數(shù)dissect_frame對frame層進(jìn)行解析,并在協(xié)議樹上填充相應(yīng)字段信息。函數(shù)最后會判斷是否有上層協(xié)議封裝,如果有則調(diào)用函數(shù)dissector_try_port在協(xié)議樹上查找對應(yīng)的解析函數(shù),這里函數(shù)dissector_try_port根據(jù)pinfo->fd->lnk_t查找對應(yīng)的上層協(xié)議處理函數(shù),pinfo->fd->lnk_t值為1,上層封裝協(xié)議為以太網(wǎng)協(xié)議,全局結(jié)構(gòu)體指針變量dissector_handle當(dāng)前的協(xié)議解析引擎句柄置為dissect_eth_maybefcs,至此,frame層解析結(jié)束。 b) 解析以太網(wǎng)層 函數(shù)call_dissector_work根據(jù)dissector_handle調(diào)用frame上層協(xié)議解析函數(shù)dissect_eth_maybefcs對以太網(wǎng)層進(jìn)行解析,并在協(xié)議樹上填充相應(yīng)字段,包括目的MAC地址和以太網(wǎng)上層協(xié)議類型等信息。函數(shù)最后會判斷是否有上層協(xié)議封裝,如果有則調(diào)用函數(shù)dissector_try_port在協(xié)議樹上查找對應(yīng)的解析函數(shù),這里函數(shù)dissector_try_port根據(jù)etype查找對應(yīng)的上層協(xié)議處理函數(shù),以太網(wǎng)字段etype為0800的報文是ip報文,上層封裝協(xié)議為IP協(xié)議,全局結(jié)構(gòu)體指針變量dissector_handle當(dāng)前的協(xié)議解析引擎句柄置為dissect_ip,至此,以太網(wǎng)層解析結(jié)束。 c) 解析IP層 函數(shù)call_dissector_work根據(jù)dissector_handle調(diào)用以太網(wǎng)上層協(xié)議解析函數(shù)dissect_ip對以太網(wǎng)層進(jìn)行解析,并在協(xié)議樹上填充相應(yīng)字段,包括版本號,源地址,目的地址等信息。函數(shù)最后會判斷是否有上層協(xié)議封裝,如果有則調(diào)用函數(shù)dissector_try_port在協(xié)議樹上查找對應(yīng)的解析函數(shù),這里函數(shù)dissector_try_port根據(jù)nxt (nxt = iph->ip_p)查找對應(yīng)的上層協(xié)議處理函數(shù),以太網(wǎng)字段nxt為06的報文是TCP報文,上層封裝協(xié)議為TCP協(xié)議,全局結(jié)構(gòu)體指針變量dissector_handle當(dāng)前的協(xié)議解析引擎句柄置為dissect_tcp,至此,IP層解析結(jié)束。 d) 解析TCP層 函數(shù)call_dissector_work根據(jù)dissector_handle調(diào)用以太網(wǎng)上層協(xié)議解析函數(shù)dissect_tcp對TCP層進(jìn)行解析,包括對TCP頭的解析和選項字段的解析,并在協(xié)議樹上填充相應(yīng)字段,包括源端口,目的端口,標(biāo)志位等信息。函數(shù)最后會判斷是否有上層協(xié)議封裝,如果有則調(diào)用函數(shù)dissector_try_port在協(xié)議樹上查找對應(yīng)的解析函數(shù),這里函數(shù)dissector_try_port根據(jù)port查找對應(yīng)的上層協(xié)議處理函數(shù),將源端口和目的端口分別賦值給low_port和high_port,根據(jù)low_port和high_port分別匹配上層協(xié)議解析函數(shù),port為80的報文是HTTP報文,上層封裝協(xié)議為HTTP協(xié)議,全局結(jié)構(gòu)體指針變量dissector_handle當(dāng)前的協(xié)議解析引擎句柄置為dissect_http,至此,TCP層解析結(jié)束。 e) 解析HTTP層 至此wireshark進(jìn)入應(yīng)用層協(xié)議檢測階段,wireshark解析dissect_http函數(shù)中注冊的字段,并提取相應(yīng)的字段值添加到協(xié)議樹中,應(yīng)用層的具體解析流程將在下面介紹。HTTP協(xié)議具體函數(shù)調(diào)用過程參見: 重要的數(shù)據(jù)結(jié)構(gòu)struct _epan_dissect_t {tvbuff_t *tvb;//用來保存原始數(shù)據(jù)包proto_tree *tree;//協(xié)議樹結(jié)構(gòu)packet_info pi;// 包括各種關(guān)于數(shù)據(jù)包和協(xié)議顯示的相關(guān)信息 };/** Each proto_tree, proto_item is one of these. */ typedef struct _proto_node {struct _proto_node *first_child;//協(xié)議樹節(jié)點的第一個子節(jié)點指針struct _proto_node *last_child; //協(xié)議樹節(jié)點的最后一個子節(jié)點指針struct _proto_node *next; //協(xié)議樹節(jié)點的下一個節(jié)點指針struct _proto_node *parent;//父節(jié)點指針field_info *finfo;//保存當(dāng)前協(xié)議要顯示的地段tree_data_t *tree_data;//協(xié)議樹信息 } proto_node;typedef struct _packet_info {const char *current_proto; //當(dāng)前正在解析的協(xié)議名稱column_info *cinfo; //wireshark顯示的信息frame_data *fd;//現(xiàn)在分析的原始數(shù)據(jù)指針union wtap_pseudo_header *pseudo_header;//frame類型信息GSList *data_src; /*frame層信息 */address dl_src; /* 源MAC */address dl_dst; /*目的MAC */address net_src; /* 源IP */address net_dst; /*目的IP */address src; /*源IP */address dst; /*目的IP */guint32 ethertype; /*以太網(wǎng)類型字段*/guint32 ipproto; /* IP協(xié)議類型*/guint32 ipxptype; /* IPX 包類型 */guint32 mpls_label; /* MPLS包標(biāo)簽*/circuit_type ctype; guint32 circuit_id; /*環(huán)路ID */const char *noreassembly_reason; /* 重組失敗原因*/gboolean fragmented; /*為真表示未分片*/gboolean in_error_pkt; /*錯誤包標(biāo)志*/port_type ptype; /*端口類型 */guint32 srcport; /*源端口*/guint32 destport; /*目的端口*/guint32 match_port; /*進(jìn)行解析函數(shù)匹配時的匹配端口*/const char *match_string; /*調(diào)用子解析引擎時匹配的協(xié)議字段指針*/guint16 can_desegment; /* 能否分段標(biāo)志*/guint16 saved_can_desegment; int desegment_offset; /*分段大小*/ guint32 desegment_len; guint16 want_pdu_tracking; guint32 bytes_until_next_pdu;int iplen; /*IP包總長*/int iphdrlen; /*IP頭長度*/int p2p_dir; guint16 oxid; /* next 2 fields reqd to identify fibre */guint16 rxid; /* channel conversations */guint8 r_ctl; /* R_CTL field in Fibre Channel Protocol */guint8 sof_eof; guint16 src_idx; /* Source port index (Cisco MDS-specific) */guint16 dst_idx; /* Dest port index (Cisco MDS-specific) */guint16 vsan; /* Fibre channel/Cisco MDS-specific *//* Extra data for DCERPC handling and tracking of context ids */guint16 dcectxid; /* Context ID (DCERPC-specific) */int dcetransporttype;guint16 dcetransportsalt; /* fid: if transporttype==DCE_CN_TRANSPORT_SMBPIPE */ guint16 decrypt_gssapi_tvb;tvbuff_t *gssapi_wrap_tvb;tvbuff_t *gssapi_encrypted_tvb;tvbuff_t *gssapi_decrypted_tvb;gboolean gssapi_data_encrypted;guint32 ppid; /* SCTP PPI of current DATA chunk */guint32 ppids[MAX_NUMBER_OF_PPIDS]; /* The first NUMBER_OF_PPIDS PPIDS which are present * in the SCTP packet*/void *private_data; /* pointer to data passed from one dissector to another *//* TODO: Use emem_strbuf_t instead */GString *layer_names; /* layers of each protocol */guint16 link_number;guint8 annex_a_used;guint16 profinet_type; /* the type of PROFINET packet (0: not a PROFINET packet) */void *profinet_conv; /* the PROFINET conversation data (NULL: not a PROFINET packet) */void *usb_conv_info;void *tcp_tree; /* proto_tree for the tcp layer */const char *dcerpc_procedure_name; /* Used by PIDL to store the name of the current dcerpc procedure */struct _sccp_msg_info_t* sccp_info;guint16 clnp_srcref; /* clnp/cotp source reference (can't use srcport, this would confuse tpkt) */guint16 clnp_dstref; /* clnp/cotp destination reference (can't use dstport, this would confuse tpkt) */guint16 zbee_cluster_id; /* ZigBee cluster ID, an application-specific message identifier that* happens to be included in the transport (APS) layer header.*/guint8 zbee_stack_vers; int link_dir; /* 3GPP messages are sometime different UP link(UL) or Downlink(DL)*/ } packet_info;因為我的主要工作是修改wireshark存儲部分源代碼,還有必要從main開始分析嗎?看到一層層的調(diào)用,要調(diào)暈了。。。。
博客寫的有點亂了,總之,不知道如何開始。。。。
總結(jié)
以上是生活随笔為你收集整理的winshark重要数据结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何调理宫寒呢
- 下一篇: 爱情就像吃芒果剧情介绍