如何获得IPv6主机的范围是什么? [英] How to get scope of an IPv6 host?

查看:215
本文介绍了如何获得IPv6主机的范围是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有对IPv6协议的很多知识,很抱歉,如果这个问题听起来很愚蠢。
当我取回我的网络中的所有IPv6地址的列表中,我得到一个字段中指定范围,如下图所示:

I don't have much knowledge about the IPv6 protocol, so sorry if the question sounds stupid. When I retrieve the list of all IPv6 addresses in my network, I get a field named scope, as shown below :

      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的链表,

In my application, I need to get those addresses for which the scope is 'Link'. I could have used a system call to ifconfig and then parsed the output to extract corresponding addresses. But the problem is, I'm using the call to getifaddrs(), which returns a linked list of structure ifaddr, given as :

       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 */
       };

现在的问题是:如何从这份名单得到与'链接'范围的地址

The question is : how to get the addresses with 'Link' scope from this list ?

推荐答案

要做到这一点,简直是检查地址是否属于在单向FE80 :: / 10 。该 IPv6地址空间可从IANA,里面详细介绍了可能的范围内有效。

One way to do this would simply be to check whether the address falls within fe80::/10. The IPv6 address space is available from IANA, which details the possible scopes available.

我下载的源$ C ​​$ C到净工具(源包的ifconfig) ,它看起来像他们解析的/ proc /净/ if_inet6 。 (注释是我自己的添加在以下code - 也低于极为简略,将最肯定不会编译。)

I downloaded the source code to net-tools (the source package for ifconfig), and it looks like they parse /proc/net/if_inet6. (Comments are my own additions in the following code — also the below is extremely abridged and will most certainly not compile.)

/* 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"));
}

因此​​,让我们来看看什么上面是解析:

So let's have a look at what the above is parsing:

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

所以,你可以看到从左侧( 0×00 全球 0x20的链路本地,第三列 0×10 环回)为范围。从网上的工具$ C $使用上面的常数c可以锻炼他们的意思。进一步的调查将需要确定这些常数更权威的来源,以及是否解析的/ proc /净/ if_inet6 是您最佳的选择。

So you can see the third column from the left (0x00 Global, 0x20 Link-Local, and 0x10 Loopback) is the scope. Using the above constants from the net-tools code you can work out what they mean. Further investigation would be required to determine a more authoritative source for such constants, and also whether parsing /proc/net/if_inet6 is your best option.

这篇关于如何获得IPv6主机的范围是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