scapy在linux环境中对pcap文件进行操作非常方便,但在windows下,特别是在python2.7环境下却会碰到各种各样的依赖包无法使用的问题,最明显的可能就属dnet和pcap的python依赖包了,因为scapy的conf.use_pcap和conf.use_dnet在windows环境下无法进行配置,在scapy\arch\windows\__init__.py中都被强行置为1了,也就是必须使用pcap和dnet依赖包。具体代码如下所示
from scapy.sendrecv import debug, srp1 from scapy.layers.l2 import Ether, ARP from scapy.data import MTU, ETHER_BROADCAST, ETH_P_ARP conf.use_pcap = 1 conf.use_dnet = 1 from scapy.arch import pcapdnet from scapy.arch.pcapdnet import * LOOPBACK_NAME="lo0" WINDOWS = True
google了一遍,基本都是在Windos+python2.6的环境下使用scapy的,很少有使用Windows+python2.7的,几经周折,又cygwin又是MinGW的总算搞定dnet和pcap在Windows+python2.7的包。
具体下载地址为:
pcap https://files.cnblogs.com/Jerryshome/pcap-1.1.win32-py2.7.rar
dnet https://files.cnblogs.com/Jerryshome/dnet-1.12.win32-py2.7.rar
以下代码对如何使用scapy完成pcap的读写做了展示,同时为解决部分scapy解析出来的Packet无法序列化的问题提供一个PicklablePacket类,具体代码如下:
import scapy from scapy.all import * from scapy.utils import PcapReader, PcapWriter import gzip,zlib,cPickle class PicklablePacket: ''' A container for scapy packets that can be pickled (in contrast to scapy pakcets themselves) ''' def __init__(self, pkt): self.contents = str(pkt) self.time = pkt.time def __call__(self): ''' Get the original scapy packet ''' pkt = scapy.layers.l2.Ether(self.contents) pkt.time = self.time return pkt def dumps(self): '''use cpickle to dump''' return gzip.zlib.compress(cPickle.dumps(self)).encode('base64') @staticmethod def loads(string): ''' load object from string ''' p = cPickle.loads(gzip.zlib.decompress(string.decode('base64'))) return p() def read(file_name, start, count): ''' read packets from pcap according to the start packet number and total count ''' reader = PcapReader(file_name) if start > 0: reader.read_all(start) if count > 0: return reader.read_all(count) else: return reader.read_all(-1) def write(file_name, packets): writer = PcapWriter(file_name, append = True) for p in packets: writer.write(p) writer.flush() writer.close() if __name__ == '__main__': packets = read('726445CD34B7273EBEA2973BBD6E784C.C39BC427.pcap', 0, 10) # packle the packets to transfer p = PicklablePacket(packets[0]) s = p.dumps() p = PicklablePacket.loads(s) print p print p.summary() serialized_packets = [PicklablePacket(p).dumps() for p in packets] deserialized_packets = [PicklablePacket.loads(s) for s in serialized_packets] write('new.pcap', packets)