This Question is almost the same as the previously asked Get the IP Address of local computer-Question. However I need to find the IP address(es) of a Linux Machine.
So: How do I - programmatically in C++ - detect the IP addresses of the linux server my application is running on. The servers will have at least two IP addresses and I need a specific one (the one in a given network (the public one)).
I'm sure there is a simple function to do that - but where?
To make things a bit clearer:
- The server will obviously have the "localhost": 127.0.0.1
- The server will have an internal (management) IP address: 172.16.x.x
- The server will have an external (public) IP address: 80.190.x.x
I need to find the external IP address to bind my application to it. Obviously I can also bind to INADDR_ANY (and actually that's what I do at the moment). I would prefer to detect the public address, though.
// Use a HTTP request to a well known server that echo's back the public IP address void GetPublicIP(CString & csIP) { // Initialize COM bool bInit = false; if (SUCCEEDED(CoInitialize(NULL))) { // COM was initialized bInit = true;
}
Further to what Steve Baker has said, you can find a description of the SIOCGIFCONF ioctl in the netdevice(7) man page.
Once you have the list of all the IP addresses on the host, you will have to use application specific logic to filter out the addresses you do not want and hope you have one IP address left.
As you have found out there is no such thing as a single "local IP address". Here's how to find out the local address that can be sent out to a specific host.
As the question specifies Linux, my favourite technique for discovering the IP-addresses of a machine is to use netlink. By creating a netlink socket of the protocol NETLINK_ROUTE, and sending an RTM_GETADDR, your application will received a message(s) containing all available IP addresses. An example is provided here.
In order to simply parts of the message handling, libmnl is convenient. If you are curios in figuring out more about the different options of NETLINK_ROUTE (and how they are parsed), the best source is the source code of iproute2 (especially the monitor application) as well as the receive functions in the kernel. The man page of rtnetlink also contains useful information.
I like jjvainio's answer. As Zan Lnyx says, it uses the local routing table to find the IP address of the ethernet interface that would be used for a connection to a specific external host. By using a connected UDP socket, you can get the information without actually sending any packets. The approach requires that you choose a specific external host. Most of the time, any well-known public IP should do the trick. I like Google's public DNS server address 8.8.8.8 for this purpose, but there may be times you'd want to choose a different external host IP. Here is some code that illustrates the full approach.
ioctl(<socketfd>, SIOCGIFCONF, (struct ifconf)&buffer);
Read
/usr/include/linux/if.h
for information on theifconf
andifreq
structures. This should give you the IP address of each interface on the system. Also read/usr/include/linux/sockios.h
for additional ioctls.