查看其他应用程序创建的现有套接字上的套接字选项?

发布于 2024-08-08 08:01:10 字数 380 浏览 10 评论 0原文

我想测试是否已在现有套接字上设置了特定的套接字选项。即,几乎您可以在以下位置看到的所有内容:

#!/usr/bin/env python
'''See possible TCP socket options'''

import socket

sockettypelist = [x for x in dir(socket) if x.startswith('SO_')]
sockettypelist.sort()
for sockettype in sockettypelist:
    print sockettype

有人知道我如何查看现有套接字(即由其他进程创建的套接字)上的选项吗?唉,我读到的有关 Python 套接字编程的几乎所有文档都是关于创建新套接字的。

I'd like to test whether particular socket options have been set on an existing socket. Ie, pretty much everything you can see in:

#!/usr/bin/env python
'''See possible TCP socket options'''

import socket

sockettypelist = [x for x in dir(socket) if x.startswith('SO_')]
sockettypelist.sort()
for sockettype in sockettypelist:
    print sockettype

Anyone know how I can see the options on existing sockets, ie those created by other processes? Alas nearly all the documentation I read on Python socket programming is about making new sockets.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梅窗月明清似水 2024-08-15 08:01:10

不幸的是,nailer 的答案仅捕获 SOL_TCP 级别套接字选项,而不捕获 SOL_SOCKET 级别套接字选项(如 SO_KEEPALIVE)。

一些发行版随 systemtap 一起提供了一些示例。其中之一是 pfiles.stp,您可以使用它从正在运行的进程的套接字获取套接字选项。文件中的示例:

$ ./pfiles.stp `pgrep udevd`
   787: udevd
  Current rlimit: 32 file descriptors
   0: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   1: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   2: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   3: S_IFDIR mode:0600 dev:0,9 ino:1 uid:0 gid:0 rdev:0,0
      O_RDONLY 
      inotify
   4: S_IFSOCK mode:0777 dev:0,4 ino:2353 uid:0 gid:0 rdev:0,0
      O_RDWR 
      socket:[2353]
      SO_PASSCRED,SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(111616)
        sockname: AF_UNIX
   5: S_IFSOCK mode:0777 dev:0,4 ino:2354 uid:0 gid:0 rdev:0,0
      O_RDWR 
      socket:[2354]
      SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(33554432)
        ulocks: rcv
   6: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
      O_RDONLY|O_NONBLOCK 
      pipe:[2355]
   7: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
      O_WRONLY|O_NONBLOCK 
      pipe:[2355]

Unfortunately, nailer's answer only catches the SOL_TCP level socket options and does not the SOL_SOCKET level ones (like SO_KEEPALIVE).

Some of the distributions ships some examples together with systemtap. One of them is pfiles.stp that you can use to get the socket options from the sockets of a running process. Example from the file:

$ ./pfiles.stp `pgrep udevd`
   787: udevd
  Current rlimit: 32 file descriptors
   0: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   1: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   2: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   3: S_IFDIR mode:0600 dev:0,9 ino:1 uid:0 gid:0 rdev:0,0
      O_RDONLY 
      inotify
   4: S_IFSOCK mode:0777 dev:0,4 ino:2353 uid:0 gid:0 rdev:0,0
      O_RDWR 
      socket:[2353]
      SO_PASSCRED,SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(111616)
        sockname: AF_UNIX
   5: S_IFSOCK mode:0777 dev:0,4 ino:2354 uid:0 gid:0 rdev:0,0
      O_RDWR 
      socket:[2354]
      SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(33554432)
        ulocks: rcv
   6: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
      O_RDONLY|O_NONBLOCK 
      pipe:[2355]
   7: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
      O_WRONLY|O_NONBLOCK 
      pipe:[2355]
榆西 2024-08-15 08:01:10

这在 Python 中是不可能的。

Linux 内核没有在 /procfs 中提供报告 TCP 套接字状态的机制(与 BSD 和其他类 Unix 操作系统不同)。由于内核不公开此信息,因此我们无法通过 python-linux-procfs 模块或类似模块看到它。

请参阅 lsof 常见问题解答项目 3.14.1

Q 。 “为什么 lsof 不报告我的方言的套接字选项、套接字状态以及 TCP 标志和值?”。

