深度剖析WinPcap之(九)——数据包的发送过程(8)

本文转自http://eslxf.blog.51cto.com/918801/214880

 

1.7.3    发送队列方式的接口实现

1.7.3.1             PacketSendPackets函数

函数发送数据包队列到网络,函数原型如下:
INT PacketSendPackets(LPADAPTER AdapterObject,
PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
参数AdapterObject指向一个_ADAPTER结构体,该结构体表示将发送数据包的网络适配器。
参数PacketBuff指向待发送数据包的缓冲区。
参数Size为参数PacketBuff所指缓冲区的大小。
参数Sync如果为TRUE,则根据时间戳发送数据包。如果为FALSE,则不根据时间戳,而是尽所能的快速发送各数据包。
函数返回值为实际所发送的字节数,如果该值小于Size参数规定的大小,那么发送过程中出现了错误。错误可能由驱动程序/适配器的问题或冲突的/假的数据包缓冲区导致。
该函数用来发送一个原始数据包缓冲区的内容到网络。该缓冲区能够包含任意数目的原始数据包,每个数据包都有一个dump_bpf_hdr结构体作为数据包的前缀。WinPcaplibpcap在文件中存储数据包使用一样的dump_bpf_hdr结构体,因此可以很直接的发送一个捕获的数据包文件。'Raw packets'意味着发送应用程序将不得不包含协议头,既然每个数据包照原来的样子被发送到网络。但是数据包的CRC并不需要计算,明显地,它将被网络接口添加。
注意:使用该函数 比直接使用一连串PacketSendPacket函数更有效率,因为数据包被缓冲到内核驱动,因此上下文的切换明显降低了。
注意:当Sync设置为TRUE,那么内核中的数据包将与一个高精度时间戳同步发送。这个操作需要消耗大量的CPU资源,但数据包的发送通常很精确(可达数微秒左右),这依赖于机器的性能计数器(performance counter)的精度。如此精度是采用pcap_sendpacket函数不可能达到的。
INT PacketSendPackets(LPADAPTER AdapterObject,
PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
{
    BOOLEAN         Res;
    DWORD           BytesTransfered, TotBytesTransfered=0;
    struct timeval BufStartTime;
    LARGE_INTEGER   StartTicks, CurTicks, TargetTicks, TimeFreq;
 
    if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER)
    {
       /*获得发送队列的起始时间戳*/
       BufStartTime.tv_sec =
((struct timeval*)(PacketBuff))->tv_sec;
       BufStartTime.tv_usec =
((struct timeval*)(PacketBuff))->tv_usec;
 
/*获的参考的时间计数器*/
       QueryPerformanceCounter(&StartTicks);
       QueryPerformanceFrequency(&TimeFreq);
       CurTicks.QuadPart = StartTicks.QuadPart;
 
       do{
           //把数据发送给驱动程序
           Res = (BOOLEAN)DeviceIoControl(
AdapterObject->hFile,
             (Sync)?BIOCSENDPACKETSSYNC:BIOCSENDPACKETSNOSYNC,
              (PCHAR)PacketBuff + TotBytesTransfered,
              Size - TotBytesTransfered,
              NULL,
              0,
              &BytesTransfered,
              NULL);
 
           TotBytesTransfered += BytesTransfered;
 
           //从循环中退出,发送结束或出错
           if(TotBytesTransfered >= Size || Res != TRUE)
              break;
 
           //计算发送下一块数据的时间间隔
           TargetTicks.QuadPart =
StartTicks.QuadPart +
(LONGLONG)((((struct timeval*)
((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec –
BufStartTime.tv_sec) * 1000000
+
(((struct timeval*)
((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec
 - BufStartTime.tv_usec)) *(TimeFreq.QuadPart
) / 1000000;
          
           //等待时间间隔的逝去
           while( CurTicks.QuadPart <= TargetTicks.QuadPart )
              QueryPerformanceCounter(&CurTicks);
 
       }
       while(TRUE);
    }
    else
    {//错误,未知设备类型
       TotBytesTransfered = 0;
    }
 
    return TotBytesTransfered;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的pcap是一个用于处理网络数据包的库。它提供了许多功能,包括捕获和解析网络数据包、读取和写入PCAP文件等。你可以使用pcap库来进行网络数据包分析、网络流量监控、网络安全等方面的开发。 在Python中,有几个pcap库可供选择,其中最常用的是libpcappcapy。你可以使用这些库来捕获网络接口上的数据包,并以不同的方式进行处理。 如果你想捕获网络接口上的数据包,可以使用pcapy库。以下是一个简单的示例代码: ```python import pcapy # 打开网络接口 dev = 'eth0' cap = pcapy.open_live(dev, 65536, True, 100) # 设置过滤器(可选) cap.setfilter('tcp') # 开始捕获数据包 count = 0 while count < 10: (header, packet) = cap.next() print(f"Packet #{count}: {packet}") count += 1 # 关闭网络接口 cap.close() ``` 上述代码将打开名为'eth0'的网络接口,并捕获前10个TCP数据包。你可以根据自己的需求进行相应的修改和扩展。 另外,如果你想解析现有的PCAP文件,可以使用scapy库。以下是一个简单的示例代码: ```python from scapy.all import * # 读取PCAP文件 pkts = rdpcap('filename.pcap') # 遍历数据包 for pkt in pkts: # 处理每个数据包 print(pkt.summary()) ``` 上述代码将读取名为'filename.pcap'的PCAP文件,并对每个数据包进行处理。你可以按照自己的需求对数据包进行解析和分析。 希望以上信息能对你有所帮助!如果有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值