I need to create a TCP session "manually", without using the connect()
function. I have tried to use RAW sockets. But in this case, I only get copies of the incoming IP packets. The original incoming packets slip through to the kernel and it generates an ACK response packet that damages my protocol.
Next, variant 2, I can write a virtual eth interface driver (kernel module) and route incoming traffic to it using iptables. But there is a patched non-original (non vanila) kernel on the machine. Normal linking of the module with the kernel is not possible.
Variant 3. I also tried not to assign an IP address to the NIC interface. In this case, the network TCP/IP layer module in the kernel is not activated and it is possible to generate and receive arbitrary IP packets on the link (ethernet) layer using the PF_PACKET
socket domain type in the socket() function. But at this time, any other applications using the TCP/IP protocol can’t work.
How can this problem be solved in other ways?
It would be nice if it were possible to intercept packets going from the network interface to the kernel, that is, intercept the SKBuf
buffer. But I don't know how to realize it.
Apparently you are trying to create a tunnel. Instead of trying to hijack an existing interface, the proper way to create a tunnel is to create a new interface, using a kernel module or TUN/TAP. However, tunnels are normally intended to receive traffic generated on the machine which runs the tunnel software, or at least routed through it. That means you will also have to set up the kernel to route the traffic to your tunnel.
You can create a new interface as a TUN/TAP interface. It is like a virtual ethernet driver except you don't need to write a new kernel module. It is designed for tunnels (hence the name).
The difference between TUN and TAP is that a TUN interface is an IP interface that receives IP packets from the kernel's IP routing system, and a TAP interface receives Ethernet packets (which may contain IP packets) so it can alternatively be part of a bridge (a virtual Ethernet switch - which only looks at the Ethernet header, not the IP header).
I think for your scenario, you will find it easiest to create a TAP interface, then create a bridge (virtual Ethernet switch) between the TAP interface, and the interface which the other host is connected to. Neither one needs an IP address - the kernel will happily pass Ethernet-layer traffic without attempting to process the IP information in the packet. Your tunnel software can then emulate a host - or tunnel to an actual host - or whatever you want it to do.
If you want the host to also be able to talk to the machine running the tunnel software - without going through the tunnel software - then you may choose to put an IP address on the bridge.