1

I have a short test program to fetch the IP address of the local machine. On Raspbian, only the loopback address is returned, while the same code on OS X return both normal and loopback IPs.

The code is

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <errno.h>
using namespace std;

int main (int argc, char * const argv[]) {
  char hostname[128];

  int result = gethostname(hostname, 127);
  if (result != 0)  {
    cout << "FATAL: gethostname failed: " << result << errno;
    return -1;
  }
  cout << "Host name is " << hostname << endl;

  struct addrinfo hints, *res;
  int errcode;
  char addrstr[100];
  void *ptr;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = PF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags |= AI_CANONNAME;

  errcode = getaddrinfo(hostname, NULL, &hints, &res);
  if (errcode != 0) {
    perror("getaddrinfo");
    return -1;
  }
  while(res) {
    inet_ntop(res->ai_family, res->ai_addr->sa_data, addrstr, 100);
    switch(res->ai_family) {
      case AF_INET:
        ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
        break;
      case AF_INET6:
        ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
        break;
      default:
        cout << "Unknown family" << endl;
    }
    inet_ntop(res->ai_family, ptr, addrstr, 100);
    printf("IPV%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4, addrstr, res->ai_canonname);
    res = res->ai_next;
  }
  return 0;
}

On OS X I get:

[Coyote]collector$ ./quick
Host name is Coyote.local
IPV4 address: 192.168.1.108 (coyote.local)
IPV6 address: fe80::223:dfff:fea0:a230 (coyote.local)

But on Raspbian I only get:

pi:~$ ./quick
Host name is pi
IPV4 address: 127.0.1.1 (pi)

yet

pi:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:62:15:fc  
          inet addr:192.168.1.162  Bcast:192.168.1.255  Mask:255.255.255.0
[...]

What do I need to do on Raspbian to get the correct result?

RussK
  • 199
  • 1
  • 17

1 Answers1

1

This is probably due to the contents of your /etc/hosts file. If your goal is to obtain the ip addresses of the system, consider using getifaddrs instead. It's of BSD origin, but works on Linux as well.

If you want for sure to know which address will be used when you connect somewhere, the best way to do it than to connect and then obtain the address using getsockname. The other option would be to read the routing tables.

Also, getnameinfo is usually a better choice than inet_ntop.

Per Johansson
  • 6,697
  • 27
  • 34
  • An interesting side note: I actually needed this information in a Ruby on Rails app. After agonizing over the work I would have to do to make getifaddrs available via Ruby, I thought, with little expectation, to look for a Ruby gem. To my amazement, I found the [system-getifaddrs](https://rubygems.org/gems/system-getifaddrs) gem which returns the results in a hash with the interface as the key and a hash of values as the value. Nice. – RussK Jul 10 '14 at 13:03