查看其他应用创建的现有套接字上的套接字选项?
-
06-07-2019 - |
题
我想测试是否在现有套接字上设置了特定的套接字选项。即,几乎所有你能看到的东西:
#!/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套接字编程的文档都是关于创建新的套接字。
解决方案
不幸的是,敲门人的答案只捕获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]
其他提示
这在Python中是不可能的。
Linux内核没有在/ procfs中提供报告TCP套接字状态的机制(与BSD和其他类Unix操作系统不同)。由于内核没有公开这些信息,我们无法通过python-linux-procfs模块或类似模块看到它。
请参阅 lsof FAQ item 3.14.1 :
Q值。 ‘为什么lsof报告我的方言的套接字选项,套接字状态和TCP标志和值?’。
甲。 '套接字选项,套接字状态,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")
}
套接字库确实是为了创建新的套接字并对它们进行操作。出于明显的安全原因,在其他进程中创建的套接字不可见:您不希望任何随机应用程序改变您管理自己的套接字的方式,或者更糟糕的是在您之前从套接字读取数据。所以套接字是系统对象,由句柄引用,(在一个体面的操作系统上)应用于它们的访问权限。这就是为什么你不能列出其他进程创建的现有套接字的原因。
最终,您可能会找到一种方法来检索套接字句柄(应该有某种方式,我记得在Windows上看到一种列出系统句柄的方法),但这仍然非常特定于您的操作系统,因此可能无法使用在python中,你可能仍然没有权利在这些套接字上执行任何操作。
现在,如果您只是想知道特定应用程序如何实现特定功能,还有其他方法:最明显的是安装代理或防火墙(我记得我的Kerio WinRoute防火墙列出了套接字选项),或者只是询问stackoverflow如何实现这一壮举。