From 339dfb39b159ef8f96f29c2344866004d972c9a0 Mon Sep 17 00:00:00 2001 From: Pierre LALET Date: Fri, 6 Jan 2017 13:43:28 +0100 Subject: [PATCH] Add a tcpdump-based L2listen socket This also includes some fixes for tcpdump() --- scapy/supersocket.py | 26 ++++++++++++++++++++++++++ scapy/utils.py | 27 ++++++++++++++++++--------- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/scapy/supersocket.py b/scapy/supersocket.py index fe80d507b..2a2c1107e 100644 --- a/scapy/supersocket.py +++ b/scapy/supersocket.py @@ -13,6 +13,7 @@ from scapy.config import conf from scapy.data import * from scapy.error import warning, log_runtime import scapy.packet +from scapy.utils import PcapReader, tcpdump class _SuperSocket_metaclass(type): def __repr__(self): @@ -174,5 +175,30 @@ class SSLStreamSocket(StreamSocket): self._buf = self._buf[x:] 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: conf.L3socket = L3RawSocket diff --git a/scapy/utils.py b/scapy/utils.py index 1215c69b8..74fc4c10e 100644 --- a/scapy/utils.py +++ b/scapy/utils.py @@ -804,7 +804,10 @@ class RawPcapNgReader(RawPcapReader): self.endian = "<" else: 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): """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' """ - 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( - [conf.prog.tcpdump if prog is None else prog, "-r", pktlist] - + (["-n"] if args is None else args), - stdin=subprocess.PIPE, + prog + (args if args is not None else []), + stdout=subprocess.PIPE if dump or getfd else None, + 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, stderr=open(os.devnull), ) @@ -1158,16 +1169,14 @@ u'64' else: tmpfile.close() proc = subprocess.Popen( - [conf.prog.tcpdump if prog is None else prog, "-r", - tmpfile.name] + (["-n"] if args is None else args), + prog + ["-r", tmpfile.name] + (args if args is not None else []), stdout=subprocess.PIPE if dump or getfd else None, stderr=open(os.devnull), ) conf.temp_files.append(tmpfile.name) else: proc = subprocess.Popen( - [conf.prog.tcpdump if prog is None else prog, "-r", "-"] - + (["-n"] if args is None else args), + prog + ["-r", "-"] + (args if args is not None else []), stdin=subprocess.PIPE, stdout=subprocess.PIPE if dump or getfd else None, stderr=open(os.devnull),