Two TCP client application with virtual interface ip - linux

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.

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?

Tunnel dynamic UDP port range

Usually I prefer finding a solution on my own, but unfortunately that didn't work out too well this time so I'm asking here.
I'm trying to deal with a server (rather a computer with no screen and debian minimal on it) which is on the usual home network. Problem is the ISP is running out of ipv4 addresses and therefore
decided to use ipv6 instead and dual-stack lite to access the ipv4 side of the internet. This means the computer is not accessible over the ipv4 address from the outside
but is able to connect to a ipv4 computer.
I do have a vserver (debian as well) which still uses only ipv4, so my plan was to use it as some kind of relay or porxy. Problem there is, I am not able to use iptables to configure NAT
since the server provider has removed that module from the kernel.
My first attempt was to use an SSH tunnel like this:
ssh -f user#vserver -R 2222:localhost:22 -N
This allows me to access the CLI over SSH which now listens on port 2222.
Next step was to open a second SSH tunnel and tunnel UDP traffic through that using socat:
homeserver:~# socat tcp4-listen:${tcpport of second tunnel},reuseaddr,fork udp:localhost:${udpport to forward traffic from}
vserver:~# socat -T15 udp4-recvfrom:${udpport to forward traffic to},reuseaddr,fork tcp:localhost:${tcpport of second tunnel}
This does work, however once the client application is trying to connect to the UDP port, the server application is trying to continue the communication on a different new port from the dynamic
port range (Ephemeral Port Range I think). That one random port of course is not being forwarded since socat is not listening to.
The second attempt also involved an SSH tunnel, only a dynamic one this time (basically a socks proxy).
I was trying to setup a virtual network device to route all the traffic through the socks proxy:
(As described in man pages from badvpn-tun2socks)
homeserver:~# openvpn --mktun --dev tun0 --user <someuser> #create tun0 device
homeserver:~# ifconfig tun0 10.0.0.1 netmask 255.255.255.0 #configure it
homeserver:~# route add <IP_vserver> gw <IP_of_original_gateway> metric #Route all traffic through tun0
homeserver:~# route add default gw 10.0.0.2 metric 6 #exept the ones to the vserver
homeserver:~# badvpn-tun2socks --tundev tun0 --netif-ipaddr 10.0.0.2 --netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:1080 \
--udpgw-remote-server-addr 127.0.0.1:7300
This needs to SSH socks-proxies since upd needs to be handled seperately.
On the vserver side of things these need to be handled as well:
vserver:~# badvpn-udpgw --listen-addr 127.0.0.1:7300
The connection between both is successful but this time the homeserver is not accessible at all. (seems to me like the vserver has no clue what to do with the packets)
I hope there is a simple fix to either of my attempts. But as it stands now,
I think my whole approach is fundamentally flawed and I'm starting to run out of ideas.
Any help would be appreciated, Thanks in advance!

Send UDP packets through no IP assigned bridge interface in Ubuntu Linux

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?

Specifying a host address for a UDP server?

So I have the option to specify an address as well as a port when setting up as a UDP server.
According to the documentation, if no address is specified then the UDP server binds to 0.0.0.0:port. The documentation says the following: If address is not specified, the OS will try to listen on all addresses.
Why would I (or why would I not) specify a host to bind to? Is it for if you have multiple network cards and you only want to listen on one - so I would specify the ip of the network card I wish to listen on?
The option is for if you have multiple IP addresses on one machine, and you don't want to use all the addresses for binding. If you were to bind on 0.0.0.0 for port 80, you'd be using port 80 on all those addresses. By specifying an address you restrict binding to one address and port.

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.

Resources