WinPcap基础知识(第八课:发送数据包)

来源:互联网 发布:宜春市网络问政 编辑:程序博客网 时间:2024/05/16 18:04

尽管WinPcap这个名字已经很清晰的表明这个库是用来捕获数据包的,但是另外一个非常有用的功能是提供了原始网络操作。这里,用户可以找到一系列函数来发送数据包,这节课我们就会向大家一一展示。注意到原始的libcap库不提供任何方法来发送数据库:这里讲的所有的函数是WinPcap扩展,它们不能在Unix系统下面工作。 用pcap_sendpacket()发送单个数据包函数原型: int pcap_sendpacket ( pcap_t * p, u_char * buf, int size ) 说明:该函数可以发送一个原始数据包到网络上。Buf包含要发送到网络上的数据包的数据(包括协议头)。注意,MAC CRC不用包含,因为它是网卡驱动计算然后添加的。返回值为0说明数据包已经成功的发送了,否则返回-1。

 

pcap_sendpacket()发送单个包

 

最简单发送一个数据包的方法如下面代码所示。打开一个适配器后,调用pcap_sendpacket()来发送一个手工数据包。Pcap_sendpacket()的参数如下:一个包含将要发送的数据缓冲区;缓冲区的长度;将要在它上面发送数据的适配器。注意到缓冲区的数据是不经过处理就被发送到网络上的,这就意味着应用程序必须要创建正确的协议头以保证发送一些有用的信息。

 

 

发送队列

Pcap_sendpacket()提供了一个简单而又直接的方法来发送一个数据包,发送队列提供了一个高级的有效的最优化机制来发送一组数据包。一个发送队列是一个用来存放即将要发送到网络上的多个数据包的容器。它有大小,大小表明了它能够存放的数据包的最大数量。发送队列是通过调用pcap_sendqueue_alloc()函数来创建的,创建时要指定所需创建的队列的大小。一旦队列创建完毕,就可以使用pcap_sendqueue_queue()来存放一个数据包在队列里面。此函数获得一个带有时间戳,长度,数据包缓冲区的pcap_pkthdr。这些参数同样被pcap_next_ex()和函数pcap_handler()接收。因此,把一个刚捕获的或者从文件中读取出来的数据包放到队列中去就是把数据包作为参数传递给pcap_sendqueue_queue()

  

看看几个函数

 

int pcap_sendqueue_queue  (  pcap_send_queue *  queue, 

 

  const struct pcap_pkthdr *  pkt_header, 

 

  const u_char *  pkt_data  ) 

 

能:向发送队列中添加一个数据包。Pcap_sendqueue_queue()方法向队列得末尾添加一个数据包。Pkt_header参数指向一个pcap_pkthdr结构体(结构体含有数据包得时间戳,长度,以及一个pkt_data指针,它指向包数据的指针)。Pcap_ptkhdr结构在Winpcaplibcap里面都是用来存放包,因此发送一个捕获文件时直接发送的。“原始包”意味着发送应用程序将必须包含协议头。

 

CRC头就不用了,那是网卡驱动程序进行计算然后加上的。

 

u_int pcap_sendqueue_transmit  (  pcap_t *  p,   

  pcap_send_queue *  queue, 

 

  int  sync  )  

 

功能:把一个装有原始包的队列发送到网络上。注意一下参数sync,它决定发送操作是否必须同步。如果是非0,数据包发送要注意时间戳(the packets are sent respecting the timestamps);否则,数据包尽可能快的发送出去。

 

为了发送一个队列,WinPcap提供了pcap_sendqueue_transmit()函数。注意一下第三个参数:如果是非空,发送就是同步的。例如:数据包的相关的时间戳也会被重视。这就需要占用大量cpu资源,因为同步方式代替在内核。。。。。(翻译不出来)

 

 注意到用pcap_sendqueue_transmit()来发送一个队列比执行一序列的pcap_sendpacket()每次发送一个数据包来说效率高的多。因为一个发送队列是一个缓冲区,在内核级大量减少了上下文切换的次数。

 

当不再需要一个队列,就可以用pcap_sendqueue_destroy()函数来释放,它会释放与之关联的所有的缓冲区。

  

下面的代码显示了怎么样使用发送队列。首先它用pcap_open_offline()函数打开一个捕获文件,然后把数据包从文件中拷贝到合适分配的队列里面。这时,开始传送队列。  

 

注意到dump文件的链路层是与使用pcap_datalink()方法来发送数据包所在的其中一个接口一致的。如果他们不同的话就会打印出一个警告:sending on a link-layer the packets captured from a different one is quite pointless.