笑看风云淡

宠辱不惊,看庭前花开花落;去留无意,望天空云卷云舒
posts - 96, comments - 48, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 ::  :: 聚合  :: 管理
在从 ipv4 到 ipv6 的升级过程中,有不少函数发生了变化。新版的 winpcap 正在慢慢地从 ipv4 向 ipv6 迁移。在这个过程中,有不少函数已经被废弃。旧的例程在新版的 winpcap 下无法使用,这其中也包括了一些著名的基于 winpcap/libpcap 的软件。比如 windump 和 snort for windows。作者在编程过程中收集了相关的资料,提出了解决方法。本文的最新版本和讨论保存在广州大学信息安全研究所 http://www.gzisi.com 网站的入侵检测文章部分。

 

很多程序员下载了 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;

 

http://msdn.microsoft.com/library/default.html?url=/library/en-us/winsock/winsock/sockaddr_storage_2.html

很多程序员仍然使用 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.html?url=/library/en-us/winsock/winsock/getnameinfo_2.html

同样,如果你不介意让程序仅能在 ipv4 上工作的话,可以用原来的函数 gethostbyname 代替。

原文地址:http://blog.chinaunix.net/u2/64540/showart_573227.html


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理