0

The problem

I have a computer that is supposed to connect to two machines (or rather sets of individual devices) via TCP. To make things tricky, these two machines share the same IP address range and also have partially identical addresses, only one is connected via one ethernet adapter and the other one via a second ethernet adapter.

Note: The address ranges were not defined by me, but by the manufacturers of these machines. I unfortunately have to live with them, as they are.

The program that should do that job is written in C/C++. The connections are outgoing from the program's point of view, so I can't just bind incoming connections and keep their id.

Possible solution

After some research (e.g. here: Problems with SO_BINDTODEVICE Linux socket option), I tried to bind the socket to a device using

setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, "adapter name", strlen("adapter name");

As it turns out, this would only work, if the program was run with superuser privileges, which I would try to avoid. Otherwise, the function returns an error code, which translates to permission denied (I forgot the exact phrase).

Other solutions?

Is there any other way, how I could achieve that?

engineer
  • 179
  • 1
  • 4
  • 10
  • *"these two machines share the same IP address range and also have partially identical addresses"* Are you saying that (for example) machine 1 and machine 2 both have IP address 192.168.1.2? Can you be more specific regarding what this means? – dbush Feb 09 '22 at 15:49
  • IMHO it duplicates https://stackoverflow.com/questions/1207746/problems-with-so-bindtodevice-linux-socket-option – 273K Feb 09 '22 at 15:52
  • Means, I have one adapter "eth1", where devices are connected as 192.168.0.2, 192.168.0.3, ... and a second adapter "eth2", where other devices are also connected as 192.168.0.2, 192.168.0.5, ... – engineer Feb 09 '22 at 15:53
  • @273K I was thinking about that as well. The other thread is about sending broadcast messages, which may or may not lead to different solutions. If you consider it a duplicate, totally fine with me. Guess I would then have to stick with the solutions from there, that I can't apply in my case. – engineer Feb 09 '22 at 15:56
  • This _may_ (or may _not_) be helpful: https://stackoverflow.com/questions/54056426/af-packet-and-ethernet/54057044#54057044 – Craig Estey Feb 09 '22 at 16:20

1 Answers1

2

Just pinning the sockets to a specific interface wouldn't do the job, since there are much more things going on... If you connect say to 192.168.0.3, the kernel looks into the routing table to find the right interface to send the packet over. You cannot have two entries in the routing table with the same subnet specification (192.168.0.0/24) if you want to use IP communication. There are two solutions that come into my mind:

  1. setup prerouting NATs for the adapters to map the addresses. For example you can map all source addesses from packages recieved by eth0 into the 192.168.0.0\24 range and all those recieved by eth1 to 192.168.1.0\24. If you add this address translation in the prerouting filter chain, the kernel won't even notice that the subnets internally use the same ip address range.

  2. If there are no duplicated ip addresses (like e.g. 192.168.0.2 in both the networks), you can setup a bridge interface. The bridge behaves like one interface, that is connected to both the networks. A bridge behaves just like a software switch. To the kernel (and to your program) it looks, as if there was only one adapter, where all the devices are plugged into.

Both solutions require superuser priviledges to setup, but after you have setup them once, your program won't need them.

Jakob Stark
  • 3,346
  • 6
  • 22
  • Thank you! Solution 1 sounds like the best idea so far. #2 is ruled out because there are some or may be some duplicate addresses. That is beyond my control – engineer Feb 09 '22 at 20:02
  • May I ask one for one more detail regarding your solution #1: If the traffic originates from the local computer, then the snat translation of e.g. 192.168.0.0/24 to 192.168.1.0/24 on one specific adapter alone won't work, right? I'm guessing, I would also need a translation in the output chain – engineer Feb 15 '22 at 16:05
  • I cannot test it right now, but i think you are right. You could try use a dnat rule in the output or post routing chain – Jakob Stark Feb 15 '22 at 18:21