netstat實現原理


因為最近接手的項目是基於嵌入式Linux openwrt的,一開始以為會跟之前的服務器開發沒什么大的區別,但是遇到問題去分析的時候才發現,工具鏈還是有些差別的,openwrt的netstat是屬於一個叫做busybox的工具集的,這個工具集是專門提供給嵌入式Linux,它的參數很簡單,居然沒有Linux下netstat的-p選項,因此當我想查看是哪些進程在監聽哪些端口時,發現只能查看有哪些監聽端口,無法得知是屬於哪個進程的,lsof也沒有-i選項。

但是有時候排查問題又必須知道哪個進程監聽了某個端口,因此就想搞清楚Linux下的netstat是怎么實現可以查看監聽端口屬於哪個進程呢。

首先想法就是去下載busybox的源代碼,但是感覺代碼太多了,費時費力,於是靈機一動想到Linux下的另一個工具strace(追蹤程序調用的系統調用),通過strace來查看netstat執行時都做了什么操作。

謝謝@Dlemon的提示,特別說明一下:

只有當netstat加了-p參數需要展示進程id時才會有下面getdents這個函數調用,因為此時需要展示進程id,而/proc/net/tcp或者/proc/net/udp中沒有包含進程id,只能去/proc目錄下遍歷。

截取了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,我們也能手動分析出自己想要的信息,進而解決問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM