2009-12-30 30 views
27

有沒有一個Linux庫能夠告訴我哪些IP套接字由哪些進程擁有?我想我正在尋找lsof -i的編程等值。最終,我想將通過libpcap看到的數據包關聯到進程。用於確定進程擁有的套接字的Linux API

更新:一對夫婦的人已經開始使用/proc/<pid>/net/tcpudp,但在我的系統提示,顯示每個進程相同的數據,所以它並不能幫助。

+0

哇。我正在編寫一個程序,現在就做這個,真是巧合 –

+1

我現在有代碼,如果你有興趣比較筆記。我在/ proc數據中看到了一些罕見的怪癖,但總體上這種方法很有效。 –

回答

45

我認爲你首先必須看看/ proc/*/fd中的開放文件夾,例如

4 -> socket:[11147] 

,然後尋找在/ proc /淨/ TCP引用的套接字(由索引節點)(或/ PROC /淨/ UDP),例如

12: B382595D:8B40 D5C43B45:0050 01 00000000:00000000 00:00000000 00000000 1000  0 11065 1 ffff88008bd35480 69 4 12 4 -1 
+0

這是缺少的鏈接。謝謝! (由於某種原因,請不要讓我高興) –

+0

你在我寫作的時候回答了這個問題,我沒有注意到......好的工作:) +1因爲OP顯然不能。 – ephemient

+0

如果2個例子中的inode相互匹配,這個答案可能會更好。 – Samveen

4

您可以從proc文件系統讀取。 「文件」,你可能想看看在 /proc/<pid>/net被發現(即TCP,UDP,UNIX)

下面是一些examples使用proc文件系統

+0

+1非常有用......謝謝:) –

+1

也許我錯過了一些東西,但/ proc/*/net/tcp顯示了不同pid的相同數據。必須顯示所有連接。我如何將每個映射回源pid? –

11

/proc文件系統提供每個進程的詳細信息,包括網絡信息。打開插座信息列於/proc/net/tcp。在tcp6文件中分別列出了IPv6套接字。套接字信息包括諸如本地和遠程端口以及套接字inode號等信息,可以通過解析/proc/{pid}/fd/*信息將其映射回過程。

如果您不熟悉/proc文件系統,它基本上是一個虛擬文件系統,它允許內核向用戶空間發佈各種有用的信息。這些文件通常是易於解析的簡單結構化文本文件。

例如,我的Ubuntu系統上我以前netcat進行測試,跑nc -l -p 8321爲偵聽端口8321.望着tcp插座信息:

$ cat /proc/net/tcp 
    sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode              
    0: 00000000:2081 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000  0 26442 1 de0c8e40 300 0 0 2 -1        
    1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 7019 1 de0c84c0 300 0 0 2 -1        

,第一行顯示它是在所有地址聆聽指向8321(0x2081)。 inode編號是26442,我們可以用它來查找/proc/{pid}/fd/*中匹配的pid,它包含一系列從文件句柄編號到設備的符號鏈接。因此,如果我們仰望的PID爲netcat,並檢查其fd映射:

$ ls -l /proc/7266/fd 
total 0 
lrwx------ 1 gavinb gavinb 64 2009-12-31 09:10 0 -> /dev/pts/1 
lrwx------ 1 gavinb gavinb 64 2009-12-31 09:10 1 -> /dev/pts/1 
lrwx------ 1 gavinb gavinb 64 2009-12-31 09:10 2 -> /dev/pts/1 
lrwx------ 1 gavinb gavinb 64 2009-12-31 09:10 3 -> socket:[26442] 

還有我們看到的文件描述符3在這個過程中被映射到插座索引節點26442,正如我們期望的那樣。因此,顯然要構建一個完整的套接字映射,您需要首先枚舉所有/proc/**/fd/*文件,查找套接字符號鏈接,然後將套接字inode與來自/proc/net/tcp的具有端點信息的表匹配。

這是lsof工具的工作方式(請參閱lsof/dialects/linux/dsocket.c的實施)。

+0

與我對Kimvais的問題相同:/ proc/*/net/tcp目錄顯示不同pid的相同數據。我如何將每個映射回源pid? –

+0

