星期四, 十一月 02, 2006

获得网卡ipv6地址列表

MS在IP Helper库中提供的函数使应用程序在运行过程中可以方便的设置和获取系统网络配置信息,IPv4的网卡配置信息获取可以使用GetAdapterInfo函数调用实现,而IPv6的信息获取,则调用GetAdaptersAddresses函数,这个函数在最新的MSDN中有比较完整的示例,但是没有演示如何处理获得的IPv6地址,这里写一下。因为MS在WindowsXP之后才正式支持IPv6,所以此函数仅在WindowsXP以后的操作系统上有效,而且好像VC6也没有这个函数的支持。
GetAdaptersAddresses函数原型为:
ULONG WINAPI GetAdaptersAddresses(
ULONG Family,
ULONG Flags,
PVOID Reserved,
PIP_ADAPTER_ADDRESSES AdapterAddresses,
PULONG SizePointer
);
详细的说明可以参见MSDN,其中一个重要的数据结构是PIP_ADAPTER_ADDRESSES,它包含网卡的配置信息,定义如下:
typedef struct _IP_ADAPTER_ADDRESSES {
//...
struct _IP_ADAPTER_ADDRESSES* Next;
PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress;
//...
} IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;
上面定义中省略的部分可以参见MSDN,其中Next指向下一个网卡的IP_ADAPTER_ADDRESSES指针,而FirstUnicastAddress就是网卡的ip地址字段,它是一个链接结构的PIP_ADAPTER_UNICAST_ADDRESS,定义如下:
typedef struct _IP_ADAPTER_UNICAST_ADDRESS {
//...
struct _IP_ADAPTER_UNICAST_ADDRESS* Next;
SOCKET_ADDRESS Address;
//...
} IP_ADAPTER_UNICAST_ADDRESS, *PIP_ADAPTER_UNICAST_ADDRESS;
其中Address就是我们需要的当前项目的ip地址的内容,而Next包含了当前的网卡(程序里就是当前使用的那个PIP_ADAPTER_ADDRESSES指针)下一个ip地址配置的相关信息。
我们在调用GetAdaptersAddresses成功后(调用需要指定标志AF_INET6或者AF_UNSPEC),获取一个sockaddr_in6(socket函数使用)的变量,可以使用如下强制类型转换语句:
((struct sockaddr_in6 *)AdapterAddresses->FirstUnicastAddress->Address.lpSockaddr);
遍历以AdapterAddresses和FirstUnicastAddress为首的链表,我们就能够得到所有网卡上配置的所有IPv6地址的列表了。

在linux下获取网卡IPv6地址列表好像读取/proc/net/if_inet6

当然了,以上讲的方法都需要首先在系统里添加IPv6支持,Windows在网络配置中添加ipv6协议,而linux运行modprobe ipv6加载ipv6模块(如果没有自动加载的话)。

6 条评论:

匿名 说...

好想并不要安装ipv6阿,我自己写的程序就可以在windowsxp以后的系统中跑!

Neil 说...

但是需要用ipv6的话当然需要安装ipv6协议栈了。而且,XP默认没有安装ipv6支持,如果不安装,估计获取ipv6地址列表也不会成功吧。

yixuan 说...

你好,
我利用
PSOCKADDR_IN6 aa = (PSOCKADDR_IN6)MALLOC(sizeof(struct sockaddr_in6));
aa= (struct sockaddr_in6 *)AdapterList->FirstAnycastAddress->Address.lpSockaddr;
总是报错,能说一下大概怎么才能得到吗?

yixuan 说...

多谢你的回复。我已经解决这个问题。非常感谢!:-)

Neil 说...

不好意思,好久没来,不知道楼上的错误具体是什么,编译时的还是运行时的?

匿名 说...

谢谢你!虽然你这篇文章很老了,但是解决了我的大问题,特地来感谢你!!