如何找到本地套接字另一端的程序?

时间:2021-01-11 07:33:24

A process on my Linux system, strace tells me, is talking on a socket which has file descriptor 10. lsof tells me that this is a unix socket with inode 11085, and netstat further tells me that inode 11085 a stream socket, and that it's connected.

我的Linux系统上的一个进程,strace告诉我,正在一个具有文件描述符10的套接字上对话。lsof告诉我这是一个带有inode 11085的unix套接字,netstat进一步告诉我,inode 11085是一个流套接字,并且它是连接的。

Given that this process doesn't have any other threads, there must therefore be another process on the system that's connected to the other end of this socket. How do I find out what it is?

考虑到这个进程没有任何其他线程,因此系统上必须有另一个进程连接到这个套接字的另一端。我怎么知道它是什么?

Update:

更新:

There's some illumination from the lsof author here. Essentially, it seems that Linux just doesn't provide this information.

这里有一些来自lsof作者的启示。实际上,Linux似乎并没有提供这些信息。

8 个解决方案

#1


9  

ss -p

will tell. (Provided the socket is not owned by the kernel itself.)

会告诉。(前提是套接字不属于内核本身。)

#2


7  

Does netstat -p help ?

netstat -p有帮助吗?

From Manpage:

从:

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

#3


4  

How about this: grep 11085 /proc/net/unix. Assuming there is a non-empty path present on the line with the inode you're interested in, grep for that path in /proc/net/unix to find the the inode for the other end of the connection, then use @efficientjelly's method to map the other inode to a pid.

那么这个呢:grep 11085 /proc/net/unix。假设在具有感兴趣的inode的行上存在一个非空路径,grep在/proc/net/unix中查找连接另一端的inode,然后使用@efficient entjelly的方法将另一个inode映射到pid。

A key point here is the fact that the two connected sockets will each have a different inode number.

这里的一个关键点是,两个连接的套接字每个都有不同的inode号。

#4


2  

Looks like if you're really desperate, you can get that information directly from Linux kernel memory by using some kernel debugger. With RHEL5's "crash" tool:

