"""ZTE: show nd6 cache [| one-line].""" from __future__ import annotations import re from typing import Any _ND6_ROW_RE = re.compile( r"^(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+(?P\S+)\s+" r"(?P\S+)\s+(?P\S+)\s*$", re.I, ) # CLI banner / wall-clock line (e.g. "14:06:53 Beijing Sun Sep 20 2026") _CLOCK_LINE_RE = re.compile(r"^\d{1,2}:\d{2}:\d{2}\b") _TIME_OF_DAY_RE = re.compile(r"^\d{1,2}:\d{2}:\d{2}$") RULE_KEYS: tuple[str, ...] = () def _looks_like_ipv6(addr: str) -> bool: a = str(addr or "").strip() if not a or ":" not in a: return False # HH:MM:SS is not an IPv6 address if _TIME_OF_DAY_RE.match(a): return False return bool(re.search(r"[0-9a-fA-F]", a)) def normalize_nd6_cache( *, raw_text: str, fsm_tables=None, vendor: str = "", device_type: str = "", command: str = "", params: dict[str, str] | None = None, ) -> list[dict[str, Any]]: _ = (vendor, device_type, command, params, fsm_tables) out: list[dict[str, Any]] = [] seen: set[tuple[str, str]] = set() for raw in str(raw_text or "").splitlines(): line = raw.strip() if not line: continue if _CLOCK_LINE_RE.match(line): continue low = line.lower() if low.startswith("s-static") or low.startswith("total cache") or low.startswith("only current"): continue if low.startswith("address") and "link" in low: continue m = _ND6_ROW_RE.match(line) if not m: continue addr = m.group("addr") if not _looks_like_ipv6(addr): continue iface = m.group("iface") key = (addr, iface) if key in seen: continue seen.add(key) out.append( { "address": addr[:128], "link_address": m.group("link")[:64], "age": m.group("age")[:64], "status": m.group("status")[:32], "interface": iface[:128], "type": m.group("type")[:32], } ) return out normalize_nd6_cache.RULE_KEYS = RULE_KEYS