0

I'm using this program to find all IP addresses of my Debian machine. Although I can remove my loopback address by using the ifa_name field of the 'ifaddrs' structure, something like

  struct ifaddrs * ifAddrsStruct=NULL;
  getifaddrs(&ifAddrsStruct);
  if (!strcmp(ifAddrIterator->ifa_name,"lo"))
   // Filter these addresses

I wanted to know is there any way I can find out, from the list of IP addresses, whether an IP address is a link-local (a network address that is intended and valid only for communications within a network segment) or not. Thanks in advance.

Community
  • 1
  • 1
302Found
  • 490
  • 7
  • 19

3 Answers3

1

This code checks if a IP4 address is a link local address.

#include <stdio.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
    struct in_addr addr = {0};
    char str[INET_ADDRSTRLEN];

    if (1 == inet_pton(AF_INET, "169.254.40.203", &addr)) {
        // 169.254.0.0 translates to 0x0000fea9
        if ((addr.s_addr & 0x0000ffff) == 0x0000fea9) {
            printf("is link local\n");
        } else {
            printf("not link local\n");
        }
    }

    return 0;
}

This might only work on little endian systems (x86, AMD64)

mwarning
  • 721
  • 5
  • 22
0

Start with:

sockaddr* addr = ifAddrsStruct->ifa_addr;

Now, link-local addresses for IPv4 are defined in the address block 169.254.0.0/16, so:

  • if addr->sa_family == AF_INET
  • compare static_cast<sockaddr_in*>(addr)->sin_addr against that range.

In IPv6, they are assigned with the fe80::/64 prefix, so:

  • if addr->sa_family == AF_INET6
  • compare static_cast<sockaddr_in6*>(addr)->sin6_addr against that prefix.
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

The following snippet can be used to determine if an ip is a link-local ipv4 address:

const char* str = "169.254.1.2";
uint32_t ipv4;

struct in_addr addrp;
if (0 != inet_aton(str, &addrp)) {
  ipv4 = addrp.s_addr;
} else {
  ipv4 = 0;
}


if ((ipv4 & 0xa9fe0000) == 0xa9fe0000) {
  // .. This ip is link-local
}
Community
  • 1
  • 1
akw
  • 2,090
  • 1
  • 15
  • 21