Wireshark for DNP3: How to Capture, Filter, and Troubleshoot

By | April 10, 2026

DNP3 (Distributed Network Protocol 3.0) is the dominant SCADA protocol in North America for electric utilities, water systems, and oil and gas. It runs over TCP or UDP on port 20000.

Wireshark fully decodes DNP3 — data link layer, transport layer, and application layer. You can see every function code, object group, data point index, quality flag, and timestamp in plain text.

But DNP3 is more complex than Modbus. It has multi-fragment responses, unsolicited messages, class-based event polling, and CRC checks at the data link layer. Knowing which Wireshark filters to use and what to look for makes the difference between solving a problem in minutes and staring at packets for hours.

This guide covers capture setup, verified display filters, how to read decoded DNP3 packets, and how to diagnose the most common DNP3 communication problems.

1. How DNP3 Appears in Wireshark

Wireshark decodes DNP3 as three layers:

LayerWhat It Shows
DNP3 Data Link LayerStart bytes (0x0564), length, control, source/destination addresses, CRC
DNP3 Transport LayerFIR/FIN bits (first/last fragment), sequence number
DNP3 Application LayerFunction code, object headers, data objects with values, quality flags, timestamps

The Info column shows a summary like:

READ - Request, Class 1, 2, 3, 0
RESPONSE - Solicited, Class 1, 2, 3, 0
UNSOLICITED RESPONSE - Class 1 Events

2. How to Capture DNP3 Traffic

Capture Filter

tcp port 20000

Or if DNP3 runs over UDP:

udp port 20000

Where to Capture

LocationWhen to Use
On the SCADA masterSee all polls and responses from every outstation
On the communication front-end processorIf the master uses a separate comm server
On a network switch (port mirroring)Non-intrusive capture
On a serial-to-Ethernet converterIf DNP3 serial traffic is converted to TCP

3. Decoding DNP3 on Non-Standard Ports

Wireshark decodes DNP3 automatically on port 20000. Many real-world installations use different ports (e.g., 4999, 5000, 19999, or vendor-specific ports).

If your DNP3 traffic appears as raw TCP data:

Fix: Use “Decode As”

  1. Right-click a packet on the non-standard port
  2. Select Decode As…
  3. Set: Field = TCP port, Value = your port, Current = DNP 3.0
  4. Click OK

Fix: Change Preferences

  1. Go to Edit → Preferences → Protocols → DNP 3.0
  2. Change the TCP Port and/or UDP Port values
  3. Click OK

4. Display Filters for DNP3

All filter field names verified against the official Wireshark DNP3 Display Filter Reference (222 fields, versions 1.0.0 to 4.6.4).

Display Filters for DNP3

Basic Filters

FilterWhat It Shows
dnp3All DNP3 traffic
tcp.port == 20000All traffic on DNP3 port
tcp.dstport == 20000Requests to outstations
tcp.srcport == 20000Responses from outstations

Address Filters

FilterWhat It Shows
dnp3.srcSource DNP3 address
dnp3.dstDestination DNP3 address
dnp3.src == 1Traffic from outstation address 1
dnp3.dst == 3Traffic to outstation address 3

Function Code Filters

FilterWhat It Shows
dnp3.al.func == 1Read requests (FC 01)
dnp3.al.func == 129Responses (FC 129 = 0x81)
dnp3.al.func == 130Unsolicited responses (FC 130 = 0x82)
dnp3.al.func == 2Write requests (FC 02)
dnp3.al.func == 3Select (CROB select, FC 03)
dnp3.al.func == 4Operate (CROB operate, FC 04)
dnp3.al.func == 5Direct operate (FC 05)
dnp3.al.func == 6Direct operate no ACK (FC 06)
dnp3.al.func == 20Enable unsolicited (FC 20)
dnp3.al.func == 21Disable unsolicited (FC 21)
dnp3.al.func == 23Delay measurement (FC 23)
dnp3.al.func == 13Cold restart (FC 13)
dnp3.al.func == 14Warm restart (FC 14)

Application Layer Filters

FilterWhat It Shows
dnp3.al.iinInternal Indications (IIN) bits
dnp3.al.iin.rstIIN — Device Restart bit
dnp3.al.iin.objuIIN — Object Unknown
dnp3.al.iin.nfcnIIN — No Function Code Support
dnp3.al.iin.cls1dIIN — Class 1 Data Available
dnp3.al.iin.cls2dIIN — Class 2 Data Available
dnp3.al.iin.cls3dIIN — Class 3 Data Available
dnp3.al.objObject group and variation
dnp3.al.indexObject point index

Data Type Filters

FilterWhat It Shows
dnp3.al.bitBinary input value (single bit)
dnp3.al.2bitDouble-bit binary input value
dnp3.al.ana.intAnalog input value (16-bit integer)
dnp3.al.ana.floatAnalog input value (float)
dnp3.al.ana.doubleAnalog input value (double)
dnp3.al.anaout.intAnalog output value (integer)
dnp3.al.anaout.floatAnalog output value (float)
dnp3.al.cntCounter value
dnp3.al.timestampObject timestamp

