Let's say I have two network interfaces:
eth0 with address 10.0.0.1
eth1 with address 192.168.0.1
Using route or ip route add I have set it to route:
All addresses to eth0
1.2.3.4 only to eth1
So packets to 1.2.3.4 should be routed to eth1, and everything else to eth0.
I then create a UDP socket and use bind() to set its local address to 192.168.0.1. Then I send a packet to 1.2.3.4.
Will it be be sent over eth1 per the routing table or eth0 because it is bound to that IP address? I tried, and it seems to be sent on eth1.
Is there a way I can force a socket to use eth0, which has a valid route to the destination, but not the most specific rule? I know about SO_BINDTODEVICE, but prefer to avoid using interface names in C code.
For sockets if you want the the Kernel and its routing table to pick the best interface for you using any available port you don't have to call bind() before sending datagram socket.
If you do bind a socket, it will be bound to a network device with that specific IP address. But does it make sense if packet can't reach destination address from that network device?
Related
Which is the source IP address in tcp socket if bind is called on a multihomed client host? Client has two interfaces eth0(IP0) and eth1(IP1) and the client tcp socket is bound to IP0. After socket, bind, connect in client, it sends a packet to server.The destination IP isservIP. But servIP and IP0 are not in a same subnet(Maybe servIP and IP1 are). Which is the source IP in the packet sent to server? And what will getsockname return?
There are two separate issues here:
1) Which IP to bind on?
When calling bind() you have an option to specify and address to bind on or you can leave this decision to TCP/IP stack on your computer. You can pass a specific address in 'addr' parameter or leave it as INADDR_ANY. You can find more information how to do it in manual page of ip(7). If you call bind() providing the valid IP address and call to bind() succeeds, then datagrams sent using the binded socket will have their source address set to the value provided in call to bind().
2) How the packet is routed?
The way your packet is routed depend only on the destination address and not the source address. It can be that your source address will be the one from eth0 and it will go out through eht1. This is because the routing system in your OS is using destination based routing as opposed to source based routing. You can always see which adapter will be used by issuing "route" command in the console of your OS and comparing the output with the destination address
I have two network interfaces (e.g. eth0 and eth1) configured as two ends of a bridge in Ubuntu Linux 14.04. They are not assigned with any IP addresses. eth0 is physically connected to a subnet. I want to send UDP packets through eth0 to a subnet connected machine. I create a UDP socket and check that it can successfully bind to eth0 (i.e. setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, eth0, strlen(eth0)), and executing sendto() reports success as well. However, the designated target machine cannot receive anything from eth0!!
Is there any Ubuntu tools/commands to trace where the UDP packets go (actually, I did try to use Wireshark. But, Wireshark cannot detect any network interface to capture!)?
And, is there any workarounds, under the situation that eth0 and eth1 must be set as a interconnected bridge with no IP addresses, to make use of eth0 to send UDP packets to other machine with designated IP address and port?
Here is my requirement.
2 TCP Client connection/Emulation from single eth port
I created two virtual interface.
ifconfig eth1:0 10.0.0.2
ifconfig eth1:1 10.0.0.3
Is is possible to create a TCP client code such that particular interface is used for TCP client establishment.
for example
./client_app eth1:0 - -- for client with ip 10.0.0.2
./client_app eth1:1 -- for client with ip 10.0.0.3
To enumerate all local interfaces and get the IP address associated to these interfaces use the system call getifaddrs().
Then use the bind() system call to bind the local side of a connection to a certain local interface's IP-address.
I have two machines each with two valid network interfaces, an Ethernet interface eth0 and a tun/tap interface gr0. The goal is to start a TCP connection on machine A using interface gr0 but then have the responses (ACKs, etc) from machine B come back over the Ethernet interface, eth0. So, machine A sends out a SYN on gr0 and machine B receives the SYN on its own gr0 but then sends its SYN/ACK back through eth0. The tun/tap device is a GNU Radio wireless link and we just want the responses to come through the Ethernet.
What's the easiest way to accomplish this? I need to research more on TCP/IP, but I was initially thinking that source-spoofing outgoing packets would tell the receiver to respond to the spoofed address (which should get routed to eth0). This would involve routing the IPs from the tun/tap interfaces through gr0 and leave the other traffic to eth0.
We are using Linux and a Python solution would be preferable.
Thanks for looking!
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.
You may be interested in enabling logging of martian packets net.ipv4.conf.all.log_martians, and disable reverse path filtering net.ipv4.conf.<interface>.rp_filter on the affected interfaces.
This sysctl vars are accesible via the sysctl utility and/or the /proc filesystem.
I have eth0 and eth1. I am creating a simple tcp program with gsoap. the endpoint is 1.2.3.4.
The endpoint receives my data, but the IP of eth0 is shown in the sender details. I would like my receiver to see eth1 instead of eth0.
Is this possible?
Use the bind(2) call to select the source IP, or create an explicit route(8) to the server via eth1. Second option is probably preferable since you don't need to modify the client source code.