send/receive data through multiple interfaces - linux

I have 2 linux based systems - a client with 2 interfaces (1 LAN, 1 modem) and a server.
I open 2 UDP sockets, and use setsockopt with SO_BINDTODEVICE to bind each socket to it's interface.
Then I send a message from client to server through each of those sockets.
Both of them reach server. Server socket reads them, and sends a reply to each of them.
Then I try to read server's reply on the client.
BUT, there is only 1 reply.
Also if I run tcpdump, I see that both of the replies are received on their relevant interfaces, on the same port that they left. Yet only one of them reaches socket. The other is lost?
The "lost" packet is not random, it's the "non" default one. If my routing table is empty, the modem one is lost. If I add a route to server ip from modem interface, the lost packet will be the lan one.
Yet, they always reach server, always return back, always seen in tcpdump, but 1 never reaches socket. How can that be?

There is an ipv4 network configuration parameter called rp_filter (reversed path validation filter). Basically, if the reply to a packet wouldn't go out the interface this packet came in, then this is a bogus packet and should be ignored. Which is why while I saw the packet on the tcpdump, it never reached socket. Disabling it did the trick.
sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.eth0.rp_filter=0
sysctl -w net.ipv4.conf.ppp0.rp_filter=0

Related

DOES router or linux kernel change the tcp headers and ip headers of packets

