How to Route Tcp/Ip Responses Through a Different Interface

How to route TCP/IP responses through a different interface?

You could add an additional address to the lo interface on each system and use these new addresses as the TCP connection endpoints. You can then use static routes to direct which path each machine takes to get to the other machine's lo address.

For example:

Machine A:
ip addr add 1.1.1.1/32 dev lo
ip route add 2.2.2.2/32 dev eth0 via <eth0 default gateway>

Machine B:
ip addr add 2.2.2.2/32 dev lo
ip route add 1.1.1.1/32 dev gr0

Then bind to 1.1.1.1 on machine A and connect to 2.2.2.2.

TCP/IP connection on a specific interface

Use the bind() function to bind the socket to either 192.168.1.3 or 192.168.1.2 before calling connect(), ConnectEx(), or WSAConnect(). That tells the socket which specific interface to use for the outgoing connection. For example:

SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

sockaddr_in localaddr = {0};
localaddr.sin_family = AF_INET;
localaddr.sin_addr.s_addr = inet_addr("192.168.1.3");
bind(s, (sockaddr*)&localaddr, sizeof(localaddr));

sockaddr_in remoteaddr = {0};
remoteaddr.sin_family = AF_INET;
remoteaddr.sin_addr.s_addr = inet_addr("192.168.1.4");
remoteaddr.sin_port = 12345; // whatever the server is listening on
connect(s, (sockaddr*)&remoteaddr, sizeof(remoteaddr));

Alternatively:

addrinfo localhints = {0};
localhints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
localhints.ai_family = AF_INET;
localhints.ai_socktype = SOCK_STREAM;
localhints.ai_protocol = IPPROTO_TCP;

addrinfo *localaddr = NULL;
getaddrinfo("192.168.1.3", "0", &localhints, &localaddr);
bind(s, localaddr->ai_addr, localaddr->ai_addrlen);
freeaddrinfo(localaddr);

addrinfo remotehints = {0};
remotehints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
remotehints.ai_family = AF_INET;
remotehints.ai_socktype = SOCK_STREAM;
remotehints.ai_protocol = IPPROTO_TCP;

addrinfo *remoteaddr = NULL;
getaddrinfo("192.168.1.4", "12345", &remotehints, &remoteaddr);
connect(s, remoteaddr->ai_addr, remoteaddr->ai_addrlen);
freeaddrinfo(remoteaddr);

How to find the interface offering the route to a specific IP in Python3?

Provided that there is any known service to connect to on the remote host, use socket.getsockname() to find out which local IP is used for connecting:

import socket

# connect to known destination, e.g. via UDP port 80
test_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
test_sock.connect(("10.2.1.1", 80))
# check which local IP was used to connect
with test_sock:
private_ip, *_ = test_sock.getsockname()

Host-device communication in terms of subnet mask and routing

the netmask can be thought as a bitmask for an IP address.

if (address1 & netmask) == (address2 & netmask) then the 2 ip addresses are considered on the same subnet. (this expression can be written in many different ways...)

the netmask is only a way to 'virtually' divide a network: the netmask is not part of the ip header, and is not transmitted on the wire. no-one knows the netmask of a device on the network, except the device itself. it is used internally inside the tcp stack of a device to take some basic routing decisions. note that there are other ways to define a subnet, which may not involve a netmask but achieves the same result: grouping multiple devices into a 'virtual' network.

a router on which a device is plugged may even have a different definition of the netmask for this same device: it does not matter as long as the router is routing packets correctly. the netmask is used primarily to automatically compute some well-known addresses: for example, the broadcast address used for udp broadcast packets is computed from the ip address of a device and its netmask.

in your specific case:

there is no physical router, but your computer is a router (it routes packets internally to the different network interfaces). your computer contains a routing table which tells which outgoing interface a specific packet should use (on windows, try route print, on linux, as root, try route).

generally, the routing table is setup so that a packet goes out on the interface which is on the same subnet as the target device. the computer uses the above logical expression on each interface to determine if the destination is on the same subnet than this interface. if the expression is true, the packet goes out. each entry has a parameter (called a metric) which allows to chose the seemingly best interface in case multiple routes are possible.

you should note that the routing table is dynamic: it can be modified manually, to add a specific route (e.g. if you know that a particular device is reachable through an interface but that device has an ip address which has no relation with this interface ip address/netmask). there are also some protocols (arp, dhcp...) used in a local network which broadcast routing informations, which are automatically handled by your system to modify the routing table.



Related Topics



Leave a reply



Submit