socket.getsockopt() and SO_ORIGINAL_DST

chris chricki at gmx.net
Fri May 21 04:26:04 EDT 2010


Hi guys,

I found a solution myself in O'Reilly's Security Power Tools. It works
seamlessly as follows:


from socket import *
SO_ORIGINAL_DST = 80
s = socket(AF_INET, SOCK_STREAM)
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s.bind(('192.168.255.254', 80))
s.listen(1)
conn, addr = s.accept()

dst = conn.getsockopt(SOL_IP, SO_ORIGINAL_DST, 16)
srv_port, srv_ip = struct.unpack("!2xH4s8x", dst)
print "original %s:%d" % (inet_ntoa(srv_ip), srv_port)


Basically, my fault was not specifying the buffer length :(

Have fun with it, whoever needs it.

Regards,
Chris


chris wrote:
> Hi guys,
> 
> On netfilter-based NAT systems there is theoretically a possibility to
> retrieve the original address *after* NAT'ing a connection. In C, this
> can be done as in squid, a transparent HTTP proxy:
> 
>   http://paste.pocoo.org/show/216495/
> 
> 
> I'd like to do the same in Python. So I started with a small script:
> 
> import socket
> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> s.bind(('', 2626))
> s.listen(1)
> conn, addr = s.accept()
> dst = conn.getsockopt(socket.SOL_IP, socket.SO_ORIGINAL_DST)
> 
> 
> 
> Since SO_ORIGINAL_DST is not defined in socket.py, the program fails:
>   AttributeError: 'module' object has no attribute 'SO_ORIGINAL_DST'
> 
> So I thought I'd be smart and look up the constant myself. Indeed, I
> found it to be defined in:
> 
>   /usr/include/linux/netfilter_ipv4.h:75:#define SO_ORIGINAL_DST 80
> 
> I replaced the getsockopt() call with
> 
>   dst = conn.getsockopt(socket.SOL_IP, 80)
> 
> and ran into a new problem:
> 
> Traceback (most recent call last):
>   File "listen.py", line 14, in <module>
>     dst = conn.getsockopt(socket.SOL_IP, 80)
>   File "<string>", line 1, in getsockopt
> socket.error: [Errno 22] Invalid argument
> 
> 
> In C, everything works fine. But I really need this problem to be solved
> in Python. Do you have any ideas?
> 
> Thanks for any support in advance and regards,
> Chris
> 
> PS: I know there are ugly work-arounds to parse /proc/net/ip_conntrack
> to do this job, but I will defenitely avoid that.
> 




More information about the Python-list mailing list