很多程序员下载了 Winpcap 3.1 或更新的版本后,会发现原来自己运行得好好的程序突然不能使用了。而且其中涉及到一些相当重要的函数,比如 pcap_loop。 winpcap 对这些函数的修改使得很多基于它的应用程序(比如windump和snort)都将作出不小的改动。当然,还有你自己编写的代码……
以下是 Windows 本身的 Winsock 编程对此问题的影响。由于新版的 Winpcap 完全使用了新的 Winsock(支持IPv6),因此下列问题可能影响到每一个程序。
这是新旧两版的 packet32.h 之间的差异
//Packet32.h
typedef struct npf_if_addr {
struct sockaddr IPAddress; ///< IP address.
struct sockaddr Su.netMask; ///< Netmask for that address.
struct sockaddr Broadcast; ///< Broadcast address.
//struct sockaddr_storage IPAddress; ///< IP address.
//struct sockaddr_storage SubnetMask; ///< Netmask for that address.
//struct sockaddr_storage Broadcast; ///< Broadcast address.
}npf_if_addr;
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/sockaddr_storage_2.asp
很多程序员仍然使用 Visual C++6 编译程序,不幸的是,VC++6中的 winsock2.h 太老了,它根本不认得 struct sockaddr_storage。因此,winpcap 自带的例程在 VC++6 下编译时会无情地抛出无数错误。事实上,该结构完全可以使用老的 sockaddr 代替。手工改动 packet32.h,将 sockaddr_storage 换成 sockaddr,编译将顺利通过。当然,这样的代码自然无法支持 IPv6 了。到目前为止,我没有找到在 VC++6 与Windows 2003中成功编译 IPv6 的例程。Windows 2000 的用户可以升级SDK,使自己的VC++6支持IPv6编程,但不幸的是这个SDK升级版检查操作系统的版本,不是2195就停止了安装,使我在 Windows XP 和 Win 2003 下无法安装。在作者写本文时,没有找到对 Win XP 和 Win 2003 的 IPv6 SDK。我没有安装那个巨达 106M 的 Windows 2003 开发升级包,但估计那个包中可能有支持 IPv6 开发所需的库和头文件。我也不排除对 for 2000 的SDK包做做手脚,提取其中的文件后能够成功运行的可能。因为 Microsoft Visual Studio.NET 2002/2003 已经对此提供了很好的支持。
躲过了 sockaddr_storage 一劫的朋友可能很快会遇到 socklen_t 和 getnameinfo 函数的错误。这两个函数包含在头文件 WS2TCPIP.H 中。很不幸,它也是一个 for IPv6 的函数,在VC++6中同样没有支持。编译时发生的错误如下:
--------------------Configuration: iflist - Win32 Debug--------------------
Compiling...
iflist.c
g:\security\ids\wpdpack\examples\iflist\iflist.c(151) : error C2065: 'socklen_t' : undeclared identifier
g:\security\ids\wpdpack\examples\iflist\iflist.c(151) : error C2146: syntax error : missing ';' before identifier 'sockaddrlen'
g:\security\ids\wpdpack\examples\iflist\iflist.c(151) : error C2065: 'sockaddrlen' : undeclared identifier
g:\security\ids\wpdpack\examples\iflist\iflist.c(160) : warning C4013: 'getnameinfo' undefined; assuming extern returning int
g:\security\ids\wpdpack\examples\iflist\iflist.c(166) : error C2065: 'NI_NUMERICHOST' : undeclared identifier
Error executing cl.exe.
iflist.exe - 4 error(s), 1 warning(s)
关于该函数,可以参考微软MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/getnameinfo_2.asp
同样,如果你不介意让程序仅能在 IPv4 上工作的话,可以用原来的函数 gethostbyname 代替。