>
HomeGuidesGuides & ToolsTrace Walkthrough
🧭 Guides & ToolsBeginner

Reading a Signalling Trace (Wireshark)

How to read a 5G/LTE control-plane capture — the protocol stack inside one packet, and an annotated walk through an attach trace.

📚 3GPP-basedlab

A signalling trace is just a recording of the control-plane messages that set up, move, and tear down a call. If you can open one in Wireshark and follow a registration from the first NGAP message to Registration Accept, you can debug most attach and mobility problems without ever touching the radio. This page teaches you how to read such a capture from scratch: where the tap points are, how the layers nest inside one packet, which display filters and panes to use, and how to walk a real attach message by message.

Why capture the control plane, and where you tap it

The control plane is the signalling that arranges everything before (and around) user data: authentication, security, context setup, session establishment, handover. When a UE fails to attach, cannot get an IP address, or drops during mobility, the answer is almost always sitting in a control-plane message that carried a reject cause, a missing IE, or a mismatched capability. A trace lets you see that message verbatim instead of guessing from counters.

What

A packet capture (.pcap or the newer .pcapng) is a time-stamped, byte-for-byte recording of frames seen on a network interface, written by libpcap-based tools such as tcpdump, dumpcap, or Wireshark itself.

Why

It is ground truth. Every field the network actually sent is there, so you can confirm exactly which IE was wrong rather than trusting a summary log.

How

You point a capture tool at the interface carrying the signalling, optionally with a capture filter (for example sctp or gtp), let it run while you reproduce the problem, and save the file.

The catch is where you can realistically tap. The radio interface — NR-Uu in 5G, LTE-Uu in LTE — is over the air and encrypted; you cannot sniff it with a NIC. So you capture on the wired interfaces between network functions, or you rely on instrumented test tools and node logs. The most productive tap points are:

Tap pointInterfaceWhat you see
gNB ↔ AMFN2 (NG-C)NGAP over SCTP, with NAS-5GS nested inside — the richest single tap for attach/mobility
eNB ↔ MMES1-MMES1AP over SCTP, with NAS-EPS nested — the LTE equivalent
SMF ↔ UPFN4PFCP — user-plane session programming (tunnels, QoS rules)
AMF ↔ SMFN11HTTP/2 SBI service calls carrying N1/N2 SM containers
gNB ↔ UPFN3GTP-U user-plane tunnels (data, not signalling)
UE / gNB test toolsimulated UuAir-interface RRC/MAC exported as Wireshark-readable frames

For a first attach investigation the single best capture is N2 (or S1-MME in LTE): one interface gives you both the RAN-signalling procedures and the NAS messages the UE exchanges with the core. Air-interface RRC is only visible if your gNB or UE simulator exports it — real deployments dump it to node logs rather than a NIC.

The protocol stack inside one packet

Reading a trace is really about reading nesting. One frame on N2 is not one protocol — it is a stack of them wrapped inside each other, outermost transport first, innermost application last. For an InitialUEMessage the layers are Ethernet / IPSCTPNGAPNAS-5GS. Wireshark shows exactly this nesting as an indented tree; learning to read the indentation is 80% of the skill.

No. 110.235gNBAMFNGAP124InitialUEMessage (RAN-UE-NGAP-ID 1) + Registration request
Ethernet II, Src: gNB (aa:bb:cc:00:00:02), Dst: AMF-GW (aa:bb:cc:00:00:10)
Internet Protocol Version 4, Src: 10.10.0.2, Dst: 10.0.0.10
Stream Control Transmission Protocol
    Source port: 60138   Destination port: 38412
    Verification tag: 0x1a2b3c4d
    DATA chunk (ordered, stream: 0, ssn: 0)
        Payload protocol identifier: NGAP (60)
NG Application Protocol (NGAP)
    NGAP-PDU: initiatingMessage (0)
        procedureCode: id-InitialUEMessage (15)
        protocolIEs
            RAN-UE-NGAP-ID: 1
            NAS-PDU: 7e004179000d... [Registration request]
