📜 ⬆️ ⬇️

Features of receiving packets through the raw socket in Linux


Linux (unlike, for example, from FreeBSD) allows you to use raw sockets not only for sending, but also for receiving data. In this place there are interesting rakes, which I stepped on. Now I hasten to show them to those who still don’t know, so that everyone, using his favorite programming language, be it C ++ or Python, can try them out.

The essence of the rake is depicted in the figure, so that those who already know, do not waste their time.

I will write examples in C, but you can transfer them to other languages ​​that provide the possibility of low-level work with the TCP \ IP stack in Linux.

Some concepts


Let me remind you that to initialize a raw socket, we pass a parameter that indicates the type of protocol. For example UDP:
')
socket(AF_INET, SOCK_RAW, IPPROTO_UDP)

I will call this protocol the level at which the raw socket works. In the example, we created a raw socket at the UDP level.

The raw socket level does not limit you in forming a packet for sending, you can independently create both UDP and IP header. But when you receive data, the most interesting begins ...

Rake


Suppose we created 2 raw sockets at the UDP level and used one of them to send a UDP packet to the UDP echo server. Echo will return us UDP payload back. So, the TCP \ IP Stack will copy the received packet to all raw sockets of the level specified in the Protocol IP field of the incoming packet. I repeat once again - on EVERYTHING , even those that are open in other applications (for this reason, an application operating with raw sockets can only be run with root privileges). Since the UDP echo server responds with a UDP packet, all raw UDP sockets of the level will receive it.

We note another important feature. Regardless of the level of the raw socket, it delivers a complete packet including IP headers.

Thus, every raw socket in Linux is a sniffer at the level at which it was created. Keep this in mind when developing applications.

Example


I did not load the note with a code. For those who are interested to try, I
laid out the example on github . There is a cmake project that collects a simple UDP echo server and an application that creates 2 raw UDP sockets, one of which sends data, but both are sent to the epoll awaiting a response. For the purity of the experiment, the echo server and the example should be started up on different machines (do not forget to correct the code in accordance with your IP shnik). For interest, you can run multiple instances of the example.

For extracurricular reading there is a good article .

Thank you for your attention and a smaller rake!

Source: https://habr.com/ru/post/183316/


All Articles