我已經更新了答案,以包含如何將套接字映射到pid的完整描述。我希望現在更清楚 - 它基本上涉及到爲套接字inode建立一個pid表,並在tcp套接字表中查找這些inode。讓我知道是否有什麼需要澄清。 – gavinb

+0

非常清楚。謝謝! –

3

你可以嘗試運行lsof的與strace的和看到的只是哪些文件在/ proc從獲取數據。

+0

直接點 –

5

/proc/<pid>/net相當於/proc/net在同一個網絡的命名空間,你–換句話說,它是「全球性」信息的所有進程。

你可以做什麼lsoffuser這樣做,它是遍歷/proc/<pid>/fd/*/proc/net/*尋找匹配inode。快速演示:

#!/bin/sh 
pgrep "[email protected]" | while read pid; do 
    for fd in /proc/$pid/fd/*; do 
     name=$(readlink $fd) 
     case $name in 
      socket:\[*\]) 
       ino=${name#*:} 
       for proto in tcp:10 tcp6:10 udp:10 udp6:10 unix:7; do 
        [[ ! -e /proc/net/${proto%:*} ]] || 
        awk " 
         \$${proto##*:} == ${ino:1:${#ino}-2} { 
          print \"${proto%:*}:\", \$0 
          exit 1 
         } 
        " /proc/net/${proto%:*} || break 
       done 
       ;; 
     esac 
    done 
done 

您可以擴展這對其他協議(我看到AX25,IPX,包,原料,raw6,udplite,udp6lite在​​太),或在您選擇的語言重寫。

12

要確定進程擁有的套接字,您可以使用netstat。這裏有一個例子w /輸出(縮短)netstat與選擇,將做你想做的。

$ sudo netstat -apeen 
Active Internet connections (servers and established) 
Proto Recv-Q Send-Q Local Address   Foreign Address   State  User  Inode  PID/Program name 
tcp  0  0 127.0.0.1:8118   0.0.0.0:*    LISTEN  138  744850  13248/privoxy 
tcp  0  0 127.0.0.1:5432   0.0.0.0:*    LISTEN  117  9612  2019/postgres 
udp  0  0 127.0.0.1:51960   127.0.0.1:51960   ESTABLISHED 117  7957  2019/postgres 
udp  0  0 0.0.0.0:68    0.0.0.0:*       0   7740  1989/dhclient 
Active UNIX domain sockets (servers and established) 
Proto RefCnt Flags  Type  State   I-Node PID/Program name Path 
unix 2  [ ACC ]  STREAM  LISTENING  7937  2019/postgres  /var/run/postgresql/.s.PGSQL.5432 
unix 2  [ ACC ]  STREAM  LISTENING  958058 8080/emacs   /tmp/emacs1000/server 
unix 2  [ ACC ]  STREAM  LISTENING  6969  1625/Xorg   /tmp/.X11-unix/X0 
unix 2  [ ]   DGRAM     9325  1989/dhclient  
unix 3  [ ]   STREAM  CONNECTED  7720  1625/Xorg   @/tmp/.X11-unix/X0 

確保您以root運行netstat否則你會得到這樣的信息:

(Not all processes could be identified, non-owned process info 
will not be shown, you would have to be root to see it all.) 

netstat manpage-apeen選項的解釋:

-a, --all 
    Show both listening and non-listening sockets. With the 
    --interfaces option, show interfaces that are not up 

-p, --program 
    Show the PID and name of the program to which each socket 
    belongs. 

-e, --extend 
    Display additional information. Use this option twice for 
    maximum detail. 

--numeric , -n 
    Show numerical addresses instead of trying to determine symbolic host, port or user names. 

--numeric-hosts 
    shows numerical host addresses but does not affect the resolution of port or user names. 

--numeric-ports 
    shows numerical port numbers but does not affect the resolution of host or user names. 

--numeric-users 
    shows numerical user IDs but does not affect the resolution of host or port names. 
+0

如果您向該進程的所有者申請sudo(如果您無法獲得root),則可以獲得該pid。 +1這個解決方案!謝謝! – gred

+1

'netstat'實際上會解析'/ proc/net/tcp'等。例如,參見[這裏](http://sourceforge.net/p/net-tools/code/ci/master/tree/netstat.c#l979)(解析'/ proc/net/tcp'的代碼) 。由'lib/pathnames.h'中定義的netstat使用的路徑。 – z9u2k

相關問題