SharpPcap4.0使用手册(笔记)

资料来源:https://www.360docs.net/doc/ae12268761.html,/KB/IP/sharppcap.aspx《https://www.360docs.net/doc/ae12268761.html,/KB/IP/sharppcap.aspx》(2011-9-14),文章对应的SharpPcap版本应该是4.0.0,因为它们是同一天发布的。

SharpPcap包含以下三个命名空间:
LibPcap:对应unix/linux/mac平台上的网络适配器
WinPcap:对应Win平台上的网络适配器,包括airpcap设备。
AirPcap:对应具有AirPcap特性的WinPcap设备。AirPcap是Win平台上用于无线网络分析的工具。

Open(DeviceMode mode, int read_timeout)函数及其重载:
当DeviceMode被设为Normal模式时,只捕捉以本机为源或目的的报文;设为Promiscuous模式时,捕捉所以流过网卡的报文(在共享式网络中有用,在目前常见的交换式网络中没啥效果,因为别人的报文不会经过你的网卡)。注意,当你的网卡处于混杂模式时,你是能够被网络中其他主机探测到的。
read_timeout是设备读取报文的超时时间,比如GetNextPacket()会在超时后返回,无论能否读到。如果网卡处于统计模式,它还决定了统计报告的时间间隔。read_timeout设为0表示无超时,读操作只有在读到报文后才返回;设为-1表示立即返回。

Capture()与StartCapture()的区别是,后者是非阻塞的,它会在另一个线程上异步捕捉;而前者则会阻塞线程知道捕捉到了足够数目的报文。二者的其他地方都非常类似,在捕捉之前需要注册到PacketArrivalEventHandler,当捕获到报文后会激活该事件,它会接收激活这一事件的对象(比如ICaptureDevice 对象),和收到的报文(包括所有的协议头)。请注意该报文没有CRC,因为网卡在校验的时候把它去掉了。另外CRC校验失败的报文均会被网卡丢弃,因此我们是捕捉不到的。

每一个Packet都包含一个PcapHeader属性,它包含了捕捉到的报文的信息(比如本次捕捉的时间戳和报文长度)。

OnPacketArrival事件有时候的确很好用,比如说从多个设备同时捕捉报文时,但是存在多线程时,它会使程序变的很复杂。这时GetNextPacket()就很好用了,它可以在你需要的时候直接返回一个报文。PS:它返回的报文为RawCapture类型,需要用Packet.ParsePacket()进行分析。而过滤器仍然有效。

libpcap和WinPcap最强大的一个特性就是过滤器,它能够有效过滤收到的报文。每个捕捉设备都会有这样一个Filter,它的过滤表达式的语法请参考(https://www.360docs.net/doc/ae12268761.html,/docs/docs_40_2/html/group__language.html)。捕捉设备会把过滤结果为true的报文拷贝给应用程序。请注意过滤表达式编译引擎要求将设备的子网掩码一并传递过去,因为有的过滤器会需要它。但是SharpPcap已经自动为我们处理了。

最新的SharpPcap用CaptureFileWriterDevice这个类来将捕获到的报文写入到文件中。CaptureFileReaderDevice用来从文件中读取

报文。

解析报文时,通过不同报文的类的GetEncapsulated()可以直接抽取出对应的真实报文。比如,TcpPacket.GetEncapsulated(e.Packet)可从e中得到TCP报文,这样就不用一次次地提取原始报文的PayLoadPacket属性了。

虽然SendPacket()为发送报文提供了简单迅速的方法,但是SendQueue类为发送多个报文提供了高级、强大和最佳的机制。它的对象实际上是一个需要发送的报文的容器。由于SendQueue功能是WinPcap独有的,因此我们建议你测试你的程序,看看跨平台支持的损失是否不足以抵消它带来的效率上的提升。请尽量避免不成熟的改进。

使用SendQueue.Add()将报文添加到待发送的queue。这个功能会提取报文的时间戳、长度和一个buffer或者Packet对象。WinPcapDevice.SendQueue(SendQueue q, SendQueueTransmitModes transmitMode)用来发送一个queue。请注意第二个参数,如果transmitMode为同步模式,则会使用报文的相对时间戳。这个操作会消耗较多的CPU因为它运行于使用 "busy wait"循环的内核驱动上。但是它的传输精度很高,基本是ms左右或更低。

使用WinPcapDevice.SendQueue()比不断调用ICaptureDevice.SendPacket()的效率更高,因为queue缓存于内核一级,它会大幅减少环境切换。当queue不再需要时,可使用SendQueue.Dispose()来释放。

获取统计信息
通过调研ICaptureDevice.Statistics属性能够获取网卡的统计信息,所有类型的ICaptureDevice都支持。WinPcap有一个扩展就是提供统计回调,这样比不断地读取统计信息效率更高。WinPcap的统计引擎使用内核级别的报文过滤器一般高效地对报文进行归类。关于详细信息请参考(https://www.360docs.net/doc/ae12268761.html,/docs/docs_41b5/html/group__NPF.html)。进行统计之前,必须Open一个设备并将其置于统计模式。本例中的程序比传统的在用户级别上抓包然后统计的程序要高效的多。Statistical mode要求最少的数据拷贝和环境气和以降低CPU占用。另外,对内存的需求也很少。副作用就是如果你的程序使用统计模式那么它只能在Windows中以WinPcap进行工作。

报文的传输速率会超过它们被处理的速率。如果报文处理很费时,比如写入磁盘或者处理代码逻辑复杂时,就会发生这种情况。有事我们可以通过使用bnf过滤器来降低报文传输速率,但是在其他情况下过滤器会很复杂。如果报文传输速率只是在短期内大于处理速率的话,我们可以简单地延缓报文的处理直到传输速率降下来。一种方法就是把报文储存到队列中,然后在后台线程中进行处理。




















相关文档
最新文档