循序渐进学习使用WINPCAP(八)

来源:互联网 发布:数据库账号密码 编辑:程序博客网 时间:2024/05/31 00:39

发送数据报

尽管WinPcap从名字上来看就表明它的主要目的是捕获数据报,但是它还为原始网络提供了一些其他有用的功能。其中之一就是用户可以找到并使用一系列完整的函数来发送数据报。

需要指出的是原来的libpcap库并不提供任何发送数据报的功能,这里所有的功能都是WinPcap的扩展功能,所以并不能够在Unix下工作。

  • 用pcap_sendpacket()来发送一个单独的数据报

下面的代码片段是一个最简单的发送数据报的方法。打开一个适配器后就可以调用pcap_sendpacket()来发送一条手工制作的数据报。这个函数包含的参数:一个装有要发送数据的缓冲区,缓冲区的长度和一个适配器。注意缓冲区里的数据将不会做任何改动,直接发送出去。这就意味着,我们必须填充好准确的协议头以便发送一些有意义的东西。

 

  • 发送队列

pcap_sendpacket()提供了一个简单直接的方法发送数据,而发送队列提供了一个高级的,强大的并且最有的机制来发送一组数据报。发送队列是一个容纳了即将发送至网络的可变数量的包的容器。它有一个大小,代表它所能容纳的最大字节数。

发送队列是由函数pcap_sendqueue_alloc()创建的,该函数指定新的发送队列的大小。

一旦发送队列被创建,pcap_sendqueue_queue()可以向发送队列中添加数据报。这个函数接受一个带有时间戳和长度的pacp_pkthdr结构以及一个装有数据报数据的缓冲区。这些参数同样应用在pcap_next_ex()和pcap_handler()函数中,所以给捕获的数据报或从文件读取的数据报放入队列就是将这些参数传递给pcap_sendqueue_queue()。

WinPcap使用pcap_sendqueue_transmit()函数来传输发送队列。注意第三个参数如果非零,那么发送将是同步的,数据报的时间戳很重要是会这样设置。这一操作需要占用很大的CPU资源,因为同步是使用忙等(busy waiting)的方式在内核驱动中完成。尽管此操作很花费CPU资源,但这通常会换来非常高精确度的数据报传输(通常误差在几个微秒上下)。

需要指出的是用pcap_sendqueue_transmit()比用一些列的pcap_sendpacket()效率来的要高,因为发送队列的数据是在内核级上被缓冲的,这就大大地减少了上下文切换的次数。

当一个队列不再需要时,可以用pcap_sendqueue_destroy()来将它删除,并且释放与此队列有关的缓冲区。

下面的程序展示了如何使用发送队列。该示例用pcap_open_offline()来打开一个捕捉文件,然后将数据从文件移到已分配的队列。这是就同步地传输队列,如果用户要求的话。

需要注意的是,转储文件的链路层会与使用pcap_datalink()发送数据报的接口之一的链路层进行比较,如果不同,则会发出警报。保证抓包文件和适配器的链路层保持一致很重要,否则传输将变得毫无意义。

附原文:

Although the name WinPcap indicates clearly that the purpose of the library is packet capture, other useful features for raw networking are provided. Among them, the user can find a complete set of functions to send packets.

Note that the original libpcap library at the moment doesn't provide any way to send packets, therefore all the functions shown here are WinPcap extensions and will not work under Unix.

  • Sending a single packet with pcap_sendpacket()

The simplest way to send a packet is shown in the following code snippet. After opening an adapter, pcap_sendpacket() is called to send a hand-crafted packet. pcap_sendpacket() takes as arguments a buffer containing the data to send, the length of the buffer and the adapter that will send it. Notice that the buffer is sent to the net as is, without any manipulation. This means that the application has to create the correct protocol headers in order to send something meaningful.

/* codes */

  • Send queues

While pcap_sendpacket() offers a simple and immediate way to send a single packet, send queues provides an advanced, powerful and optimized mechanism to send a collection of packets. A send queue is a container for a variable number of packets that will be sent to the network. It has a size, that represents the maximum amount of bytes it can store.

A send queue is created calling the pcap_sendqueue_alloc() function, specifying the size of the new send queue.

Once the send queue is created, pcap_sendqueue_queue() can be used to add a packet to the send queue. This function takes a pcap_pkthdr with the timestamp and the length and a buffer with the data of the packet. These parameters are the same as those received by pcap_next_ex() and pcap_handler(), therefore queuing a packet that was just captured or read from a file is a matter of passing these parameters to pcap_sendqueue_queue().

To transmit a send queue, WinPcap provides the pcap_sendqueue_transmit() function. Note the third parameter: if nonzero, the send will be synchronized, i.e. the relative timestamps of the packets will be respected. This operation requires a remarkable amount of CPU, because the synchronization takes place in the kernel driver using "busy wait" loops. Although this operation is quite CPU intensive, it often results in very high precision packet transmissions (often around few microseconds or less).

Note that transmitting a send queue with pcap_sendqueue_transmit() is much more efficient than performing a series of pcap_sendpacket(), because the send queue is buffered at kernel level drastically decreasing the number of context switches.

When a queue is no longer needed, it can be deleted with pcap_sendqueue_destroy() that frees all the buffers associated with the send queue.

The next program shows how to use send queues. It opens a capture file with pcap_open_offline(), then it moves the packets from the file to a properly allocated send queue. At his point it transmits the queue, synchronizing it if requested by the user.

Note that the link-layer of the dumpfile is compared with the one of the interface that will send the packets using pcap_datalink(), and a warning is printed if they are different -- it is important that the capture-file link-layer be the same as the adapter's link layer for otherwise the tranmission is pointless.

/* codes */

#end

原创粉丝点击