1. 程式人生 > >STM32開發筆記52:STM32F4+DP83848乙太網通訊指南系列(六):Wireshark使用

STM32開發筆記52:STM32F4+DP83848乙太網通訊指南系列(六):Wireshark使用

本章為系列指南的第六章,這一章我們暫時離開Keil,離開STM32,離開C語言,這一章我們要去了解一些乙太網相關的知識,特別是學習使用大名鼎鼎的除錯乙太網通訊程式的利器:WireShark。

幀結構

我們從小就聽說過計算機中全都是二進位制的0和1,這個道理幾乎連考不上三本的文科生都懂,但是很難有直觀的感受,甚至連由16個bit,也就是16個二進位制的0/1構成的十六進位制0/F,再由兩個十六進位制的0/F形成的0x00/0xFF這種Byte(位元組),都很難直觀感受到,畢竟計算機世界太豐富了,各類色彩,圖片,網站,視訊,遊戲充斥著我們的日常,所謂「亂花漸欲迷人眼,淺草才能沒馬蹄」,形形色色的計算機資源就是「亂花」,其背後單調的Byte才是「淺草」,我們在網路通訊時只需要Byte的顆粒度,至於細化到bit的精度,只有在研究純電子電路時才會涉及到。如果說如何傳輸bit是PHY層負責的問題,那麼如何構造和解析Byte就是MAC層要肩負的責任了。

由Byte組成的一個個網路幀,勢必要按照一定的格式進行排列,就像如果要你自己自己編排一個串列埠通訊的協議,你也一定會考慮包頭、包尾、校驗位這些。

Ethernet V2協議在鏈路層規定了一個基本的幀結構,如下:

目標MAC 源MAC 型別 資料 迴圈冗餘校驗FCS
6位元組 6位元組 2位元組 46-1500位元組 4位元組

因此,最小的幀長度是6 + 6 + 2 + 46 + 4 = 64個Byte,最大長度是6 + 6 + 2 + 1500 + 4 = 1518個Byte。

上表最後4個Byte形成了一組迴圈冗餘的CRC校驗資料,很遺憾的是我們能通過軟體手段監聽出來的幀結構都不會含有這段資料,因為網絡卡在接受到報文後就會立即對資料進行校驗,凡是不滿足校驗規則的資料包會直接丟棄,不會觸發作業系統的乙太網事件。因此你能監聽到的報文都是符合規則的,網絡卡交給上層軟體應用時也會自動將校驗資料剝離。此外,具體的迴圈冗餘CRC校驗的演算法是什麼大家也不用管了,在使用STM32呼叫發包指令時,MAC層會幫我們計算好的。

一個典型的ARP幀報文如下:

ff ff ff ff ff ff 00 11 0e 0b 03 8a 08 06 00 01
08 00 06 04 00 01 00 11 0e 0b 03 8a c0 a8 01 c7
00 00 00 00 00 00 c0 a8 01 fe 00 00 00 00 00 00
00 00 00 00 00 00 00 00 20 20 20 20

這是一個最簡單的60Byte的ARP報文(另有4個FCS校驗資料被網絡卡吞了,總長度64Byte),看上去是不是像是亂碼,完全無法理解,彆著急,下面介紹網路程式設計的神器WireShark。

WireShark·線路鯊魚

這款名字裡帶有「鯊魚」的軟體,真的是名副其實,大鱷級的網路程式設計神器:精確到微妙級別的底層網路包監聽,內建上千種網路協議,上下文分析得絲絲入扣,你通過它即可完全理解整個網路上正在發生了什麼。無論是初學網路的思科學員想一窺網路的究竟,還是努力工作的程式設計師需要進行協議的分析,亦或是躲在陰暗處的黑客試圖在交換機上颳起一場網路風暴,WireShark都能助你一臂之力。

軟體下載地址:https://www.wireshark.org/#download

WireShark為了能夠監聽到網路底層的資料包,在Windows上使用了叫做winpcap的技術,而winpcap又是使用了libpcap這個庫,這樣的呼叫關係其實是為了解決一件事:能在作業系統上層操作底層網路資料包。

