Get gateways of all interfaces in C++ for Linux - c++

Using netstat or route, and probably several other commands it is fairly simple to retrieve the default gateway in the main routing table. (Although extracting it is still harder than I expected it to be) But I have not found any way of finding each gateway for each interface.
Specifically I have wlan0 and eth0 interfaces, and each have their own standard gateway. Is there anyway to extract them from somewhere. Preferably in C++, for Linux distributions. (Ubuntu 12.04 to be specific)
EDIT:
Perhaps my terminology is not correct, so I will try to clarify :
If I have solely my wlan0 interface operational on my laptop (i.e. I disconnect the lan cable).
I have a default gateway with IP *.*.108.1, and local IP of *.*.108.56.
Now if I connect the ethernet cable, I get a default gateway of *.*.105.129 and a local IP of *.*.105.170. The subnet mask for both is 255.255.255.128.
I would like to use both by setting my routing tables accordingly.
Perhaps if I misunderstood the purpose of the gateway, then let me explain my main goal.
I would like to be able to specify that Wireless connection is used, instead of the ethernet cable, and vice versa.
EDIT2:
These are the routing commands I use to redirect UDP packets from port 5555 to be sent over wlan
iptables -A OUTPUT -o wlan0 -t mangle -p udp --sport 5555 -j MARK --set-mark 1
ip rule add fwmark 1 table 1
ip route add dev wlan0 default via *.*.108.1 table 1
For the last command I need to provide some gateway, which is what I am looking for.

Related

C++ sockets: communication between PCs over internet

I'm writing a program on Windows using winsocks that can send messages to another computer. The client connects with the server in the other computer and begin exchanging data.
It works fine on my local network using local addresses(192.168.1.*), but I can't communicate with public addresses (216.185.45.129); not even my own. I can successfully connect to a website on port 80, but not to my laptop at home using its public IP address, regardless of what ports I use (unreserved ports).
So I did research online and the only solution that seems to work is port forwarding.
-But is there absolutely no other way to achieve this?
-How do other programs like Teamviewer connect to other computers on the network then?
-Is there an already open but typically unused port that I can use?
-At the very least, can I forward the ports on my router but not have the client do anything? Or maybe have my program forward the ports automatically.
The main problem is, that every router is using NAT to distinguish different computer in your lokal network against the WAN. He need to do this, because you got only one IP in the internet, but several devices in your home. To archive this, he uses groups of ports. That means, if you use to send maybe from port 2048 to a webserver in internet with two devices, the router gives one device another port (like 2049). The response has the Port of the requester, so the router can map it back. Unfortunately most router always map ports so you never now which port you have from the internet side.
There are two common ways to work around and archive your goal.
Port Fowarding
You can force most router not to map special ports but bind them to unique MAC addresses. You can use UPNP to config most router to do that, but I do not recommend that for security reasons and also it does not work in many enviroments where Router do not allow UPNP manipulation.
Most router have port forwarding abilities for gaming reasons (mostly it is used in P2P networks)
It works with TCP and UDP.
NAT Traversal
The common way is NAT traversal, also known as NAT hole punching. I will describe it in short for UDP. You can find a wiki explanation here for TCP and for UDP here. Unfortunately you need a server in the internet both clients can reach. Here the steps:
Both clients contact the server. The server now know IP and PORT of both clients.
Server send back the information to the clients.
Both(!) clients send now packages to each other on the known address.
It is necessary that both client send a UDP package and have to accept that the first package get lost. The reason is the router. Most router only accept packages from a source on a mapped PORT if a client has send a package to that source before.
UPDATE
Regarding to a comment of Remy Lebau I changed the Firewall piercing part to NAT Traversal as it was partly wrong.

How to configure internet access in Oracle Solaris 10 installed in a virtual box

