※==================================================================
※本连载文章说明:
※1、连载首发于《软件报》(http://www.sweek.com)2006年21期(2006年5月22日);
※2、此次网上连载采用的是原稿件结构,内容与《软件报》发表略有不同;
※3、谢绝除《软件报》及其相关刊物之外的传统媒体部分或全部转载;
※4、谢绝任何收费媒体、网络转载;
※5、原作者:uruseibest ,blog:http://blog.csdn.net/uruseibest;
※6、如有其它疑问,请联系作者;
※7、如有转载,必须连同本说明一并发表,否则将追究转载者责任。
※======================================================================
第三章 IPHLPAPI 的其它函数
第一节 IPHLPAPI 的其它函数
IPHLPAPI还有以下的函数,这里给出C语言的函数原型和参数说明,具体说明详见MSDN2003。
1、GetAdapterIndex:从名称获得一个适配器的序号
DWORD GetAdapterIndex( LPWSTR AdapterName, PULONG IfIndex);
AdapterName:[输入] 指定了适配器名称的Unicode字符串
IfIndex:[输出] 指向一个指向适配器序号的ULONG变量指针
返回值:成功,返回0;失败,返回错误代码。
2、GetAdaptersAddresses:返回和适配器关联的地址
DWORD WINAPI GetAdaptersAddresses( ULONG Family, DWORD Flags, PVOID Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen);
Family:[输入] 获得地址族,必须是以下值之一:
AF_INET 仅返回IPv4地址
AF_INET6 仅返回IPv6地址
AF_UNSPEC 从所有的地址族返回地址
Flags:[输入]返回地址类型,这个参数为0或是以下值的联合值:
GAA_FLAG_INCLUDE_PREFIX 返回IPv6地址前缀
GAA_FLAG_SKIP_UNICAST 不返回unicast地址
GAA_FLAG_SKIP_ANYCAST 不返回anycast地址
GAA_FLAG_SKIP_FRIENDLY_NAME 不返回适配器的友好名称
GAA_FLAG_SKIP_MULTICAST 不返回多点传送(multicast)地址
GAA_FLAG_SKIP_DNS_SERVER 不返回DNS服务器地址
Reserved:[输入] 调用程序必须将此参数置为NULL
pAdapterAddresses:[输入,输出] 指向一段IP_ADAPTER_ADDRESSES缓存,成功的话,该缓存包含地址信息。
pOutBufLen:[输出] 返回pAdapterAddresses所在缓存的大小
返回值:成功,返回0;失败,返回错误代码。
3、GetPerAdapterInfo:返回与适配器相应的指定接口的信息
DWORD GetPerAdapterInfo(ULONG IfIndex,PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen);
IfIndex:[输入] 一个接口的序号。函数将返回与这个序号相应的适配器接口信息。
pPerAdapterInfo:[输出]指向一个接收适配器信息的IP_PER_ADAPTER_INFO类型。
pOutBufLen:[输入]指向一个指定了IP_PER_ADAPTER_INFO类型ULONG变量。如果指定的大小不够大,将设置为须要的大小并返回ERROR_BUFFER_OVERFLOW错误。
返回值:成功,返回0;失败,返回错误代码。
备注:个人觉得实际使用时候,获取IfIndex比较困难,不如用GetAdaptersInfo。
4、GetUniDirectionalAdapterInfo:接收本机安装的单向适配器的信息
DWORD GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo, PULONG dwOutBufLen);
pIPIfInfo:[输出]指向一个接收本机已安装的单向适配器的信息的IP_UNIDIRECTIONAL_ADAPTER_ADDRESS类型。
dwOutBufLen:[输出]指向一个ULONG变量用来保存pIPIfInfo参数缓存的大小。
返回值:成功,返回0;失败,返回错误代码。
5、CreateProxyArpEntry:为本地电脑指定的IP地址创建一个代理服务器地址解析协议(Proxy Address Resolution Protocol :PARP) 接口
DWORD CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex);
dwAddress:[输入] 作为代理服务器的电脑的IP地址。
dwMask:[输入]指定了dwAddress的IP地址对应的子网掩码。
dwIfIndex:[输入]代理服务地址解析协议(ARP)接口的索引通过dwAddress识别IP地址。换句话说,当dwAddress一个地址解析协议(ARP)请求在这个接口上被收到的时候,本地电脑的物理地址的接口作出响应。如果接口类型不支持地址解析协议(ARP),比如:端对端协议(PPP),那么调用失败。
返回值:成功,返回0;失败,返回错误代码。
6、DeleteProxyArpEntry:删除由dwAddress和dwIfIndex参数指定的PARP接口
DWORD DeleteProxyArpEntry( DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex);
dwAddress:[输入] 作为代理服务器的电脑的IP地址
dwMask:[输入] 对应dwAddress的子网掩码
dwIfIndex::[输入]对应IP 地址dwAddress指定的支持代理服务器地址解析协议(Proxy Address Resolution Protocol :PARP)的电脑的接口序号。
返回值:成功,返回0;失败,返回错误代码。
7、FlushIpNetTable:从ARP表中删除指定接口的ARP接口
DWORD FlushIpNetTable( DWORD dwIfIndex);
dwIfIndex:[输入] 将要删除的ARP接口的序号
返回值:成功,返回0;失败,返回错误代码。
8、GetFriendlyIfIndex:获得一个接口序号并返回一个反向兼容的接口序号
DWORD GetFriendlyIfIndex( DWORD IfIndex);
IfIndex:[输入] 来自反向兼容或者“友好”的接口序号
返回值:成功,返回0;失败,返回错误代码。
9、GetIfEntry:返回指定接口的信息
DWORD GetIfEntry( PMIB_IFROW pIfRow);
pIfRow:[输入,输出] 成功返回一个指向本机接口信息的MIB_IFROW类型;输出,需设置MIB_IFROW的dwIndex 为想要获取信息的接口的序号。
返回值:成功,返回0;失败,返回错误代码。
10、SetIfEntry:设置一个接口的管理状态
DWORD SetIfEntry( PMIB_IFROW pIfRow);
pIfRow:[输入] 指向一个MIB_IFROW类型。dwIndex成员指定了要设置管理状态的接口;dwAdminStatus成员指定了新的管理状态,为以下值之一:
MIB_IF_ADMIN_STATUS_UP 接口可被管理;
MIB_IF_ADMIN_STATUS_DOWN 接口不能被管理。
返回值:成功,返回0;失败,返回错误代码。
11、GetIcmpStatisticsEx:返回本机IPv4 ICMP或IPv6 ICMP统计表。
DWORD GetIcmpStatisticsEx( PMIB_ICMP_EX pStats, DWORD dwFamily);
pStats :[输出] 指向一个本机收到ICMP 统计表的MIB_ICMP类型。
dwFamily :[输入]返回ICMP 统计表的协议族,必须数以下值:
AF_INET Internet Protocol version 4 (IPv4)
AF_INET6 Internet Protocol version 6 (IPv6)
返回值:成功,返回0;失败,返回错误代码。
12、GetIpStatisticsEx:返回IP统计表并支持IPv6协议族
DWORD GetIpStatisticsEx( PMIB_IPSTATS pStats, DWORD dwFamily);
pStats:[输出] 指向一个收到本机IP统计表的MIB_IPSTATS类型。
dwFamily:[输入]协议族,以下值之一:
AF_INET Internet Protocol version 4 (IPv4).
AF_INET6 Internet Protocol version 6 (IPv6).
返回值:成功,返回0;失败,返回错误代码。
13、Icmp6CreateFile打开一个句柄,使IPv6的 ICMP回应请求能被发出
HANDLE Icmp6CreateFile(void);
返回值:成功,返回一个句柄,失败,返回0。
14、IcmpParseReplies:解析提供的响应缓存,返回ICMP响应创建数目
DWORD IcmpParseReplies(LPVOID ReplyBuffer, DWORD ReplySize);
ReplyBuffer :[输入] 被IcmpSendEcho2传递的缓存。它被重写来保留ICMP_ECHO_REPLY类型的阵列,它的类型为PICMP_ECHO_REPLY。
ReplySize:[输入] ReplyBuffer的大小。
返回值:成功,返回ICMP响应创建的数目,失败,返回0。
备注:此函数不能被用于之前传递给IcmpSendEcho的响应缓存;IcmpSendEcho在返回给使用者前解析那些缓存。仅和IcmpSendEcho2一起使用此函数。
15、Icmp6ParseReplies:分析被供给答复的缓存,返回IPv6 ICMP数字响应发现
DWORD Icmp6ParseReplies( LPVOID ReplyBuffer, DWORD ReplySize);
ReplyBuffer:[输入]传给Icmp6SendEcho2的缓存,是被重写用来保留ICMP_ECHO_REPLY类型的阵列,它的类型是PICMP_ECHO_REPLY。
ReplySize:[输入] ReplyBuffer的大小。
返回值:成功,返回IPv6 ICMP响应创建的数目;失败,返回0。
16、IcmpSendEcho2:发送一个IPv6 ICMP Echo要求并立即返回或者超时返回
DWORD IcmpSendEcho2(HANDLE IcmpHandle,HANDLE Event,FARPROC ApcRoutine,PVOID ApcContext,IPAddr DestinationAddress,LPVOID RequestData,WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout);
IcmpHandle:[输入] 由IcmpCreateFile打开的句柄
Event:[输入]用来标志无论何时ICMP响应到达的事件
ApcRoutine:[输入] 被调用的程序当前正调用线程在一个警告线程(alertable thread)中并且一个ICMP回复到达。.
ApcContext:[输入] 当IcmpSendEcho2 成功调用后用于ApcRoutine的可选参数
DestinationAddress:[输入] 响应要求的目的地
RequestData:[输入] 包含于请求中要发送的数据的缓存
RequestSize:[输入] requestdata缓存的大小,字节
RequestOptions:[输入] 指向请求的IP头选项的IP_OPTION_INFORMATION类型的指针,可为空。
ReplyBuffer:[输出]保存请求响应得缓存。成功调用,缓存包含一个跟随选项和数据的ICMP_ECHO_REPLY类型的阵列。缓存必须足够大来保存至少一个ICMP_ECHO_REPLY 类型,它必须足够大至少保存9个或更多字节的数据。
ReplySize:[输出] replybuffer的大小,字节
Timeout:[输出] 等待回应时间,毫秒
返回值:成功,返回收到储存在ReplyBuffer中的回应的数目。失败,返回0。
备注:①当使用异步 (ApcRoutine或者Event被指定),ReplyBuffer和ReplySize必须同意响应。ICMP响应数据被拷贝到ReplyBuffer,函数调用者必须使用IcmpParseReplies解析异步。IPv6,使用Icmp6SendEcho2和Icmp6ParseReplies。
②对于Windows 95/98/Me,参数Event、ApcRoutine、ApcContext被忽略。
17、SetIpStatistics:启用或者禁止转发IP包或设置本机TTL值
DWORD SetIpStatistics( PMIB_IPSTATS pIpStats);
pIpStats:[输入] 指向一个MIB_IPSTATS类型。调用者应该为此类型的dwForwarding和dwDefaultTTL成员设置新值。保持某个成员的值,使用MIB_USE_CURRENT_TTL或者 MIB_USE_CURRENT_FORWARDING。
返回值:成功,返回0;失败,返回错误代码。
备注:①在实际使用中,好像只能设置TTL的值,别的值设置有可能导致错误87(参数错误)或者虽然调用成功,但是并没有达到预期那样设置成功;②设置默认的生存时间(TTL),也可以使用SetIpTTL函数。
18、IpReleaseAddress:释放一个之前通过DHCP获得的IP地址
DWORD IpReleaseAddress( PIP_ADAPTER_INDEX_MAP AdapterInfo);
AdapterInfo:[输入]指向一个IP_ADAPTER_INDEX_MAP类型,指定了要释放的和IP地址关联的适配器。
返回值:成功,返回0;失败,返回错误代码。
19、IpRenewAddress:更新一个之前通过DHCP获得的IP地址租期
DWORD IpRenewAddress( PIP_ADAPTER_INDEX_MAP AdapterInfo);
AdapterInfo:[输入]指向一个IP_ADAPTER_INDEX_MAP类型,指定了与适配器关联的IP地址更新。
返回值:成功,返回0;失败,返回错误代码。
20、NotifyAddrChange:当IP地址到接口的映射表发生改变,将引发一个通知
DWORD NotifyAddrChange( PHANDLE Handle, LPOVERLAPPED overlapped);
Handle:[输出]指向一个HANDLE变量,用来接收一个句柄handle使用到异步通知中。
警告:不能关掉这个句柄。
overlapped:[输入]指向一个OVERLAPPED类型,通知调用者任何IP地址到接口的映射表改变。
返回值:成功,如果调用者指定Handle和overlapped参数为空,返回NO_ERROR;如果调用者指定非空参数,返回ERROR_IO_PENDING。失败,使用FormatMessage获取错误信息。
备注:①如果调用者指定Handle和overlapped参数为空,对NotifyAddrChange的调用将会被阻止直到一个IP地址改变发生。
②调用者指定了一个handle变量和一个OVERLAPPED类型,调用者可以使用返回的handle以及OVERLAPPED类型来接收路由表改变的异步通知。
21、NotifyRouteChange:IP路由表发生改变将引起一个通知
DWORD NotifyRouteChange( PHANDLE Handle, LPOVERLAPPED overlapped);
Handle:[输出]指向一个HANDLE变量,此变量接收一个用作异步通知的句柄。
overlapped:[输入]指向一个OVERLAPPED类型,此类型通知调用者路由表的每一个改变。
返回值:成功,如果调用者指定Handle和overlapped参数为空,返回NO_ERROR;如果调用者指定非空参数,返回ERROR_IO_PENDING。失败,使用FormatMessage获取错误信息。
备注:①如果调用者指定Handle和overlapped参数为空,对NotifyRouteChange的调用将会被阻止直到一个路由表改变发生。
②调用者指定了一个handle变量和一个OVERLAPPED类型,调用者可以使用返回的handle以及OVERLAPPED类型来接收路由表改变的异步通知。
22、CreateIpForwardEntry:创建一个路由到本地电脑IP路由表
DWORD CreateIpForwardEntry( PMIB_IPFORWARDROW pRoute);
pRoute:[输入]指向指定了新路由信息的MIB_IPFORWARDROW类型的指针,调用者必须指定这个类型的所有成员值,必须指定PROTO_IP_NETMGMT作为MIB_IPFORWARDROW类型中dwForwardProto成员的值。
返回值:成功,返回0;失败,返回错误代码。
备注:①修改现有的路由表中的路由,使用SetIpForwardEntry函数。
②调用者不能指定路由协议,例如:PROTO_IP_OSPF作为MIB_IPFORWARDROW类型的dwForwardProto成员的值,路由协议标识符仅仅用来识别通过路由表接收到的路由信息。 例如:PROTO_IP_OSPF被用来识别通过OSPF路由表接收到的路由信息。
③MIB_IPFORWARDROW类型中的dwForwardPolicy成员在当前未使用,调用者应该将它设置为0。
④MIB_IPFORWARDROW类型中的 DwForwardAge成员仅仅用来当路由和远程数据服务(Remote Access Service :RRAS)正在运行,并且仅用于路由的PROTO_IP_NETMGMT类型。
⑤这个函数执行了一个特许操作,需要有必须的权限才能执行。
23、DeleteIpForwardEntry:从本地电脑的IP路由表中删除一个路由
DWORD DeleteIpForwardEntry( PMIB_IPFORWARDROW pRoute);
pRoute: [输入] 指向一个MIB_IPFORWARDROW类型。这个类型指定了识别将要删除的路由的信息。调用者必须指定类型中以下成员的值:dwForwardIfIndex;dwForwardDest;dwForwardMask;dwForwardNextHop;dwForwardPolicy。
返回值:成功,返回0;失败,返回错误代码。
备注:①MIB_IPFORWARDROW类型是GetIpForwardTable返回的。接下来,再将此类型投递给DeleteForwardEntry函数,便可删除指定的路由条目了。
② MIB_IPFORWARDROW类型的 dwForwardPolicy目前未使用,应该设置为0。
24、EnableRouter:增加涉及的enable-IP-forwarding要求的数目
DWORD WINAPI EnableRouter( HANDLE* pHandle, OVERLAPPED* pOverlapped);
pHandle:指向一个句柄
pOverlapped:指向一个OVERLAPPED类型。除了hEvent成员,类型中的其它成员必须设置为0。hEvent成员应该包含一个有效的事件对象的句柄。使用CreateEvent函数来创建这个事件对象。
返回值:成功,返回ERROR_IO_PENDING;失败,调用FormatMessage获取更多错误信息。
25、GetBestInterface:返回包含到指定IP地址的最佳路由接口序号
DWORD GetBestInterface( IPAddr dwDestAddr, PDWORD pdwBestIfIndex);
dwDestAddr:[输入]目标IP地址
pdwBestIfIndex:[输出] 指向一个包含到指定IP地址的最佳路由接口序号的DWORD变量
返回值:成功,返回0;失败,返回错误代码。
26、GetBestInterfaceEx:返回包含到指定IPv4或IPv6地址的最佳路由接口序号
DWORD GetBestInterface( struct sockaddr* pDestAddr, PDWORD pdwBestIfIndex);
dwDestAddr:[输入]目标IP地址,包含了一个sockaddr类型
pdwBestIfIndex:[输出] 指向一个包含到指定IP地址的最佳路由接口序号的DWORD变量
返回值:成功,返回0;失败,返回错误代码。
27、GetBestRoute:返回包含到指定IP地址的最佳路由
DWORD GetBestRoute(DWORD dwDestAddr,DWORD dwSourceAddr,PMIB_IPFORWARDROW pBestRoute);
dwDestAddr:[输入]目标IP地址
dwSourceAddr:[输入]源IP地址。这个Ip地址是本地电脑上相应的接口,如果有多个最佳路由存在,函数选择使用这个接口的路由。这个参数是可选的,调用者可以指定这个参数为0。
pBestRoute:[输出] 指向一个包含了最佳路由的MIB_IPFORWARDROW类型
返回值:成功,返回0;失败,返回错误代码。
28、SetIpForwardEntry:从本机IP路由表中修改一个现有的路由
DWORD SetIpForwardEntry( PMIB_IPFORWARDROW pRoute);
pRoute:[输入]指向一个为现有路由指定了新信息的MIB_IPFORWARDROW类型。调用者必须将此类型的dwForwardProto设置为PROTO_IP_NETMGMT。调用者同样必须指定该类型中以下成员的值:dwForwardIfIndex,dwForwardDest,dwForwardMask,dwForwardNextHop,dwForwardPolicy。
返回值:成功,返回0;失败,返回错误代码。
备注:①在IP路由表中创建一个新的路由,使用CreateIpForwardEntry函数;
②调用者不能指定一个路由协议,比如:不能将MIB_IPFORWARDROW的dwForwardProto 设置为PROTO_IP_OSPF。路由协议标识符(id)是用来标识通过指定的路由协议收到的路由信息。例如:PROTO_IP_OSPF是用来标识通过OSPF路有协议收到的路由信息;
③MIB_IPFORWARDROW类型中的dwForwardPolicy成员目前没有使用,指定为0。
29、UnenableRouter:减少涉及的enable-IP-forwarding要求数目
DWORD WINAPI UnenableRouter(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount);
pOverlapped:指向一个OVERLAPPED类型。此类型必须和对EnableRouter的调用一样。
lpdwEnableCount:[out, optional]指向接收涉及剩余数目的DWORD变量。
备注:如果调用EnableRouter的进程没有调用UnenableRouter而终止,系统会减少IP推进涉及的数目就象调用了UnenableRouter一样。调用UnenableRouter后,使用CloseHandle来关闭OVERLAPPED类型中的事件对象的句柄。
返回值:成功,返回0;失败,返回错误代码。
30、GetTcpStatisticsEx:返回本机TCP 统计表并支持IPv6协议族
DWORD GetTcpStatisticsEx( PMIB_TCPSTATS pStats, DWORD dwFamily);
pStats:[输出]指向一个接收本机TCP统计表的MIB_TCPSTATS类型。
dwFamily:[输入]接收的统计表的协议族。为以下参数之一:
AF_INET Internet Protocol version 4 (IPv4);
AF_INET6 Internet Protocol version 6 (IPv6)。
返回值:成功,返回0;失败,返回错误代码。
31、GetUdpStatisticsEx:返回本机UDP统计表并支持IPv6协议族
DWORD GetUdpStatisticsEx( PMIB_UDPSTATS pStats, DWORD dwFamily);
pStats:[输出]指向一个接收到本机UDP统计表的MIB_UDPSTATS类型
dwFamily:[输入] 接收的统计表的协议族。为以下参数之一:
AF_INET Internet Protocol version 4 (IPv4).
AF_INET6 Internet Protocol version 6 (IPv6).
返回值:成功,返回0;失败,返回错误代码。