以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 安全理论 』 (http://bbs.xml.org.cn/list.asp?boardid=65) ---- [原创]关于Winpcap和NDIS数据包的问题 (http://bbs.xml.org.cn/dispbbs.asp?boardid=65&rootid=&id=33473) |
-- 作者:binaryluo -- 发布时间:6/1/2006 9:33:00 AM -- [原创]关于Winpcap和NDIS数据包的问题 问题一:Winpcap捕获到的数据包是什么? pcap_open()函数的第二个参数snaplen表示的是需要保存的数据包的长度,对于被过滤器接收到的每一个数据包,仅仅只有开始的‘snaplen’个字节被保存到缓冲区然后被传递给用户应用程序。例如,snaple等于100意味着仅仅保存每一个数据包开始的100个字节。在某些操作系统中(例如xBSD和Win32),数据包驱动程序可以被配置了只捕获数据包的首部:这样可以减少要拷贝的数据量从而提高抓包的效率。如果想要获得完整的数据包,可以把snaplen赋值为65535,因为65535远远大于我们所遇到的最大的MTU。下图(截自《TCP/IP详解卷一:协议》)列出了最常见的MTU: [点击在新窗口查看原始图片] pcap_handler()中的第二个参数struct pcap_pkthdr *pkt_header是与抓包驱动程序相关的一些头部信息,但它不是协议头。第三个参数const u_char *pkt_data是指向数据包的指针,包括协议头。如下图(截自winpcap文档)所示: [点击在新窗口查看原始图片] 因此表明winpcap捕获到的数据包就是一些字节流,该字节流以一个MTU的实际大小作为一个数据包,所以前面如果在pcap_open()里设置了snaplen是65535就可以保证以65535字节为一个数据包的大小,如果MTU小于65535,多出来的字节将添0(这里我已经用winpcap抓获数据包分析过)。
总结: 先回顾下winpcap的内部结构图(截自winpcap文档): [点击在新窗口查看原始图片] Winpcap提供了两个不同的库:packet.dll和wpcap.dll前者提供了一个底层API,伴随着一个独立于Microsoft操作系统的编程接口,这些API可以直接用来访问驱动的函数;后者导出了一组更强大的与libpcap一致的高层抓包函数库(capture primitives),这些函数使得数据包的捕获以一种与网络硬件和操作系统无关的方式进行 Winpcap的NPF捕获到的数据包是什么还是依赖于NDIS的库函数。不过根据NPF发送的数据格式可以判断它捕获到的数据包应该也是字节流,因为NPF允许发送的数据包可以没有按照任何的协议进行封装,因为封装的工作是在应用程序里完成的,也就是说NPF根本不关心上层传下来的是什么,只要传下来就发送;按照发送数据包的思路推想接收数据包也应该是这样的,NPF不关心接收到的是什么东西,反正它以你规定的snaplen为单位读取数据交给上层应用程序,由应用程序来判断该数据到底是怎么封装的,也就是Packet.dll或更上层应用程序。
问题二:Ndis库函数从网卡拷贝过来的数据包是什么? NDIS数据包被协议驱动分配的,填以数据,并且为了将这些数据发送出去而传递给更低层的NDIS驱动。通常,协议驱动分配一个数据包并且把它传递给一个NIC驱动,然后NIC驱动把接收到的数据拷贝到协议驱动所提供的数据包中。NDIS提供了分配和操作包装数据包结构体的函数。下图(截自DDK)阐明了一个数据包的结构: [点击在新窗口查看原始图片] 000000: 00 A0 CC 63 08 1B 00 40 : 95 49 03 5F 08 00 45 00 ...c...@.I._..E. 000010: 00 3C 82 47 00 00 20 01 : 94 C9 C0 A8 01 20 C0 A8 .<.G.. ...... .. 000020: 01 40 08 00 48 5C 01 00 : 04 00 61 62 63 64 65 66 .@..H\....abcdef 000030: 67 68 69 6A 6B 6C 6D 6E : 6F 70 71 72 73 74 75 76 ghijklmnopqrstuv 000040: 77 61 62 63 64 65 66 67 : 68 69 wabcdefghi...... 这个ping是由下面的命令来初始化的: C:> ping 192.168.1.64 并发送伴随着默认的32字节数据的ICMP响应请求。Ping数据包的总长度是74字节。下图(截自http://www.ndis.com/papers/ndispacket/ndispacket1.htm)阐明了一个NDIS_PACKET用来表示被封装好的数据包数据的简单方式: [点击在新窗口查看原始图片] NDIS_PACKET有一个NDIS_BUFFER链,NDIS_BUFFER描述了包含完整数据包数据的74字节大小的虚拟存储空间。 下面这个图比上面那个图稍微复杂一点,它阐明了NDIS_PACKET表示封装好的数据包数据的另一种方式: [点击在新窗口查看原始图片] 这个NDIS_PACKET有两个链在一起的NDIS_BUFFER,第一个NDIS_BUFFER表示了包含以太帧头部的14字节虚拟存储空间,第二个NDIS_BUFFER表示以太帧的有效负载(数据)的60字节虚拟存储空间。 尽管上面两个图有助于理解如何使用一个NDIS_PACKET,但是还必须注意一点这些结构体是透明的。我们不能直接访问结构体的这些域,只能通过NDIS库提供的函数来访问它们。NDIS提供的用来检查NDIS_PACKET和NDIS_BUFFER的函数很少,下面列举几个(详细信息看DDK):NdisQueryPacket,NdisQueryBuffer,NidsGetNextBuffer,NdisQueryBufferSafe。
总结: |
-- 作者:linxia -- 发布时间:5/16/2007 5:05:00 PM -- hao xuexi |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
31.250ms |