Stock Wireshark dissectors already decode GTPv1-C, GTPv2-C, GTP-U and PFCP. The hard part is seeing one subscriber scenario across control plane, user plane and PFCP — and noticing 3GPP mistakes that still parse as individual packets.
This article covers what stock Wireshark already gives you, what GTP Session Tracker adds, how planes are correlated, and documented limits. Use lab captures or data you are authorized to inspect; do not share production subscriber identifiers.
What stock Wireshark already does
Wireshark’s display-filter reference exposes fields such as gtpv2.teid and, for many GTPv2 pairs, gtpv2.response_in / gtpv2.response_to. You can filter one TEID or jump request↔response within that protocol.
What it does not give you out of the box is a single session id that merges:
- GTPv2-C (and GTPv1-C) signalling,
- the PFCP session that provisioned the same F-TEID / F-SEID,
- and the GTP-U G-PDUs that later use those TEIDs.
SIP already has dialog/call tracking; mobile-core captures need the same idea across three protocol families.
What GTP Session Tracker adds
GTP Session Tracker is one Lua file for Wireshark (GUI menus and tshark fields). The product page and plugin header (v2.0) agree on the model:
- Messages from GTPv1-C, GTPv2-C, GTP-U (G-PDU) and PFCP are correlated into logical sessions.
- Legs that share an F-TEID or F-SEID are merged into one canonical session id.
- Display filter
gtpsess.session == Nthen shows that whole session across those protocols. - Sessions related only by UE IP or a shared tunnel are related, not merged (pools are reused; link only while the earlier session is open).
- Common 3GPP problems are raised as Wireshark expert items and as short codes on
gtpsess.violation.
Fields (exact names)
| Field | Meaning |
|---|---|
gtpsess.session |
Canonical session id after merge |
gtpsess.leg |
Per-protocol leg id before merge (shown when it differs) |
gtpsess.linked |
Related sessions (UE IP / shared tunnel) |
gtpsess.role |
Procedure |
gtpsess.plane |
Plane |
gtpsess.state |
Session state after this message |
gtpsess.imsi / gtpsess.apn |
Session IMSI and APN/DNN when present |
gtpsess.handover |
Set on the message that moved a GTP-U endpoint |
gtpsess.violation |
Short anomaly code(s) on the packet |
Anomalies flagged as experts
| Expert / idea | When |
|---|---|
| Retransmission | Same sender, message type and sequence number within the retransmission window (preference, default 30 s) |
| Orphan response | Response with no matching request in the capture |
| TEID zero | A session-initiating GTPv2-C Create Session Request or GTPv1-C Create PDP Context Request whose header TEID is non-zero and was never allocated by the receiver earlier in the capture. A legitimate initiating request with TEID=0 is not flagged; the plugin does not check for zero TEIDs where a non-zero value is required (TS 29.274 7.2.1 / TS 29.060 7.3.1, as cited by the plugin) |
| TEID collision | Control TEID reused at an IP while the previous session is still open |
| Procedure failed | Procedure completed with a non-acceptance Cause |
| Unknown GTP-U | G-PDU TEID not announced by any earlier control-plane message |
| PFCP SEID | Session Establishment Request without SEID=0 in the header (TS 29.244 7.2.2.4.1) |
| Handover | GTP-U endpoint of the session changed (handover / path switch) |
Menus and stability
- Tools > GTP-PFCP Session Tracker > Session Analysis — summary of sessions, legs, states, unrecognised GTP-U TEIDs, per-session frames and duration (GUI).
- Tools > GTP-PFCP Session Tracker > Reset and reload
- Packet list right-click: Apply GTP/PFCP session filter
- Preference: Retransmission window (seconds)
Each frame is analysed once after open/reload and cached by frame number, so experts stay stable across clicks and filters. State resets on file open/reload.
Install (from the product page)
- Download
gtp_session_tracker_v2.1.luafrom the official Dropbox link on GTP Session Tracker (SHA-256 published on that page). - Copy it into your Personal Lua Plugins folder (Help > About Wireshark > Folders): typically
%APPDATA%\Wireshark\pluginson Windows or~/.local/lib/wireshark/pluginson Linux. - Analyze > Reload Lua Plugins (Ctrl+Shift+L) or restart Wireshark.
- Open a capture that contains GTP/PFCP, then use the right-click session filter or Session Analysis.
No separate installer: Wireshark loads the Lua file directly.
Practical reading workflow
- Open the capture (lab-generated or authorized).
- Right-click a GTP or PFCP packet → Apply GTP/PFCP session filter, or type
gtpsess.session == Nonce you know N from the packet details or Session Analysis. - Confirm control-plane TEIDs/F-TEIDs match later GTP-U G-PDUs for the same session id.
- Open Expert Information or filter
gtpsess.violation. - Check
gtpsess.linkedwhen two sessions share a UE IP but were not merged — expected, not a bug. - For tshark, the plugin documents that merged ids on every frame need
tshark -2 -R frame(plain-2builds no tree in pass 1, so the plugin only runs in pass 2).
To produce correlated lab traffic without a live core, see the Mobile Core article and Mobile Core. This plugin analyses captures; it does not generate them.
Limitations (as documented)
- UE IP creates related sessions only; it does not merge sessions.
- Session Analysis and some menu actions are GUI-only; tshark still exposes fields with the
-2 -R framecaveat above. - Frames seen before a later merge (e.g. PFCP before the GTPv2 response that shares an F-TEID) are canonicalised at display time — hence the two-pass tshark form.
- It flags selected issues cited against TS 29.060 / 29.274 / 29.244; it is not a full conformance suite.
- Field extractors use
pcall: a missing field in an older Wireshark does not abort load; that IE simply contributes nothing.
FAQ
Is gtpsess.session == N enough to see GTP-U as well as GTP-C?
Yes for TEIDs announced on the control/PFCP legs that were merged into that session. G-PDUs whose TEID was never announced are flagged as unknown GTP-U instead of silently joining.
Why do I see related sessions instead of one big merge?
Sessions tied only by UE IP (or a shared tunnel link) stay separate and appear in gtpsess.linked, because address pools are reused.
Does stock Wireshark already merge PFCP and GTP-U?
Stock filters work per protocol (for example gtpv2.teid). Cross-protocol session merge is what this plugin adds.
Can I use this in tshark CI?
Yes, with the documented two-pass form tshark -2 -R frame … so merged session ids appear on every frame.
Where do I get the file hash?
The product and downloads pages publish size and SHA-256 for gtp_session_tracker_v2.1.lua; verify after download.