在Linux中使用ioctl获取IPv6地址

12

我尝试在我的Linux操作系统中获取IPv6地址,如下所示:

sd = Socket_m(AF_INET6_m, SOCK_DGRAM_m, 0);

ifc.ifc_buf = buffer_p;
ifc.ifc_len = buffSize;
Ioctl_m(sd, SIOCGIFCONF, &ifc);

如果为接口配置了任何IPv4地址,则它将成功工作,但是如果接口只有一个IPv6地址,则该地址不会被ioctl返回。

例如,因为只配置了IPv6地址,我无法获取以下接口的IPv6地址:

br1       Link encap:Ethernet  HWaddr 00:10:18:2D:BB:34  
          inet6 addr: fe80::210:18ff:fe2d:be54/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:194244850 errors:0 dropped:0 overruns:0 frame:0
          TX packets:72005 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:12331900995 (11760.6 Mb)  TX bytes:6192406 (5.9 Mb)
2个回答

19

是的,那个ioctl已经过时了,不会返回IPv6地址。每个平台获取IPv6地址的方式都不同:

  • Linux:如果你愿意冒险,可以使用NETLINK;如果你有一个相对新的glibc版本,可以使用getifaddrs;否则,可以读取/proc/net/if_inet6(例如在Android上)。
  • Darwin或FreeBSD:使用getifaddrs
  • Solaris:使用SIOCGLIFCONF
  • AIX:使用SIOCGIFCONF,它实际上返回IPv4和IPv6地址(因为他们在struct sockaddr中有一个sa_len字段,所以实际上支持这个)。

非常感谢您的澄清,您能帮我理解"/proc/net/if_inet6"格式吗?我如何确定UP和非回环地址?我阅读了http://www.tldp.org/HOWTO/Linux+IPv6-HOWTO/proc-net.html,但并不清楚... - Yury Bushev
文档相当清晰 - 你需要的是“接口标志”。请参阅系统头文件(“if.h”)中的值,以获取IFF_LOOPBACKIFF_UP。如果您正在尝试使用shell解析if_inet6,则可以使用awk提取正确的字段,并使用“&”与相关常量进行AND运算。 - Nicholas Wilson

5

使用ioctl在linux中获取IPv6地址

这可能不起作用。

来自man 7 netdevice

SIOCGIFCONF

返回接口(传输层)地址列表。目前,这仅适用于兼容性的AF_INET(IPv4)地址。

[...]

注释

[...]

本地IPv6 IP地址可以通过/proc/net或rtnetlink(7)找到。


我无法像Nicholas Wilson建议的那样使用路由套接字,我需要一种与LSB兼容的方式,但似乎这是不可能的? - Yury Bushev
@Unmanner:如果您需要知道套接字绑定到本地的地址,请使用getsockname()。如果您需要找出所有本地接口的地址,请使用getifaddrs()或按照Nicholas Wilson在他的答案中提出的建议读取/proc/net/if_inet6 - alk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接