Quality Flag Filters

FilterWhat It Shows
dnp3.al.biq.b0 == 0Binary input — Offline (not online)
dnp3.al.biq.b1 == 1Binary input — Restart flag set
dnp3.al.biq.b2 == 1Binary input — Comm Fail
dnp3.al.biq.b3 == 1Binary input — Remote Force
dnp3.al.biq.b5 == 1Binary input — Chatter Filter active
dnp3.al.aiq.b2 == 1Analog input — Comm Fail
dnp3.al.aiq.b5 == 1Analog input — Over-Range

CRC Filter

FilterWhat It Shows
dnp.data_chunk.CRC.statusCRC check status for data chunks
dnp.hdr.CRC.statusCRC check status for the data link header

Combination Examples

All unsolicited responses from a specific outstation:

dnp3.al.func == 130 && dnp3.src == 5

All responses with Restart IIN bit set:

dnp3.al.iin.rst == 1

Analog input events with Comm Fail quality:

dnp3.al.aiq.b2 == 1

Filter by a specific point index:

dnp3.al.index == 42 && dnp3.al.ana.float

Slow responses (> 2 seconds between packets):

dnp3 && frame.time_delta > 2

5. How to Read a Decoded DNP3 Packet

Click on a DNP3 packet and expand the three layers:

Data Link Layer

DNP 3.0 Data Link Layer
    Start Bytes: 0x0564
    Length: 15
    Control: 0xc0 (DIR, PRM, FCV=0, FCB=0, Func: Unconfirmed User Data)
    Destination: 3
    Source: 1
    Header CRC: 0xABCD [correct]
  • Source/Destination = DNP3 addresses (not IP addresses)
  • DIR = direction (1 = master → outstation, 0 = outstation → master)
  • PRM = primary message (1 = from initiator)

Transport Layer

DNP 3.0 Transport Layer
    FIR: 1, FIN: 1, Sequence: 0
  • FIR = first fragment. FIN = last fragment. Both 1 = single-fragment message.
  • If FIR=1 and FIN=0, the message is multi-fragment — look for the next fragment.

Application Layer

DNP 3.0 Application Layer
    Application Control: FIR, FIN, Sequence 0
    Function Code: RESPONSE (129)
    Internal Indications: Class 1 Events
    Object: Binary Input - Packed Format (Obj: 01, Var: 01)
        Index: 0, Value: 1
        Index: 1, Value: 0
    Object: Analog Input - 16-Bit (Obj: 30, Var: 01)
        Index: 0, Quality: Online, Value: 2301
        Index: 1, Quality: Online, Value: 1456

6. What a Healthy DNP3 Conversation Looks Like

A typical DNP3 TCP poll cycle:

#DirectionDNP3 Info
1Master → OutstationREAD – Class 1, 2, 3, 0
2Outstation → MasterRESPONSE – Solicited, Binary Inputs, Analog Inputs, Counters
3Master → OutstationREAD – Class 1, 2, 3, 0
4Outstation → MasterRESPONSE – Solicited (no events, static data only)

Key signs of healthy communication:

  • Every READ has a matching RESPONSE
  • IIN bits show no errors (no Restart, no Object Unknown, no Comm Fail)
  • All quality flags show Online
  • Responses arrive within 100–500 ms
  • No TCP retransmissions

7. Diagnosing No Response from an Outstation

Filter: dnp3 && ip.addr == <outstation IP>

What You SeeCauseFix
READ sent, no RESPONSEOutstation offline or not reachablePing the outstation. Check cable and port 20000.
TCP SYN, no SYN-ACKOutstation is down or firewall blocks port 20000Check power. Check firewall rules.
RESPONSE with IIN Restart bitOutstation recently restartedMaster should send Confirm and re-enable unsolicited.
RESPONSE with IIN Object UnknownMaster requested an object the outstation does not supportCheck the outstation’s device profile for supported objects.

8. Diagnosing Unsolicited Response Problems

DNP3 outstations can send unsolicited responses when events occur, without waiting for a poll.

Filter: dnp3.al.func == 130

ProblemWhat You SeeFix
No unsolicited responsesOutstation never sends FC 130Master must send Enable Unsolicited (FC 20). Verify outstation config.
Unsolicited responses but master does not confirmOutstation keeps retransmitting the same unsolicited responseMaster must send Application Confirm after receiving unsolicited data.
Events missingOutstation sends unsolicited but some events are lostCheck event buffer size on outstation. Buffer may overflow between polls.

9. Diagnosing Data Quality Issues

Every DNP3 data point has quality flags. Bad quality means the value is unreliable.

Filter: dnp3.al.biq.b0 == 0 (binary inputs not online) or dnp3.al.aiq.b2 == 1 (analog inputs with Comm Fail)

