From c569826ff1ced6a664737416aa34f27566391fa2 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 4 Oct 2021 16:22:12 -0400 Subject: [PATCH] Improve scan result with missing neigh entries If no neigh table is present for a given address, send a packet to induce kernel activity. Then wait for a bit over 2 seconds to allow for 2 retries (at default settings) and then proceed assuming all findable neighbor table entries will be found. --- .../confluent/discovery/protocols/slp.py | 29 ++++++++++++++----- .../confluent/discovery/protocols/ssdp.py | 11 +++---- confluent_server/confluent/neighutil.py | 2 ++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/confluent_server/confluent/discovery/protocols/slp.py b/confluent_server/confluent/discovery/protocols/slp.py index 1fc92558..2a049674 100644 --- a/confluent_server/confluent/discovery/protocols/slp.py +++ b/confluent_server/confluent/discovery/protocols/slp.py @@ -104,8 +104,6 @@ def _parse_slp_packet(packet, peer, rsps, xidmap): if not parsed: return addr = peer[0] - if '%' in addr: - addr = addr[:addr.index('%')] mac = neighutil.get_hwaddr(addr) if mac: identifier = mac @@ -413,8 +411,7 @@ def rescan(handler): for addr in scanned['addresses']: if addr in known_peers: break - ip = addr[0].partition('%')[0] # discard scope if present - macaddr = neighutil.get_hwaddr(ip) + macaddr = neighutil.get_hwaddr(addr[0]) if not macaddr: continue known_peers.add(addr) @@ -478,10 +475,9 @@ def snoop(handler, protocol=None): while r: for s in r: (rsp, peer) = s.recvfrom(9000) - ip = peer[0].partition('%')[0] if peer in known_peers: continue - mac = neighutil.get_hwaddr(ip) + mac = neighutil.get_hwaddr(peer[0]) if not mac: continue known_peers.add(peer) @@ -534,14 +530,31 @@ def snoop(handler, protocol=None): def active_scan(handler, protocol=None): known_peers = set([]) + net4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + net6 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + toprocess = [] + # Implement a warmup, inducing neighbor table activity + # by kernel and giving 2 seconds for a retry or two if + # needed for scanned in scan(): + toprocess.append(scanned) + for addr in scanned['addresses']: + macaddr = neighutil.get_hwaddr(addr[0]) + if not macaddr: + if ':' in addr[0]: + net6.sendto(b'\x00', (addr[0], 8989)) + else: + net4.sendto(b'\x00', (addr[0], 8989)) + eventlet.sleep(2.2) + for scanned in toprocess: for addr in scanned['addresses']: if addr in known_peers: break - ip = addr[0].partition('%')[0] # discard scope if present - macaddr = neighutil.get_hwaddr(ip) + macaddr = neighutil.get_hwaddr(addr[0]) if not macaddr: continue + if not scanned.get('hwaddr', None): + scanned['hwaddr'] = macaddr known_peers.add(addr) else: scanned['protocol'] = protocol diff --git a/confluent_server/confluent/discovery/protocols/ssdp.py b/confluent_server/confluent/discovery/protocols/ssdp.py index 2f6aa822..d9e5e13d 100644 --- a/confluent_server/confluent/discovery/protocols/ssdp.py +++ b/confluent_server/confluent/discovery/protocols/ssdp.py @@ -63,8 +63,7 @@ def active_scan(handler, protocol=None): for addr in scanned['addresses']: if addr in known_peers: break - ip = addr[0].partition('%')[0] # discard scope if present - hwaddr = neighutil.get_hwaddr(ip) + hwaddr = neighutil.get_hwaddr(addr[0]) if not hwaddr: continue known_peers.add(addr) @@ -130,10 +129,9 @@ def snoop(handler, byehandler=None, protocol=None, uuidlookup=None): rsp = rsp.split(b'\r\n') method, _, _ = rsp[0].split(b' ', 2) if method == b'NOTIFY': - ip = peer[0].partition('%')[0] if peer in known_peers: continue - mac = neighutil.get_hwaddr(ip) + mac = neighutil.get_hwaddr(peer[0]) if not mac: continue known_peers.add(peer) @@ -309,10 +307,9 @@ def check_cpstorage(urldata): def _parse_ssdp(peer, rsp, peerdata): - ip = peer[0].partition('%')[0] - nid = ip + nid = peer[0] mac = None - mac = neighutil.get_hwaddr(ip) + mac = neighutil.get_hwaddr(peer[0]) if mac: nid = mac headlines = rsp.split(b'\r\n') diff --git a/confluent_server/confluent/neighutil.py b/confluent_server/confluent/neighutil.py index ded62ea3..72f1106c 100644 --- a/confluent_server/confluent/neighutil.py +++ b/confluent_server/confluent/neighutil.py @@ -76,6 +76,8 @@ def _update_neigh(): def get_hwaddr(ipaddr): + if '%' in ipaddr: + ipaddr, _ = ipaddr.split('%', 1) hwaddr = None if os.name == 'nt': return hwaddr