Concluded·6 Aug 2026 · 6 min read

Scoring five industrial protocols against the 62443 foundational requirements

tcpdump 4.99.4 · tshark 4.6.7 · eclipse-mosquitto 2.0.22 · Modbus TCP · EtherNet/IP · S7comm · MQTT · OPC UA

This scores five captures against the seven foundational requirements of IEC 62443. The captures already existed. They came out of four earlier labs on an isolated network, one protocol at a time, and each was taken to answer a narrower question than this one. Putting them side by side turned out to answer a question none of them asked individually, which is what a passive capture can actually tell you about compliance.

The short answer is four of the seven, and the three it cannot tell you are the interesting ones.

The rig

Five packet captures, all from an isolated lab network, all against equipment under my own control. Modbus TCP against a pump simulator polled by a live client. EtherNet/IP against a CIP tag server. S7comm against a data-block server. MQTT against a broker carrying a tank model. OPC UA against a server offering two security policies at once.

Capture with tcpdump 4.99.4 on the bridge the traffic crossed, which stands in for a mirror port on a real switch. Decode with tshark 4.6.7. The broker is eclipse-mosquitto 2.0.22. The EtherNet/IP, S7comm and OPC UA simulators ran on a throwaway stack that has since been torn down, so those three package versions are not pinned here; if you reproduce this, pin them yourself and expect small differences in what the dissectors name things.

Nothing was captured on a routable segment and nothing here is a walkthrough for doing this to somebody else's plant. The finding is a scorecard and a fix.

What a tap can answer, and what it cannot

The seven foundational requirements are identification and authentication control, use control, system integrity, data confidentiality, restricted data flow, timely response to events, and resource availability. Before scoring anything it is worth being strict about which of those a packet capture is evidence for.

Four of them, it is. Either a credential crosses the wire or it does not. Either a write from an arbitrary host was accepted or it was refused. Either the frame carries integrity protection or nothing above the TCP checksum would notice a change. Either the process value is recoverable from the payload or it is not. Those are all observable facts about bytes that were captured.

Three of them, it is not, and this is where a scorecard becomes dishonest if you let it. Restricted data flow is a property of the network drawing. A tap sitting inside one zone cannot observe a boundary that the traffic never had to cross, and finding no zone violations in a capture taken entirely within one zone is not evidence of anything. Timely response to events is out of band by definition; the absence of an alert in a pcap says nothing about whether a detection system exists somewhere else. Resource availability needs a load or failure test, and no such test was run here, so there is nothing to report.

not answerable from a captureFR1who you areFR2what you may doFR3not alteredFR4not readableFR5who talks to whomFR6noticingFR7under stressModbus TCPEtherNet/IPS7commMQTTOPC UA✗ nothing in the protocol○ available, switched off◐ depends which way in
Five captures scored against the seven requirement groups. The last three columns are grey because a packet capture is not evidence for them either way — greying them is the point, not a gap in the work.

So the grid ships with three columns greyed. That is the honest shape of the result, and it is also the finding, for reasons that come back at the end.

Modbus TCP

100 frames over 12.071 seconds between two hosts on the pump segment.

tshark -r modbus.pcap -d tcp.port==5020,mbtcp -Y modbus \
       -T fields -e modbus.func_code | sort | uniq -c
  14  2      read discrete inputs
  46  3      read holding registers
  14  4      read input registers
   4  6      write single register     <- two requests, two responses

The four function-code-6 frames are the whole story: a write to the speed register and the restore afterwards. No credential was offered because the protocol has no field to carry one, and the write was honoured. Identification fails, use control fails, integrity fails because nothing above the TCP checksum would detect a modified frame, and confidentiality fails because forty-six read responses decode straight to process values.

FC03read holding registers46FC02read discrete inputs14FC04read input registers14FC06write single register4100 frames over 12.071 seconds. The four marked frames are a write to the speed register and the restore.
Every Modbus frame in the capture, by function code. The four write frames carry no more authority than the ninety-six reads, and nothing in the traffic distinguishes them.

EtherNet/IP

21 frames, 0.061 seconds. CIP services 0x4c read tag, 0x4d write tag, 0x52, with replies 0xcc and 0xcd.

tshark -r enip.pcap -Y cip -T fields -e frame.number -e ip.src -e cip.service -e cip.symbol

The same four failures as Modbus, plus one worth calling out separately: the tag names travel in clear. MOTOR_CMD and SETPOINT are readable without any decoding effort at all. That is a confidentiality loss beyond the values, because tag names are the plant's vocabulary, and an observer who reads them learns what the system is for.

