linux – 如何获取IPv6主机的范围?
发布时间:2020-12-13 23:57:11 所属栏目:Linux 来源:网络整理
导读:我对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
我对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 %20sn",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是否是您的最佳选择. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |