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.
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]
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")
}
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.