You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@jauling reverse engineered a Goodtop ZX310S-8T2XS and posted the protocol
and a payload sample. That is enough to implement it:
GET /authorize?loginusr=<md5(user)>&loginpwd=<md5(pass)>
GET /port_statistics.json
Selected with a new firmware key, defaulting to html so nothing changes for
the existing devices. switchclient.JSONClient satisfies the same
collector.SwitchClient interface as the HTML client, so the collector does
not know which family is in use; the package split from the refactor is
what makes this a new file rather than a rewrite.
Notable details
The credentials are hashed separately here, loginusr and loginpwd, unlike
the HTML family which sends one md5(username+password) token. A test pins
that the combined token is never sent to this firmware.
Ports arrive as top-level Port_N keys rather than an array, so they are
collected and sorted numerically. Go map iteration is random and Port_10
sorts before Port_2 lexically, either of which would attach counters to the
wrong label.
Link_Status carries speed and duplex together ("2500MbpsFull"), so the
family publishes port_link_speed_mbps. A 2.5G port that negotiated 1G is
one of the more useful things to alert on with these switches. The metric
is omitted for the HTML family, which does not report it, and for any port
without a link.
No PoE endpoint has been reported, so poe with firmware: json is refused at
startup rather than failing every scrape.
Testing
A fixture built from the payload in the issue, a maxlinear fakeswitch
profile with its own self-tests, and an acceptance case that runs the real
exporter against it. Verified end to end: port_link_speed_mbps reports
1000, 2500, 10000 and 100 for the emulated ports and is absent for the
unlinked ones.
Implemented from a report, not from hardware. The device table marks it
untested and asks for confirmation.
Also corrects the Sodola contributor back to @dennyreiter, which an earlier
commit in this branch had changed by mistake.
@@ -105,6 +106,7 @@ password: "password" # Web interface password
105
106
poll_rate_seconds: 10# Minimum delay between two polls of the switch
106
107
timeout_seconds: 5# Per-request timeout
107
108
poe: false # Scrape the PoE pages (1/0 also accepted)
109
+
firmware: html # html (default) or json, see below
108
110
```
109
111
110
112
Unknown keys are rejected, so a misspelled option fails at startup instead of being ignored.
@@ -137,6 +139,26 @@ web:
137
139
138
140
TLS is served with a minimum version of TLS 1.2. `/healthz` is intentionally left unauthenticated so container health checks keep working. When the endpoint is bound to a non-loopback address without authentication, the exporter logs a warning at startup.
139
141
142
+
### Firmware families
143
+
144
+
Two device families are supported. `firmware: html` is the default and covers
145
+
every device in the table above: an RTL8373 style web interface whose statistics
146
+
are scraped from `/port.cgi`.
147
+
148
+
`firmware: json` covers MaxLinear based devices that authenticate through
149
+
`/authorize`and serve `/port_statistics.json`, reported for the Goodtop
150
+
ZX310S-8T2XS in [issue #6](https://github.com/pvelati/cheap-switch-exporter/issues/6).
151
+
Two differences worth knowing:
152
+
153
+
- It reports the negotiated link speed, so `port_link_speed_mbps` is published.
154
+
The HTML family does not expose it and omits the metric.
155
+
- No PoE endpoint has been reported for it, so `poe: true` together with
156
+
`firmware: json` is refused at startup rather than failing every scrape.
157
+
158
+
This family is implemented from the protocol and payload in the issue and
159
+
verified against an emulated device. Nobody has confirmed it against real
160
+
hardware yet; reports welcome.
161
+
140
162
### Polling behaviour
141
163
142
164
`poll_rate_seconds`is the minimum delay between two polls of the switch. Scrapes arriving inside that window are answered from the previous result, including failures. That keeps a redundant pair of Prometheus servers, or a short scrape interval, from overwhelming a device whose web interface serves one session at a time. Set it to `0` to poll on every scrape.
@@ -153,6 +175,7 @@ The exporter now authenticates lazily: it requests the statistics page, and only
153
175
154
176
- `port_state`: Port enabled/disabled status (1=Enable, 0=Disable)
155
177
- `port_link_status`: Port link up/down status (1=Link Up, 0=Link Down)
178
+
- `port_link_speed_mbps`: Negotiated speed in Mbps, only with `firmware: json`
156
179
- `port_tx_good_pkt`: Transmitted good packets
157
180
- `port_tx_bad_pkt`: Transmitted bad packets
158
181
- `port_rx_good_pkt`: Received good packets
@@ -244,6 +267,7 @@ go run ./cmd/fakeswitch -list-profiles
244
267
| `unauthorized` | HTTP 401 |
245
268
| `slow` | Never answers in time |
246
269
| `flaky` | Drops the session every other request |
270
+
| `maxlinear` | The JSON firmware of issue #6, with negotiated link speeds |
0 commit comments