From eec0a2ce6380687b1c3414e0eb430177afee09fe Mon Sep 17 00:00:00 2001 From: gpotter2 <10530980+gpotter2@users.noreply.github.com> Date: Sun, 9 Jul 2023 19:36:09 +0200 Subject: [PATCH 1/6] Scapy terminal improvements This commit changes the following: - .scapy_startup.py and .scapy_prestart.py are moved to .config/scapy/startup.py and .config/scapy/prestart.py - the Scapy terminal now supports ptpython and bpython, in addition to the existing IPython --- doc/scapy.1 | 8 +- scapy/config.py | 5 +- scapy/main.py | 260 +++++++++++++++++++++++++++++++++++++------- test/regression.uts | 55 ++++++++++ 4 files changed, 281 insertions(+), 47 deletions(-) diff --git a/doc/scapy.1 b/doc/scapy.1 index a58643d63c2..6981fdd692a 100644 --- a/doc/scapy.1 +++ b/doc/scapy.1 @@ -51,13 +51,13 @@ increase log verbosity. Can be used many times. use FILE to save/load session values (variables, functions, instances, ...) .TP \fB\-p\fR PRESTART_FILE -use PRESTART_FILE instead of $HOME/.scapy_prestart.py as pre-startup file +use PRESTART_FILE instead of $HOME/.config/scapy/prestart.py as pre-startup file .TP \fB\-P\fR do not run prestart file .TP \fB\-c\fR STARTUP_FILE -use STARTUP_FILE instead of $HOME/.scapy_startup.py as startup file +use STARTUP_FILE instead of $HOME/.config/scapy/startup.py as startup file .TP \fB\-C\fR do not run startup file @@ -82,7 +82,7 @@ lists scapy's main user commands. this object contains the configuration. .SH FILES -\fB$HOME/.scapy_prestart.py\fR +\fB$HOME/.config/scapy/prestart.py\fR This file is run before Scapy core is loaded. Only the \fBconf\fP object is available. This file can be used to manipulate \fBconf.load_layers\fP list to choose which layers will be loaded: @@ -92,7 +92,7 @@ conf.load_layers.remove("bluetooth") conf.load_layers.append("new_layer") .fi -\fB$HOME/.scapy_startup.py\fR +\fB$HOME/.config/scapy/startup.py\fR This file is run after Scapy is loaded. It can be used to configure some of the Scapy behaviors: diff --git a/scapy/config.py b/scapy/config.py index a3a79e87ed4..2bcbcced91a 100755 --- a/scapy/config.py +++ b/scapy/config.py @@ -726,8 +726,9 @@ class Conf(ConfClass): version = ReadOnlyAttribute("version", VERSION) session = "" #: filename where the session will be saved interactive = False - #: can be "ipython", "python" or "auto". Default: Auto - interactive_shell = "" + #: can be "ipython", "bpython", "ptpython", "ptipython", "python" or "auto". + #: Default: Auto + interactive_shell = "auto" #: if 1, prevents any unwanted packet to go out (ARP, DNS, ...) stealth = "not implemented" #: selects the default output interface for srp() and sendp(). diff --git a/scapy/main.py b/scapy/main.py index 25860a941a0..8e81ff944a6 100644 --- a/scapy/main.py +++ b/scapy/main.py @@ -9,6 +9,7 @@ import builtins +import pathlib import sys import os import getopt @@ -40,6 +41,10 @@ List, Optional, Union, + overload, +) +from scapy.compat import ( + Literal, ) LAYER_ALIASES = { @@ -59,15 +64,22 @@ ] -def _probe_config_file(cf): - # type: (str) -> Union[str, None] - cf_path = os.path.join(os.path.expanduser("~"), cf) - try: - os.stat(cf_path) - except OSError: +def _probe_config_file(*cf, default=None): + # type: (str, Optional[str]) -> Union[str, None] + path = pathlib.Path(os.path.expanduser("~")) + if not path.exists(): + # ~ folder doesn't exist. Unsalvageable return None - else: - return cf_path + cf_path = path.joinpath(*cf) + if not cf_path.exists(): + if default is not None: + # We have a default ! set it + cf_path.parent.mkdir(parents=True, exist_ok=True) + with cf_path.open("w") as fd: + fd.write(default) + return str(cf_path.resolve()) + return None + return str(cf_path.resolve()) def _read_config_file(cf, _globals=globals(), _locals=locals(), @@ -119,8 +131,23 @@ def _validate_local(k): return k[0] != "_" and k not in ["range", "map"] -DEFAULT_PRESTART_FILE = _probe_config_file(".scapy_prestart.py") -DEFAULT_STARTUP_FILE = _probe_config_file(".scapy_startup.py") +# Default scapy prestart.py config file + +DEFAULT_PRESTART = """ +# Scapy pre-start config file +# see https://scapy.readthedocs.io/en/latest/api/scapy.config.html#scapy.config.Conf +# for all available options + +# default interpreter +conf.interactive_shell = "auto" + +# color theme +conf.color_theme = DefaultTheme() +""".strip() + +DEFAULT_PRESTART_FILE = _probe_config_file(".config", "scapy", "prestart.py", + default=DEFAULT_PRESTART) +DEFAULT_STARTUP_FILE = _probe_config_file(".config", "scapy", "startup.py") def _usage(): @@ -299,6 +326,16 @@ def update_ipython_session(session): pass +def _scapy_prestart_builtins(): + # type: () -> Dict[str, Any] + """Load Scapy prestart and return all builtins""" + return { + k: v + for k, v in importlib.import_module(".config", "scapy").__dict__.copy().items() + if _validate_local(k) + } + + def _scapy_builtins(): # type: () -> Dict[str, Any] """Load Scapy and return all builtins""" @@ -412,11 +449,29 @@ def update_session(fname=None): update_ipython_session(scapy_session) +@overload +def init_session(session_name, # type: Optional[Union[str, None]] + mydict, # type: Optional[Union[Dict[str, Any], None]] + ret, # type: Literal[True] + ): + # type: (...) -> Dict[str, Any] + pass + + +@overload +def init_session(session_name, # type: Optional[Union[str, None]] + mydict=None, # type: Optional[Union[Dict[str, Any], None]] + ret=False, # type: Literal[False] + ): + # type: (...) -> None + pass + + def init_session(session_name, # type: Optional[Union[str, None]] mydict=None, # type: Optional[Union[Dict[str, Any], None]] ret=False, # type: bool ): - # type: (...) -> Optional[Dict[str, Any]] + # type: (...) -> Union[Dict[str, Any], None] from scapy.config import conf SESSION = {} # type: Optional[Dict[str, Any]] @@ -557,34 +612,21 @@ def interact(mydict=None, argv=None, mybanner=None, loglevel=logging.INFO): # Reset sys.argv, otherwise IPython thinks it is for him sys.argv = sys.argv[:1] + if PRESTART_FILE: + _read_config_file( + PRESTART_FILE, + interactive=True, + _locals=_scapy_prestart_builtins() + ) + SESSION = init_session(session_name, mydict=mydict, ret=True) if STARTUP_FILE: - _read_config_file(STARTUP_FILE, interactive=True) - if PRESTART_FILE: - _read_config_file(PRESTART_FILE, interactive=True) - - if not conf.interactive_shell or conf.interactive_shell.lower() in [ - "ipython", "auto" - ]: - try: - import IPython - from IPython import start_ipython - except ImportError: - log_loading.warning( - "IPython not available. Using standard Python shell " - "instead.\nAutoCompletion, History are disabled." - ) - if WINDOWS: - log_loading.warning( - "On Windows, colors are also disabled" - ) - conf.color_theme = BlackAndWhite() - IPYTHON = False - else: - IPYTHON = True - else: - IPYTHON = False + _read_config_file( + STARTUP_FILE, + interactive=True, + _locals=SESSION + ) if conf.fancy_prompt: from scapy.utils import get_terminal_width @@ -659,8 +701,110 @@ def interact(mydict=None, argv=None, mybanner=None, loglevel=logging.INFO): banner_text += "\n" banner_text += mybanner - if IPYTHON: - banner = banner_text + " using IPython %s\n" % IPython.__version__ + # Configure interactive terminal + + if conf.interactive_shell not in [ + "ipython", + "python", + "ptpython", + "ptipython", + "bpython", + "auto"]: + log_loading.warning("Unknown conf.interactive_shell ! Using 'auto'") + conf.interactive_shell = "auto" + + # Auto detect available shells. + # Order: + # 1. IPython + # 2. bpython + # 3. ptpython + + if conf.interactive_shell == "auto": + try: + import IPython + conf.interactive_shell = "ipython" + except ImportError: + try: + import bpython + conf.interactive_shell = "bpython" + except ImportError: + try: + import ptpython + conf.interactive_shell = "ptpython" + except ImportError: + log_loading.warning( + "No alternative Python interpreters found ! " + "Using standard Python shell instead." + ) + conf.interactive_shell = "python" + + # Check IPython import + if conf.interactive_shell in ["ipython", "ptipython"]: + try: + import IPython # noqa: F811 + except ImportError: + log_loading.warning("IPython requested but not found !") + conf.interactive_shell = "python" + + # Check bpython import + if conf.interactive_shell == "bpython": + try: + import bpython # noqa: F811 + except ImportError: + log_loading.warning("bpython requested but not found !") + conf.interactive_shell = "python" + + # Check ptpython import + ptpython_configure = lambda repl: None + if conf.interactive_shell in ["ptpython", "ptipython"]: + try: + import ptpython # noqa: F811,F401 + except ImportError: + log_loading.warning("ptpython requested but not found !") + conf.interactive_shell = "python" + + def ptpython_configure(repl): + # type: (Any) -> None + # Hide status bar + repl.show_status_bar = False + # Complete while typing (versus only when pressing tab) + repl.complete_while_typing = False + # Enable auto-suggestions + repl.enable_auto_suggest = True + # Disable exit confirmation + repl.confirm_exit = False + # Show signature + repl.show_signature = True + # Apply Scapy color theme: TODO + # repl.install_ui_colorscheme("scapy", + # Style.from_dict(_custom_ui_colorscheme)) + # repl.use_ui_colorscheme("scapy") + + # Display warning when using the default REPL + if conf.interactive_shell == "python": + log_loading.info( + "When using the default Python shell, AutoCompletion, History are disabled." + ) + if WINDOWS: + log_loading.info( + "On Windows, colors are also disabled" + ) + conf.color_theme = BlackAndWhite() + + # Start IPython or ptipython + if conf.interactive_shell in ["ipython", "ptipython"]: + if conf.interactive_shell == "ptipython": + from ptpython.ipython import embed + banner = banner_text + " using IPython %s" % IPython.__version__ + try: + from importlib.metadata import version + ptpython_version = " " + version('ptpython') + except ImportError: + ptpython_version = "" + banner += " and ptpython%s\n" % ptpython_version + else: + banner = banner_text + " using IPython %s\n" % IPython.__version__ + from IPython import start_ipython as embed try: from traitlets.config.loader import Config except ImportError: @@ -669,7 +813,7 @@ def interact(mydict=None, argv=None, mybanner=None, loglevel=logging.INFO): "available." ) try: - start_ipython( + embed( display_banner=False, user_ns=SESSION, exec_lines=["print(\"\"\"" + banner + "\"\"\")"] @@ -700,12 +844,46 @@ def interact(mydict=None, argv=None, mybanner=None, loglevel=logging.INFO): cfg.HistoryAccessor.hist_file = conf.histfile cfg.InteractiveShell.banner1 = banner # configuration can thus be specified here. + _kwargs = {} + if conf.interactive_shell == "ptipython": + _kwargs["configure"] = ptpython_configure try: - start_ipython(config=cfg, user_ns=SESSION) + embed(config=cfg, user_ns=SESSION, **_kwargs) except (AttributeError, TypeError): code.interact(banner=banner_text, local=SESSION) - else: + # Start ptpython + elif conf.interactive_shell == "ptpython": + log_loading.warning("ptpython support is currently partially broken") + try: + from importlib.metadata import version + ptpython_version = " " + version('ptpython') + except ImportError: + ptpython_version = "" + banner = banner_text + " using ptpython%s\n" % ptpython_version + from ptpython.repl import embed + # ptpython has no banner option + print(banner) + embed( + locals=SESSION, + history_filename=conf.histfile, + title="Scapy %s" % conf.version, + configure=ptpython_configure + ) + # Start bpython + elif conf.interactive_shell == "bpython": + banner = banner_text + " using bpython %s\n" % bpython.__version__ + from bpython.curtsies import main as embed + embed( + args=["-q", "-i"], + locals_=SESSION, + banner=banner, + welcome_message="" + ) + # Start Python + elif conf.interactive_shell == "python": code.interact(banner=banner_text, local=SESSION) + else: + raise ValueError("Invalid conf.interactive_shell") if conf.session: save_session(conf.session, SESSION) diff --git a/test/regression.uts b/test/regression.uts index eb51d61863a..0ba879690aa 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -540,8 +540,19 @@ scapy_delete_temp_files() assert len(conf.temp_files) == 0 = Emulate interact() +~ interact + import mock, sys from scapy.main import interact + +from scapy.main import DEFAULT_PRESTART_FILE +# By now .config/scapy/startup.py should have been created +with open(DEFAULT_PRESTART_FILE, "r") as fd: + OLD_DEFAULT_PRESTART = fd.read() + +with open(DEFAULT_PRESTART_FILE, "w+") as fd: + fd.write("conf.interactive_shell = 'ipython'") + # Detect IPython try: import IPython @@ -568,6 +579,50 @@ except: interact_emulator(extra_args=["-d"]) # Extended += Emulate interact() and test startup.py with ptpython +~ interact + +import sys +import mock + +from scapy.main import DEFAULT_PRESTART_FILE +# By now .config/scapy/startup.py should have been created +with open(DEFAULT_PRESTART_FILE, "w+") as fd: + fd.write("conf.interactive_shell = 'ptpython'") + +called = [] +def checker(*args, **kwargs): + locals = kwargs.pop("locals") + assert locals["IP"] + history_filename = kwargs.pop("history_filename") + assert history_filename == conf.histfile + called.append(True) + +ptpython_mocked_module = Bunch( + repl=Bunch( + embed=checker + ) +) + +modules_patched = { + "ptpython": ptpython_mocked_module, + "ptpython.repl": ptpython_mocked_module.repl, + "ptpython.repl.embed": ptpython_mocked_module.repl.embed, +} + +with mock.patch.dict("sys.modules", modules_patched): + try: + interact() + finally: + sys.ps1 = ">>> " + +# Restore +with open(DEFAULT_PRESTART_FILE, "w") as fd: + print(OLD_DEFAULT_PRESTART) + r = fd.write(OLD_DEFAULT_PRESTART) + +assert called + = Test explore() with GUI mode ~ command From d7abfc8945506ae004862509524c0b291a199c4b Mon Sep 17 00:00:00 2001 From: gpotter2 <10530980+gpotter2@users.noreply.github.com> Date: Tue, 18 Jul 2023 23:22:13 +0200 Subject: [PATCH 2/6] Add conf.ipython_use_jedi --- scapy/config.py | 2 ++ scapy/main.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scapy/config.py b/scapy/config.py index 2bcbcced91a..e69ea2ca9ab 100755 --- a/scapy/config.py +++ b/scapy/config.py @@ -729,6 +729,8 @@ class Conf(ConfClass): #: can be "ipython", "bpython", "ptpython", "ptipython", "python" or "auto". #: Default: Auto interactive_shell = "auto" + #: Configuration for "ipython" to use jedi (disabled by default) + ipython_use_jedi = False #: if 1, prevents any unwanted packet to go out (ARP, DNS, ...) stealth = "not implemented" #: selects the default output interface for srp() and sendp(). diff --git a/scapy/main.py b/scapy/main.py index 8e81ff944a6..e0127507cbd 100644 --- a/scapy/main.py +++ b/scapy/main.py @@ -838,7 +838,9 @@ def ptpython_configure(repl): conf.version) # As of IPython 6-7, the jedi completion module is a dumpster # of fire that should be scrapped never to be seen again. - cfg.Completer.use_jedi = False + # This is why the following defaults to False. Feel free to hurt + # yourself (#GH4056) :P + cfg.Completer.use_jedi = conf.ipython_use_jedi else: cfg.TerminalInteractiveShell.term_title = False cfg.HistoryAccessor.hist_file = conf.histfile From 189a4e3b971b95597c488a54386fc17ad42fb064 Mon Sep 17 00:00:00 2001 From: gpotter2 <10530980+gpotter2@users.noreply.github.com> Date: Fri, 21 Jul 2023 15:26:17 +0000 Subject: [PATCH 3/6] Apply guedou suggestions --- scapy/config.py | 3 +- scapy/main.py | 105 ++++++++++++++++++++++-------------------------- 2 files changed, 51 insertions(+), 57 deletions(-) diff --git a/scapy/config.py b/scapy/config.py index e69ea2ca9ab..c027ebb9b8d 100755 --- a/scapy/config.py +++ b/scapy/config.py @@ -785,7 +785,8 @@ class Conf(ConfClass): #: history file histfile = os.getenv('SCAPY_HISTFILE', os.path.join(os.path.expanduser("~"), - ".scapy_history")) + ".config", "scapy", + "history")) #: includes padding in disassembled packets padding = 1 #: BPF filter for packets to ignore diff --git a/scapy/main.py b/scapy/main.py index e0127507cbd..02fb878f688 100644 --- a/scapy/main.py +++ b/scapy/main.py @@ -719,66 +719,37 @@ def interact(mydict=None, argv=None, mybanner=None, loglevel=logging.INFO): # 2. bpython # 3. ptpython + _IMPORTS = { + "ipython": ["IPython"], + "bpython": ["bpython"], + "ptpython": ["ptpython"], + "ptipython": ["IPython", "ptpython"], + } + if conf.interactive_shell == "auto": - try: - import IPython - conf.interactive_shell = "ipython" - except ImportError: + # Auto detect + for imp in ["IPython", "bpython", "ptpython"]: try: - import bpython - conf.interactive_shell = "bpython" + importlib.import_module(imp) + conf.interactive_shell = imp.lower() + break except ImportError: - try: - import ptpython - conf.interactive_shell = "ptpython" - except ImportError: - log_loading.warning( - "No alternative Python interpreters found ! " - "Using standard Python shell instead." - ) - conf.interactive_shell = "python" - - # Check IPython import - if conf.interactive_shell in ["ipython", "ptipython"]: - try: - import IPython # noqa: F811 - except ImportError: - log_loading.warning("IPython requested but not found !") - conf.interactive_shell = "python" - - # Check bpython import - if conf.interactive_shell == "bpython": - try: - import bpython # noqa: F811 - except ImportError: - log_loading.warning("bpython requested but not found !") - conf.interactive_shell = "python" - - # Check ptpython import - ptpython_configure = lambda repl: None - if conf.interactive_shell in ["ptpython", "ptipython"]: - try: - import ptpython # noqa: F811,F401 - except ImportError: - log_loading.warning("ptpython requested but not found !") + continue + else: + log_loading.warning( + "No alternative Python interpreters found ! " + "Using standard Python shell instead." + ) conf.interactive_shell = "python" - def ptpython_configure(repl): - # type: (Any) -> None - # Hide status bar - repl.show_status_bar = False - # Complete while typing (versus only when pressing tab) - repl.complete_while_typing = False - # Enable auto-suggestions - repl.enable_auto_suggest = True - # Disable exit confirmation - repl.confirm_exit = False - # Show signature - repl.show_signature = True - # Apply Scapy color theme: TODO - # repl.install_ui_colorscheme("scapy", - # Style.from_dict(_custom_ui_colorscheme)) - # repl.use_ui_colorscheme("scapy") + if conf.interactive_shell in _IMPORTS: + # Check import + for imp in _IMPORTS[conf.interactive_shell]: + try: + importlib.import_module(imp) + except ImportError: + log_loading.warning("%s requested but not found !" % imp) + conf.interactive_shell = "python" # Display warning when using the default REPL if conf.interactive_shell == "python": @@ -791,8 +762,27 @@ def ptpython_configure(repl): ) conf.color_theme = BlackAndWhite() + # ptpython configure function + def ptpython_configure(repl): + # type: (Any) -> None + # Hide status bar + repl.show_status_bar = False + # Complete while typing (versus only when pressing tab) + repl.complete_while_typing = False + # Enable auto-suggestions + repl.enable_auto_suggest = True + # Disable exit confirmation + repl.confirm_exit = False + # Show signature + repl.show_signature = True + # Apply Scapy color theme: TODO + # repl.install_ui_colorscheme("scapy", + # Style.from_dict(_custom_ui_colorscheme)) + # repl.use_ui_colorscheme("scapy") + # Start IPython or ptipython if conf.interactive_shell in ["ipython", "ptipython"]: + import IPython if conf.interactive_shell == "ptipython": from ptpython.ipython import embed banner = banner_text + " using IPython %s" % IPython.__version__ @@ -855,6 +845,8 @@ def ptpython_configure(repl): code.interact(banner=banner_text, local=SESSION) # Start ptpython elif conf.interactive_shell == "ptpython": + # ptpython has special, non-default handling of __repr__ which breaks Scapy. + # For instance: >>> IP() log_loading.warning("ptpython support is currently partially broken") try: from importlib.metadata import version @@ -873,8 +865,9 @@ def ptpython_configure(repl): ) # Start bpython elif conf.interactive_shell == "bpython": - banner = banner_text + " using bpython %s\n" % bpython.__version__ + import bpython from bpython.curtsies import main as embed + banner = banner_text + " using bpython %s\n" % bpython.__version__ embed( args=["-q", "-i"], locals_=SESSION, From a24252eba8342108bcaed2d3495de90e0be7ca27 Mon Sep 17 00:00:00 2001 From: gpotter2 <10530980+gpotter2@users.noreply.github.com> Date: Sat, 22 Jul 2023 17:37:23 +0200 Subject: [PATCH 4/6] Rename fancy_prompt to fancy_banner --- scapy/config.py | 5 ++++- scapy/main.py | 13 ++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/scapy/config.py b/scapy/config.py index c027ebb9b8d..2f600ff3eac 100755 --- a/scapy/config.py +++ b/scapy/config.py @@ -904,7 +904,10 @@ class Conf(ConfClass): contribs = dict() # type: Dict[str, Any] crypto_valid = isCryptographyValid() crypto_valid_advanced = isCryptographyAdvanced() - fancy_prompt = True + #: controls whether or not to display the fancy banner + fancy_banner = True + #: controls whether tables (conf.iface, conf.route...) should be cropped + #: to fit the terminal auto_crop_tables = True #: how often to check for new packets. #: Defaults to 0.05s. diff --git a/scapy/main.py b/scapy/main.py index 02fb878f688..acec404bb73 100644 --- a/scapy/main.py +++ b/scapy/main.py @@ -143,6 +143,9 @@ def _validate_local(k): # color theme conf.color_theme = DefaultTheme() + +# force-use libpcap +# conf.use_pcap = True """.strip() DEFAULT_PRESTART_FILE = _probe_config_file(".config", "scapy", "prestart.py", @@ -531,7 +534,7 @@ def init_session(session_name, # type: Optional[Union[str, None]] def _prepare_quote(quote, author, max_len=78): # type: (str, str, int) -> List[str] """This function processes a quote and returns a string that is ready -to be used in the fancy prompt. +to be used in the fancy banner. """ _quote = quote.split(' ') @@ -584,7 +587,7 @@ def interact(mydict=None, argv=None, mybanner=None, loglevel=logging.INFO): if opt == "-h": _usage() elif opt == "-H": - conf.fancy_prompt = False + conf.fancy_banner = False conf.verb = 1 conf.logLevel = logging.WARNING elif opt == "-s": @@ -628,7 +631,7 @@ def interact(mydict=None, argv=None, mybanner=None, loglevel=logging.INFO): _locals=SESSION ) - if conf.fancy_prompt: + if conf.fancy_banner: from scapy.utils import get_terminal_width mini_banner = (get_terminal_width() or 84) <= 75 @@ -853,7 +856,7 @@ def ptpython_configure(repl): ptpython_version = " " + version('ptpython') except ImportError: ptpython_version = "" - banner = banner_text + " using ptpython%s\n" % ptpython_version + banner = banner_text + " using ptpython%s" % ptpython_version from ptpython.repl import embed # ptpython has no banner option print(banner) @@ -867,7 +870,7 @@ def ptpython_configure(repl): elif conf.interactive_shell == "bpython": import bpython from bpython.curtsies import main as embed - banner = banner_text + " using bpython %s\n" % bpython.__version__ + banner = banner_text + " using bpython %s" % bpython.__version__ embed( args=["-q", "-i"], locals_=SESSION, From 74f12f35a23f07c28d6dc75a9e7dfb433be8ef15 Mon Sep 17 00:00:00 2001 From: gpotter2 <10530980+gpotter2@users.noreply.github.com> Date: Sat, 22 Jul 2023 18:03:53 +0200 Subject: [PATCH 5/6] Minor documentation tweaks --- .../animation-scapy-themes-demo.gif | Bin 41319 -> 0 bytes doc/scapy/usage.rst | 19 +----------------- scapy/main.py | 2 +- 3 files changed, 2 insertions(+), 19 deletions(-) delete mode 100755 doc/scapy/graphics/animations/animation-scapy-themes-demo.gif diff --git a/doc/scapy/graphics/animations/animation-scapy-themes-demo.gif b/doc/scapy/graphics/animations/animation-scapy-themes-demo.gif deleted file mode 100755 index 5a7a8331db88adbd91069dfb7990e39610067b77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41319 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 ZVTov7Hrg{blN0(l5#{V|0c Date: Sat, 29 Jul 2023 11:26:41 +0200 Subject: [PATCH 6/6] Add another common setting --- scapy/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scapy/main.py b/scapy/main.py index 6a88f9f37dd..464e125e965 100644 --- a/scapy/main.py +++ b/scapy/main.py @@ -134,7 +134,7 @@ def _validate_local(k): # Default scapy prestart.py config file DEFAULT_PRESTART = """ -# Scapy pre-start config file +# Scapy CLI 'pre-start' config file # see https://scapy.readthedocs.io/en/latest/api/scapy.config.html#scapy.config.Conf # for all available options @@ -144,6 +144,9 @@ def _validate_local(k): # color theme (DefaultTheme, BrightTheme, ColorOnBlackTheme, BlackAndWhite, ...) conf.color_theme = DefaultTheme() +# disable INFO: tags related to dependencies missing +# log_loading.setLevel(logging.WARNING) + # force-use libpcap # conf.use_pcap = True """.strip()