I have installed solaris 10 in virtual box 4.1.2. The installation was successful but it is not accessing internet.I have tried to create a bridged network which is a similar thing I did to Debian Installation and worked but it's still not working in the solaris. Please can anybody help solve this problem?
I know this is a very old question but just posting for reference of others here. I wrote this blog post on configuring networking for Solaris 11 in VirtualBox.
We will go through configuring NAT, HostOnly and Bridged Adaptors. First we have to go to Setting for the Solaris VM in VirtualBox and from there to the Network Tab.
Even though eventually we will add three network adaptors, I suggest we start by enabling only one adaptor as it might be hard to figure out which is which inside Solaris one we enable several network adaptors at once and try to configure them inside Solaris.
Configuring Bridge Adaptor
So to start with let’s turn on BridgedAdaptor. Make sure you press OK and save the changes. Now start up the VM and log-in.
Solaris 11 has this concept of “Network Configuration Profiles (ncp)”. There is
Automatic – Uses DHCP to obtain network configuration (IP address, router and DNS) from any of the connected ethernet interfaces. Do not support hot swapping of interfaces and IPMP.
Manual (DefaultFixed NCP) – interfaces needs to be manually configured using dladm and ipadm commands. Also called as DefaultFixed NCP. Supports hot swapping of interfaces and IPMP.
We want to use Manual profile. You can get a list of these by “netadm list” (network administration) command.
In the about output we can see “Automatic” is disabled and “DefaultFixed” is online. This is because I have already enabled it when installing Solaris. So if you don’t have DefaultFixed online run following commands.
netadm disable -p ncp Automatic
netadm enable -p ncp DefaultFixed
Now let’s run “dladm” (data link administration) command. You will see something similar to following.
Now we have to create IP configuration and for that we use “ipadm” (IP administration) command.
ipadm create-ip net0
Here net0 is the name I have given for IP configuration. You can use the LINK name you got as the output of “dladm” command.
To configure the configuration we created. Following command can be used.
ipadm create-addr -T static -a local=192.168.1.190/24 net0/v4
-T specifies either static, dhcp or addrconf (for IPv6) types of addresses.
-a specifies address
v4 is used to denote IP v4 but it can be any random string used to identify the interface.
Note that as we are configuring BridgedAdaptor we need a public IP for this interface and we are making it static.
To view the configurations following command can be used.
ipadm show-addr
That is about it for BridgeAdaptor configuration.
Configuring Route
Now we have to configure routes. To view routes run “route -p -n show”.
To add default route,
route -p add default 192.168.1.1
If you want to delete a mistakenly added route you can use a command like
route -p delete default 192.168.1.100
Now you must be able to ping to this VM within the network.
Configuring HostOnly Adaptor
Configuring HostOnly Adaptor is similar to configuring BridgeAdaptor. You have to enable that from the VirtualBox setting first and then inside the VM you will be able to identify the newly added data link by “dladm” command. So you can configure that. Only difference would be that you will have to use an IP in 192.168.56.xxx range as it is the default range for VirtualBox host only IPs.
Configuring NAT
Configuring NAT has a slight difference. That is for NAT we will be using dhcp and not static. So command for configuring IP address is different.
ip-adm create-addr -T dhcp net2/v4
Configuring DNS
Adding DNS name server
rajind#solaris:~# svccfg -s dns/client
svc:/network/dns/client> setprop config/nameserver = (8.8.8.8 8.8.4.4)
svc:/network/dns/client> listprop config
config application
config/value_authorization astring solaris.smf.value.name-service.dns.client
config/nameserver net_address 8.8.8.8 8.8.4.4
svc:/network/dns/client> exit
rajind#solaris:~#
rajind#solaris:~# svcadm refresh dns/client
rajind#solaris:~# svcadm restart dns/client
Setting name service switch
rajind#solaris:~# svccfg -s name-service/switch
svc:/system/name-service/switch> setprop config/host = "files dns"
svc:/system/name-service/switch> listprop config
config application
config/default astring files
config/value_authorization astring solaris.smf.value.name-service.switch
config/printer astring "user files"
config/host astring "files dns"
svc:/system/name-service/switch> exit
rajind#solaris:~#
rajind#solaris:~# svcadm refresh name-service/switch
rajind#solaris:~# svcadm restart name-service/switch
Many thanks to the authors of these blog posts.
http://thegeekdiary.com/how-to-configure-an-ip-address-in-solaris-11/
http://thegeekdiary.com/installing-oracle-solaris-11-in-virtualbox/
https://w3hol.wordpress.com/2011/12/29/setting-static-ip-address-on-solaris-11/
If you leave the default VirtualBox network configuration (NAT) and if you configure Solaris to use DHCP, you should be able to access the Internet as long as the host OS is already connected to it.
In Vb set your nic to bridged.
In Solaris:
Set a fixed ip.
Set your default gateway.
Set /etc/resolv.conf to your nameserver
Set /etc/nsswitch.conf to files dns
Check by pinging a "web-site"
Also check with nslookup
This should all work fine.

C++ UDP Socket port multiplexing

