AbCip controller browse ignores the authored EtherNet/IP port (#534 defect, discovery half) — browses whatever answers on 44818 #539

Closed
opened 2026-08-05 04:31:26 -04:00 by dohertj2 · 0 comments
Owner

Found by the live /run gate for the raw-modal picker live-config fix
(docs/plans/2026-08-05-raw-modal-picker-live-config.md Task 5), 2026-08-05.

Symptom

An AbCip device authored with a non-default EtherNet/IP port browses the wrong controller.
On the docker-dev rig, a device at ab://10.100.0.35:44999/1,0 (nothing listening on 44999):

  • Test Connect → FAILED · CONNECT FAILED: CONNECTIONREFUSED (correct — the probe honours the port).
  • "Browse controller" in the tag modal's AB CIP address builder → succeeded, returning the
    full nine-tag symbol table of the fixture on 44818.

Re-pointed at ab://127.0.0.1/1,0 the browse fails as expected (ERRORTIMEOUT), so the browse is
genuinely live — it is only the port that is dropped.

Cause

This is Gitea #534's defect, surviving in the AbCip discovery call sites. The data path was
fixed by introducing AbCipTagCreateParams.LibplctagGateway (host:port), but the two
discovery-path libplctag tags still pass the bare Gateway:

  • src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/LibplctagTagEnumerator.cs:33 — Gateway = deviceParams.Gateway
  • src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/LibplctagTemplateReader.cs:24 — Gateway = deviceParams.Gateway

vs. the correct src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/LibplctagTagRuntime.cs:24 —
Gateway = p.LibplctagGateway.

libplctag silently substitutes its own 44818 default for a bare host, so the authored port does not
merely fail to apply — the browse redirects to whatever answers on the default port, which on a
plant network is another PLC. That is #534's own wording, and it applies verbatim here: an operator
browsing device B can be shown device A's symbol table and commit tags against it.

The AbLegacy driver has no discovery path, so it is not affected.

Why the existing tests do not catch it

Same reason #534 went unnoticed: the AbCip fixture sits on the default 44818, where the bug is
invisible by construction. A regression test must assert the composed gateway string for a
non-default port at the enumerator/template-reader seam (the AbCipTagCreateParams → libplctag
Tag construction), not run against the fixture.

Fix

Use deviceParams.LibplctagGateway at both sites. Consider making the bare Gateway property
harder to reach by accident from a call site that builds a libplctag Tag.

Found by the live `/run` gate for the raw-modal picker live-config fix (`docs/plans/2026-08-05-raw-modal-picker-live-config.md` Task 5), 2026-08-05. ## Symptom An AbCip device authored with a **non-default EtherNet/IP port** browses the wrong controller. On the docker-dev rig, a device at `ab://10.100.0.35:44999/1,0` (nothing listening on 44999): - **Test Connect** → `FAILED · CONNECT FAILED: CONNECTIONREFUSED` (correct — the probe honours the port). - **"Browse controller"** in the tag modal's AB CIP address builder → **succeeded**, returning the full nine-tag symbol table of the *fixture on 44818*. Re-pointed at `ab://127.0.0.1/1,0` the browse fails as expected (`ERRORTIMEOUT`), so the browse is genuinely live — it is only the **port** that is dropped. ## Cause This is Gitea #534's defect, surviving in the AbCip **discovery** call sites. The data path was fixed by introducing `AbCipTagCreateParams.LibplctagGateway` (`host:port`), but the two discovery-path libplctag tags still pass the bare `Gateway`: - `src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/LibplctagTagEnumerator.cs:33` — `Gateway = deviceParams.Gateway` - `src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/LibplctagTemplateReader.cs:24` — `Gateway = deviceParams.Gateway` vs. the correct `src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/LibplctagTagRuntime.cs:24` — `Gateway = p.LibplctagGateway`. libplctag silently substitutes its own 44818 default for a bare host, so the authored port does not merely fail to apply — the browse **redirects to whatever answers on the default port**, which on a plant network is another PLC. That is #534's own wording, and it applies verbatim here: an operator browsing device B can be shown device A's symbol table and commit tags against it. The AbLegacy driver has no discovery path, so it is not affected. ## Why the existing tests do not catch it Same reason #534 went unnoticed: the AbCip fixture sits on the default 44818, where the bug is invisible by construction. A regression test must assert the composed gateway string for a **non-default** port at the enumerator/template-reader seam (the `AbCipTagCreateParams` → libplctag `Tag` construction), not run against the fixture. ## Fix Use `deviceParams.LibplctagGateway` at both sites. Consider making the bare `Gateway` property harder to reach by accident from a call site that builds a libplctag `Tag`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#539