如何查找IP地址是否为链路本地地址

时间:2013-10-28 16:42:23

标签: c++ linux networking ip-address

我正在使用this程序查找Debian计算机的所有IP地址。虽然我可以使用'ifaddrs'结构的ifa_name字段删除我的环回地址,例如

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

我想知道有什么方法可以从IP地址列表中找出IP地址是否是本地链接(网络地址仅用于网段内的通信)或者不。提前致谢。

3 个答案:

答案 0 :(得分:1)

此代码检查IP4地址是否为链接本地地址。

#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;
}

这可能仅适用于小端系统(x86,AMD64)

答案 1 :(得分:0)

开始于:

sockaddr* addr = ifAddrsStruct->ifa_addr;

现在,IPv4的链接本地地址在地址块169.254.0.0/16中定义,因此:

  • if addr->sa_family == AF_INET
  • static_cast<sockaddr_in*>(addr)->sin_addr与该范围进行比较。

在IPv6中,它们被分配了fe80::/64前缀,因此:

  • if addr->sa_family == AF_INET6
  • static_cast<sockaddr_in6*>(addr)->sin6_addr与该前缀进行比较。

答案 2 :(得分:0)

以下代码段可用于确定ip是否是本地链接的ipv4地址:

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
}