Skip to content

Commit 55d7120

Browse files
gpotter2guedou
authored andcommitted
Support terminal title (#1193)
* Support terminal title * Docstring
1 parent 71ac357 commit 55d7120

2 files changed

Lines changed: 34 additions & 14 deletions

File tree

scapy/arch/windows/__init__.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import os, re, sys, socket, time, itertools, platform
1313
import subprocess as sp
1414
from glob import glob
15-
import tempfile
15+
import ctypes, tempfile
1616
from threading import Thread, Event
1717

1818
import scapy
@@ -76,6 +76,13 @@ def _encapsulate_admin(cmd):
7676
# rights, which will execute the command
7777
return "Start-Process PowerShell -windowstyle hidden -Wait -Verb RunAs -ArgumentList '-command &{%s}'" % cmd
7878

79+
def _windows_title(title=None):
80+
"""Updates the terminal title with the default one or with `title`
81+
if provided."""
82+
if conf.interactive:
83+
title = title or "Scapy v" + conf.version
84+
ctypes.windll.kernel32.SetConsoleTitleW(title)
85+
7986
def _suppress_file_handles_inheritance(r=100):
8087
"""HACK: python 2.7 file descriptors.
8188
@@ -135,6 +142,7 @@ def __init__(self):
135142
self.query(["echo @off"]) # Remove header
136143
else:
137144
self.query(["$FormatEnumerationLimit=-1"]) # Do not crop long IP lists
145+
_windows_title() # Reset terminal title
138146

139147
def run(self):
140148
while self.running:
@@ -144,7 +152,7 @@ def run(self):
144152
else:
145153
self.buffer.append(read_line.decode("utf8", "ignore") if six.PY3 else read_line)
146154

147-
def query(self, command):
155+
def query(self, command, crp=True, rst_t=False):
148156
self.query_complete.clear()
149157
if not self.running:
150158
self.__init__(self)
@@ -155,7 +163,9 @@ def query(self, command):
155163
self.process.stdin.write(query.encode())
156164
self.process.stdin.flush()
157165
self.query_complete.wait()
158-
return self.buffer[1:] # Crops first line: the command
166+
if rst_t:
167+
_windows_title()
168+
return self.buffer[crp:] # Crops first line: the command
159169

160170
def close(self):
161171
self.running = False
@@ -209,6 +219,7 @@ def _vbs_exec_code(code, split_tag="@"):
209219
for l in data:
210220
yield l
211221
os.unlink(tmpfile.name)
222+
_windows_title()
212223

213224
def _get_hardware_iface_guid(devid):
214225
"""
@@ -389,6 +400,7 @@ def test_windump_npcap():
389400
try:
390401
p_test_windump = sp.Popen([conf.prog.tcpdump, "-help"], stdout=sp.PIPE, stderr=sp.STDOUT)
391402
stdout, err = p_test_windump.communicate()
403+
_windows_title()
392404
_output = stdout.lower()
393405
return b"npcap" in _output and not b"winpcap" in _output
394406
except:
@@ -538,7 +550,7 @@ def mode(self):
538550
"""Get the interface operation mode.
539551
Only available with Npcap."""
540552
self._check_npcap_requirement()
541-
return plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "mode"], stdout=sp.PIPE).communicate()[0].strip())
553+
return POWERSHELL_PROCESS.query([_WlanHelper, self.guid[1:-1], "mode"], crp=False, rst_t=True)[0].strip()
542554

543555
def ismonitor(self):
544556
"""Returns True if the interface is in monitor mode.
@@ -561,7 +573,7 @@ def availablemodes(self):
561573
Only available with Npcap."""
562574
# According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11
563575
self._check_npcap_requirement()
564-
return plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "modes"], stdout=sp.PIPE).communicate()[0].strip()).split(",")
576+
return POWERSHELL_PROCESS.query([_WlanHelper, self.guid[1:-1], "modes"], crp=False, rst_t=True)[0].split(",")
565577

