← Ordo Artificum

netgear-tool

Netgear managed switch SDK & CLI

A Python SDK and Cisco IOS-style CLI for Netgear Smart Managed Plus switches. Configure VLANs, QoS, port mirroring, IGMP snooping, rate limits, and more from Python or an interactive shell — no browser, no REST API, no SSH required.

Early development — use with caution github.com/jfrancis42/netgear-tool

New project — limited hardware coverage

Developed and tested against a single GS105Ev2 (5-port gigabit, firmware V1.6.0.24). Other Netgear Smart Managed Plus switches that share the same web UI (GS108Ev3, GS116Ev2, etc.) are likely compatible but have not been verified. The API and CLI command set may change without notice. Verify each operation on your hardware before use in production.

What it is

Netgear Smart Managed Plus switches have no REST API, no SSH, and no serial console — their only configuration interface is an HTTP web UI on port 80. netgear-tool reverse-engineers that web interface to expose a clean Python SDK and an interactive CLI that feels like a Cisco IOS shell.

The SDK reads state by fetching .cgi pages and parsing configuration out of HTML <input type="hidden"> form elements — there are no JavaScript variable assignments to parse. Configuration writes are standard HTTP POST requests that must include a session-specific CSRF hash extracted from the page's GET response.

Authentication uses an unusual MD5 challenge: the firmware sends a random nonce in a custom HTTP response header, the SDK interleaves it with the password character by character, and MD5-hashes the result. The session cookie contains RFC 6265-invalid characters that Python's cookie jar silently drops; the SDK works around this by extracting the raw Set-Cookie header directly.

Python SDK

One file, one dependency (requests). Drop netgear_switch.py into your project and import.

from netgear_switch import Switch, PortSpeed, RateLimit
with Switch('192.168.0.1', password='secret') as sw:
    # Read
    info = sw.get_system_info()
    for port in sw.get_port_settings():
        print(port)
    # Configure 802.1Q VLANs
    sw.set_dot1q_enabled(True)
    sw.add_vlan(10)
    sw.set_vlan_membership(10, '11112') # ports 1-4 untagged, 5 tagged
    sw.set_port_pvid(1, 10)
    # Rate limiting
    sw.set_rate_limit(3, RateLimit.M64, RateLimit.NO_LIMIT)

Full read coverage

System info (firmware, MAC, IP, model, serial), port state and statistics, rate limits, port mirroring, IGMP snooping, loop detection, broadcast filtering, QoS mode, Green Ethernet (read-only), 802.1Q VLAN membership and PVIDs, cable diagnostics.

Full write coverage

Everything readable is writable except power saving (see firmware note below), plus factory reset, reboot, and password change.

Single-session limit handled transparently

The switch allows only one active web session at a time. The SDK always calls logout() on exit (via the context manager) to free the slot for the next caller.

Interactive CLI

A modal shell modelled after Cisco IOS. Commands can be abbreviated to their shortest unambiguous prefix. The no prefix and do prefix (run exec commands from config sub-modes) work as expected.

$ python3 cli.py 192.168.0.1
switch# show interfaces
switch# show vlan
switch# show running-config
switch# configure terminal
switch(config)# loop-detection
switch(config)# igmp snooping vlan 1
switch(config)# vlan 10
switch(config-vlan-10)# exit
switch(config)# interface gi1
switch(config-if-gi1)# switchport access vlan 10
switch(config-if-gi1)# bandwidth ingress 32m
switch(config-if-gi1)# exit
switch(config)# end
switch# show run
Mode Selected commands
Exec show version / interfaces / vlan / qos / ip / port-mirror / running-config, reload, write erase
Config hostname, ip address, [no] loop-detection, [no] broadcast-filter, [no] igmp snooping, qos mode, [no] monitor session, vlan, interface
Interface [no] shutdown, speed, [no] flowcontrol, switchport mode access/trunk, switchport access/trunk vlan, bandwidth ingress/egress
VLAN tagged <ports>, untagged <ports>

Known limitations

Ports cannot be fully removed from VLAN 1

The GS105Ev2 firmware silently rejects any attempt to remove a port from VLAN 1. Ports configured as access on another VLAN remain tagged members of VLAN 1 in the firmware — they simply have their PVID set to the access VLAN so untagged traffic is steered correctly.

Power saving (Green Ethernet) — read-only

set_power_saving() sends the POST successfully but the firmware ignores it — a subsequent GET always returns the hardware-controlled state. The method is provided for completeness and may work on other models.

Cable diagnostics — result parsing not yet implemented

test_cable() currently returns the raw HTML response from the firmware. Structured parsing of cable length and fault type is pending.

Single hardware revision tested

Only the GS105Ev2 (firmware V1.6.0.24) has been tested. Other Netgear Smart Managed Plus models are expected to be compatible but have not been verified.

Requirements

pip install requests
# Python 3.8+
# Tested: GS105Ev2, firmware V1.6.0.24