3

I'm working on a TCP/IP implementation, for an embedded device, that I want to test from a Linux user space process using raw sockets.

raw(7) says that

Raw sockets may tap all IP protocols in Linux, even protocols like ICMP or TCP which have a protocol module in the kernel. In this case, the packets are passed to both the kernel module and the raw socket(s).

I need to disable this kernel processing (at least on a specific destination port) in order to test my implementation. I think there's some manipulation involving iptables which can do this, but frankly I'm no Linux guru. I appreciate any help.

  • Have you tried what it is you're trying to do without making any changes? My experience is that raw sockets are raw sockets. It may cook the data when accessing it via a specific protocol, but if you're dealing explicitly with raw sockets, you should be fine. – wfaulk May 8 '12 at 21:34
  • You may have an easier time creating iptables rules to block the reply traffic that the kernel generates than creating iptables rules to block the kernel from seeing them in the first place while still allowing your raw socket to see them. The effect would be the same except that the kernel would do some processing for nothing. I haven't tried this though, so YMMV. – Celada May 8 '12 at 21:44
  • wfaulk -- if I receive e.g. a SYN on the port of interest, the kernel stack will respond to it and screw up my implementation's handshake. Is there an iptables parameter for kernel generated packets? – Peter Woo May 8 '12 at 22:17
  • all the packets on output chain are kernel generated, but this includes the packets your app is sending. – DukeLion Aug 9 '13 at 13:53
2

Kernel handles TCP handshake by default

Try to make a TCP connection

$ telnet localhost 8877
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

Here connection is refused by kernel directly.

To stop kernel handling TCP connections, you can add netfilter rules. Following command makes kernel ignore TCP packets coming to port 8877

sudo iptables -A INPUT -p tcp --destination-port 8877 -j DROP

Now try doing a TCP connection again

$ telnet localhost 8877
Trying 127.0.0.1...
^C (Killed by me as it gets stuck here)

Kernel does not do the TCP handshake now, and you should be able to implement TCP in userspace as you will still see the packets 1.

To cleanup the netfilter rule after you are done, use

sudo iptables -D INPUT -p tcp --destination-port 8877 -j DROP
  • 1
    According to the man page for iptables, wouldn't QUEUE be more appropriate than DROP? – aeb0 Jan 9 '17 at 0:11
  • Possibly, as both seem to prevent kernel from handling TCP, but I don't now much about how QUEUE works – Mustafa Serdar Şanlı Jan 10 '17 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.