566578
def setmode(self, mode):
567579
"""Set the interface mode. It can be:
@@ -583,51 +595,54 @@ def setmode(self, mode):
583595
5: "wfd_client"
584596
}
585597
m = _modes.get(mode, "unknown") if isinstance(mode, int) else mode
586-
return not POWERSHELL_PROCESS.query([_encapsulate_admin(_WlanHelper + " " + self.guid[1:-1] + " mode " + m)])
598+
return not POWERSHELL_PROCESS.query([_encapsulate_admin(_WlanHelper + " " + self.guid[1:-1] + " mode " + m)], rst_t=True)
587599

588600
def channel(self):
589601
"""Get the channel of the interface.
590602
Only available with Npcap."""
591603
# According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11
592604
self._check_npcap_requirement()
593-
x = plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "channel"],
594-
stdout=sp.PIPE).communicate()[0].strip())
605+
x = POWERSHELL_PROCESS.query([_WlanHelper, self.guid[1:-1], "channel"],
606+
crp=False)[0].strip()
595607
return int(x)
596608

597609
def setchannel(self, channel):
598610
"""Set the channel of the interface (1-14):
599611
Only available with Npcap."""
600612
# According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11
601613
self._check_npcap_requirement()
602-
return not POWERSHELL_PROCESS.query([_encapsulate_admin(_WlanHelper + " " + self.guid[1:-1] + " channel " + str(channel))])
614+
return not POWERSHELL_PROCESS.query([_encapsulate_admin(_WlanHelper + " " + self.guid[1:-1] + " channel " + str(channel))],
615+
rst_t=True)
603616

604617
def frequence(self):
605618
"""Get the frequence of the interface.
606619
Only available with Npcap."""
607620
# According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11
608621
self._check_npcap_requirement()
609-
return plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "freq"], stdout=sp.PIPE).communicate()[0].strip())
622+
x = POWERSHELL_PROCESS.query([_WlanHelper, self.guid[1:-1], "freq"], crp=False, rst_t=True)[0].strip()
623+
return int(x)
610624

611625
def setfrequence(self, freq):
612626
"""Set the channel of the interface (1-14):
613627
Only available with Npcap."""
614628
# According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11
615629
self._check_npcap_requirement()
616-
return not POWERSHELL_PROCESS.query([_encapsulate_admin(_WlanHelper + " " + self.guid[1:-1] + " freq " + str(freq))])
630+
return not POWERSHELL_PROCESS.query([_encapsulate_admin(_WlanHelper + " " + self.guid[1:-1] + " freq " + str(freq))],
631+
rst_t=True)
617632

618633
def availablemodulations(self):
619634
"""Get all available 802.11 interface modulations.
620635
Only available with Npcap."""
621636
# According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11
622637
self._check_npcap_requirement()
623-
return plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "modus"], stdout=sp.PIPE).communicate()[0].strip()).split(",")
638+
return POWERSHELL_PROCESS.query([_WlanHelper, self.guid[1:-1], "modus"], crp=False, rst_t=True)[0].strip().split(",")
624639

625640
def modulation(self):
626641
"""Get the 802.11 modulation of the interface.
627642
Only available with Npcap."""
628643
# According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11
629644
self._check_npcap_requirement()
630-
return plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "modu"], stdout=sp.PIPE).communicate()[0].strip())
645+
return POWERSHELL_PROCESS.query([_WlanHelper, self.guid[1:-1], "modu"], crp=False, rst_t=True)[0].strip()
631646

632647
def setmodulation(self, modu):
633648
"""Set the interface modulation. It can be:
@@ -659,7 +674,8 @@ def setmodulation(self, modu):
659674
10: "mimo-ofdm",
660675
}
661676
m = _modus.get(modu, "unknown") if isinstance(modu, int) else modu
662-
return not POWERSHELL_PROCESS.query([_encapsulate_admin(_WlanHelper + " " + self.guid[1:-1] + " mode " + m)])
677+
return not POWERSHELL_PROCESS.query([_encapsulate_admin(_WlanHelper + " " + self.guid[1:-1] + " mode " + m)],
678+
rst_t=True)
663679

664680
def __repr__(self):
665681
return "<%s %s %s>" % (self.__class__.__name__, self.name, self.guid)

scapy/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,10 @@ def interact(mydict=None,argv=None,mybanner=None,loglevel=20):
524524
apply_ipython_style(shell=cfg.TerminalInteractiveShell)
525525
cfg.TerminalInteractiveShell.confirm_exit = False
526526
cfg.TerminalInteractiveShell.separate_in = u''
527+
if int(IPython.__version__[0]) >= 6:
528+
cfg.TerminalInteractiveShell.term_title_format = "Scapy v" + conf.version
529+
else:
530+
cfg.TerminalInteractiveShell.term_title = False
527531
cfg.HistoryAccessor.hist_file = conf.histfile
528532
cfg.InteractiveShell.banner1 = banner
529533
# configuration can thus be specified here.

0 commit comments

Comments
 (0)