A. “套接字选项、套接字状态以及 TCP 标志和值无法通过 /proc 文件系统获得。”

但是 SystemTap 的网络 Tapset 提供了一个 tcp.setsockopt 断点,可用于拦截进程设置的套接字选项,然而,这将在 stap 而不是 python 中处理。

我创建了所需的 Tapset,如下所示:

# Show sockets setting options

# Return enabled or disabled based on value of optval
function getstatus(optlen)
{
    if ( optlen == 1 )
        return "enabling"
    else
        return "disabling"
}

probe begin
{
    print ("\nChecking for apps making socket calls\n")
}

# See apps setting a socket option 
probe tcp.setsockopt
{
    status = getstatus(user_int($optval))
    printf ("  App '%s' (PID %d) is %s socket option %s... ", execname(), pid(), status, optstr)
}

# Check setting the socket option worked
probe tcp.setsockopt.return
{
    if ( ret == 0 )
        printf ("success")
    else
        printf ("failed")
    printf ("\n")    
}


probe end
{
    print ("\nClosing down\n")
}

This is not possible in Python.

The Linux kernel does not provide a mechanism in /procfs to report on TCP socket states (unlike BSD and other Unix-like OSs). As the kernel doesn't expose this info, we can't see it via the python-linux-procfs module or similar.

See lsof FAQ item 3.14.1:

Q. ‘Why doesn't lsof report socket options, socket states, and TCP flags and values for my dialect?’.

A. 'socket options, socket states, and TCP flags and values are not available via the /proc file system.'

However SystemTap's Network tapset provides a tcp.setsockopt breakpoint which can be used to intercept socket options set by a process, however this would be handled in stap rather than python.

I created the required tapset as follows:

# Show sockets setting options

# Return enabled or disabled based on value of optval
function getstatus(optlen)
{
    if ( optlen == 1 )
        return "enabling"
    else
        return "disabling"
}

probe begin
{
    print ("\nChecking for apps making socket calls\n")
}

# See apps setting a socket option 
probe tcp.setsockopt
{
    status = getstatus(user_int($optval))
    printf ("  App '%s' (PID %d) is %s socket option %s... ", execname(), pid(), status, optstr)
}

# Check setting the socket option worked
probe tcp.setsockopt.return
{
    if ( ret == 0 )
        printf ("success")
    else
        printf ("failed")
    printf ("\n")    
}


probe end
{
    print ("\nClosing down\n")
}
掐死时间 2024-08-15 08:01:10

套接字库确实是创建新的套接字并操作它们。由于明显的安全原因,在其他进程中创建的套接字是不可见的:您不希望任何随机应用程序改变您管理自己的套接字的方式,或者更糟糕的是在您之前从您的套接字读取数据。因此套接字是系统对象,由句柄引用,(在一个不错的操作系统上)适用于它们的访问权限。这就是为什么您无法列出其他进程创建的现有套接字的原因。

最终,你可能会找到一种方法来检索套接字句柄(应该有一种方法,我记得在 Windows 上看到过一种列出系统句柄的方法),但这仍然是特定于你的操作系统的,所以可能在 python 中不可用,并且您可能仍然无权在这些套接字上执行任何操作。

现在,如果您只是想知道特定应用程序如何实现特定功能,还有其他方法:最明显的是安装代理或防火墙(我记得我的 Kerio WinRoute 防火墙列出了套接字选项),或者只是询问 stackoverflow关于如何实现这一壮举。

the socket library is indeed to create new sockets and manipulate them. sockets created in other processes are not visible for obvious security reasons: you would not want any random application changing the way you manage your own socket, or worse reading data from your socket before you. so sockets are system objects, referenced by a handle, with (on a decent OS) access rights applying to them. that's why you can't list existing sockets created by other processes.

eventually, you may find a way to retrieve socket handles (there should be a way somewhere, i remember seeing a way to list system handles on Windows), but this would still be very specific to your OS, so likely not available in python, and you may still not have the right to perform anything on those sockets.

now, if you are only curious to know how a specific application achieved a specific feature, there are other ways: the most obvious is installing a proxy or a firewall (i remember that my Kerio WinRoute Firewall listed socket options), or just asking stackoverflow about how to achieve this feat.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文