NAS-5GS Mobile Management Message
    Extended protocol discriminator: 5GS mobility management (126)
    Message type: Registration request (0x41)
    5GS registration type: initial (1)

Notice how the tree resets to column 0 four times — once per protocol layer (Ethernet, IP, SCTP, NGAP, then NAS-5GS). Everything indented under a layer is a field of that layer. Read top to bottom and each question answers the next: which machines (Ethernet/IP), which association and dissector (SCTP ports + PPID), which RAN procedure (NGAP procedureCode), and finally which NAS message the UE actually sent (NAS-5GS Message type).

Ethernet / IP SCTP (ports + PPID) NGAP (procedureCode + IEs) NAS-5GS (NAS-PDU) which two machines are talking which association; picks the dissector which RAN procedure is running what the UE told the core Figure 1. One N2 packet, outermost transport to innermost NAS payload.
Figure 1. Layer nesting inside a single N2 InitialUEMessage.
🎯

Key: The innermost layer is the one that usually carries the answer. Transport and RAN layers tell you the delivery succeeded; the NAS message tells you what the UE and core agreed (or disagreed) about.

Wireshark essentials: panes, filters, streams

Wireshark has three stacked panes and you use all three. The packet list (top) is one row per frame — number, time, source, destination, protocol, length, and an info summary. The packet details (middle) is the nested tree from the previous section for whichever row you selected. The packet bytes (bottom) is the raw hex; you rarely need it except to confirm an octet a dissector got wrong.

The single most important skill is the display filter — the expression bar that hides everything except matching frames. It does not delete packets, only shows a subset, so you can iterate freely. Type a protocol name to keep only that protocol, or a field expression to zoom in:

Display filterShows
ngapAll NGAP (N2) signalling
nas-5gsAll 5G NAS, whether standalone or nested in NGAP
sctpThe SCTP transport carrying NGAP/S1AP
s1apLTE S1-MME signalling
gtpGTP-C and GTP-U tunnels
sipIMS/VoLTE session signalling
ip.addr == 10.10.0.2All frames to or from that gNB
ngap.procedureCode == 15Only InitialUEMessage procedures

Filters combine with &&, ||, and !: ngap && nas-5gs isolates NGAP frames that carry a NAS payload, and !sctp.chunk_type == 3 hides SCTP SACKs so heartbeats stop cluttering the list. Right-clicking any field in the details pane offers Apply as Filter, which writes the correct expression for you — the fastest way to learn field names.

Follow Stream (right-click → Follow) reassembles one conversation end to end. For HTTP/2 SBI or SIP it stitches the request/response pairs; for SCTP it follows one association so you see a single UE's NGAP dialogue without interleaving.

🔧

How the dissector gets chosen: On SCTP, each DATA chunk carries a Payload Protocol Identifier (PPID). Wireshark reads the PPID to decide which dissector to hand the payload to — PPID 60 means NGAP, 18 means S1AP, 1 means M3AP, and so on. If a capture shows raw bytes where you expect NGAP, the sender used a non-standard PPID; fix it with Decode As and point the SCTP port or PPID at the NGAP dissector.

Colouring rules give the list visual meaning: TCP resets and SCTP aborts turn red, retransmissions go black-on-red, and you can add a custom rule (for example, colour nas-5gs.mm.message_type == 0x44, a Registration reject, bright orange) so failures jump out of a long trace.

Reading NAS inside NGAP

The most confusing thing for newcomers is that NAS is not a separate packet on the wire. NAS messages travel between the UE and the AMF as an opaque octet string — the NAS-PDU IE — carried inside NGAP procedures such as InitialUEMessage, DownlinkNASTransport, and UplinkNASTransport. The RAN never interprets NAS; it only relays the bytes. Wireshark, however, recognises the NAS-PDU IE and automatically re-dissects those bytes as NAS-5GS, showing them as a fresh layer at column 0 below the NGAP tree.

So when you select an InitialUEMessage and expand it, you get two things in one row: the NGAP envelope (procedure code, RAN-UE-NGAP-ID, location) and, nested through the NAS-PDU, the full Registration request the UE composed — its registration type, its concealed identity (SUCI), its security capabilities, and its requested slices.

