0

It was suggested in an answer here, Get the IP address of the machine, one could use getifaddrs() to obtain the IP address of the machine the program was running on, which worked great :D:D

However, running the same program on two different systems, one displayed

SERVER_ADDRESS lo 127.0.0.1
SERVER_ADDRESS eth0 129.xxx.xxx.xxx
SERVER_ADDRESS virbr0 192.zzz.zzz.1

while the other displayed

SERVER_ADDRESS lo0 127.0.0.1
SERVER_ADDRESS en0 192.yyy.yyy.yyy

I was going to use strcmp to differentiate ethernet, but now I realized it doesn't work across systems since different strings may be printed out.

Is there a function (or better way) to check whether or not an ifa_name is ethernet or not?

Community
  • 1
  • 1
Some Noob Student
  • 14,186
  • 13
  • 65
  • 103

3 Answers3

7

To (again) state this explicitly: All addresses of the 127.0.0.0/255.0.0.0 net (range) as there are the addresses from 127.0.0.0 to 127.255.255.255, are defined to be treated as local loopback addresses. Data addressed to such will not leave the local machine.

Anyhow as you are already using getifaddrs() live is easy .. - just test the member ifa_flags of the structure(s) struct ifaddrs returned for IFF_LOOPBACK like so:

#include <sys/types.h>
#include <ifaddrs.h>
#include <net/if.h> /* for IFF_LOOPBACK */

...

struct ifaddrs * pIfAddrs = NULL;

if (!getifaddrs(&pIfAddrs)) {
  /* Test if the first interface is looping back to the local host. */
  int iIsLoopBack = (0 != (pIfAddrs->ifa_flags & IFF_LOOPBACK)); 
  ...
}

...

/* clean up */
if (pIfAddrs) {
  freeifaddrs(pIfAddrs);
  pIfAddrs = NULL;
}

...
alk
  • 69,737
  • 10
  • 105
  • 255
  • Thanks @alk, I was looking for something like this! Is there a man page that talks about different IFF_XXX? I need to identify `ethernet` specifically because it also shows `virbr0 192.zzz.zzz.z`. I'm afraid `IFF_LOOPBACK` will not exclude 192.zzz.zzz.zzz – Some Noob Student Nov 12 '11 at 16:04
  • @sheldon The difference between the 127.x.y.z. addresses and the addresses use in the internet and the difference of the 127.x.y.z. addresses to those mentioned in the reference posted by alex gray is different. ;-) Let latter are private by convention but not in the way they are treated technically, the 127.x.y.z are treated private technically as they are not routed to the outside of the host which uses them. So distinguishing the addresses referenced by alex gray needs to be done by actually testing the addresses' values. The interfaces to only detect 127.x.y.z address as private (local). – alk Nov 12 '11 at 17:30
  • I've read here http://www.kernel.org/doc/man-pages/online/pages/man7/netdevice.7.html regarding different types of `ifa_flags`. Could you point out which flags may be able to identify an ethernet connection? Thanks! – Some Noob Student Nov 13 '11 at 01:54
  • You might take a look at the net-tools package's sources from which also `ifconfig` comes to see how this can be done ... and lots of other things too. I'd also could have done this now to pull out some examples for you, but as it's a sunny sunday I prefer go hiking today ... ;-) – alk Nov 13 '11 at 08:08
  • You could pull the original net-tools sources from here: http://ftp.de.debian.org/debian/pool/main/n/net-tools/net-tools_1.60.orig.tar.gz (look around in `lib/interface.c` and `lib/hw.c`) and also have nice and sunny day! :-) – alk Nov 13 '11 at 08:13
2

You're likely to run into more than just that issue.. say for example there are multiple NICs, vLANs, WANS that look like LANS, and vice-versa, etc.

What is known? 127.X.X.X Throw out that result and you've got your non-loopbacks.

If you want to know if the address is private or not.. you'll then have to go down this road.

Community
  • 1
  • 1
Alex Gray
  • 16,007
  • 9
  • 96
  • 118
1
/* Output:
Name: 'eth0' Addr: 'xxx.xxx.xxx.xxx'
Name: 'eth0:0' Addr: 'xxx.xxx.xxx.xxx'
*/

    struct ifaddrs *ifaddr;
    char ip[255];

    if (getifaddrs(&ifaddr) == -1)
       {
          //sprintf(ip[0], "%s", strerror(errno));
       }
       else
       {
          struct ifaddrs *ifa;
          int i = 0, family;
          for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
          {
             if (ifa->ifa_addr == NULL)
             {
                continue;
             }
             family = ifa->ifa_addr->sa_family;
             if (family == AF_INET || family == AF_INET6)
             {
                if(!(ifa->ifa_flags & IFF_LOOPBACK) && (family == AF_INET) && getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0)
                {
                   printf("Name: '%s' Addr: '%s'\n", ifa->ifa_name, ip);
                }
             }
          }
       }
       freeifaddrs(ifaddr);
Nitinkumar Ambekar
  • 969
  • 20
  • 39