看起来如果您真的很绝望,您可以通过使用一些内核调试器直接从Linux内核内存中获得这些信息。RHEL5的“崩溃”工具:

  • get uncompressed vmlinux image (eg. install kernel-debuginfo rpm, or extract vmlinux file from that rpm)
  • 获取未压缩的vmlinux映像(例如。安装kernel-debuginfo rpm,或者从该rpm中提取vmlinux文件)
  • run crash /path/to/vmlinux
  • 运行/路径/ / vmlinux崩溃
  • net -s 12345 lists all sockets for PID 12345
  • net -s 12345列出PID 12345的所有套接字
  • find the interesting socket (has to be of family/type UNIX:STREAM), and note its SOCK value:
    • PID: 12345 TASK: e903d000 CPU: 0 COMMAND: "someapp"
    • 任务:e903d000 CPU: 0命令:“someapp”
    • FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
    • FD套接字短袜系列:类型源端口目的地端口
    • 36 cadd0240 c8a64040 UNIX:STREAM
    • 36 cadd0240 c8a64040 UNIX:流
  • 找到有趣的套接字(必须是家庭/类型UNIX:STREAM),并注意它的袜子值:PID: 12345任务:e903d000 CPU: 0命令:“someapp”FD套接字短袜族:类型源端口:端口36 cadd0240 c8a64040 UNIX:STREAM
  • you now have the address of the unix_sock struct for this socket
    • basically, unix_sock.peer.name is the name structure of the other end of the socket
    • 基本上,unix_sock.peer.name是套接字另一端的名称结构
    • print it with:p *(*(*((struct unix_sock*)( (struct unix_sock*)0xc8a64040)->peer)).addr).name
    • 打印时使用:p *(*(*((struct unix_sock*)(struct unix_sock*)0xc8a64040)->peer) .addr).name
  • 现在,您已经有了这个套接字的unix_sock结构的地址,基本上,unix_sock.peer.name是套接字另一端的名称结构,并将其打印为:p *(*(*(*(((struct unix_sock*))(struct unix_sock*)0xc8a64040) .addr .name

Really sad that this information is not directly exported to userspace.

很遗憾这个信息没有直接导出到用户空间。

#5


2  

I have observed that :

我注意到:

Inode of the fd that called connect() on the client side, is always exactly one greater than the one that you got back from the accept() call on the server side.

在客户端调用connect()的fd的Inode总是比服务器端的accept()调用返回的Inode大1。

Example output from my prog:

我的prog输出示例:

client_fd=4
/proc/4436/fd/4
inode=3072
is socket
node: 3072 socket: /tmp/unix.socket
f0be8960: 00000003 00000000 00000000 0001 03  3072 /tmp/unix.socket

/proc/9293/fd/43
fd:43
inode=3073
is socket
node: 3073 socket: 
f0be81e0: 00000003 00000000 00000000 0001 03  3073

The bound path does not show in /proc/net/unix though.

但是,绑定路径不显示在/proc/net/unix中。

YMMV and i have not investigated the underlying mechanics.

YMMV和我没有研究过基础力学。

#6


2  

I wrote a tool which uses the gdb method to reliably get socket peer information, kernel debug symbols not needed.

我编写了一个工具,它使用gdb方法可靠地获取套接字对等信息,而不需要内核调试符号。

To get the process connected to a given socket, pass it the inode number:

要将进程连接到给定的套接字,请将inode号传递给它:

# socket_peer 11085
3703 thunderbird 

To find out for all processes at once use netstat_unix, it adds a column to netstat's output:

为了一次性查明所有进程使用netstat_unix,它在netstat的输出中增加了一列:

# netstat_unix
Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Peer PID/Program name  Path
unix  3      [ ]         STREAM     CONNECTED     6825     982/Xorg             1497/compiz            /tmp/.X11-unix/X0
unix  3      [ ]         STREAM     CONNECTED     6824     1497/compiz          982/Xorg                 
unix  3      [ ]         SEQPACKET  CONNECTED     207142   3770/chromium-brows  17783/UMA-Session-R       
unix  3      [ ]         STREAM     CONNECTED     204903   1523/pulseaudio      3703/thunderbird       
unix  3      [ ]         STREAM     CONNECTED     204902   3703/thunderbird     1523/pulseaudio           
unix  3      [ ]         STREAM     CONNECTED     204666   1523/pulseaudio      3703/thunderbird       
...

Try netstat_unix --dump if you need output that's easy to parse.
See https://github.com/lemonsqueeze/unix_sockets_peers for details.

尝试netstat_unix——如果需要易于解析的输出,请转储。有关详细信息,请参阅https://github.com/lemonsqueeze/unix_sockets_peers。

For info, the inode +1/-1 hack isn't reliable. It works most of the time but will fail or (worse) return the wrong socket if you're out of luck.

对于信息,inode +1/-1黑客是不可靠的。它在大多数情况下都是有效的,但是如果你运气不好的话,它会失败或者(更糟糕)返回错误的插座。

#7


1  

If for some reason you have no luck with the appropriate lsof and netstat options, you can also do the following:

如果由于某些原因,你没有幸运的lsof和netstat选项,你也可以做如下:

find /proc -lname '*11085*' 2> /dev/null

#8


0  

lsof | grep 11085

lsof | grep 11085

lsof should be executed as root.

应该以root身份执行lsof。

I've been experimenting with lsof on my Linux system and lsof -U shows that all the numbers under the column NODE are unique.

我在Linux系统上进行了lsof的实验,lsof -U显示列节点下的所有数字都是唯一的。

#1


9  

ss -p

will tell. (Provided the socket is not owned by the kernel itself.)

会告诉。(前提是套接字不属于内核本身。)

#2


7  

Does netstat -p help ?

netstat -p有帮助吗?

From Manpage:

从:

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

#3


4  

How about this: grep 11085 /proc/net/unix. Assuming there is a non-empty path present on the line with the inode you're interested in, grep for that path in /proc/net/unix to find the the inode for the other end of the connection, then use @efficientjelly's method to map the other inode to a pid.

那么这个呢:grep 11085 /proc/net/unix。假设在具有感兴趣的inode的行上存在一个非空路径,grep在/proc/net/unix中查找连接另一端的inode,然后使用@efficient entjelly的方法将另一个inode映射到pid。

A key point here is the fact that the two connected sockets will each have a different inode number.

这里的一个关键点是,两个连接的套接字每个都有不同的inode号。

#4


2  

Looks like if you're really desperate, you can get that information directly from Linux kernel memory by using some kernel debugger. With RHEL5's "crash" tool:

看起来如果您真的很绝望,您可以通过使用一些内核调试器直接从Linux内核内存中获得这些信息。RHEL5的“崩溃”工具:

  • get uncompressed vmlinux image (eg. install kernel-debuginfo rpm, or extract vmlinux file from that rpm)
  • 获取未压缩的vmlinux映像(例如。安装kernel-debuginfo rpm,或者从该rpm中提取vmlinux文件)
  • run crash /path/to/vmlinux
  • 运行/路径/ / vmlinux崩溃
  • net -s 12345 lists all sockets for PID 12345
  • net -s 12345列出PID 12345的所有套接字
  • find the interesting socket (has to be of family/type UNIX:STREAM), and note its SOCK value:
    • PID: 12345 TASK: e903d000 CPU: 0 COMMAND: "someapp"
    • 任务:e903d000 CPU: 0命令:“someapp”
    • FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
    • FD套接字短袜系列:类型源端口目的地端口
    • 36 cadd0240 c8a64040 UNIX:STREAM
    • 36 cadd0240 c8a64040 UNIX:流
  • 找到有趣的套接字(必须是家庭/类型UNIX:STREAM),并注意它的袜子值:PID: 12345任务:e903d000 CPU: 0命令:“someapp”FD套接字短袜族:类型源端口:端口36 cadd0240 c8a64040 UNIX:STREAM
  • you now have the address of the unix_sock struct for this socket
    • basically, unix_sock.peer.name is the name structure of the other end of the socket
    • 基本上,unix_sock.peer.name是套接字另一端的名称结构
    • print it with:p *(*(*((struct unix_sock*)( (struct unix_sock*)0xc8a64040)->peer)).addr).name
    • 打印时使用:p *(*(*((struct unix_sock*)(struct unix_sock*)0xc8a64040)->peer) .addr).name
  • 现在,您已经有了这个套接字的unix_sock结构的地址,基本上,unix_sock.peer.name是套接字另一端的名称结构,并将其打印为:p *(*(*(*(((struct unix_sock*))(struct unix_sock*)0xc8a64040) .addr .name

Really sad that this information is not directly exported to userspace.

很遗憾这个信息没有直接导出到用户空间。

#5


2  

I have observed that :

我注意到:

Inode of the fd that called connect() on the client side, is always exactly one greater than the one that you got back from the accept() call on the server side.

在客户端调用connect()的fd的Inode总是比服务器端的accept()调用返回的Inode大1。

Example output from my prog:

我的prog输出示例:

client_fd=4
/proc/4436/fd/4
inode=3072
is socket
node: 3072 socket: /tmp/unix.socket
f0be8960: 00000003 00000000 00000000 0001 03  3072 /tmp/unix.socket

/proc/9293/fd/43
fd:43
inode=3073
is socket
node: 3073 socket: 
f0be81e0: 00000003 00000000 00000000 0001 03  3073

The bound path does not show in /proc/net/unix though.

但是,绑定路径不显示在/proc/net/unix中。

YMMV and i have not investigated the underlying mechanics.

YMMV和我没有研究过基础力学。

#6


2  

I wrote a tool which uses the gdb method to reliably get socket peer information, kernel debug symbols not needed.

我编写了一个工具,它使用gdb方法可靠地获取套接字对等信息,而不需要内核调试符号。

To get the process connected to a given socket, pass it the inode number:

要将进程连接到给定的套接字,请将inode号传递给它:

# socket_peer 11085
3703 thunderbird 

To find out for all processes at once use netstat_unix, it adds a column to netstat's output:

为了一次性查明所有进程使用netstat_unix,它在netstat的输出中增加了一列:

# netstat_unix
Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Peer PID/Program name  Path
unix  3      [ ]         STREAM     CONNECTED     6825     982/Xorg             1497/compiz            /tmp/.X11-unix/X0
unix  3      [ ]         STREAM     CONNECTED     6824     1497/compiz          982/Xorg                 
unix  3      [ ]         SEQPACKET  CONNECTED     207142   3770/chromium-brows  17783/UMA-Session-R       
unix  3      [ ]         STREAM     CONNECTED     204903   1523/pulseaudio      3703/thunderbird       
unix  3      [ ]         STREAM     CONNECTED     204902   3703/thunderbird     1523/pulseaudio           
unix  3      [ ]         STREAM     CONNECTED     204666   1523/pulseaudio      3703/thunderbird       
...

Try netstat_unix --dump if you need output that's easy to parse.
See https://github.com/lemonsqueeze/unix_sockets_peers for details.

尝试netstat_unix——如果需要易于解析的输出,请转储。有关详细信息,请参阅https://github.com/lemonsqueeze/unix_sockets_peers。

For info, the inode +1/-1 hack isn't reliable. It works most of the time but will fail or (worse) return the wrong socket if you're out of luck.

对于信息,inode +1/-1黑客是不可靠的。它在大多数情况下都是有效的,但是如果你运气不好的话,它会失败或者(更糟糕)返回错误的插座。

#7


1  

If for some reason you have no luck with the appropriate lsof and netstat options, you can also do the following:

如果由于某些原因,你没有幸运的lsof和netstat选项,你也可以做如下:

find /proc -lname '*11085*' 2> /dev/null

#8


0  

lsof | grep 11085

lsof | grep 11085

lsof should be executed as root.

应该以root身份执行lsof。

I've been experimenting with lsof on my Linux system and lsof -U shows that all the numbers under the column NODE are unique.

我在Linux系统上进行了lsof的实验,lsof -U显示列节点下的所有数字都是唯一的。