Ip

獲取程序使用的套接字的IP地址

  • June 1, 2019

給定一個程序 ID(使用套接字),我想獲取套接字端點上的 IP。

例如,當創建新的 SSH 會話時,每個會話的 sshd 惡魔分叉程序。我想獲取該會話的 IP 端點。

我發現這個邏輯可行:

  1. 列出所有 TCP 套接字,“cat /proc/net/tcp”

  2. 列出輸入程序的所有文件描述符和 grep “socket”:“ls -la /proc/PID/fd | grep socket"

  3. 合併結果

輸出#1:

root@L137B-DV3:/home/ilan# cat /proc/net/tcp
 sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
...
 18: 519A0A0A:E0D1 3C890A0A:C006 01 00000000:00000000 00:00000000 00000000     0        0 10494 1 ffff88003c44f640 20 4 30 10 -1
 19: 519A0A0A:9930 3C890A0A:C004 01 00000000:00000000 00:00000000 00000000     0        0 10496 1 ffff88003c44ee80 20 4 32 10 -1
 20: 519A0A0A:01BD 59890A0A:C1FA 01 00000000:00000000 02:0004F47D 00000000     0        0 76451 2 ffff88003b39d740 21 4 30 10 -1

輸出#2

root@L137B-DV3:/home/ilan# ls -la /proc/4038/fd/ | grep socket
lrwx------ 1 root root 64 Jun  4 13:40 30 -> socket:[6347]
lrwx------ 1 root root 64 Jun  4 13:40 32 -> socket:[76483]
lrwx------ 1 root root 64 Jun  4 13:40 35 -> socket:[6357]
lrwx------ 1 root root 64 Jun  4 13:40 36 -> socket:[76451]
lrwx------ 1 root root 64 Jun  4 13:40 6 -> socket:[76453]

我們看到inode 76451是合併結果,socket ip地址是localhost:519A0A0A和remote:59890A0A。

我的問題是:

  1. 是否可以“cat /proc/net/tcp”一個特定的程序?我試過 cat /proc/PID/net/tcp - 它返回與 cat /proc/net/tcp 相同的結果。

2.有沒有更有效的方法來檢索IP?

您可以使用以下命令列出 PID 的打開文件lsof

lsof -p <PID>

但您可能更喜歡在 ssh 程序上使用命令名稱過濾:

# filters on both ssh and sshd command (client/server)
lsof -i -na -c /sshd?/ -sTCP:ESTABLISHED

並結合兩者當然:

lsof -p <PID> -i -na -sTCP:ESTABLISHED

獲取通過 TCP/UDP 偵聽的本地 IP 地址和埠列表:

netstat -planu | awk '/^udp / {print $4}'

通過 /proc 文件系統獲取相同的資訊:

for h in $(awk 'NR>1{print $2}' /proc/net/tcp); do
printf "%s:%d\n" $(printf "%d." $(echo ${h%:*}|sed 's/../0x& /g'|tr ' ' '\n'|tac)|sed 's/\.$/\n/') 0x${h#*:}; done

其次是

ip_addr=$(echo 0F01A8C0 | sed -e 's/\(..\)\(..\)\(..\)\(..\)/echo $((0x\4)).$(echo $((0x\3))).$(echo $((0x\2))).$(echo $((0x\1)))/e')

然後在 awk

awk 'NR>1{split($2, addr, ":"); for(i=0;i<4;i++){
printf("%d.",strtonum("0x" substr(addr[1],2*i+1,2)))}; print ":" strtonum("0x" addr[2]);}' /proc/net/udp

只需要反轉點分小數。

echo 0F01A8C0 | awk '{str = sprintf("0x%s", $0); ip = strtonum(str); \
printf ("%d.%d.%d.%d\t",rshift(and(ip,0x000000ff),00),
                       rshift(and(ip,0x0000ff00),08),
                       rshift(and(ip,0x00ff0000),16),
                       rshift(and(ip,0xff000000),24))}'

最終的:

awk 'NR>1 {
   split($2, a, ":");
  patsplit(a[1],h,/.{2}/);
  for(i=4;i>0;i--){
    h[i]=strtonum("0x" h[i]);
  };
  printf("%d.%d.%d.%d:%d\n",h[4],h[3],h[2],h[1],strtonum("0x" a[2]));
}' /proc/net/udp

來源:https ://wiki.christophchamp.com/index.php?title=Unix_sockets

引用自:https://unix.stackexchange.com/questions/447786