在 Python Scapy 中从 STDIN 读取 .pcap 文件
Reading .pcap file from STDIN in Python Scapy
有没有办法在 Python Scapy(使用 rdpcap)中从标准输入读取 .pcap?每次我尝试任何操作都会出错(无法读取文件)。
用法是这样的:
python main.py < test_linux.pcap
我已经实现了使用参数读取文件,但我还需要从 STDIN 读取文件。
非常感谢。
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()
如果您不想使用临时文件,则必须重新实现 RawPcapReader
和 PcapReader
以获取 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)
@tintin 的回答完全正确,但现在 scapy 可以使用文件描述符作为 rdpcap()
和 PcapReader()
.
的参数
所以 rdpcap(sys.stdin)
应该会按预期工作(如果你使用足够新的 Scapy 版本)!
有没有办法在 Python Scapy(使用 rdpcap)中从标准输入读取 .pcap?每次我尝试任何操作都会出错(无法读取文件)。
用法是这样的:
python main.py < test_linux.pcap
我已经实现了使用参数读取文件,但我还需要从 STDIN 读取文件。
非常感谢。
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()
如果您不想使用临时文件,则必须重新实现 RawPcapReader
和 PcapReader
以获取 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)
@tintin 的回答完全正确,但现在 scapy 可以使用文件描述符作为 rdpcap()
和 PcapReader()
.
所以 rdpcap(sys.stdin)
应该会按预期工作(如果你使用足够新的 Scapy 版本)!