我們平時在C++,JAVA中談論到的網路程式設計,其實所處的層級都是高層,回想一下那些Socket程式設計所講到的知識,一般上來就會講TCP/UDP,也就是處在高層應用開發的高度來講,網路程式設計非TCP即UDP,別無其他。在《STM32F4+DP83848乙太網通訊指南第一章:知識儲備》裡我講到乙太網分為很多層(按照OSI模型有七層,按照TCP/IP協議有五層),除了應用層以外,我們還有很多底層的資料包跑在網路上(比如ARP資料包、ICMP資料包等),這些資料包大部分不是由一般程式設計人員通過各種網路應用程式發起的,那麼它們是由誰發起的,又是由誰來負責接受和解析呢?這個答案是網絡卡、交換機,以及作業系統,這些資料包關係到網路的通路、拓撲、路由,使用者層面一般不需要了解和控制,對作業系統來說,一般也是不會讓使用者隨意觸碰甚至自行構建網路幀的。

WireShark利用winpcap做到了監聽底層網路包,它嚴格地限制了自己無法對網路資料進行修改、編輯、轉發。一旦普通使用者對乙太網的瞭解更多一些,並且能夠利用WireShark處理和轉發網路包,那對於網路安全真是一件非常恐怖的事情。

說了這麼多,其實都是在講一些周邊知識。WireShark的安裝步驟我就不贅述了,下載和安裝都是很簡單的,現在我們來看看上面提到的那份看上去像亂碼的ARP資料包,其實它就是我用WireShark捕獲到的,上面的「亂碼」只不過是我用十六進位制的方式直接複製出來,接下來我們看看這份資料包在WireShark的幫助下會不會更清晰一點:

如上圖所示,在WireShark的幫助下,資料包中每一個結構都清晰可見,WireShark幫助我們將一堆十六進位制的Byte理解得就如同json資料一樣清晰,其內建的數千種網路協議,使得WireShark對各種各樣的網路包每一位的作用都瞭如指掌。在軟體的下方區域點選任意一位Byte,它都會在中部區域將這一位的含義和作用清晰地顯示出來。

我們再來看一個稍微複雜點的IPV4資料包,是我們常用的一個ping指令發出去的ICMP幀,在WireShark上顯示74個Byte:

同樣,WireShark幫助我們理解起來要非常清晰,截圖其實並不能很好地體現,我們在使用WireShark的時候隨時可以用滑鼠點選任意位元組,顯示其含義。

廣播和點對點

最後我們再介紹一些交換機的附帶知識,我們知道網路幀一般會在開頭的6個位元組標明這個網路幀的接受裝置的MAC地址,如果這個包要向區域網內所有裝置進行廣播,比如上面那個ARP包,這六個位元組一般為FF FF FF FF FF FF,如果這個包要向一個特定的裝置進行通訊,這六個位元組則為一個確定的MAC地址,比如上面那個ICMP包,其指向了交換機,交換機收到了以後需要向上行網路請求。

如果區域網內的主機A需要向主機B傳送一個點對點的資料,那麼封裝後的乙太網幀的前六個位元組就為主機B的MAC地址,交換機收到後會查詢自己的維護的對映表,比如找到自己的埠2上的裝置的MAC地址就是B的地址,那麼交換機就向埠2上的網線投送這個資料包,交換機其他埠上的裝置就收不到這則資料包了。

那麼我們在做乙太網協議分析時,一般是處於主機C的位置來監聽和分析A和B的通訊,大多數情況下他們之間是點對點通訊,主機C在區域網中是觀察不到這些資料包的,因為交換機壓根就不將A和B的通訊資料轉發給主機C。

這時候就要祭出又一款硬體神器了:帶有埠映象功能的網管型交換機

利用這種交換機,可以進入管理控制介面,配置埠對映,將裝置A和裝置B之間通訊的雙向資料全都轉發給裝置C,方便WireShark進行協議分析,最終我們可以根據分析出來的協議,在嵌入式STM32中編寫自己的協議棧,實現DIY的裝置D,與裝置A進行通訊,取代裝置B。

上圖就是我購買的一款網管型交換機中配置埠對映的介面。

小結

這一章我們對乙太網的幀結構有了一個基本的認識,瞭解了網路上跑的各種資料包在MAC層的表現形式,能夠運用WireShark觀察一些簡單的由各種十六進位制資料組成的資料包,最後我們還了解了如何運用網管型交換機配置埠對映,在區域網中的C端監聽A和B的通訊。

以上,為下一步在STM32嵌入式裝置中編寫網路協議打下了基礎。