標籤:系統調用 add 監聽連接埠 adl 的區別 檔案 哪些 串連 記錄
因為最近接手的項目是基於嵌入式Linux openwrt的,一開始以為會跟之前的伺服器開發沒什麼大的區別,但是遇到問題去分析的時候才發現,工具鏈還是有些差別的,openwrt的netstat是屬於一個叫做busybox的工具集的,這個工具集是專門提供給嵌入式Linux,它的參數很簡單,居然沒有Linux下netstat的-p選項,因此當我想查看是哪些進程在監聽哪些連接埠時,發現只能查看有哪些監聽連接埠,無法得知是屬於哪個進程的,lsof也沒有-i選項。
但是有時候排查問題又必須知道哪個進程監聽了某個連接埠,因此就想搞清楚Linux下的netstat是怎麼實現可以查看監聽連接埠屬於哪個進程呢。
首先想法就是去下載busybox的原始碼,但是感覺代碼太多了,費時費力,於是靈機一動想到Linux下的另一個工具strace(追蹤程式調用的系統調用),通過strace來查看netstat執行時都做了什麼操作。
截取了strace輸出的某一段,可以看到,調用open以及readlink遍曆了/proc/3055/fd/目錄下的所有檔案,大家都知道這個目錄是進程開啟檔案的目錄。
在strace輸出的最後,可以看到調用了open開啟/proc/net/udp檔案,並讀取裡面的內容將其解析輸出,這裡面就記錄了所有udp串連的資訊,同時/proc/net/tcp對應tcp串連、/proc/net/unix對應Unix socket串連。
根據這個檔案的標題可以知道,第二列是local address,但是由於是16進位編碼,所以需要我們手動轉換成10進位。
這裡其實可以發現,/proc/net/udp這個檔案中的資訊是不包含進程資訊的,所以這也是為什麼netstat在開始的時候會先遍曆所有/proc/xx/fd目錄,因為netstat可以通過inode將/proc/net/udp中的行和/proc/xx/fd中的檔案關聯起來,這樣就可以得到某一行udp串連的進程資訊(因為inode是唯一的)。
所以,分析到這裡,我猜測busybox中的netstat應該是沒有遍曆所有/proc/xx/fd這一步,僅僅是讀取了/proc/net/udp檔案並解析輸出。
明白了netstat的原理,那麼即使遇到不提供netstat -p選項的嵌入式Linux,我們也能手動分析出自己想要的資訊,進而解決問題。
netstat實現原理