Quality FlagMeaningCommon Cause
Not Online (b0=0)Point is offlineI/O module failure, wiring problem
Restart (b1=1)Value not updated since device restartDevice just restarted — wait for first scan
Comm Fail (b2=1)Communication failure to the field deviceSerial link down, I/O module not responding
Remote Force (b3=1)Value is being forced by the masterCheck if an operator forced this point
Local Force (b4=1)Value is being forced locallyCheck if someone forced this at the outstation
Over-Range (b5=1, analog only)Analog value exceeds sensor rangeCheck sensor wiring. Check scaling.

10. Diagnosing CRC Errors

DNP3 uses CRC-16 checksums at the data link layer. Wireshark verifies every CRC.

Filter: dnp.hdr.CRC.status or dnp.data_chunk.CRC.status

If CRCs fail, the data link frame is corrupted. This usually means:

  • Noise on the communication link (especially serial-to-Ethernet converters)
  • Bad cable or connector
  • Electrical interference near communication cables
  • Baud rate mismatch (if converted from serial)

11. Diagnosing Slow Polls and Timeouts

Filter: dnp3 && frame.time_delta > 2

SymptomCauseFix
Response takes > 1 secondOutstation overloaded or slow linkReduce poll rate. Increase response timeout.
Multi-fragment response with long gapsLarge data set fragmented across many packetsNormal for integrity polls with thousands of points.
Timeout after partial responseFragment lost or outstation buffer overflowCheck for TCP retransmissions. Reduce data request size.

12. Filtering by Point Index and Data Type

To track a specific point:

dnp3.al.index == 42

This shows all packets containing point index 42 — any object type. To narrow it down:

dnp3.al.index == 42 && dnp3.al.ana.float

This shows only packets where analog input index 42 appears with a float value.

Other useful combinations:

FilterWhat It Tracks
dnp3.al.index == 0 && dnp3.al.bitBinary input point 0
dnp3.al.index == 10 && dnp3.al.ana.intAnalog input point 10 (16-bit)
dnp3.al.index == 5 && dnp3.al.cntCounter point 5
dnp3.al.index == 0 && dnp3.al.anaout.floatAnalog output point 0 (float)

13. Useful Wireshark Columns for DNP3 Analysis

Column TitleTypeField Name
DNP3 Src AddrCustomdnp3.src
DNP3 Dst AddrCustomdnp3.dst
Function CodeCustomdnp3.al.func
Delta TimeCustomframe.time_delta_displayed
Source IPNormalip.src
Destination IPNormalip.dst

14. Common DNP3 Problems and What They Look Like in Wireshark

ProblemWireshark SymptomFilter
Outstation offlineTCP SYN with no SYN-ACKtcp.flags.syn == 1 && tcp.port == 20000
Firewall blockingTCP RST after SYNtcp.flags.reset == 1 && tcp.port == 20000
Wrong DNP3 addressREAD sent, outstation ignores (no RESPONSE)dnp3.dst — verify address matches outstation config
Unsolicited not enabledNo FC 130 packets from outstationdnp3.al.func == 130 — if empty, send Enable Unsolicited
Object not supportedRESPONSE with IIN Object Unknowndnp3.al.iin.obju == 1
Device restartedRESPONSE with IIN Restartdnp3.al.iin.rst == 1
CRC errorsData chunk CRC failuresdnp.data_chunk.CRC.status
Slow responseLarge time delta between request and responsednp3 && frame.time_delta > 2
Packet lossTCP retransmissionstcp.analysis.retransmission && tcp.port == 20000
Connection dropsTCP RST or FIN during active sessiontcp.flags.reset == 1 && tcp.port == 20000

Summary

Wireshark decodes every layer of DNP3 — data link CRC, transport fragments, and full application layer with function codes, object groups, point values, quality flags, and timestamps.

The key things to remember:

  • DNP3 runs on TCP/UDP port 20000. Use Decode As if your system uses a different port.
  • Use dnp3 as the main display filter
  • Use dnp3.al.func to filter by function code (1=Read, 129=Response, 130=Unsolicited)
  • Use dnp3.src and dnp3.dst to filter by DNP3 address (not IP address)
  • Use dnp3.al.iin.rst to find devices that have restarted
  • Use dnp3.al.index to track a specific data point across the capture
  • Use dnp3.al.biq.b2 or dnp3.al.aiq.b2 to find points with Comm Fail quality
  • Check CRC status with dnp.hdr.CRC.status and dnp.data_chunk.CRC.status

💡 Tip: Use the free DNP3 Frame Decoder Tool to decode any DNP3 frame byte by byte — including data link CRC, transport header, function codes, and object headers.

Author: Zakaria El Intissar

I'm an automation and industrial computing engineer with 12 years of experience in power system automation, SCADA communication protocols, and electrical protection. I build tools and write guides for Modbus, DNP3, IEC 101/103/104, and IEC 61850 on ScadaProtocols.com to help engineers decode, analyze, and troubleshoot real industrial communication systems.

Leave a Reply

Your email address will not be published. Required fields are marked *