如何从 Linux 进程外部获取其套接字上的套接字信息?

如何从 Linux 进程外部获取其套接字上的套接字信息?

我特别感兴趣的是监听 TCP 套接字,但获取套接字的所有套接字(struct sock,如内核的 include/net/sock.h 中所定义)信息就好了。

例如,此 ss 输出显示绑定到 8080 的 TCP 套接字。

tcp    LISTEN     20     128                    *:8080                  *:*      uid:500 ino:32355 sk:ffff8801b11ca880
      rto:1000 mss:536 cwnd:10

我假设 sk:*** 是此套接字的 (struct sock) 结构的地址。我没有找到任何可以抓取 sk 结构并打印其字段的工具。我可以使用某些东西进入(是内核还是进程?)内存,并将 ffff8801b11ca880 处的数据解释为 (struct sock) 吗?

答案1

该地址位于内核空间中,因为最高 16 位已设置(FFFF)。要继续操作,您需要 GDB 和正在运行的内核的调试符号。我使用的是 CentOS,因此以下方法对我有用:

# yum install gdb
# yum install --enablerepo=base-debuginfo kernel-debuginfo
# gdb /usr/lib/debug/lib/modules/`uname -r`/vmlinux /proc/kcore

之后,你可以像使用用户空间进程一样使用 GDB,只不过它是内核:

(gdb) explore (struct sock *)0xffff8801b11ca880

答案2

这完全取决于您的需要。

结构 sock 中包含的大部分信息(不是struct socket) 仅用于调试。TCP 套接字表的转储包含在/proc/net/tcp,UDP、IGMP、raw、arp、UNIX-domain 也是如此。这是一张普通的 ascii 表,其内容由此输出第 1 行的标题简要概括:

 more /proc/net/tcp
 sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
 0: 00000000:228B 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 15159 1 ffff8801a1ee2300 100 0 0 10 0                     
 1: 00000000:CC4B 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 13835 1 ffff8801a1ee0700 100 0 0 10 0    

并在人过程(5)页面如下:

/proc/net/tcp

保存 TCP 套接字表的转储。除了调试之外,大部分信息都无用。“sl”值是套接字的内核哈希槽,“local_address”是本地地址和端口号对。“rem_address”是远程地址和端口号对(如果已连接)。“St”是套接字的内部状态。“tx_queue”和“rx_queue”是内核内存使用情况的传出和传入数据队列。“tr”、“tm->when”和“rexmits”字段保存内核套接字状态的内部信息,仅用于调试。“uid”字段保存套接字创建者的有效 UID。

这些信息可以通过以下命令读取和更方便地显示:lsof-i或者网络状态-4

相关内容