I was looking into raw sockets. so I created one raw socket client and other one is server. on two different computers. I am using ISP provided router. so I sent spoofed packet (with iphdr struct's saddr of different computer on same network) from client but when the packet received at the server the source ip in packet's ip header was correct (the real sender address=client address) plus the source port and destination port of tcphdr were something different too (which really didnt make sense). So I assumed that my ISP provided router is doing something funny -- OR I am completely wrong correct if this is a normal ip protocol. if I am correct then what steps should i take to configure my router so it does not mess up with tcp and ip headers of incoming packets plus the sync=1 at sender's end became sync=0 of tcphdr. I am using local IPs plus I am trying to implement tcp using raw socket server. I have configured iptables on server as well with sync allowed on my bounded port
iptables -I INPUT -p tcp --dport xxxx --syn -j ACCEPT
WHat settings do I need to do on server in iptables so my socket incoming packets wont be dropped nor any header be touched so I can get all packets required for tcp to keep coming in. plus what setting do I need to do on router so,if its cause problem then, it wont
Update 1:
after spending some time to the problem I found that one cause could be my kernel tcp stack dropping the incoming sync packets. so I looked around and found that in the tcp stack there is work done to make this happening. So I changed the sysctl.conf in /etc to allow sync packets to come in through by adding or uncommenting this line
net.ipv4.tcp_syncookies=1
Then I rebooted the system but still no difference. is it because somehow I have to reload my sysctl.conf file. if this is the case or any related case then please fill in.
Update 2
I have reloaded sysctl.conf after allowing syn packets and now I am getting syn packets from client application. but the destination port different. also along with syn=1, ack=1 is also coming in same packet. is this also something kernel is doing. please explain. as long as I know this is not how tcp works (tcp handshake) and I am connecting from client using stream socket

Different order of packets in Wireshark vs tcpdump/libpcap?

I noticed that for the transfer of one-packet file from remote FTP site to localhost on Linux, Wireshark can always capture the packets in correct order but not in tcpdump/libpcap or simple recvfrom on RAW_PACKET with promiscuous mode on.
In the former, the "transfer complete" response is always before the single data packet (in different connections so no TCP reordering), but in the latter the data packet always arrives first - which is clearly wrong according to the protocol and the implementation of FTP servers since "transfer complete" is sent after the data is sent out - and if the client has received it before data it'd stop waiting for data connection, which didn't happen since I can see the data clearly. So the libpcap/tcpdump actually captures packets in wrong order but no such problem in Wireshark?
How is this possible?? Wireshark also uses libpcap...
For FTP protocol payload is transferred in separate TCP connection, there is no promises about order of packets in parallel TCP connection (actually there is no promise in order of packets even in same TCP connection, your host should order them).
server has two open sockets.
it writes file to data socket
immediately after that it writes "transfer complete" to control sockets.
the difference between 2 & 3 is several microseconds.
Packets run thru the internet, they could even choose different paths
They came to your machine in random order.
p.s. also tcpdump file has number of packet and timestamp. Packets are not necessarily written sorted by timestamps. Wireshark could order them when showing, take a look on order field.

Linux socket UDP server - exchanging messages between 2 servers on 2 machines

I am working on a small linux socket project. The goal is to have multiple servers (ie. 1,2,3,4,5) that listen for send get and ACK packets from each of their respective clients. I am currently attempting to implement a routing table protocol whereby 2 servers (A, B) exchange their routing tables (vectors containing respective clients, server name, and number of hops). The issue I am having is with binding a socket to B's external address from A and vice-versa. From what I have read you do not bind to anything other than a local address except in certain cases. What I am wondering is how do I simply fire off a UDP packet from one server to another knowing the (static) IP address of each server?
What I am wondering is how do I simply fire off a UDP packet from one
server to another knowing the (static) IP address of each server?
The short answer is, you can't. At least on the Internet proper, only unicast is widely supported, which means that in order to send a UDP packet to another machine, you'll need to know its IP address (somehow).
The longer answer is: The first thing you often need to do is discover the target machines' IP addresses. That might be a matter of having the user manually enter a list of IP addresses, or if the target machines are on the same LAN, you can program a mechanism for auto-discovering them by having your program send out a broadcast or multicast UDP query packet. Make sure any instances of your program running on the same LAN receive that packet and respond to it by sending back a response UDP packet (the responses can be sent by by unicast or multicast or broadcast, your choice), and then your query-originating computer can know from the responses it receives which other IP addresses your program is presently also running on.
Note that a lot of computers and network devices run firewalls that reject incoming UDP packets by default, so if you packets don't seem to be getting through that is a likely reason why.

Minimum requirements for custom networking stack to send UDP packets?

(edit: solved -- see below)
This is my situation:
TL-MR3020 -----ethernet----- mbed
OpenWRT C/C++ custom networking stack
192.168.2.1 192.168.2.16
TL-MR3020 is a Linux embedded router
mbed is an ARM microcontroller.
On the network I just want them to exchange messages using UDP packets on port 2225. In particular, TL-MR3020 has to periodically send packets every second to 192.168.2.16:2225, while mbed has to periodically send packets every 50ms to 192.168.2.1:2225.
Everything was good untill I removed the network stack library from mbed (lwIP, not so lightweight for me) and written a new minimal stack.
My new stacks sends 5 gratuitous ARP reply just after the ethernet link gets up, then starts sending and receiving udp packets.
Now TL-MR3020 doesn't receive any UDP packet. In particular, with ifconfig I can see packets coming, but my application can't get them.
Also, if I connect my laptop instead of the TL-MR3020, I can see the UDP packets coming, using Wireshark. There's nothing wrong, except done for my application.
I have a node.js script that has to receive the packets, but it doesn't receive nothing, but if I send UDP packets from local to local, the script receives them.
I think that my application is OK also because neither SOCAT can receive the UDP packets using socat - UDP-LISTEN:2225.
I've already checked on TL-MR3020:
arp table has the correct ip-mac assiciation
destination MAC address matches the incoming interface
destination IP address matches the incoming interface
IP checksum: wireshark says good=false, bad=false
UDP checksum: wireshark says good=false, bad=false
So, I'm asking... what are the minimum requirements for a custom networking stack to send UDP packets?
SOLVED:
You need a good checksum in the IP header.
UDP checksum, my case, can be set to zero.
tcpdump is very helpful (thanks to AndrewMcDonnell)

How do I prevent Linux kernel from responding to incoming TCP packets?

For my application, I need to intercept certain TCP/IP packets and route them to a different device over a custom communications link (not Ethernet). I need all the TCP control packets and the full headers. I have figured out how to obtain these using a raw socket via socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); This works well and allows me to attach filters to just see the TCP port I'm interested in.
However, Linux also sees these packets. By default, it sends a RST when it receives a packet to a TCP port number it doesn't know about. That's no good as I plan to send back a response myself later. If I open up a second "normal" socket on that same port using socket(PF_INET, SOCK_STREAM, 0); and listen() on it, Linux then sends ACK to incoming TCP packets. Neither of these options is what I want. I want it to do nothing with these packets so I can handle everything myself. How can I accomplish this?
I would like to do the same thing. My reason is from a security perspective… I am wanting to construct a Tarpit application. I intent to forward TCP traffic from certain source IPs to the Tarpit. The Tarpit must receive the ACK. It will reply with a SYN/ACK of its own. I do not want the kernel to respond. Hence, a raw socket will not work (because the supplied TCP packets are teed), I need to also implement a Divert socket. That's about all I know so far… have not yet implemented.

Resources