[scanner] add minimal error handling, consolidate CLI args processing
This commit is contained in:
parent
acf9bf91f1
commit
a4464209b6
3 changed files with 37 additions and 63 deletions
|
@ -492,12 +492,16 @@ def get_parsers():
|
|||
help='Try to configure detected hosts')
|
||||
parser['scan'].add_argument(
|
||||
'-I', '--interfaces',
|
||||
action='append', default=[],
|
||||
action='append', default=[], required=True,
|
||||
help='On which interfaces to scan/trigger')
|
||||
parser['scan'].add_argument(
|
||||
'-d', '--delay',
|
||||
action='store', default=3600,
|
||||
help='How long to wait before reconfiguring after last try')
|
||||
action='store', default=3600, type=int,
|
||||
help='How long (seconds) to wait before reconfiguring after last try')
|
||||
parser['scan'].add_argument(
|
||||
'-t', '--trigger-delay',
|
||||
action='store', default=5, type=int,
|
||||
help='How long (seconds) to wait between ICMPv6 echo requests')
|
||||
parser['scan'].set_defaults(func=cdist.scan.commandline.commandline)
|
||||
|
||||
for p in parser:
|
||||
|
|
|
@ -24,26 +24,29 @@ import sys
|
|||
|
||||
log = logging.getLogger("scan")
|
||||
|
||||
|
||||
# define this outside of the class to not handle scapy import errors by default
|
||||
# CLI processing is defined outside of the main scan class to handle
|
||||
# non-available optional scapy dependency (instead of crashing mid-flight).
|
||||
def commandline(args):
|
||||
log.debug(args)
|
||||
|
||||
# Check if we have the optional scapy dependency available.
|
||||
try:
|
||||
import cdist.scan.scan as scan
|
||||
except ModuleNotFoundError:
|
||||
print('cdist scan requires scapy to be installed! Exiting.',
|
||||
file=sys.stderr)
|
||||
log.error('cdist scan requires scapy to be installed. Exiting.')
|
||||
sys.exit(1)
|
||||
|
||||
processes = []
|
||||
|
||||
# Default operation mode.
|
||||
if not args.mode:
|
||||
# By default scan and trigger, but do not call any action
|
||||
# By default scan and trigger, but do not call any action.
|
||||
args.mode = ['scan', 'trigger', ]
|
||||
|
||||
# We run each component in a separate process since they
|
||||
# must not block on each other.
|
||||
processes = []
|
||||
|
||||
if 'trigger' in args.mode:
|
||||
t = scan.Trigger(interfaces=args.interfaces)
|
||||
t = scan.Trigger(interfaces=args.interfaces, sleeptime=args.trigger_delay)
|
||||
t.start()
|
||||
processes.append(t)
|
||||
log.debug("Trigger started")
|
||||
|
|
|
@ -61,20 +61,22 @@ import datetime
|
|||
|
||||
import cdist.config
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
log = logging.getLogger("scan")
|
||||
|
||||
|
||||
class Trigger(object):
|
||||
"""
|
||||
Trigger an ICMPv6EchoReply from all hosts that are alive
|
||||
"""
|
||||
|
||||
def __init__(self, interfaces=None, verbose=False):
|
||||
def __init__(self, interfaces, sleeptime, verbose=False):
|
||||
self.interfaces = interfaces
|
||||
|
||||
# Used by scapy / send in trigger/2.
|
||||
self.verbose = verbose
|
||||
|
||||
# Wait 5 seconds before triggering again - FIXME: add parameter
|
||||
self.sleeptime = 5
|
||||
# Delay in seconds between sent ICMPv6EchoRequests.
|
||||
self.sleeptime = sleeptime
|
||||
|
||||
def start(self):
|
||||
self.processes = []
|
||||
|
@ -93,9 +95,12 @@ class Trigger(object):
|
|||
time.sleep(self.sleeptime)
|
||||
|
||||
def trigger(self, interface):
|
||||
packet = IPv6(dst="ff02::1{}".format(interface)) / ICMPv6EchoRequest()
|
||||
log.debug("Sending request on %s", interface)
|
||||
try:
|
||||
log.debug("Sending ICMPv6EchoRequest on %s", interface)
|
||||
packet = IPv6(dst="ff02::1%{}".format(interface)) / ICMPv6EchoRequest()
|
||||
send(packet, verbose=self.verbose)
|
||||
except Exception as e:
|
||||
log.error( "Could not send ICMPv6EchoRequest: %s", e)
|
||||
|
||||
|
||||
class Scanner(object):
|
||||
|
@ -103,7 +108,7 @@ class Scanner(object):
|
|||
Scan for replies of hosts, maintain the up-to-date database
|
||||
"""
|
||||
|
||||
def __init__(self, interfaces=None, args=None, outdir=None):
|
||||
def __init__(self, interfaces, args=None, outdir=None):
|
||||
self.interfaces = interfaces
|
||||
|
||||
if outdir:
|
||||
|
@ -148,47 +153,9 @@ class Scanner(object):
|
|||
|
||||
def scan(self):
|
||||
log.debug("Scanning - zzzzz")
|
||||
try:
|
||||
sniff(iface=self.interfaces,
|
||||
filter="icmp6",
|
||||
prn=self.handle_pkg)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
t = Trigger(interfaces=["wlan0"])
|
||||
t.start()
|
||||
|
||||
# Scanner can listen on many interfaces at the same time
|
||||
s = Scanner(interfaces=["wlan0"])
|
||||
s.scan()
|
||||
|
||||
# Join back the trigger processes
|
||||
t.join()
|
||||
|
||||
# Test in my lan shows:
|
||||
# [18:48] bridge:cdist% ls -1d fe80::*
|
||||
# fe80::142d:f0a5:725b:1103
|
||||
# fe80::20d:b9ff:fe49:ac11
|
||||
# fe80::20d:b9ff:fe4c:547d
|
||||
# fe80::219:d2ff:feb2:2e12
|
||||
# fe80::21b:fcff:feee:f446
|
||||
# fe80::21b:fcff:feee:f45c
|
||||
# fe80::21b:fcff:feee:f4b1
|
||||
# fe80::21b:fcff:feee:f4ba
|
||||
# fe80::21b:fcff:feee:f4bc
|
||||
# fe80::21b:fcff:feee:f4c1
|
||||
# fe80::21d:72ff:fe86:46b
|
||||
# fe80::42b0:34ff:fe6f:f6f0
|
||||
# fe80::42b0:34ff:fe6f:f863
|
||||
# fe80::42b0:34ff:fe6f:f9b2
|
||||
# fe80::4a5d:60ff:fea1:e55f
|
||||
# fe80::77a3:5e3f:82cc:f2e5
|
||||
# fe80::9e93:4eff:fe6c:c1f4
|
||||
# fe80::ba69:f4ff:fec5:6041
|
||||
# fe80::ba69:f4ff:fec5:8db7
|
||||
# fe80::bad8:12ff:fe65:313d
|
||||
# fe80::bad8:12ff:fe65:d9b1
|
||||
# fe80::ce2d:e0ff:fed4:2611
|
||||
# fe80::ce32:e5ff:fe79:7ea7
|
||||
# fe80::d66d:6dff:fe33:e00
|
||||
# fe80::e2ff:f7ff:fe00:20e6
|
||||
# fe80::f29f:c2ff:fe7c:275e
|
||||
except Exception as e:
|
||||
log.error( "Could not start listener: %s", e)
|
||||
|
|
Loading…
Reference in a new issue