views:

400

answers:

2

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.

+1  A: 

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.

Adrien Plisson
Understood re: security, but one would hope the root/SYSTEM user would be able to see the options set on all processes.My purposes are for diagnosis of other apps.
nailer
A: 

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")
}
nailer