wireshark不久前升級到1.10.0穩定版,這個版本正如其版本號同樣,相比1.8.x有較大變化。html
咱們先說說在windows下編譯的問題,1.8.4/1.8.6版本的編譯見個人文章:http://www.cnblogs.com/zzqcn/archive/2013/04/23/3039110.html,這是重要的參考。更早的版本編譯也是大同小異。這裏要說一句,我在網上搜到的wireshark Windows下編譯貌似全是我寫的,csdn上那個blackboyofsnp也是我。windows
編譯時的操做系統是Windows 7 32bit, 編譯器是Visual C++ 2012,並帶有Windows SDK v7.1。app
1. 神馬?VC++ 2012?? 沒錯,1.10.0終於支持VC++2012了,這是我發現的最大亮點。我終於不用爲了編譯它而在電腦上裝多個版本的VS了,並且避免了CRT衝突的問題。函數
2. wireshark 1.10.0在Windows下的編譯須要<Windows SDK>/include目錄中的win32.mak文件,正好我裝了Windows SDK 7.1,因而在編譯以前的環境配置批處理腳本中加入了下面這一句:post
set INCLUDE=%INCLUDE%;C:\Program Files\Microsoft SDKs\Windows\v7.1A\Includespa
此時個人bat腳本內容以下所示:操作系統
@echo off set PATH=%PATH%:. set PATH=%PATH%;d:\dev\cygwin\bin set INCLUDE=%INCLUDE%;C:\Program Files\Microsoft SDKs\Windows\v7.1A\Include echo 設置 Visual Studio environment... "C:\Program Files\Microsoft Visual Studio 11.0\Common7\Tools\vsvars32.bat" title Command Prompt (MSVC++ 2012)
是的,除了以上的1,2以外,其餘應該沒啥變化了,照之前的編譯方法編譯便可。提示:注意debug/release版本和CRT版本哦,見config.nmake文件的LOCAL_LDFLAGS=/DEBUG這一行。debug
接下來講說1.10.0版本和動態調用libwireshark.dll協議解析庫有關的一些變化。指針
1. 廢棄了原來的/epan/libwireshark.def文件和WS_VAR_IMPORT(這個定義在\wireshark-1.8.x/CMakeLists.txt中),而是採用一種叫作C++ Visibility的技術,這種技術其實我也不懂啦,我只以爲Visibility, Niubility,傻傻分不清楚。。。 學有餘力的同窗請參考 http://gcc.gnu.org/wiki/Visibility。相關的宏定義在/ws_symbol_export.h中。code
這會影響到咱們調用時頭文件的一些聲明,我建議在wireshark調用函數聲明所在的頭文件的最上面,#include ws_symbol_export.h。好比:
#if WIRESHARK_VERSION == WIRESHARK_1_10_0 #include "ws_symbol_export.h" #elif (WIRESHARK_VERSION == WIRESHARK_1_8_6 || WIRESHARK_VERSION == WIRESHARK_1_8_4) // see \wireshark-1.8.4\CMakeLists.txt, #481 #define WS_VAR_IMPORT __declspec(dllimport) extern #else #error 不支持此版本的wireshark #endif
2. 解析器執行函數epan_dissect_run()的第2個參數從void* pseudo_header改成struct wtap_pkthdr *phdr,這但是核心函數啊啊啊。。。必需要改,並且要多#include一個/wiretap/wtap.h。在你本身程序的具體調用的代碼中,也要初始化好這個結構哦
3. (不關心IP地址查詢的同窗可能不須要關心第3點。但注意一下是好事)GeoIP模塊的初始化再也不放在epan_init()中,而是使用一個不可見的回調函數geoip_db_post_update_cb來自動更新GeoIP配置。ChangeLogs裏有幾個blablabla地註釋了一通這種方法的好處,好比配置選項更新後不須要當即重啓wireshark就可以使改動生效。可尼瑪苦了我了。
【如下說法可能不許確,但我確實遇到這問題。】這個改動會形成如下後果:若是你本身的調用程序(也就是調用libwireshark.dll進行解析的程序啦)所在電腦上也安裝了wireshark原版,並且wireshark中的GeoIP選項(在Edit/Preferences菜單->Name Resolution->GeoIP database directories)設置了的話,可能會使你的程序只能解析到IP層,就致使運行時斷言失敗而返回,由於GeoIP相關的指針非法。
作爲第3方調用程序,咱們沒法執行到回調函數。爲此我HACK了wireshark源碼,在/epan/geoip_db.h & .c中添加了一個導出函數geoip_update_force(),在其中調用geoip_db_post_update_cb,源碼以下:
geoip_db.h
/* * Hacked by blackboycpp, 2013/06/22 * * for GeoIP bug in wireshark 1.10.0, becaz my app can't call the update callback */ WS_DLL_PUBLIC void geoip_update_force(void);
geoip_db.c
// 定義在geoip_db_post_update_cb()下面 void geoip_update_force(void) { const gchar* err; uat_load(geoip_db_paths_uat, &err); geoip_db_post_update_cb(); }
改完後編譯本身的libwireshark.dll。這也意味着你的程序將沒法使用原版的libwireshark.dll,由於你改了嘛。
最後記得在你程序的init_dissection()執行以前(或以後??)調用一下咱們HACK上去的這個geoip_update_force()函數。