S7comm

21 frames, 10 of them S7, in 0.0014 seconds.

Job  Setup communication (0xf0)  ->  Ack
Job  Read Var  (0x04)            ->  Ack
Job  Write Var (0x05)            ->  Ack
Job  Read Var  (0x04)            ->  Ack
Job  Write Var (0x05)            ->  Ack

Values 0x05dc and 0x1068 each appear twice in the clear. The point of the ladder is what is missing from it: there is no authentication step anywhere before the write, because nothing in the exchange asked for one.

Access protection levels do exist on devices of this family. They were not enabled here. That is worth stating precisely, because it is tempting to score it as partial credit and it is not: this is identification absent, with the capability available and switched off. That distinction is the entire subject of the companion piece.

clientcontrolleran authentication step would sit hereSetup communication (0xf0)acknowledgedRead Var (0x04)acknowledgedWrite Var (0x05)acknowledgedRead Var (0x04)acknowledgedWrite Var (0x05)acknowledgedTwenty-one frames, ten of them S7, in 0.0014 seconds. Both written values are readable in the capture.
The whole exchange, request and acknowledgement, in the order it was captured. Nothing sits between opening the connection and writing to the data block, because nothing asked to.

MQTT

2,364 frames over 12.515 seconds, 26 distinct publish topics.

tshark -r mqtt.pcap -Y 'mqtt.msgtype==1' \
       -T fields -e frame.number -e ip.src -e mqtt.conflags

Two connect frames, both with flags 0x02. Clean session set, and the two bits that would carry a username and a password both clear. The broker accepted the session.

On the command topic, 51 frames carry the normal duty value and 2 carry a 0: the instruction and the broker's relay of it to the legitimate subscriber, which had no means of distinguishing the source.

The number worth keeping: the host that sent it accounts for 14 frames out of 2,364. Six-tenths of one percent of the traffic. Any detection tuned to traffic volume watches that go by.

connect flags = 0x020username0password0will retain0will QoS0will QoS0will flag1clean session0reservedBoth connect frames carried this byte. The broker accepted the session and the client named itself to nobody.
The connect byte from the captured session, bit by bit. Two of these being empty is the entire authentication story for this broker.

This is the first protocol in the set where the fix lives at the protocol layer. Transport encryption and per-client permissions were both available and neither was on.

OPC UA

52 frames, 34 of them OPC UA, in 1.068 seconds. Both policies offered on the same endpoint, five frames each:

http://opcfoundation.org/UA/SecurityPolicy#None
http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256

The same value was read through both. The IEEE-754 double for 42.0 appears exactly once in the entire capture:

tshark -r opcua.pcap -T fields -e tcp.payload | tr -d '\n' \
  | grep -o 0000000000004540 | wc -l        # 1

Pump appears 29 times in clear, so the unsecured session leaks the address space and not merely one value. Through the secured door, identification, integrity and confidentiality all hold. Through the unsecured one, none of them do. One server, one second apart, two answers.

52 frames · both reads returned 42.0readable here, once00 00 00 00 00 00 45 40The second read of the same value is somewhere on this strip and cannot be found.
Every frame in the OPC UA capture, laid end to end. The value 42.0 was read twice and is legible at exactly one place on this strip.

The three columns that stayed grey

Restricted data flow would have stopped all five. Every capture describes a host reaching something it had no business reaching, and a zone boundary is what removes that reach.

Timely response to events would have caught the one that segmentation might have missed. Fourteen frames out of 2,364 is invisible to volume thresholds and obvious to anything watching for a command from an unfamiliar source.

Resource availability was not tested and is not claimed.

FR1FR2FR3FR4FR5FR6FR7the capture answers thesethese pass straight throughRestricted data flow lives in the drawing. Noticing lives outside the traffic. Behaviour under stress was never tested here.
What a tap on the wire can establish, against what the standard asks about. Three questions pass straight through it and come out no better answered than they went in.

That is the result worth taking away. The requirements a capture cannot reach are the requirements that would have prevented every finding above, which is a reasonable explanation for why the standard puts its weight on systems rather than on wire formats. It is also, from the opposite direction, the argument this series has been making since the first Modbus post: the protocol was never the control.

Reproducing this

Every command above runs against a saved capture, so the analysis half needs no lab at all. Standing up the traffic side needs equipment you own and a segment that routes nowhere. Score the four answerable columns, leave the other three grey, and be suspicious of any scorecard that fills in all seven from a pcap.

Newsletter

New essays, by email.

SCADA, cloud, AI, and the plant floor — a short email when something new is published. No noise, unsubscribe anytime.