# 第?7?章?高級
**目錄**
+ [7.1\. 說明](#calibre_link-131)
+ [7.2\. "Follow TCP Stream"](#calibre_link-130)
+ [7.2.1\. "Follow TCP Stream"對話框](#calibre_link-132)
+ [7.3\. 時間戳](#calibre_link-120)
+ [7.3.1\. Wireshark內置](#calibre_link-133)
+ [7.3.2\. 捕捉文件格式](#calibre_link-134)
+ [7.3.3\. 準確性](#calibre_link-135)
+ [7.4\. 時區](#calibre_link-136)
+ [7.4.1\. 正確設置你的計算機的時區](#calibre_link-137)
+ [7.4.2\. Wireshark和時區的關系](#calibre_link-138)
+ [7.5\. 重組包](#calibre_link-105)
+ [7.5.1\. 什么是重組包](#calibre_link-139)
+ [7.5.2\. 如何用Wireshark重組包](#calibre_link-140)
+ [7.6\. 名稱解析](#calibre_link-86)
+ [7.6.1\. 名字解析的流弊](#calibre_link-141)
+ [7.6.2\. 以太網名字解析(mac層)](#calibre_link-142)
+ [7.6.3\. IP地址解析(網絡層)](#calibre_link-143)
+ [7.6.4\. IPX名稱解析(網絡層)](#calibre_link-144)
+ [7.6.5\. TCP/UDP端口名解析(傳輸層)](#calibre_link-145)
+ [7.7\. 校檢和](#calibre_link-114)
+ [7.7.1\. Wireshark校檢和驗證](#calibre_link-146)
+ [7.7.2\. Checksum offloading](#calibre_link-147)
## 7.1.?說明
在本節將介紹Wireshark的一些高級特性
## 7.2.?"Follow TCP Stream"
如果你處理TCP協議,想要查看Tcp流中的應用層數據,"Following TCP streams"功能將會很有用。如果你項查看telnet流中的密碼,或者你想嘗試弄明白一個數據流。或者你僅僅只需要一個顯示過濾來顯示某個TCP流的包。這些都可以通過Wireshark的"Following TCP streams"功能來實現。
在包列表中選擇一個你感興趣的TCP包,然后選擇Wireshark工具欄菜單的"Following TCP Streams"選項(或者使用包列表鼠標右鍵的上下文菜單)。然后,Wireshark就會創建合適的顯示過濾器,并彈出一個對話框顯示TCP流的所有數據。如[圖?7.1 “"Follow TCP Stream"對話框”](#calibre_link-164 "圖?7.1.?"Follow TCP Stream"對話框")所示
> 
> 注意
> 值得注意的是:Follow Tcp Stream會裝入一個顯示過濾來選擇你已經選擇的Tcp流的所有包。
### 7.2.1.?"Follow TCP Stream"對話框
**圖?7.1.?"Follow TCP Stream"對話框**

流的內容出現的順序同他們在網絡中出現的順序一致。從A到B的通信標記為紅色,從B到A的通信標記為藍色。當然,如果你喜歡的話你可以從"Edit/Preferences"菜單項的"Colores"修改顏色。
非打印字符將會被顯示為圓點。XXX - What about line wrapping (maximum line length) and CRNL conversions?
在捕捉過程中,TCP流不能實時更新。想得到最近的內容需要重新打開對話框。
你可以在此對話框執行如下操作:
1. **Save As** 以當前選擇格式保存流數據。
2. **Print** 以當前選擇格式打印流數據。
3. **Direction** 選擇流的顯示方向("Entire conversation", "data from A to B only" or "data from B to A only").
4. **Filter out this stream** 應用一個顯示過濾,在顯示中排除當前選擇的TCP流。
5. **Close** 關閉當前對話框。移除對當前顯示過濾的影響。
你可以用以下格式瀏覽流數據。
1. **AsCII**。在此視圖下你可以以ASCII凡是查看數據。當然最適合基于ASCII的協議用,例如HTTP.
2. **EBCDIC**。For the big-iron freaks out there.(不知道這句是什么意思, EBCDIC 是IBM公司的字符二進制編碼標準。)
3. **HEX Dump**. 允許你查看所有數據,可能會占用大量屏幕空間。適合顯示二進制協議。
4. **C Arrays.** 允許你將流數據導入你自己的C語言程序。
5. **RAW**。 允許你載入原始數據到其他應用程序做進一步分析。顯示類似與ASCII設置。但“save As”將會保存為二進制文件。
## 7.3.?時間戳
時間戳,時間戳的精度,等等是在讓人感到困惑。本節將向你介紹介紹Wireshark處理時間戳時都發生了什么。
在包被捕捉時,每個包在進入時都被加上時間戳,這個時間戳將會保存在捕捉文件中,所以他們也可以在以后分析時使用。
那么說,時間戳是從哪里來的呢?是捕捉的時候產生的。Wireshark從 libpcap(WinPcap) libraray(庫)中獲得時間戳。而libpcap(winpcap)又是從操作系統內核獲得的時間。如果捕捉數據是從捕捉文件載入的,很顯然Wireshark從文件中獲得時間戳數據。
### 7.3.1.?Wireshark內置
Wireshak內置的格式使用的時間戳格式由日期(從1.1.1970開始)和時間(從凌晨起,納秒(10億分之一秒)為單位)組成。你可以調整Wireshark在包列表的時間戳顯示方式。見[第?3.7?節 “"View"菜單”](#calibre_link-31 "3.7.?"View"菜單")的"Time Display Format"項。
當讀取或寫入捕捉文件時,Wireshark按需要在內置格式和其他捕捉文件格式間進行時間戳轉換。
捕捉時,Wireshark使用libpcap(WinPcap)捕捉庫(支持納秒精度)。除非你在專用的捕捉硬件上進行捕捉,一般這樣的精度已經足夠了。
### 7.3.2.?捕捉文件格式
Wireshark支持的捕捉文件格式都帶有時間戳。不同的捕捉文件格式的時間戳精度有很大不同,從秒"0"到納秒 "0.123456789"都有。大多數格式捕捉文件存儲的時間戳都是固定精度的,些捕捉文件格式甚至存儲了時間戳精度本身(可能是出于方便)。
大多數被Wireshark(和或多其他工具)使用的libpcap捕捉文件格式都僅支持固定的百萬分之一固定精度"0.123456"
> 
> 注意
> 寫入數據到一個實際支持精度比你寫入數據精度低的格式文件中,可能會導致數據丟失。例如:如果你載入一個納秒精度的捕捉文件,然后將其存儲為libpcap文件(百萬分之一秒精度)。Wireshark很明顯會將時間精度調整為百萬分之一秒。
### 7.3.3.?準確性
經常有人問:"Wireshark的時間戳的準確性如何?"。實際上,Wireshark自身不會創建時間戳,而是通過其他的地方得到時間并顯示他們。所以,準確性取決于你實用的捕捉系統(操作系統,性能。。。)。因此以上問題很難通過通常的途徑回答。
> 
> 注意
> 通常USB連接的網絡適配器提供的精度非常差。入口的實際上“占用很長的時間和走很曲折的路”才能穿過USB數據線到系統內核。而數據包只有被系統內核處理過以后才會打上時間戳,這種時間戳機制將會導致準確性大大降低。
> 結論:如果你需要精確的時間戳,請不要使用USB連接的網卡!(筆者的注腳:有沒有網卡在USB硬件上提前加上時間戳的?)[[17](#calibre_link-167)]
side bar ceshi
[[17](#calibre_link-168)] 譯者注:前文提到,時間戳是Wireshark用庫獲取的時間加在包上的,不知為何有此一問。難道以后要識別硬件是否有時間戳功能。
## 7.4.?時區
當你在各地旅行時,會碰到時區的困擾。如果你從其他時區得到捕捉文件,時區問題會給你帶來更大的困擾:-)
首先,下面有兩個原因說明你為什么**完全不需要**考慮時區問題:
* 你僅對兩個包的時間戳的差別有興趣,你并不需要了解捕捉包的實際的日期和時間(通常是這樣)。
* 很可能你不會得到不同與你所在時區的包文件,所以你基本上碰不到時區問題。例如:你的團隊的所有都和你工作在一個時區。
**表?7.1.?**
**什么是時區?**
人們希望時間和日升日落對應。早成應該是6點鐘,天黑應該在20:00.這些時間又隨著四季變化。如果地球上每個人使用同樣的全局時間,將只有一小部分人的日落和時間對應,這將會導致混亂。
因此,人們將地球劃分為不同的區域,每個區域都有一個本地時間對應本地的日升日落。
時區基于UTC(Coordinated Universal Time)或者Zulu 時間(軍事和航空)。舊有的GTM(格林尼治時間)已不再使用,因為它有少許誤差(與UTC相比達到0.9秒)。UTC起始時區等于0(位于格林威治,英格蘭),所有的時區和它的偏在在-12~+14小時之間!
例如:如果你住在柏林,你的時區將比UTC早1小時,所以你的時區應該是"+1"(與UTC時間比較的差別,以小時為單位)。柏林的3點和UTC的兩點鐘表示同一個時刻。
有些地區要加以注意,因為那里的時區不是用整小時的。(比如:新德里的時區是 UTC+05:30)
更多相關信息見[http://en.wikipedia.org/wiki/time_zone](http://en.wikipedia.org/wiki/time_zone)和[http://en.wikipedia.org/wiki/Coordinated_Universal_Time](http://en.wikipedia.org/wiki/Coordinated_Universal_Time)。
**表?7.2.?**
什么是時DST?
Daylight Saving Time(DST),又稱為夏令時,目的是在夏天的幾個月里“拯救”白天的時間(夏季白晝較長,如果按照傳統的作息時間,比較可惜,不過我不認為)。為了達到這個目的,很多國家(但不是所有的)增加一個DST小時到UTC中。所以你還得加個小時(極少數地方甚至是2小時)的時差來計算你的時區。
不幸的是,DST并未在全世界范圍內被啟用。你可能同樣注意到,北半球和南半球的夏令時是剛好相反的(比如:歐洲是夏季時,澳大利亞則是冬季)。
注意:不管DST怎樣,UTC在全年都是一致的。
更多相關信息見[http://en.wikipedia.org/wiki/Daylight_saving](http://en.wikipedia.org/wiki/Daylight_saving).
### 7.4.1.?正確設置你的計算機的時區
### 7.4.2.?Wireshark和時區的關系
## 7.5.?合并包
### 7.5.1.?什么是合并包
網絡協議經常需要傳輸較大的數據塊,在傳輸時,底層協議可能不支持這樣大的數據塊(比如網絡包大小的限制),或者是像像TCP一樣的流數據,TCP流完全不知道數據分塊情況。(原文為:or is stream-based like TCP, which doesn't know data chunks at all.)
在這種情況下,網絡協議必須確定數據塊分段的邊界,并(如果有必要)將數據塊分割為多個包。很明顯在接受端也需要有找到數據塊分段邊界的機制。
> ![[提示]](https://box.kancloud.cn/2016-01-14_56970a172d0d5.png)
> 提示
> 在Wireshark里面,這個機制/方法被稱為**合并/reasembling**,在特定協議的描述可能不盡相同(例如:desegmentation, defragmentation, ...)
### 7.5.2.?如何用Wireshark合并包
對那些可以被Wireshark識別的協議,Wireshark通常處理過程為:查找、解碼、顯示數據塊。Wireshark會嘗試查找數據塊對應的包,在"Packet Bytes"面板的附加頁面顯示合并以后的數據。(關于“Packet Bytes”面板的詳細介紹,見[第?4.7?節 “"View"菜單”](#calibre_link-31 "4.7.?"View"菜單"))
**圖?7.2.?帶有合并包附加選項卡"Packet Bytes面板"**

> ![[注意]](https://box.kancloud.cn/2016-01-14_56970a171a4c5.png)
> 注意
> 合并可能發生在多個協議層,所以在"Packet Bytes"面板可能會見到多個附加頁選項卡
> ![[注意]](https://box.kancloud.cn/2016-01-14_56970a171a4c5.png)
> 注意
> 你會在數據塊的最后一個包看到合并后的數據。
以HTTP Get應答為例:請求數據(例如一個HTML頁面)返回時。Wireshark會顯示一個16進制轉儲數據在"Packet Bytes"面板的一個名為"Uncompressed entity body"新選項卡。
默認情況下,首選項中合并功能被設置為允許。在2005年9月之前默認值是不允許。如果你的首選項是在200年9月之前設置的,你得確認一下,合并包選項的設置。合并包對分析網絡包作用非常大。
允許和禁止合并包設置對協議來說還有兩項要求。
1. 下層的協議(如:TCP)必須支持合并。通常協議支持合并與否都是通過協議的參數設置的。
2. 高層協議協議(如:HTTP)必須使用合并機制來合并分片的數據。這些也同樣可以通過協議參數來允許或禁止。
在設置高層協議的時候tooltip會提醒你同樣需要考慮低層的協議設置。
## 7.6.?名稱解析
名字解析嘗試將數字地址解析成適合人們閱讀格式。有兩種方法可以完成這項工作:通過系統/網絡服務(例如獲取主機名)和/或 Wireshark指定的賦值文件。關于通過賦值文件進行解析的詳情,可以參見???
名字解析可以分協議層進行允許,禁止設置。
### 7.6.1.?名字解析的流弊
名字解析在使用Wireshark時有重要價值,甚至可以節約大量時間。不幸的是,名字解析也有它自己的缺點。
* **名字解析經常會不可用**。服務器可能不知道需要被解析的名字,或者服務器不可用。又或者需要解析的名字在賦值配置文件中找不到。
* **名字解析并沒有存儲在捕捉文件或其他什么地方**。因此你以后打開捕捉文件或者在其他設備上打開文件有可能發現名字解析不可用。每次打開捕捉文件可能會發現部分地址略微發生變化,也許僅僅是因為無法連接到名字解析服務器(之前還是可以連接的)
* **DNS可能會增加額外的包到Wireshark中**。你會在包文件中看到由Wireshark請求DNS服務生成的包進出你的機器。
* **解析名稱被Wireshark緩存**。這對設備性能有一定需求。但是,如果名字解析信息在wireshark運行時發生變化,wireshark不會注意到這個變化,因為它是從緩存進行解析的。如果這些信息在Wireshark運行時變化了,例如獲取一個新DHCP租約,Wireshark不會注意到。(這些是針對DNS還是所有信息?有多少機器使用動態dns注冊?)
> ![[提示]](https://box.kancloud.cn/2016-01-14_56970a172d0d5.png)
> 提示
> 名字解析在包列表填入時已經完成。如果一個包填入包列表以后被解析,包列表的內容不會立即更改,相反解析結果會被緩存,你可以使用"View/Reload"重建包列表,來正確顯示名字解析結果。但在捕捉過程中這樣做沒有效果。
### 7.6.2.?以太網名字解析(mac層)
嘗試將MAC地址(e.g. 00:09:5b:01:02:03)解析為適合閱讀的地址("Human readable")
**ARP名字解析(系統服務)** Wireshark會向操作系統發出請求,將以太網地址轉換為對應的IP地址(e.g. 00:09:5b:01:02:03->192.168.0.1)
**Ethernet codes(ethers file)** 如果ARP解析錯誤,Wireshark會嘗試將以太網地址解析為已知設備名。這種解析需要用戶指定一個ethers文件為mac地址分配名稱。(e.g. 00:09:5b:01:02:03 -> homerouter).
**Ethernet manufacturer codes (manuf file)** 如果ARP解析和ethers文件都無法成功解析,Wireshark會嘗試轉換mac地址的前三個字節為廠商名的縮寫。mac地址的前三個字節是IEEE為各廠商分配的獨立地址(通過前三個字節可以得出每個網絡設備的供應商,當然這些也是可以被篡改的。,)(e.g. 00:09:5b:01:02:03 -> Netgear_01:02:03).
### 7.6.3.?IP地址解析(網絡層)
將IP地址(e.g. 216.239.37.99)轉換為適合閱讀的地址/"Human readable"
**DNS/ADNS name resolution(system/library service)**Wireshark會向操作系統(或ADSN library 地址-名稱解析詞典?)請求,將IP地址轉換為相關聯的主機名(e.g. 216.239.37.99 -> www.1.google.com).此時DNS服務正在同步請求DNS服務器,所以Wireshark會停止相應直到DNS請求的響應返回。如果可能的話,你可以考慮使用ADNS library(這樣可以避免等待網絡相應。)
> ![[警告]](https://box.kancloud.cn/2016-01-14_56970a170c848.png)
> 警告
> 如果名稱解析服務器不可用,允許網絡名稱解析使Wireshark明顯變慢,因為wireshark會等待名字解析結果直到超時。在這種情況你應該使用ADNS。
**DNS vs. ADNS** 這里是一個簡短的對比:兩個都是用來轉換ip地址為其他易讀的地址"Human readable"(域名)。通常DNS用gethostname()將地址轉換為名稱。通常首先是查詢hosts文件(e.g. /etc/hosts,/windows/system32/drivers/etc/hosts)看能否找到匹配實體。如果找不到,會向指定的DNS服務器查詢。
DNS和ADNS真正的區別在于等待DNS服務器名字解析。gethost()會一直等待知道名字被解析或者返回錯誤。如果DNS服務器不可用,可能會占用很長時間(好幾秒)。ADNS服務會略微有點不同。它也同樣向DNS服務器發出請求,但不會等待服務器應答。它會立即相應Wireshark。此時的地址(和后續地址)在ADNS得到結果前不會顯示解析名稱。如前文書中說道,解析結果被保存在緩存中,你需要使用"View/Reload"菜單更新這些字段來顯示解析名稱。
**hosts name resolution(hosts file)** 如果dns解析不成功,Wireshark會嘗試使用用戶提供的主機文件將IP地址轉換為對應的主機名。(e.g. 216.239.37.99 -> www.google.com)
### 7.6.4.?IPX名稱解析(網絡層)
**ipxnet name resolution (ipxnets file) (筆者未作解釋)**
### 7.6.5.?TCP/UDP端口名解析(傳輸層)
翻譯TCP/UDP端口(e.g.80)為更加易讀的玩意"human readable"[[15](#calibre_link-115)]
**TCP/UDP port conversion (system service)** Wireshark會向操作系統發出請求,轉換TCP/UDP端口為已知名稱(e.g. 80->http)。
XXX - mention the role of the /etc/services file (but don't forget the files and folders section)!
[[15](#calibre_link-116)] 應該是指將端口翻譯為服務名
## 7.7.?校檢和
很多協議使用校檢和來驗證數據的完整性/正確性。
> ![[提示]](https://box.kancloud.cn/2016-01-14_56970a172d0d5.png)
> 提示
> 應用校檢和在這里也被成為**redundancy check**(冗余校檢?)
> **校檢和是做什么的?**
>
> 校驗和是用來驗證傳輸數據或存儲數據的數據部分的正確性。一個檢驗和是數據部分進行摘要計算的出的數字。
>
> 網絡數據在傳輸過程中經常會產生錯誤,例如數據錯誤,字節重復等。數據接收方可能。
>
> 正因為傳輸過程中會伴隨錯誤,網絡協議會經常使用校驗和檢測這些錯誤。發送方會對數據進行檢驗和計算,并將數據和檢驗和一起發送。接收方使用同樣的方法計算數據部分的校驗和,如果收到的校驗和計算出來的校驗和不匹配,就表示數據有錯誤。
>
> 有些校驗和方法可以通過計算得出發生需要被修復錯誤的數據位置,并修復(簡單的)錯誤。
>
> 如果那些錯誤無法修復,接收方會丟棄錯誤的數據包。根據協議的不同,數據丟失會僅僅被丟棄,也有可能發送端會根據數據丟失情況重傳需要的數據包。
>
> 使用校驗和可以大量減少傳輸錯誤數量。但任何檢驗和算法都無法確保100%檢測到所有錯誤,依然有少量的錯誤會無法被檢測到。
>
> 校驗和的算法有很多,例如最經常被使用的檢驗和算法CRC32(循環冗余校驗)。特的的網絡協議選擇的校驗算法取決于希望網絡媒介達到的出錯率上限、錯誤檢測的重要性,處理載入計算的性能,其他方面需要的性能。
>
> 關于檢驗和的更多信息可以參考:http://en.wikipedia.org/wiki/Checksum
### 7.7.1.?Wireshark校檢和驗證
Wireshark會對很多協議進行檢驗和驗證,如:TCP、IP。。。
它會和"normal receiver"做一樣的計算.然后在包詳情面板顯示檢驗和字段的內容,e.g.:[correct], [invalid, must be 0x12345678] 以及其他類似的內容。
如果校驗和驗證選項被打開或正在進行校驗和檢測,合并包特性不會被執行。這是為了避免錯誤的的連接數據擾亂內部數據。
### 7.7.2.?Checksum offloading
檢驗和計算可能由網絡網絡驅動,協議驅動,甚至是硬件完成。
例如:以太網傳輸硬件計算以太網循環容易校驗,接受硬件驗證這個校驗。如果接受驗證發現錯誤,Wireshark將不會接收到這個包,以太網硬件會直接丟棄這個包。
高層校驗通常是由協議執行,并將完成后的包轉交給硬件。
比較新的網絡硬件可以執行一些高級功能,如IP檢驗和計算,這被成為checksum offloading。網絡驅動不會計算校驗和,只是簡單將校驗和字段留空或填入無效信息,交給硬件計算。
> ![[注意]](https://box.kancloud.cn/2016-01-14_56970a171a4c5.png)
> 注意
> checksum offloading經常會導致混亂,因為網絡包在檢驗和計算之前轉交給Wireshark。Wireshark得到包的檢驗和字段是空的,必然會顯示檢驗和錯誤,盡管這個包在從網絡硬件發出的時候是帶有校驗和的。
Checksum offloading會引起混淆,讓你屏幕上看到大量的[invalid]信息,引起你的反感。前面提到過,錯誤的檢驗和會導致包無法合并,更難進行包數據分析。
你可以采取兩種方法避免Checksum offloading 問題
* 在驅動程序上關閉checksum offloading選項,如果可用的話。[[16](#calibre_link-171)]
* 通過首選項關閉Wireshark上特定協議的校驗和驗證。
[[16](#calibre_link-172)] 在Windows平臺如果驅動支持,應該是計算機管理->設備管理器->網絡適配器->對應網卡的屬性-高級選項