Linux linux raw socket programming question

I am trying to create a raw socket that sends and receives a message with the ip / tcp header under linux. I can successfully bind to a port and receive a tcp message (i.e.: syn) However, the message seems to be processed by os, but not mine. I just read it (e.g. wirehark). My raw socket binds to port 8888, and then I try to connect to that port. In wirehark, this shows that port 8888 answers "the first time" when it receives a "syn" request. In my program, he shows that he is receiving a new message, and he is not responding with any message.

Any way to bind to this port? (forbid to process it)

Here is part of my code, I am trying to shorten this error checking for easy reading

sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); int tmp = 1; const int *val = &tmp; setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof (tmp)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(8888); bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); //call recv in loop 
0
source share
4 answers

When your kernel receives a SYN / ACK from a remote host, it does not detect that it sent a SYN to this IP: PORT combination (which was sent from your raw socket), so it assumes an error and sends an RST to the remote host . This problem can be solved by setting up an IP filter that blocks all TCP traffic on this port (for this, check the iptables man page). Thus, you do not need to program in kernel space and will not affect existing TCP kernel modules.

+4
source

man 7 raw says:

Role-based sockets can use all IP protocols in Linux, even protocols such as ICMP or TCP, which have a protocol module in the kernel. In this case, packets are transmitted to both the kernel module and raw sockets.

I assume that you cannot "make TCP" on a raw socket without interference from the kernel if your kernel does not have enough TCP support, which, of course, is not what you want. What raw sockets are suitable for other IP protocols that the kernel does not process, or for special applications, such as sending created ICMP packets.

+2
source

To access the source headers, you do not bind the raw socket to the port. This is not done.

Just write the sniffer, β€œPICK UP” of all incoming packets and find out β€œYOURS”. It will also give you access to the entire contents of packages, etc.

Here's how you do it:

 int sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ; while(true) { saddr_size = sizeof saddr; //Receive a packet data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , (socklen_t*)&saddr_size); if(data_size <0 ) { printf("Recvfrom error , failed to get packets\n"); return 1; } //Now process the packet ProcessPacket(buffer , data_size); } 

In the ProcessPacket function, analyze the package and see if they belong to your application.

+2
source

Edit: If you intend to program raw sockets, check this .

It has some examples of how to send and receive raw packets.

If you want to use sockets like SOCK_STREAM and SOCK_SEQPACKET , connection oriented:

You need to say this to listen after binding to this address: port.

 int connectionQueue = 10; if ( -1 == listen(sockfd, connectionQueue) ) { // Error occurred } 

After that, you will need to check the handle of incoming connections using select and accept the incoming connection to the server socket (which will lead to the rejection of new connections) or a dedicated client socket.

+1
source

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


All Articles