43 lines
1.5 KiB
Python
43 lines
1.5 KiB
Python
# services/net_info.py
|
|
import subprocess
|
|
import json
|
|
|
|
def _run(cmd: list[str]) -> str:
|
|
return subprocess.check_output(cmd, text=True).strip()
|
|
|
|
def _first_ipv4_cidr_from_ip_json(ip_json: dict) -> str | None:
|
|
# Find first IPv4 on the interface
|
|
for addr in ip_json.get("addr_info", []):
|
|
if addr.get("family") == "inet" and addr.get("local") and addr.get("prefixlen") is not None:
|
|
return f'{addr["local"]}/{addr["prefixlen"]}'
|
|
return None
|
|
|
|
def get_iface_cidr(iface: str) -> str | None:
|
|
# ip -j addr show dev eth0
|
|
raw = _run(["ip", "-j", "addr", "show", "dev", iface])
|
|
data = json.loads(raw)
|
|
if not data:
|
|
return None
|
|
return _first_ipv4_cidr_from_ip_json(data[0])
|
|
|
|
def get_default_gw_for_iface(iface: str) -> str | None:
|
|
lines = _run(["ip", "route", "show", "default", "dev", iface]).splitlines()
|
|
for line in lines:
|
|
parts = line.split()
|
|
if parts and parts[0] == "default":
|
|
try:
|
|
idx = parts.index("via")
|
|
return parts[idx + 1]
|
|
except ValueError:
|
|
continue
|
|
except IndexError:
|
|
continue
|
|
return None
|
|
|
|
def get_eth0_dhcp_snapshot() -> dict:
|
|
iface = "eth0"
|
|
cidr = get_iface_cidr(iface) or ""
|
|
gw = get_default_gw_for_iface(iface) or ""
|
|
if not cidr or not gw:
|
|
raise RuntimeError("Could not determine eth0 CIDR and/or default gateway")
|
|
return {"iface": iface, "cidr": cidr, "gw": gw} |