Add a tcpdump-based L2listen socket

This also includes some fixes for tcpdump()
This commit is contained in:
Pierre LALET 2017-01-06 13:43:28 +01:00
parent 94bab875ac
commit 339dfb39b1
2 changed files with 44 additions and 9 deletions

View File

@ -13,6 +13,7 @@ from scapy.config import conf
from scapy.data import * from scapy.data import *
from scapy.error import warning, log_runtime from scapy.error import warning, log_runtime
import scapy.packet import scapy.packet
from scapy.utils import PcapReader, tcpdump
class _SuperSocket_metaclass(type): class _SuperSocket_metaclass(type):
def __repr__(self): def __repr__(self):
@ -174,5 +175,30 @@ class SSLStreamSocket(StreamSocket):
self._buf = self._buf[x:] self._buf = self._buf[x:]
return pkt return pkt
class L2ListenTcpdump(SuperSocket):
desc = "read packets at layer 2 using tcpdump"
def __init__(self, iface=None, promisc=None, filter=None, nofilter=False,
prog=None, *arg, **karg):
self.outs = None
args = ['-w', '-', '-s', '65535']
if iface is not None:
args.extend(['-i', iface])
if not promisc:
args.append('-p')
if not nofilter:
if conf.except_filter:
if filter:
filter = "(%s) and not (%s)" % (filter, conf.except_filter)
else:
filter = "not (%s)" % conf.except_filter
if filter is not None:
args.append(filter)
self.ins = PcapReader(tcpdump(None, prog=prog, args=args, getfd=True))
def recv(self, x=MTU):
return self.ins.recv(x)
if conf.L3socket is None: if conf.L3socket is None:
conf.L3socket = L3RawSocket conf.L3socket = L3RawSocket

View File

@ -804,7 +804,10 @@ class RawPcapNgReader(RawPcapReader):
self.endian = "<" self.endian = "<"
else: else:
raise Scapy_Exception("Not a pcapng capture file (bad magic)") raise Scapy_Exception("Not a pcapng capture file (bad magic)")
self.f.seek(0) try:
self.f.seek(0)
except:
pass
def read_packet(self, size=MTU): def read_packet(self, size=MTU):
"""Read blocks until it reaches either EOF or a packet, and """Read blocks until it reaches either EOF or a packet, and
@ -1139,11 +1142,19 @@ To get a JSON representation of a tshark-parsed PacketList(), one can:
u'64' u'64'
""" """
if isinstance(pktlist, basestring): if prog is None:
prog = [conf.prog.tcpdump]
elif isinstance(prog, basestring):
prog = [prog]
if pktlist is None:
proc = subprocess.Popen( proc = subprocess.Popen(
[conf.prog.tcpdump if prog is None else prog, "-r", pktlist] prog + (args if args is not None else []),
+ (["-n"] if args is None else args), stdout=subprocess.PIPE if dump or getfd else None,
stdin=subprocess.PIPE, stderr=open(os.devnull),
)
elif isinstance(pktlist, basestring):
proc = subprocess.Popen(
prog + ["-r", pktlist] + (args if args is not None else []),
stdout=subprocess.PIPE if dump or getfd else None, stdout=subprocess.PIPE if dump or getfd else None,
stderr=open(os.devnull), stderr=open(os.devnull),
) )
@ -1158,16 +1169,14 @@ u'64'
else: else:
tmpfile.close() tmpfile.close()
proc = subprocess.Popen( proc = subprocess.Popen(
[conf.prog.tcpdump if prog is None else prog, "-r", prog + ["-r", tmpfile.name] + (args if args is not None else []),
tmpfile.name] + (["-n"] if args is None else args),
stdout=subprocess.PIPE if dump or getfd else None, stdout=subprocess.PIPE if dump or getfd else None,
stderr=open(os.devnull), stderr=open(os.devnull),
) )
conf.temp_files.append(tmpfile.name) conf.temp_files.append(tmpfile.name)
else: else:
proc = subprocess.Popen( proc = subprocess.Popen(
[conf.prog.tcpdump if prog is None else prog, "-r", "-"] prog + ["-r", "-"] + (args if args is not None else []),
+ (["-n"] if args is None else args),
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=subprocess.PIPE if dump or getfd else None, stdout=subprocess.PIPE if dump or getfd else None,
stderr=open(os.devnull), stderr=open(os.devnull),