Open Wireshark and search the protocol list for ICCP or TASE.2. You won’t find either. There has never been a dedicated ICCP dissector, which confuses many engineers the first time they capture an inter-control-center link — the traffic is right there on port 102, and Wireshark calls it something else.
Here’s the thing that makes it simple: ICCP is an MMS application, so Wireshark’s MMS dissector decodes it. Everything you see is MMS PDUs whose variable names and calling patterns happen to be TASE.2. Once you know the patterns, an ICCP capture reads fluently.
This guide covers the ICCP-specific side: capturing the right traffic, telling ICCP apart from IEC 61850 in mixed captures, and reading the association, data setup, transfer reports, and device controls on the wire. The shared MMS machinery — the PRES context fix, the full MMS filter reference, custom columns — is already covered in the Wireshark for IEC 61850 MMS guide, and everything there applies here unchanged.
Table of Contents
Capturing ICCP traffic
Capture filter:
tcp port 102 or tcp port 3782
TCP port 102 carries standard ICCP traffic, while 3782 is commonly used for TLS-secured ICCP. If your link runs on 3782, the payload is encrypted and you’ll need the session keys to see MMS at all — the approach is covered in decrypting encrypted industrial protocol traffic.
Capture the association setup. Same rule as 61850 MMS, but harder to satisfy: Wireshark needs the presentation-layer negotiation to decode MMS, and ICCP associations are designed to stay up for months. You can rarely just restart the link to generate a fresh association. Two ways out:
Either capture during a planned event — commissioning, failover test, maintenance window — when the association will be re-established anyway. Or apply the manual fix: configure the PRES user context (OID 1.0.9506.2.1) exactly as described in section 3 of the 61850 guide. The fix is identical because the presentation layer is identical.
Where to capture. The natural points are the ICCP server (or gateway/communications processor) itself, a SPAN port on the switch in front of it, or the WAN edge router. On a dual-server redundant setup, capture at both servers or you’ll only see half the story during a failover. And remember both directions matter: on most links your center is client and server at once, so a one-sided capture shows your questions without their answers.
Is this ICCP or IEC 61850?
Both protocols are MMS on port 102, and in a utility network you’ll meet both — sometimes traversing the same capture. Wireshark labels both “MMS.” Three tells separate them in seconds:
Look at the variable names. 61850 object references are long and structured, with $ separators: IED1PROT/MMXU1$MX$TotW$mag$f. ICCP names are flat identifiers, 32 characters maximum, no separators: SUBST_X_MW, Transfer_Set_Name, Bilateral_Table_ID. One glance at a Read request settles it.
Look for the ICCP signature variables. Only a TASE.2 server exposes TASE.2_Version, Supported_Features, Bilateral_Table_ID, and Next_DSTransfer_Set. Any of these in a capture is a positive ICCP identification. A display filter that catches most ICCP conversations early:
mms contains "Bilateral_Table_ID" || mms contains "Next_DSTransfer_Set"
Look at the domain names. In 61850, mms.domainId shows logical device names built from IED names. In ICCP, the domain is the ICC name from the bilateral table — typically a control center designation the two organizations agreed on.
Look at the peers. An IED talking to a station SCADA is 61850. Two servers across a WAN link, in different IP ranges belonging to different organizations, is ICCP.
Reading a healthy ICCP startup
When an association does come up, the capture tells a story in a fixed order. Knowing the sequence lets you spot exactly where an unhealthy link stops.
1. Protocol stack establishment. TCP handshake, then one packet each: COTP connection request/confirm (TSELs inside), session connect (SSELs), and the presentation connect carrying ACSE’s AARQ. In the AARQ, expand the ACSE layer: the calling AP title and AE qualifier are the identity the server is about to check against its bilateral table.
2. MMS Initiate. mms.initiate_RequestPDU_element and its response — negotiated PDU sizes and service support, same as any MMS association.
3. The ICCP handshake reads. The client typically reads TASE.2_Version, Supported_Features, and Bilateral_Table_ID right after the association. This is the client verifying protocol version, capability blocks, and — critically — that both sides run the same table version. If your capture shows the client disconnecting right after reading Bilateral_Table_ID, you’ve found a table version mismatch without reading a single log file.
4. Discovery and data set setup. GetNameList requests enumerate available objects. Then either reads of predefined data sets or DefineNamedVariableList requests creating client-defined ones — each listing the exact point names being grouped.
5. Transfer set startup. The client reads Next_DSTransfer_Set to obtain a free transfer set name, then issues an MMS Write to that transfer set variable. That Write is the Start Transfer operation, and its content is the full transmission parameter block: interval, integrity check period, RBE flag, buffer time, the conditions requested. When someone asks “what reporting parameters is the link actually running?”, this one packet is the authoritative answer — more authoritative than either side’s configuration screen.
6. Reports begin. From here the server pushes InformationReports and the link settles into its steady state.
Transfer reports on the wire
Filter:
mms.informationReport_element
ICCP reports are MMS InformationReports carrying the data set values. What makes them readable is the special transfer set objects most links include in the data set: look inside the report for Transfer_Set_Name (which transfer set produced this), Transfer_Set_Time_Stamp (when), and DSConditions_Detected (why — interval elapsed, object changed, integrity timeout, operator request).
Two patterns to recognize:
Full reports vs RBE reports. An interval or integrity-triggered report carries every element of the data set. A report-by-exception report carries only what changed — so consecutive reports from the same transfer set legitimately differ in size and content. Small reports are not missing data; they’re the efficiency working.
Report cadence as a health check. Filter one transfer set’s reports and look at the timing column. Interval reports should arrive on the agreed period like a metronome; an integrity-triggered full refresh should appear on its longer cycle. Gaps, drift, or bursts point at server load or condition misconfiguration before anyone opens a vendor tool.
Device control on the wire
This is the sequence worth memorizing, because it looks nothing like 61850 controls.
An ICCP select-before-operate exchange appears as:
- Select — an MMS Read of the device variable. The response carries the CheckBackID, the value agreed in the bilateral table. A Read as the arming step surprises everyone coming from 61850, where select is a write to SBOw.
- Operate — an MMS Write to the device variable, within the agreed timeout. The Write response confirms the server accepted the command — not that the breaker moved.
- Feedback — a transfer report. Actual device state comes back through the associated indication point in a subsequent InformationReport. When analyzing a control that “failed silently,” don’t stop at the Operate response; follow the indication point in the reports that follow.
Direct-control devices skip step 1. Tag handling appears as Reads and Writes of the tag variable in the same style.
So in a capture, a complete remote control action reads: Read (small response containing CheckBackID) → Write (command value) → InformationReport (state change). Three packets tell the whole story.
Errors and refusals: which layer, which cause
Where a connection attempt dies in the capture maps directly to what’s misconfigured — the same layered logic as the ICCP protocol stack guide, now visible in packets:
| What you see in Wireshark | Layer | Likely cause |
|---|---|---|
| TCP SYN, no SYN-ACK or immediate RST | TCP/IP | Firewall, wrong IP, service down |
| COTP connection refused after TCP opens | Transport | TSEL mismatch |
| Session or presentation refuse | Session/Presentation | SSEL or PSEL mismatch |
| ACSE AARE with result “rejected” | Application association | AP title / AE qualifier not in the peer’s bilateral table |
Association up, mms.confirmed_ErrorPDU_element with access errors | TASE.2 | Object not granted in the bilateral table, or name mismatch |
Client disconnects right after reading Bilateral_Table_ID | TASE.2 | Table version mismatch between the two centers |
| MMS Reject PDU | MMS | Peer sent a service or object class the profile excludes |
| Association drops with TCP RST after long idle | Network path | Middlebox idle timeout killing a healthy long-lived connection |
That last row deserves emphasis for ICCP specifically: associations are meant to live for months, which makes them the canary for every aggressive firewall state timeout and NAT table cleanup on the WAN path. If your capture shows periodic clean re-associations at a suspiciously round interval, go read the firewall config before blaming either ICCP endpoint.
ICCP display filter quick reference
The full MMS filter set is in the 61850 MMS guide; these are the combinations that earn their keep on ICCP links:
| Filter | Use |
|---|---|
tcp.port == 102 | All traffic on the standard ICCP port, decoded or not |
mms | Everything, both directions |
mms contains "Bilateral_Table_ID" | Startup handshake / version checks |
mms.informationReport_element | All transfer reports |
mms.read_Request || mms.write_Request | Client-initiated operations, including Select/Operate |
mms.confirmed_ErrorPDU_element | Everything the server rejected |
mms.initiate_RequestPDU_element || acse | Association establishment traffic |
mms.domainId (as column) | Which partner domain each packet belongs to |
mms.invokeID (as column) | Match requests to responses on busy links |
tcp.stream eq N | Isolate one association on multi-link captures |
Summary
No ICCP dissector exists because none is needed — ICCP is MMS, and Wireshark’s MMS dissector plus the PRES context fix decodes it fully. Capture on ports 102 and 3782, ideally when an association establishes. Identify ICCP by its flat variable names, its signature variables, and its bilateral-table domain names. Read the startup sequence in order — protocol stack establishment, Initiate, handshake reads, data set setup, transfer set start — and any failure names its own layer. Remember the ICCP control signature: Select is a Read, Operate is a Write, and the truth about the device arrives later in a transfer report.
