Get Local IP-Address using Boost.Asio

MOnsDaR picture MOnsDaR · Apr 20, 2010 · Viewed 33.5k times · Source

I'm currently searching for a portable way of getting the local IP-addresses. Because I'm using Boost anyway I thought it would be a good idea to use Boost.Asio for this task.

There are several examples on the net which should do the trick. Examples:

Official Boost.Asio Documentation

Some Asian Page

I tried both codes with just slight modifications. The Code on Boost.Doc was changed to not resolve "www.boost.org" but "localhost" or my hostname instead. For getting the hostname I used boost::asio::ip::host_name() or typed it directly as a string.

Additionally I wrote my own code which was a merge of the above examples and my (little) knowledge I gathered from the Boost Documentation and other examples.

All the sources worked, but they did just return the following IP:
127.0.1.1 (That's not a typo, its .1.1 at the end)
I run and compiled the code on Ubuntu 9.10 with GCC 4.4.1

A colleague tried the same code on his machine and got
127.0.0.2 (Not a typo too...)
He compiled and run on Suse 11.0 with GCC 4.4.1 (I'm not 100% sure)

I don't know if it is possible to change the localhost (127.0.0.1), but I know that neither me or my colleague did it. ifconfig says loopback uses 127.0.0.1. ifconfig also finds the public IP I am searching for (141.200.182.30 in my case, subnet is 255.255.0.0)

So is this a Linux-issue and the code is not as portable as I thought? Do I have to change something else or is Boost.Asio not working as a solution for my problem at all?

I know there are much questions about similar topics on Stackoverflow and other pages, but I cannot find information which is useful in my case. If you got useful links, it would be nice if you could point me to it.

PS: Here is the modified code I used from Boost.Doc:

#include <boost/asio.hpp>
using boost::asio::ip::tcp;    

boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(boost::asio::ip::host_name(), "");
tcp::resolver::iterator iter = resolver.resolve(query);
tcp::resolver::iterator end; // End marker.
while (iter != end)
{
    tcp::endpoint ep = *iter++;
    std::cout << ep << std::endl;
}

Answer

SJL picture SJL · Jan 11, 2012

Here's a trick I learned from python network programming (google) to figure out my machine's ip address. This only works if you have an internet connection and can connect to google.com and does give me my home machine's 192.168.x.x private address.

try {
    boost::asio::io_service netService;
    udp::resolver   resolver(netService);
    udp::resolver::query query(udp::v4(), "google.com", "");
    udp::resolver::iterator endpoints = resolver.resolve(query);
    udp::endpoint ep = *endpoints;
    udp::socket socket(netService);
    socket.connect(ep);
    boost::asio::ip::address addr = socket.local_endpoint().address();
    std::cout << "My IP according to google is: " << addr.to_string() << std::endl;
 } catch (std::exception& e){
    std::cerr << "Could not deal with socket. Exception: " << e.what() << std::endl;

 }