multiple IP addresses, chooce the sender - linux

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.

Related

Does routing affect a socket with a bound source address?

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?

Which interface linux will use between eth0 and eth0.1?

I have a VPS on which eth0 is configured , i want to configure a interface eth0.1 but i want to know if i will configure this new interface the data flow will be divided between eth0 and eth0.1 ?
I want to use eth0 Ip address for all the data flow on server like custom written scripts and eth0.1 Ip address to access it from browser as i have web-server on it.
Linux, by default, will send all packets out the default interface for the subnet, which is most likely eth0.
iproute2 attempts to solve this problem by redirecting packets out on the same interface on which they have been received.
http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
So, to answer your question, most packets on your system will probably already go out eth0 (assuming it's the same subnet).
If you set up an alias interface, eth0.1 (from your example), any programs listening on either all interfaces, or specifically, to eth0.1 will be able to receive packets on that IP address.
To add a secondary IP address you use the : separator on the interface name. Suppose you have eth0 assigned with 11.22.33.44 and you also want it to work with 11.22.33.55. Then you would just do:
ifconfig eth0:1 11.22.33.55
If you don't touch routing through the ip route command, 11.22.33.55 won't ever be used as an outbound interface, unless you're answering a request that points to 11.22.33.55 itself, so there are two more things to do.
The first is setting up your webserver's listening address to 11.22.33.55 instead of 'any' IP or 11.22.33.44. This depends on your webserver, in the case of apache check out the Listen directive.
The second thing, if you use a domain, to do is setting up a DNS record to point to 11.22.33.55 instead of 11.22.33.44. Take care because a domain name can't be resolved to a different address depending on the destination port, so you'll need a domain name for each interface. The alternative is directly using the IP address 11.22.33.44 for the script stuff and using the domain name for the webserver only.
After you've done this you can safely use tcpdump, iptables & friends on both the physical and the virtual interface.

using netcat for external loop-back test between two ports

I am writing a test script to exercise processor boards for a burn-in cycle during manufacturing. I would like to use netcat to transfer files from one process, out one Ethernet port and back into another Ethernet port to a receiving process. It looks like netcat would be an easy tool to use for this.
The problem is that if I set up the ethernet ports with IP addresses on separate IP sub nets and attempt to transfer data from one to the other, the kernel's protocol stack detects an internal route and although the data transfer completes as expected, it does NOT go out over the wire. The packets are routed internally.
That's great for network optimization but it foils the test I want to do.
Is there easy way to make this work? Is there a trick with iptables that would work? Or maybe things you can do to the route table?
I use network name spaces to do this sort of thing. With each of the adapters in a different namespace the data traffic definitely goes through the wire instead of reflecting in the network stack. The separate namespaces also prevent reverse packet filters and such from getting in the way.
So presume eth0 and eth1, wiht iperf3 as the reflecting agent (ping server or whatever). [DISCLAIMER:text from memory, all typos are typos, YMMV]
ip netns add target
ip link set dev eth1 up netns target
ip netns exec target ip address add dev eth1 xxx.xxx.xxx.xxx/y
ip netns exec target iperf3 --server
So now you've created the namespace "target", moved one of your adapters into that namespace. Set its IP address. And finally run your application in the that target namespace.
You can now run any (compatible) program in the native namespace, and if it references the xxx.xxx.xxx.xxx IP address (which clearly must be reachable with some route) will result in on-wire traffic that, with a proper loop-back path, will find the adapter within the other namespace as if it were a different computer all together.
Once finished, you kill the daemon server and delete the namespace by name and then the namespace members revert and you are back to vanilla.
killall iperf3
ip netns delete target
This also works with "virtual functions" of a single interface, but that example requires teasing out one or more virtual functions --- e.g. SR-IOV type adapters -- and handing out local mac addresses. So I haven't done that enough to have a sample code tidbit ready.
Internal routing is preferred because in the default routing behaviour you have all the internal routes marked as scope link in the local table. Check this out with:
ip rule show
ip route show table local
If your kernel supports multiple routing tables you can simply alter the local table to achieve your goal. You don't need iptables.
Let's say 192.168.1.1 is your target ip address and eth0 is the interface where you want to send your packets out to the wire.
ip route add 192.168.1.1/32 dev eth0 table local

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

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.

gsoap client multiple ethernets

I have a linux system with two eth cards. eth0 and eth1. I am creating a client that sends
to endpoint 1.2.3.4.
I send my webservice with soap_call_ functions. How can I select eth1 instead of eth0?
the code is like that
soap_call_ns__add(&soap, server, "", a, b, &result);
How can I set inside the &soap variable the eth0 or the eth1?
(gsoap does not have a bind for clients... like soap_bind)
You want outgoing packages from your host to take a specific route (in this case a specific NIC)? If that's the case, then you have to adjust kernels routing tables.
Shorewall has excellent documentation on that kind of setup. You'll find there info about how to direct certain traffic through a particular network interface.
for gsoap we need to manually bind(2) before connect(3) in tcp_connect

Resources