2015-10-16 48 views
2

有沒有辦法在Python Scapy中使用stdin讀取.pcap(使用rdpcap)?每次我嘗試任何東西時,都會收到錯誤消息(無法讀取文件)。從Python中的STDIN中讀取.pcap文件Scapy

用法是這樣的:

python main.py < test_linux.pcap 

我已經實現了使用參數讀取文件,但我還需要從標準輸入讀。

非常感謝。

回答

2

rdpcap()接口只接受文件名和文件名,因爲它在內部對該文件名執行open(filename)操作。下面是通過臨時文件解決方法:

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) 
+0

非常感謝您提供非常有見地的解釋。最終我轉向了C++實現,這是IMO更快,但使用起來有點麻煩。 – Petr

1

通過@tintin答案是完全正確的,但現在Scapy的可以使用文件描述符作爲參數爲rdpcap()PcapReader()

所以rdpcap(sys.stdin)應該像預期的那樣工作(如果您使用最近版本的Scapy)!