How can I create a client UDP socket in C++ so that it can listen on a port which is being listened to by another application? In other words, how can I apply port multiplexing in C++?
I want to listen on only one port
You can do that with a sniffer. Just ignore the packets from different ports.
I might need to stop it from sending out some particular packets, because my program will send it instead of the original application
Okay, here I suggest you to discard sniffers, and use a MITM technique.
You'll need to rely on a PREROUTING firewall rule to divert the packets to a "proxy" application. Assuming UDP, Linux, iptables, and the "proxy" running on the same host, here's what the "proxy" actually needs to do:
1. Add the firewall rule to divert the packets (do it manually, if you prefer):
iptables -t nat -A PREROUTING -i <iface> -p <proto> --dport <dport>
-j REDIRECT --to-port <newport>
2. Bind and listen on <newport>.
3. Relay all the traffic between the 2 endpoints (client, and original destination). If you're running the "proxy" on a different host, use getsockopt with SO_ORIGINAL_DST to retrieve the original destination address.
It might sound tricky, but... yeah, that's because it's a bit tricky :-)
Consult your firewall documentation if my assumption diverges.
This is just packet sniffing like tcpdump or snoop, open up a raw socket and pull everything from the wire and filter as you require. You will probably want to use libpcap to make things a little easier.
Without administrator or super-user privileges you will need the target application to open ports with SO_REUSEADDR and SO_REUSEPORT as appropriate for the platform. The caveat being you can only receive broadcast and multicast packets, unicast packets are delivered to the first open socket.
This is not multiplexing - that term is reserved for handling I/O on multiple channels in the same process and where things like select(2) and poll(2) are most useful.
What you are asking for is multicast. Here is the basic example.
Note that IP reserves a special range of addresses (a.k.a. groups) for multicasting. These get mapped to special ethernet addresses. The listener(s) would have to join the multicast group, while sender does not have to, it just sends as usual.
Hope this helps.

List of all hosts on LAN network

How can I get all the IP addresses and associated host names in a LAN?
To get the list of interfaces and IP addresses, use getifaddrs().
Search for interfaces with ifa_addr->sa_family == AF_INET
The IP address is in sin_addr.s_addr.
You can then use gethostbyaddr() to look up the DNS name for that IP address.
Update:
It was pointed out to me that the OP was probably asking about discovering other hosts, rather than the addresses of interfaces on the local machine.
There is no reliable way to discover other machines on the local area network, but there are a couple of tricks.
Ping method: Use the ping utility (or a programatic equivalent) to ping the local broadcast address, then see who responds. The broadcast address can be found by listing the interfaces as shown above. I believe ICMP does not require root access under OSX. Note that many systems may have ICMP ping disabled or firewalled, so you will only get responses from the non-stealth ones.
ARP method: Check the system ARP cache to see what IP addresses have been recently active. This will only show systems which have broadcast packets on the same network segment in recent minutes.
Both methods can be blocked by firewalls, routers, and even switches, so the exact borders of the "LAN" can be pretty narrow. Both methods can be implemented programmatically, but it might be simpler and more portable to just call out to the command line ping or arp commands.

Sending data between two ethernet interfaces on the same box

I would like to send data between two ethernet interfaces that are connected with a crossover cable in Linux. The two ethernet interfaces are on the same box. I defined the ethernet interfaces to have different static ip addresses (1.2.3.4 and 5.6.7.8) and have been using sockets to send bytes from one IP address to the other. I want to emphasize that I want the data to leave the box one interface of the box and get received on the other interface of the same box. One consequence of this is that unplugging the cable would prevent communication between the client and server on the same box.
The kernel is smarter than me I guess and decides it doesn't need to send information out on the wire and routes the data directly between the sockets internally, thus negating the test. I have tried to use SO_BINDTODEVICE to force the client to send data out of a particular interface, but the server never sees it. I am really stuck and this doesn't seem like it should be this difficult.
There are two entries in the route -n table
Dest Gateway Genmask flags metric use interface
1.2.3.0 0.0.0.0 255.255.255.0 U 0 0 eth0
5.6.7.0 0.0.0.0 255.255.255.0 U 0 0 eth1
You can not communicate using IP between 1.2.3.4/24 to 5.6.7.8/24 without going though a router. The problem is that IP can only talk to other computers in the same network segment. To calulate the network address you need to do a logic AND between both the interface address and the subnet mask. This will give you the network addresses. If the two network addresses are different then a router will be required. In your example you will have network address 1.2.3.0 and 5.6.7.0. Because these are different it will will to send data.
More importantly most network stacks are smart enough to see that if both interfaces are on the same computer it will not send the data all the way to the phyical interface. It will probably only send the message though the IP stack. But again it would need to be vaild address for it to work.
You should even be able to test a similar setup using just loopback network devices. (virtual network cards.)
Try using the following two IP addresses:
192.168.64.1
192.168.64.2
I'm not sure this is the problem, but 1.2.3.4 and 5.6.7.8 aren't on the same subnet. (Because when you apply the mask to each one, you don't get the same network address, as the Dest column is showing you.)