14

Im trying to retrieve the current iptables chains configured on the system via python. If I strace the iptables command, it outputs:

strace iptables -L INPUT
socket(PF_INET, SOCK_RAW, IPPROTO_RAW)  = 3
getsockopt(3, SOL_IP, 0x40 /* IP_??? */, "filter\0\377`\2\351\1\0\210\377\377\210}\313\276\0\210\377\377\354\206\0\201\377\377\377\377"..., [84]) = 0

full output here: http://pastebin.com/e7XEsaZV

In python I create the socket obj and try to call getsockopt and it errors:

>>> s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
>>> s.getsockopt(socket.SOL_IP, 0x40)
Traceback (most recent call last):
  File "<pyshell#46>", line 1, in <module>
    s.getsockopt(socket.SOL_IP, 0x40)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 22] Invalid argument
>>>
>>> s = socket.socket(2, socket.SOCK_RAW, socket.IPPROTO_RAW)
>>> s.getsockopt(socket.SOL_IP, 0x41)
Traceback (most recent call last):
  File "<pyshell#48>", line 1, in <module>
    s.getsockopt(socket.SOL_IP, 0x41)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 22] Invalid argument
>>> 

Is this just not possible?

4
  • Since your question is regarding python, I removed the C tag. Commented May 5, 2011 at 1:48
  • I seem to be missing the relationship between iptables and your python socket... perhaps a dumb question, but would you mind elaborating on the relationship between the two? Commented May 5, 2011 at 2:07
  • @Mike I might be missing something major I'm just trying to emulate the iptables command in Python and looking at the strace on the iptables command, I assumed (im not really a developer) that the getsockopt is how the current iptables configured in the kernel are retrieved. I might be WAY wrong, but i didn't see any ioctls etc. Commented May 5, 2011 at 2:11
  • when you say emulate iptables, what specifically are you trying to emulate in python? Commented May 5, 2011 at 2:13

2 Answers 2

18

Have you seen python-iptables?

Python-iptables provides python bindings to iptables under Linux. Interoperability with iptables is achieved via using the iptables C libraries (libiptc, libxtables, and the iptables extensions), not calling the iptables binary and parsing its output.

Sign up to request clarification or add additional context in comments.

1 Comment

i SWEAR i looked for this before trying to reinvent the wheel. Again, thank you.
0

The reason for error 22 is obvious. getsockopt() call with type IPT_SO_GET_INFO requires third argument of a pointer to struct ipt_getinfo. The struct has include file in my Linux at /usr/include/linux/netfilter_ipv4/ip_tables.h.

Further, there are more requirements. The buffer size given for getsockopt() call needs to match the size of struct, in my machine that is 84 bytes. Why this call really fails is the requirement of struct member .name must indicate which table you're interested in querying. Unspecified size and random bytes a table name will result in this error 22.

With Python, ultimately all this fails as there is no API for entering user defined bytes as an argument for getsockopt(). Assuming IPT_SO_GET_INFO would work, the natural next step would be to read all the chains of a table with a IPT_SO_GET_ENTRIES, which in Python is also impossible. Python's getsockopt() won't allow buffers larger than 1024 bytes. In any real Linux using IPtables, the chain rules can easily exceed that 1 KiB limit.

A good C example on how to read IPtables rules is at https://github.com/mozilla/rr/blob/master/src/test/netfilter.c

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.