当前位置:   article > 正文

dpkt和scapy对处理大pcap包分析对比_scapy和dpkt性能

scapy和dpkt性能

对于scapy对pcap包的处理在我之前的一篇博客中有写:

https://blog.csdn.net/qq_38231051/article/details/81460427

这里对用scapy包对大pcap文件处理做出了简单的解决方法,但scapy包处理这种大文件有一个没法忍的缺点就是:

太慢了!!!

没错,特别慢,基本一个1G的文件要15分钟+,每跑一次数据我就得去看一集数码宝贝....

然后果然被要求优化。

emmmm

我试了试,用scapy直接遍历不做任何操作得12分钟+,没办法,就只能另寻出路了。


其实在我用spcay包之前我就用过dpkt,但......

dpkt的资料是真的少啊啊啊,

还是靠着万能的google捞到了自己想要的东西。跑1G数据(含数据处理)2分钟。优化后基本80s吧,不是很记得了。。。

不说废话了。。。。


这里分两部分,读pcap和写pcap文件(用dpkt写pcap文件的资料也是特少,我是看源码发现他有这个函数的。。。。)

dpkt读pcap文件

  1. f = open('new1.pcap','rb')
  2. pcap = dpkt.pcap.Reader(f)
  3. for ts,buf in pcap:
  4. pass

ts是timestemp时间戳,buf(二进制数据)是主体的数据包信息。

如果我们想获取每个数据包的ip地址应该怎么做呢?

  1. #由buf这个二进制数据转化为Ethernet类的对象
  2. eth = dpkt.ethernet.Ethernet(buf)
  3. ip_src = eth.data.src #这里是获取这个数据包的源ip
  4. #要注意的是,这里的源ip是以二进制的方式返回的,如果我们要获取点分十进制的ip地址
  5. #可以这样做
  6. def inet_to_str(inet):
  7. try:
  8. return socket.inet_ntop(socket.AF_INET,inet)
  9. except:
  10. return False#这里因为具体需要我把IPv6给丢弃了
  11. #如果希望IPv6也能获取可以这样
  12. #return socket.inet_ntop(socket.AF_INET6,inet)
  13. ip_src = inet_to_str(eth.data.src)
  14. ip_dst = inet_to_str(eth.data.dst)#目的ip

如果要获取数据包的其他信息的话可以在官文文档中查看

https://dpkt.readthedocs.io/en/latest/print_packets.html

这里简单的贴一部分我的代码:

  1. #coding=utf-8
  2. import dpkt
  3. import socket
  4. import time
  5. def inet_to_str(inet):
  6. try:
  7. return socket.inet_ntop(socket.AF_INET,inet)
  8. except:
  9. return False
  10. def getip():
  11. f = open('new1.pcap','rb')#要以rb方式打开,用r方式打开会报错
  12. pcap = dpkt.pcap.Reader(f)
  13. for ts,buf in pcap:
  14. print(ts)打印时间戳
  15. eth=dpkt.ethernet.Ethernet(buf)
  16. #这里也是对没有IP段的包过滤掉
  17. if eth.type != dpkt.ethernet.ETH_TYPE_IP:
  18. continue
  19. ip = eth.data
  20. ip_src = inet_to_str(ip.src)
  21. ip_dst = inet_to_str(ip.dst)
  22. print(ip_src+'-->'+ip_dst)
  23. if __name__=='__main__':
  24. getip()

这段代码在python3.6 centos7系统下运行没有问题


dpkt写文件

百度google了几次的我还以为dpkt不能写pcap文件呢,最后在dpkt官方文档看到了Writer方法,然后用dpkt.pcap.Writer在google找到了许多例子。

这是一个简单的例子:

  1. f = open("new.pcap","wb")
  2. writer = dpkt.pcap.Writer(test)
  3. writer.writerpkt(eth,ts=ts)#参数意义可以对应上面的读文件中的两个参数
  4. test.flush()
  5. test.close()

这里只是一个整体的写法,我们来看一下细节方面,比如,我们怎么把一个数据包中的源地址和目的地址改为我们需要的:

  1. test = open("new.pcap","wb")
  2. writer = dpkt.pcap.Writer(test)
  3. f=open("old.pcap",'rb')
  4. packets = dpkt.pcap.Reader(f)
  5. for ts,buf in packets:
  6. eth = dpkt.ethernet.Ethernet(buf)
  7. eth.data.src = socket.inet_pton(socket.AF_INET,"127.0.0.1")#这里是将点分十进制转化成二进制
  8. eth.data.dst = socket.inet.pton(socket.AF_INET,"127.0.0.2")
  9. writer.writepkt(eth,ts=ts)#如果不加ts参数的话,这个数据包的时间戳默认是当前时间!
  10. test.flush()
  11. test.close()

源码不方便贴,上面的代码我没测试过。。。。如果报错,可能是该数据包没有ip的src,dst地址,就需要像之前读pcap那个一样进行协议过滤。也可能是其他小问题。可以多去google看官方文档学习。也可以留言一起交流。


总结

dpkt性能毫无疑问是比scapy更加有优势的,但dpkt这个包用起来远没有scapy包方便,如果只是小包处理的话,建议scapy,可以节省踩坑的时间。scapy中文资料也更加的多。如果要求性能的话我还是推荐dpkt。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/200840
推荐阅读
  

闽ICP备14008679号