代码之家  ›  专栏  ›  技术社区  ›  mikemaccana

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

  •  3
  • mikemaccana  · 技术社区  · 15 年前

    我想测试是否在现有的套接字上设置了特定的套接字选项。也就是说,几乎所有你能看到的东西:

    #!/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 socket编程中读到的几乎所有文档都是关于生成新的套接字的。

    3 回复  |  直到 11 年前
        1
  •  2
  •   Cajga    12 年前

    不幸的是,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]
    
        2
  •  2
  •   mikemaccana    15 年前

    这在Python中是不可能的。

    Linux内核不提供/procfs中报告TCP套接字状态的机制(与BSD和其他类似于Unix的OSS不同)。由于内核不公开这些信息,所以我们无法通过python-linux procfs模块或类似模块看到这些信息。

    lsof FAQ item 3.14.1 :

    问:为什么lsof不为我的方言报告socket选项、socket状态和tcp标志和值?艾斯。

    a.“socket选项、socket状态和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")
    }
    
        3
  •  1
  •   Adrien Plisson    15 年前

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

    最终,您可能会找到一种检索套接字句柄的方法(应该有一种方法,我记得看到了一种在Windows上列出系统句柄的方法),但这仍然是非常特定于您的操作系统的,因此在Python中可能不可用,并且您可能仍然没有在这些套接字上执行任何操作的权利。

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