pretty code

顯示具有 ARP 標籤的文章。 顯示所有文章
顯示具有 ARP 標籤的文章。 顯示所有文章

2021年12月23日 星期四

ARP 廣播封包苦主

下午想要修一個 bug 時,板子一直無法取得 IP,抓了封包一看,又是一堆 ARP 廣播封包在網路流竄。

比較特別的是,不像兩年前一樣,是某台設備網路設定有誤才導致狂發廣播封包。稍微看了一下,只看到很多台電腦像是很正常的在問某些電腦的 MAC,單只看一台的網路流量不會很多,偏偏看起來是一整個子網路的每台電腦都有狂問 ARP 的現象,於是又把我的板子打掛了。

一時之間,福至心靈,突然覺得會不會跟最近疑似 IT 透過群組原則自動安裝的 ivanti 管理軟體有關?在 Google 大神的幫助之下,果然有人也有這個問題,看起來是跟尋找設備的 agent 有關,因為 agent 要 ping 電腦,故才會一直發 ARP 封包,而我猜那些電腦應該是沒有上網的,故也沒有回應?

該 agent 使用 XDD 協定來尋找設備,簡單來說 agent 會監聽 ARP 廣播封包,當它發現有新的設備出現在網路上時,便把該 IP 記錄起來,並在各個 agent 間協調,只有一台 agent 會負責 ping 新設備。

聽起來是很棒啦?但該軟體一定是那邊沒做好,才會導致這個情況,光所謂的協調我覺得要考慮的點就很多了。



從 C:\ProgramData\LANDesk\Log\SelfElectController.log 中,確實也可以看到相關跡象。


2021/12/24 更新

今天除了找到 Go package 來發送 ARP 封包,也找到 Win32 API 來發送 ARP 封包,要做測試就更方便了。

2019年11月29日 星期五

一個 ARP 廣播封包的故事

ARP 協定是在乙太區域網路中常用到的一個協定,當我們有資料要傳給區域網路上的某台裝置時,由於上層僅知道 IP 資訊,故需要使用 ARP 協定來得知該裝置的 MAC。

一般來說,系統都會有內建的 ARP table,以 Windows 來說,可以使用 "arp -a" 來觀看,如果在 table 中找不到對應的 IP,就會發出 ARP 廣播封包來得到該台裝置的 MAC,而這個封包的目的 MAC 便會是 "FF:FF:FF:FF:FF:FF",表示要傳給區域網路中的所有節點。


我們有個專案會使用 UEFI Shell 開機且定時的使用 HTTP Web API 跟 Server 溝通,以得知接下來要做的測試並回報測試結果。

某天我們拿到了新的板子,恰巧的是網路卡晶片也改了,這時原本正常的測試都無法順利進行,不是 DHCP 取不到 IP 就是 HTTP Web API 無法正常工作。當然,一開始會直覺是因為新板子的緣故。

由於此板已經在私人的網路環境測試過,DHCP 看起來都正常工作,只好詢問公司 IT 是否有更改公司區域網路設定,不料 IT 並沒有修改設定,這段期間也有將自己電腦接到該板子所使用的 port 測試,看起來網路也都正常,偏偏兩者合起就來就是無法正常工作,這中間還做了很多實驗,但都無助於問題解決。

沒辦法只好動用 Wireshark 和 mirror port switch 了,首先可以確認的是某些時候不論是 DHCP 的回應封包或是測試 Server 的 SYN-ACK 封包,都有正常送回板子端,但不知道什麼緣故,板子會認為沒有收到封包,結果便是 DHCP 取不到 IP 以及 HTTP Web API 失效。

雖然從封包可以證明問題似乎是出自板子端,但對解決問題還是沒有幫助,畢竟在我們自己的私人網路環境都是正常的。幸好在截取封包的過程中,發現有一個設備不斷的在發出 ARP 廣播封包且每次要詢問的 IP 都不一樣,從比例來看,至少佔了封包數的 40 % 以上( 因為是 mirror 故這個數字可能 double 了 ),這是個不正常的現象,一般來說,大部份都會是 IPV4 封包佔的比例會是最高,ARP 應該是 10% 以下較為合理。


將此情況回報給 IT 後,據 IT 的說法是該台設備的使用者誤將 DHCP 設定設成固定 IP,導致該設備不斷的發出 ARP 廣播封包。說也奇怪,在 ARP 廣播封包消失後,我們的板子就恢復正常了,個人猜測是因為 UEFI Network Stack 的 implement 無法處理此類情況,畢竟 UEFI 只是個單執行緒的精簡 OS?

雖然後續測試看起來都正常了,但到底是不是因為 ARP 廣播封包所引起?這個問題一直在我心頭縈迴不去,看來證明它的方式便是想辦法創造出一樣的環境。

Google 了一下,想要發出 ARP 封包看起來在 Windows 下不可行,幸好這個世界上還有萬能 OS - Linux 存在,只要使用 RAW Socket 便可以順利的發出 ARP 廣播封包。

萬事具備,只欠東風,使用 Switch 架設了一個私人網路環境,並配合測試 Server 配置,設定了相關裝置的固定 IP,原本只是簡單寫個 for loop scrip 10000 + C code 發送 ARP 廣播封包,但板子看起來卻是一切正常?靈機一動之下,判斷是壓力不夠,在開啟另外一個終端機並執行相同的 script 後,我們的板子終於宣告不治,一直要等到 ARP 廣播封包結束後才能恢復正常。


能夠確認自己的判斷並重現問題,我想這才是 RD 的本事所在,真不枉費我寫了 14 年的 Code。

2021/12/24 更新

原來是我誤會 Windows 了,Windows 有提供一個 SendARP 的 Win32 API,故我們在 Windows 下也可以發送 ARP 封包,重點是可以用 Go!另外,我也找到一個 Go package 可以在 Linux 下發送 ARP 封包,這樣就更容易做測試了。