No. 110.235gNBAMFNGAP124InitialUEMessage, Registration request (initial)
NG Application Protocol (NGAP)
    NGAP-PDU: initiatingMessage (0)
        procedureCode: id-InitialUEMessage (15)
        protocolIEs
            RAN-UE-NGAP-ID: 1
            NAS-PDU: 7e004179000d0119... [dissected below]
            UserLocationInformation: nR-CGI (PLMN 311/480, NCI 0x00A1B2C0)
            RRCEstablishmentCause: mo-Signalling (3)
NAS-5GS Mobile Management Message
    Extended protocol discriminator: 5GS mobility management (126)
    Security header type: Plain NAS message, not protected (0)
    Message type: Registration request (0x41)
        5GS registration type: initial (1)
        5GS mobile identity: SUCI, MCC=311 MNC=480, scheme=ECIES profile A
        ngKSI: no key available (7)
        UE security capability: 5G-EA0/1/2, 5G-IA1/2

Read it as a handoff: NGAP tells you the gNB relayed the UE's first message and where the UE is; the nested NAS-5GS tells you the UE is doing an initial registration, is hiding its identity behind a SUCI, and has no security key yet (ngKSI = 7). In LTE the same pattern holds — NAS travels as a NAS-EPS octet string inside S1AP and Wireshark re-dissects it identically.

An annotated attach, packet by packet

Here is the spine of a registration as it appears on N2. Follow the numbers and read the one-line cue under each block — that is the field to check first.

No. 110.235gNBAMFNGAP124InitialUEMessage + Registration request
NG Application Protocol (NGAP)
    procedureCode: id-InitialUEMessage (15)
    RAN-UE-NGAP-ID: 1
    NAS-PDU: Registration request (initial), SUCI 311/480

Look for: Message type: Registration request and 5GS registration type. This is where the dialogue starts and where the RAN-UE-NGAP-ID is born.

No. 130.290AMFgNBNAS-5GS58DownlinkNASTransport, Authentication request
NG Application Protocol (NGAP)
    procedureCode: id-DownlinkNASTransport (4)
    AMF-UE-NGAP-ID: 1   RAN-UE-NGAP-ID: 1
NAS-5GS Mobile Management Message
    Message type: Authentication request (0x56)
        ngKSI: 0   ABBA: 0x0000
        Authentication parameter RAND / AUTN present

Look for: the appearance of AMF-UE-NGAP-ID (the core now has a context) and RAND/AUTN in the NAS. Still Plain NAS, so every field is readable.

No. 150.340AMFgNBNAS-5GS44DownlinkNASTransport, Security mode command
NAS-5GS Mobile Management Message
    Security header type: Integrity protected (1)
    Message type: Security mode command (0x5d)
        Selected NAS security algorithms: 5G-EA2, 5G-IA2
        ngKSI: 0   Replayed UE security capabilities present

Look for: Selected NAS security algorithms. From the UE's Security mode complete onward, NAS is ciphered and only headers stay visible.

No. 160.360AMFgNBNGAP96InitialContextSetupRequest
NG Application Protocol (NGAP)
    procedureCode: id-InitialContextSetup (14)
    AMF-UE-NGAP-ID: 1   RAN-UE-NGAP-ID: 1
    SecurityKey: K_gNB (256-bit)
    UESecurityCapabilities / GUAMI / AllowedNSSAI present

Look for: SecurityKey (the K_gNB handed to the gNB) and AllowedNSSAI. This NGAP-only procedure sets up AS security and the UE context on the RAN.

No. 180.400AMFgNBNAS-5GS72DownlinkNASTransport, Registration accept
NAS-5GS Mobile Management Message
    Security header type: Integrity protected and ciphered (2)
    Message type: Registration accept (0x42)
        5G-GUTI assigned
        TAI list / Allowed NSSAI present

Look for: Message type: Registration accept and the assigned 5G-GUTI. If instead you see Registration reject, the 5GMM cause field is your root cause. This is the message that means the attach succeeded.

Common gotchas

A few things routinely trip people up when they first read control-plane traces.

