分类: C/C++
2008-04-22 22:43:17
很多程序员下载了 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 subnetmask; ///< 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;
很多程序员仍然使用 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:
同样,如果你不介意让程序仅能在 ipv4 上工作的话,可以用原来的函数 gethostbyname 代替。