Files
christianmanivong 0052ba7884 feat: Intel AMT driver over WS-Management (0.1.0)
An `amt` driver (napalm_amt.AmtDriver), a ManagementControllerDriver for the
management controller of Intel vPro machines, with its own lean WS-Management
client (requests + ElementTree, HTTP Digest, ports 16992/16993).

It reads the machine's identity, hardware with the SMBIOS system UUID, firmware
(AMT with build, BIOS), power state and the hardware event log, reports what AMT
listens on (plain HTTP or TLS, KVM incl. port 5900, IDE-R), and switches the
machine's power. AMT cannot be reset over WS-Management, so there is no
reboot_host. Discovery recognises AMT by its ports and its Server header.

Tested against Intel's published AMT 12 recordings (go-wsman-messages,
Apache-2.0, see NOTICE). `python -m napalm_amt.record` records a real AMT
read-only; the first test devices are two Lenovo ThinkCentre M910x.
2026-10-18 14:55:32 +02:00

58 lines
1.9 KiB
Python

"""AMT's own network ports (``AMT_EthernetPortSettings``).
AMT shares the machine's network controller: the wired port has the host's MAC address
and, in DHCP mode, the host's IP address too. A port without a MAC address is a wireless
port on a machine without a WLAN card.
"""
from __future__ import annotations
import ipaddress
from typing import Any
from napalm_amt.parsers.common import is_true, text
_Instance = dict[str, Any]
_WIRELESS = "3" # PhysicalConnectionType: 0 integrated LAN, 1 discrete LAN, 2 dock, 3 WLAN
def _mac(value: str) -> str:
mac = value.replace("-", ":").lower()
return "" if not mac.replace(":", "").strip("0") else mac
def _prefix(mask: str) -> int | None:
if not mask:
return None
try:
return ipaddress.IPv4Network(f"0.0.0.0/{mask}").prefixlen
except ValueError:
return None
def parse_ethernet_ports(ports: list[_Instance]) -> list[dict[str, Any]]:
"""The ports in use: name (``wired``/``wireless``), MAC, link, DHCP, whether AMT shares
the host's IP address, and its own address where AMT reports one."""
parsed: list[dict[str, Any]] = []
for port in ports:
mac = _mac(text(port.get("MACAddress")))
if not mac:
continue
name = "wireless" if text(port.get("PhysicalConnectionType")) == _WIRELESS else "wired"
if any(p["name"] == name for p in parsed):
name = f"{name}{len(parsed)}"
dhcp = is_true(port.get("DHCPEnabled"))
ip = text(port.get("IPAddress"))
parsed.append(
{
"name": name,
"mac_address": mac,
"link_up": is_true(port.get("LinkIsUp")),
"dhcp": dhcp,
"shared_ip": is_true(port.get("SharedDynamicIP" if dhcp else "SharedStaticIp")),
"ip": ip,
"prefix_length": _prefix(text(port.get("SubnetMask"))) if ip else None,
}
)
return parsed