Encrypted NAS. After Security mode command/complete, NAS messages carry Security header type = Integrity protected and ciphered. Wireshark can show the header and the message type wrapper but the plaintext body is opaque — you will not see the IEs unless you feed Wireshark the keys or capture before security activates. If a field you need has gone missing mid-trace, this is usually why.

SCTP multihoming and multiple streams. An SCTP association can run over two IP paths (multihoming), so the same logical link may show two source addresses; do not mistake them for two associations. Within one association there are many streams, and different UEs' NGAP dialogues ride different stream numbers — filter by SCTP verification tag or use Follow Stream to isolate one UE rather than reading by IP alone.

Wrong PPID. If NGAP shows up as undecoded data, the sender set a non-standard Payload Protocol Identifier. Use Decode As to map the SCTP port or PPID to the NGAP dissector.

Fragmented reassembly. Large messages (a big RRCReconfiguration, a fat InitialContextSetupRequest) span multiple SCTP DATA chunks or IP fragments. Keep Allow subdissector to reassemble enabled, and read the frame Wireshark marks as the reassembled whole, not the individual fragments.

GTP-U versus GTP-C. Both use the name GTP but are different planes: GTP-C (control) on port 2123 signals tunnel management in EPC, while GTP-U (user) on port 2152 carries the actual data on N3/S1-U. When chasing signalling, filter gtp can flood you with user-plane frames — narrow to gtpv2 for control or exclude udp.port == 2152.

Q&A Quick Q&A

Q. Why can't I just capture the air interface directly?

A. NR-Uu/LTE-Uu are radio and ciphered; a NIC can't sniff them. You capture on wired interfaces like N2/S1-MME or export RRC from an instrumented gNB/UE simulator.

Q. Where does the NAS message live in a trace?

A. As the NAS-PDU octet-string IE inside an NGAP procedure (InitialUEMessage, DownlinkNASTransport, UplinkNASTransport). Wireshark auto-dissects it as a NAS-5GS layer.

Q. How does Wireshark know a payload is NGAP and not S1AP?

A. From the SCTP PPID: 60 = NGAP, 18 = S1AP. If it's non-standard, use Decode As.

Q. Half my NAS fields disappeared partway through the trace — bug?

A. No. After Security mode command, NAS is ciphered (Security header type = protected and ciphered), so only the header is visible without keys.

Q. Which single filter is most useful for an attach?

A. ngap && nas-5gs to see every N2 frame that carries a NAS message, then ngap.procedureCode to jump to a specific procedure.

Display-filter reference

Keep this table beside you. Start broad (a protocol name), confirm the conversation, then narrow to a field once you know what you are chasing.

FilterWhat it shows
ngapAll N2 (5G RAN) signalling
s1apAll S1-MME (LTE RAN) signalling
nas-5gs5G NAS, standalone or nested in NGAP
nas-epsLTE NAS, nested in S1AP
ngap && nas-5gsOnly NGAP frames carrying a NAS PDU
ngap.procedureCode == 15InitialUEMessage only
ngap.procedureCode == 14InitialContextSetup only
nas-5gs.mm.message_type == 0x41Registration request
nas-5gs.mm.message_type == 0x44Registration reject (find failures fast)
sctpSCTP transport (associations, heartbeats)
sctp.verification_tag == 0x1a2b3c4dOne specific SCTP association
pfcpN4 session programming (SMF↔UPF)
gtpv2GTP-C control signalling only
gtp && udp.port == 2152GTP-U user-plane tunnels (N3)
sipIMS/VoLTE call signalling
ip.addr == 10.10.0.2All traffic to/from one node
http2SBI service calls (N11 and other N* SBIs)
📎

Spec note: NGAP is defined in 3GPP TS 38.413, S1AP in TS 36.413, 5G NAS in TS 24.501, and SCTP for NG in the transport annexes of TS 38.412 — Wireshark's field names track these ASN.1 definitions closely, so the tree you read maps almost one-to-one onto the spec.

Where to go next

Now that you can read a capture, walk a full attach and the interface it rides on.

Registration Call FlowNGAP (N2)Reading the call-flow pages