我需要确定一个特定的字符串是否是有效的IPv4或IPv6地址的文字。 如果我理解正确的话,这样做对POSIX系统的正确方法是使用inet_pton
将其转换为一个网络地址结构,看看它是否成功。 Windows Vista和更高版本具有InetPton
基本上做同样的事情。 但据我所知,Windows XP不申报或者那些,我需要能够正确地做到这一点的XP。 所以,问题是什么系统函数的使用要做到这一点?
最糟糕的情况下,我可以写一个函数来分析它自己,但我宁愿它也因此被彻底的测试标准,系统功能,正确处理所有极端情况和诸如此类的东西。 这已经够糟糕了,微软不能仅仅宣布inet_pton
像其他人一样,并与去InetPton
为他们的新的操作系统。
在Windows XP中,你可以使用这些功能:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
int inet_pton(int af, const char *src, void *dst)
{
struct sockaddr_storage ss;
int size = sizeof(ss);
char src_copy[INET6_ADDRSTRLEN+1];
ZeroMemory(&ss, sizeof(ss));
/* stupid non-const API */
strncpy (src_copy, src, INET6_ADDRSTRLEN+1);
src_copy[INET6_ADDRSTRLEN] = 0;
if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) {
switch(af) {
case AF_INET:
*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
return 1;
case AF_INET6:
*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
return 1;
}
}
return 0;
}
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{
struct sockaddr_storage ss;
unsigned long s = size;
ZeroMemory(&ss, sizeof(ss));
ss.ss_family = af;
switch(af) {
case AF_INET:
((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
break;
case AF_INET6:
((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
break;
default:
return NULL;
}
/* cannot direclty use &size because of strict aliasing rules */
return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)?
dst : NULL;
}
而已。 链接与WS2_32库。
但据我所知,Windows XP不申报或者那些,我需要能够正确地做到这一点的XP。
InetPton文档指出以下要求:
- 最低支持的客户端:Windows Vista中[桌面应用程序仅]
- 最低支持的服务器:在Windows Server 2008 [桌面应用程序仅]
最糟糕的情况下,我可以写一个函数来分析它自己,但我宁愿它也因此被彻底的测试标准,系统功能,正确处理所有极端情况和诸如此类的东西。
如何从OSS网络工具的代码的一部分的依赖Wireshark的 ?
你可以找到自己的inet_pton的重新实现他们的源代码库 。
许可证(见下文)是非常宽松的,所以这可能是一个很好的选择。
许可使用,复制,修改和分发本软件用于任何目的使用或不付费特此授予,前提是上述版权声明和本许可声明出现在所有副本。
翻翻SDK头文件,我觉得inet_pton()
中声明“C:\ Program Files文件\微软的SDK \的Windows \ V7.1 \包含\ WS2tcpip.h”。 InetPton
只是#定义了这一点。
因此,它似乎MS毕竟是提供适当的接口,但只有在Vista开始。 不过XP没有IPv6的支持,值得一提的是,如果我没有记错。
另一种选择是自己与两个电话把它包起来WSAAddressToString()
一个与AF_INET
,一个用AF_INET6
。 我猜这里从文档,还没有尝试过。