微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

linux – 如何获取IPv6主机的范围?

我对IPv6协议知之甚少,很抱歉,这个问题听起来很愚蠢.
当我检索网络中所有IPv6地址的列表时,我得到一个名为scope的字段,如下所示:

      inet6 addr: 2001:470:1:82::11/64 Scope:Global
      inet6 addr: 2001:470:1:82::10/64 Scope:Global
      inet6 addr: 2001:470:1:82::13/64 Scope:Global
      inet6 addr: fe80::21d:9ff:fe69:2c50/64 Scope:Link
      inet6 addr: 2001:470:1:82::12/64 Scope:Global
      inet6 addr: 2001:470:1:82::15/64 Scope:Global
      inet6 addr: 2001:470:1:82::14/64 Scope:Global
      inet6 addr: 2001:470:1:82::5/64 Scope:Global
      inet6 addr: 2001:470:1:82::17/64 Scope:Global
      inet6 addr: 2001:470:1:82::6/64 Scope:Global
      inet6 addr: 2001:470:1:82::16/64 Scope:Global
      inet6 addr: 2001:470:1:82::7/64 Scope:Global
      inet6 addr: 2001:470:1:82::19/64 Scope:Global
      inet6 addr: 2001:470:1:82::8/64 Scope:Global
      inet6 addr: 2001:470:1:82::18/64 Scope:Global
      inet6 addr: 2001:470:1:82::9/64 Scope:Global
      inet6 addr: 2001:470:1:82::1b/64 Scope:Global
      inet6 addr: 2001:470:1:82::a/64 Scope:Global
      inet6 addr: 2001:470:1:82::1a/64 Scope:Global
      inet6 addr: 2001:470:1:82::b/64 Scope:Global
      inet6 addr: 2001:470:1:82::1d/64 Scope:Global
      inet6 addr: 2001:470:1:82::c/64 Scope:Global
      inet6 addr: 2001:470:1:82::1c/64 Scope:Global
      inet6 addr: 2001:470:1:82::d/64 Scope:Global
      inet6 addr: 2001:470:1:82::1f/64 Scope:Global
      inet6 addr: 2001:470:1:82::e/64 Scope:Global
      inet6 addr: 2001:470:1:82::1e/64 Scope:Global
      inet6 addr: 2001:470:1:82::f/64 Scope:Global
      inet6 addr: ::1/128 Scope:Host

在我的应用程序中,我需要获取范围为“链接”的那些地址.我可以使用系统调用ifconfig然后解析输出提取相应的地址.但问题是,我正在使用getifaddrs()调用,它返回结构ifaddr的链表,给出如下:

       struct ifaddrs {
           struct ifaddrs  *ifa_next;    /* Next item in list */
           char            *ifa_name;    /* Name of interface */
           unsigned int     ifa_flags;   /* Flags from SIocgIFFLAGS */
           struct sockaddr *ifa_addr;    /* Address of interface */
           struct sockaddr *ifa_netmask; /* Netmask of interface */
           union {
               struct sockaddr *ifu_broadaddr;
                                /* broadcast address of interface */
               struct sockaddr *ifu_dstaddr;
                                /* point-to-point destination address */
           } ifa_ifu;
       #define              ifa_broadaddr ifa_ifu.ifu_broadaddr
       #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr
           void            *ifa_data;    /* Address-specific data */
       };

问题是:如何从此列表中获取具有“链接”范围的地址?

解决方法:

一种方法是检查地址是否在fe80 :: / 10范围内. IPv6 address space可从IANA获取,详细说明了可用的范围.

我将源代码下载到net-tools(ifconfig的源包),它们看起来像是解析/ proc / net / if_inet6. (注释是我自己在以下代码添加内容 – 以下内容也非常简略,并且肯定不会编译.)

/* some defines collected around the place: */

#define _PATH_PROCNET_IFINET6   "/proc/net/if_inet6"
#define IPV6_ADDR_LOOPBACK      0x0010U
#define IPV6_ADDR_LINKLOCAL     0x0020U
#define IPV6_ADDR_SITELOCAL     0x0040U
#define IPV6_ADDR_COMPATv4      0x0080U

int scope; /* among other stuff */

/* looks like here we parse the contents of /proc/net/if_inet6: */

if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
          addr6p[0], addr6p[1], addr6p[2], addr6p[3],
          addr6p[4], addr6p[5], addr6p[6], addr6p[7],
      &if_idx, &plen, &scope, &dad_status, devname) != EOF) {

/* slightly later: */

printf(_(" Scope:"));
switch (scope) {
case 0:
    printf(_("Global"));
    break;
case IPV6_ADDR_LINKLOCAL:
    printf(_("Link"));
    break;
case IPV6_ADDR_SITELOCAL:
    printf(_("Site"));
    break;
case IPV6_ADDR_COMPATv4:
    printf(_("Compat"));
    break;
case IPV6_ADDR_LOOPBACK:
    printf(_("Host"));
    break;
default:
    printf(_("UnkNown"));
}

那么让我们来看看上面解析的内容

$cat /proc/net/if_inet6
20010db8000008000000000000000001 03 40 00 00     eth0
fe800000000000000000000000004321 03 40 20 80     eth0
00000000000000000000000000000001 01 80 10 80       lo

因此,您可以看到左侧的第三列(0x00 Global,0x20 Link-Local和0x10 Loopback)是范围.使用网络工具代码中的上述常量,您可以找出它们的含义.需要进一步调查以确定这些常量的更权威的来源,以及解析/ proc / net / if_inet6是否是您的最佳选择.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