MCPcopy Create free account
hub / github.com/PierreGode/Ragnar / _parse_poe

Function _parse_poe

network_diagnostics.py:328–396  ·  view source on GitHub ↗

Extract Power-over-Ethernet state from an lldpctl port's Power-via-MDI TLV (dot3 / LLDP-MED). A PoE-capable switch advertises this, so it tells us whether the port supplies power and at what class/wattage. Returns None when the neighbour advertised no power TLV.

(port)

Source from the content-addressed store, hash-verified

326
327 The only trustworthy 'can it reach the internet' signal we can get without
328 sending traffic. NOT `ip route get <ip> oif <iface>`: forcing oif makes the
329 kernel synthesize an answer for an interface that has no route at all (it
330 will happily report a route out of an address-less eth0, borrowing another
331 interface&#x27;s src), so that check silently passes for exactly the interfaces
332 we need to exclude."""
333 res = _run(['ip', 'route', 'show', 'default', 'dev', iface], timeout=5)
334 return res['rc'] == 0 and bool(res['out'].strip())
335
336
337def _iface_default_gateway(iface):
338 """The gateway of this interface&#x27;s own default route, or None. Lets a test
339 pinned to a NIC ping *that* link&#x27;s gateway instead of the global one (which
340 may sit on a different segment entirely)."""
341 res = _run(['ip', 'route', 'show', 'default', 'dev', iface], timeout=5)
342 m = re.search(r'\bvia\s+(\S+)', res['out'] or '')
343 return m.group(1) if m else None
344
345
346def _egress_iface(preferred=None):
347 """Best interface to originate an *egress* test (speedtest) from: the
348 caller&#x27;s pin, else a wired port that can actually reach the internet, else
349 the default-route interface.
350
351 Deliberately NOT _capture_iface(): that one prefers any wired port with
352 carrier, which for the sensor deployment is exactly the SPAN/monitor leg —
353 fine to sniff, useless to originate from. An address alone isn&#x27;t enough
354 either: a Ragnar plugged into a switch gets a DHCP lease on that segment but
355 reaches the internet over WiFi, so a wired port only qualifies as egress if
356 it has a default route. Binding to one that doesn&#x27;t is what produces
357 speedtest-cli's 'Cannot retrieve speedtest configuration / urlopen error
358 timed out&#x27;."""
359 if _valid_iface(preferred or ''):
360 return preferred
361 dflt = _default_route_iface()
362 wired = []
363 for name in _list_iface_names(include_virtual=False):
364 if _is_wireless(name) or name.startswith(('tun', 'tap', 'wg', 'zt', 'tailscale')):
365 continue
366 try:
367 with open(f'/sys/class/net/{name}/carrier') as f:
368 if f.read().strip() != '1':
369 continue
370 except OSError: # admin-down or vanished — not a candidate
371 continue
372 v4, _ = _iface_addrs(name)
373 if v4 and _iface_has_default_route(name):
374 wired.append(name)
375 if wired:
376 return dflt if dflt in wired else sorted(wired)[0]
377 return dflt
378
379
380def do_speedtest(interface=None):
381 """Run a bandwidth test. Supports both the Ookla `speedtest` CLI and the
382 python `speedtest-cli`; returns download/upload in Mbps.
383
384 `interface` pins which local interface the test originates from; '' / None
385 auto-selects (a wired port that can reach the internet first — see

Callers 1

_parse_lldp_ifaceFunction · 0.85

Calls 7

valFunction · 0.85
_poe_class_numFunction · 0.85
_poe_standardFunction · 0.85
_poe_wattsFunction · 0.85
_scalarFunction · 0.85
truthyFunction · 0.85
getMethod · 0.45

Tested by

no test coverage detected