【问题标题】:Reading .pcap file from STDIN in Python Scapy在 Python Scapy 中从 STDIN 读取 .pcap 文件
【发布时间】:2015-10-16 07:51:38
【问题描述】:

有没有办法在 Python Scapy(使用 rdpcap)中从标准输入读取 .pcap?每次我尝试任何东西时都会出错(无法读取文件)。

用法是这样的:

python main.py < test_linux.pcap

我已经实现了使用参数读取文件,但我还需要从 STDIN 读取。

非常感谢。

【问题讨论】:

    标签: python stdin scapy


    【解决方案1】:

    rdpcap() 接口接受一个文件名和一个文件名,因为它在内部对该文件名执行open(filename) 操作。这是通过 tempfile 的解决方法:

    from scapy.all import *
    import tempfile
    import sys
    
    if __name__=="__main__":
      ftmp = tempfile.NamedTemporaryFile(delete=True)
      ftmp.write(sys.stdin.read())
      ftmp.flush()
      print rdpcap(ftmp.name)
      ftmp.close()
    

    如果您不想使用临时文件,则必须重新实现 RawPcapReaderPcapReader 以获取 FD 而不是文件名。

    from scapy.all import *
    import sys
    
    class RawPcapReaderFD(RawPcapReader):
        """A stateful pcap reader. Each packet is returned as a string"""
    
        def __init__(self, fd):
            self.filename = "dummy"
            try:
                self.f = fd
                magic = self.f.read(4)
            except IOError:
                self.f = fd
                magic = self.f.read(4)
            if magic == "\xa1\xb2\xc3\xd4": #big endian
                self.endian = ">"
            elif  magic == "\xd4\xc3\xb2\xa1": #little endian
                self.endian = "<"
            else:
                raise Scapy_Exception("Not a pcap capture file (bad magic)")
            hdr = self.f.read(20)
            if len(hdr)<20:
                raise Scapy_Exception("Invalid pcap file (too short)")
            vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr)
    
            self.linktype = linktype
    
    class PcapReader(RawPcapReaderFD):
        def __init__(self, fd):
            RawPcapReaderFD.__init__(self, fd)
            try:
                self.LLcls = conf.l2types[self.linktype]
            except KeyError:
                warning("PcapReader: unknown LL type [%i]/[%#x]. Using Raw packets" % (self.linktype,self.linktype))
                self.LLcls = conf.raw_layer
    
    
    print PcapReader(sys.stdin).read_all(-1)
    

    【讨论】:

    • 非常感谢您非常有见地的解释。最终我切换到了 C++ 实现,它比 IMO 更快,但使用起来有点棘手。
    【解决方案2】:

    @tintin 的回答完全正确,但现在 scapy 可以使用文件描述符作为 rdpcap()PcapReader() 的参数。

    所以rdpcap(sys.stdin) 应该可以按预期工作(如果您使用的是最新版本的 Scapy)!

    【讨论】:

      猜你喜欢
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 2013-12-04
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      相关资源
      最近更新 更多