From 3f5e7ca2359500ff9c6626097ba5356cfe5da23a Mon Sep 17 00:00:00 2001 From: Guillaume Valadon Date: Mon, 25 Mar 2019 21:37:59 +0100 Subject: [PATCH] Check if tcpdump binary exists --- scapy/sendrecv.py | 8 +++++++- scapy/utils.py | 4 ++++ test/regression.uts | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/scapy/sendrecv.py b/scapy/sendrecv.py index 4d54b9f29d8..054b1a3f368 100644 --- a/scapy/sendrecv.py +++ b/scapy/sendrecv.py @@ -17,10 +17,11 @@ import time import types +from scapy.arch.common import TCPDUMP from scapy.compat import plain_str from scapy.data import ETH_P_ALL from scapy.config import conf -from scapy.error import warning +from scapy.error import Scapy_Exception, warning from scapy.packet import Packet, Gen from scapy.utils import get_temp_file, tcpdump, wrpcap, \ ContextManagerSubprocess, PcapReader @@ -802,6 +803,11 @@ def sniff(count=0, store=True, offline=None, prn=None, lfilter=None, sniff_sockets[opened_socket] = "socket0" if offline is not None: flt = karg.get('filter') + + if not TCPDUMP and flt is not None: + message = "tcpdump is not available. Cannot use filter!" + raise Scapy_Exception(message) + if isinstance(offline, list): sniff_sockets.update((PcapReader( fname if flt is None else diff --git a/scapy/utils.py b/scapy/utils.py index 2bf552b4e55..99f03dd6e05 100644 --- a/scapy/utils.py +++ b/scapy/utils.py @@ -32,6 +32,7 @@ base64_bytes, hex_bytes, lambda_tuple_converter, bytes_encode from scapy.error import log_runtime, Scapy_Exception, warning from scapy.pton_ntop import inet_pton +from scapy.arch.common import TCPDUMP ########### # Tools # @@ -1581,6 +1582,9 @@ def tcpdump(pktlist, dump=False, getfd=False, args=None, prog = [prog] else: raise ValueError("prog must be a string") + if prog[0] == conf.prog.tcpdump and not TCPDUMP: + message = "tcpdump is not available. Cannot use tcpdump() !" + raise Scapy_Exception(message) if linktype is not None: # Tcpdump does not support integers in -y (yet) diff --git a/test/regression.uts b/test/regression.uts index f88b14f0b44..539cb6b228d 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -6688,6 +6688,26 @@ fdesc.close() assert list(pktpcap[TCP]) == list(pktpcap_tcp) os.unlink(filename) += Check offline sniff() without a tcpdump binary +~ tcpdump +import mock + +conf_prog_tcpdump = conf.prog.tcpdump +conf.prog.tcpdump = "tcpdump_fake" + +from scapy.arch.common import _check_tcpdump + +@mock.patch("scapy.sendrecv.TCPDUMP", _check_tcpdump()) +def _test_sniff_notcpdump(): + try: + sniff(offline="fake.pcap", filter="tcp") + assert False + except Scapy_Exception: + assert True + +_test_sniff_notcpdump() +conf.prog.tcpdump = conf_prog_tcpdump + = Check wrpcap(nano=True) fdesc, filename = tempfile.mkstemp() fdesc = os.fdopen(fdesc, "wb") @@ -6774,6 +6794,7 @@ assert r.linktype == DLT_EN10MB = Check tcpdump() ~ tcpdump +from io import BytesIO * No very specific tests because we do not want to depend on tcpdump output pcapfile = BytesIO(b'\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00e\x00\x00\x00\xcf\xc5\xacVo*\n\x00(\x00\x00\x00(\x00\x00\x00E\x00\x00(\x00\x01\x00\x00@\x06|\xcd\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91|\x00\x00\xcf\xc5\xacV_-\n\x00\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x11|\xce\x7f\x00\x00\x01\x7f\x00\x00\x01\x005\x005\x00\x08\x01r\xcf\xc5\xacV\xf90\n\x00\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x01|\xde\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x00\xf7\xff\x00\x00\x00\x00') data = tcpdump(pcapfile, dump=True, args=['-nn']).split(b'\n') @@ -6782,6 +6803,26 @@ assert b'IP 127.0.0.1.20 > 127.0.0.1.80:' in data[0] assert b'IP 127.0.0.1.53 > 127.0.0.1.53:' in data[1] assert b'IP 127.0.0.1 > 127.0.0.1:' in data[2] +* Non existing tcpdump binary + +import mock + +conf_prog_tcpdump = conf.prog.tcpdump +conf.prog.tcpdump = "tcpdump_fake" + +from scapy.arch.common import _check_tcpdump + +@mock.patch("scapy.utils.TCPDUMP", _check_tcpdump()) +def _test_tcpdump_notcpdump(): + try: + tcpdump(IP()/TCP()) + assert False + except Scapy_Exception: + assert True + +_test_tcpdump_notcpdump() +conf.prog.tcpdump = conf_prog_tcpdump + # Also check with use_tempfile=True (for non-OSX platforms) pcapfile.seek(0) or None tempfile_count = len(conf.temp_files)