|Fundamentals

Reading a SIP Trace: Practical Troubleshooting

Capture and analyze SIP traffic with Wireshark and sngrep. Includes example traces for normal calls, NAT issues, and failed registrations.

SIP Signaling From the Wire Up: Part 11 of 12

Everything in this series has been building toward this: the ability to capture SIP traffic, find the call you're interested in, and follow it through the signaling to figure out where things went wrong. This is the post where we get hands on with real tools and walk through real traces.

The good news is that SIP's text based design makes it far more readable than most network protocols. You don't need expensive proprietary analyzers. The tools we'll cover here are either free or built into the systems you're already using.

Wireshark

Wireshark is the general purpose packet capture tool that every network technician should have in their toolkit. It captures all network traffic on an interface and provides powerful filtering and analysis capabilities. For SIP specifically, Wireshark has built in features that make call analysis significantly easier.

Capturing SIP traffic

To capture SIP traffic, you need to run Wireshark on a machine that can see the SIP packets. This could be the PBX itself, a mirror port on a switch, or any machine on the network path between the endpoints you're interested in.

The simplest capture filter to isolate SIP is by port:

udp port 5060

This captures all UDP traffic on port 5060, which is the default SIP port for unencrypted traffic. If your deployment uses a non-standard port, adjust accordingly. If you're using TLS, the default port is 5061 and you'll need tcp port 5061, though the encrypted payload won't be readable without the decryption keys.

If you don't apply a capture filter, Wireshark captures everything, and you'll need to use a display filter afterward to isolate SIP. The display filter for SIP is simply:

sip

Finding your call

In a busy system, there might be dozens or hundreds of simultaneous calls. Finding the specific call you're investigating is the first challenge. There are several approaches.

If you know the caller or callee's number or extension, use a display filter:

sip contains "5551234567"

This shows every SIP message that contains that phone number anywhere in the message. Once you find the INVITE for your call, note the Call-ID from the headers. Then filter on that Call-ID to see every message in the dialog:

sip.Call-ID == "[email protected]"

Wireshark's VoIP analysis features

Wireshark has a dedicated VoIP analysis view that's enormously helpful. Under the Telephony menu, select Telephony > VoIP Calls to see a list of all VoIP calls in the capture, combining SIP signaling with RTP stream information. You can select a call and click the "Flow Sequence" button to see its complete message sequence as a ladder diagram, the same visual representation we used in post 3, generated directly from the capture data. You can also click "Play Streams" to actually listen to the RTP audio from the capture. Being able to hear what the call sounded like is incredibly useful when debugging quality issues.

Reading the ladder diagram

The ladder diagram view in Wireshark shows each SIP message as an arrow between the sending and receiving IP addresses, labeled with the method or response code. A normal completed call looks like this:

10.0.0.50             10.0.0.1             192.168.1.100
    |--- INVITE -------->|                      |
    |<-- 100 Trying ------|                      |
    |                     |--- INVITE ---------->|
    |                     |<-- 180 Ringing ------|
    |<-- 180 Ringing ------|                      |
    |                     |<-- 200 OK -----------|
    |<-- 200 OK -----------|                      |
    |--- ACK ------------>|                      |
    |                     |                      |
    |          [RTP flows between endpoints]     |
    |                     |                      |
    |--- BYE ------------>|                      |
    |                     |--- BYE ------------->|
    |                     |<-- 200 OK -----------|
    |<-- 200 OK -----------|                      |

When a call fails, the diagram will deviate from this pattern, and the deviation tells you what went wrong. An INVITE that goes out but gets no response at all (no 100 Trying, nothing) means the message isn't reaching the first hop. An INVITE that gets a 100 Trying from the proxy but nothing beyond that means the proxy can't reach the destination. A 4xx or 5xx final response tells you the call was explicitly rejected, and the code tells you why.

sngrep

sngrep is a specialized SIP capture tool that runs in the terminal. It's faster and more focused than Wireshark for SIP analysis because it's designed specifically for SIP and nothing else. On many Linux based PBX systems, sngrep is the quickest way to see what's happening with SIP traffic in real time.

To install sngrep on a Debian or Ubuntu based system:

apt install sngrep

Launch it with:

sngrep

By default, sngrep captures on all interfaces and shows a list of SIP dialogs as they happen. Each row represents a call with the source, destination, method, and current status. You can filter in real time by pressing F7 and entering filter criteria.

Selecting a dialog and pressing Enter shows the ladder diagram for that call. Selecting a specific message in the ladder and pressing Enter shows the full SIP message content. This three level navigation, from call list to flow to message detail, makes it fast to drill from "which call had a problem" to "what exactly was in the message."

sngrep also supports reading from a pcap file:

sngrep -I capture.pcap

This is useful when someone has already captured traffic with tcpdump or Wireshark and you want to analyze the SIP content quickly. For a browser-based alternative, the PCAP analyzer extracts SIP flows and RTP statistics from uploaded capture files without installing anything.

Filtering sngrep

sngrep supports capture filters on the command line:

sngrep host 10.0.0.50
sngrep port 5060
sngrep host 10.0.0.50 and port 5060

You can also filter by SIP method or header content using the interactive filter (F7 key) once sngrep is running.

PBX built in logging

Most PBX platforms have built in SIP debug logging that can be enabled without setting up a separate capture tool. This is often the first thing you have access to when troubleshooting because it doesn't require installing anything or setting up port mirroring.

Asterisk

Enable SIP debug logging in the Asterisk CLI:

asterisk -rvvv
sip set debug on

Or for PJSIP (the newer SIP stack in Asterisk):

pjsip set logger on

This dumps every SIP message to the console in real time. The output is verbose but readable. Each message is shown with the full headers and body, prefixed by whether it was received or transmitted. You can filter the output by piping through grep to find specific Call-IDs, phone numbers, or response codes.

FreeSWITCH

Enable SIP trace in FreeSWITCH:

sofia global siptrace on

Or for a specific profile:

sofia profile internal siptrace on

The output is similar to Asterisk: full SIP messages with direction indicators.

3CX

3CX provides SIP trace functionality through its management console. The trace output can be downloaded as a file and analyzed with sngrep or a text editor. 3CX also has a built in SIP log viewer that formats the messages and provides basic call flow visualization.

Walking through example traces

Let's look at three scenarios to practice reading traces.

Trace 1: Successful call (what normal looks like)

10.0.0.50 --> 10.0.0.1   INVITE sip:[email protected]
10.0.0.1  --> 10.0.0.50  SIP/2.0 100 Trying
10.0.0.1  --> 192.168.1.100  INVITE sip:[email protected]
192.168.1.100 --> 10.0.0.1   SIP/2.0 180 Ringing
10.0.0.1  --> 10.0.0.50  SIP/2.0 180 Ringing
192.168.1.100 --> 10.0.0.1   SIP/2.0 200 OK
10.0.0.1  --> 10.0.0.50  SIP/2.0 200 OK
10.0.0.50 --> 192.168.1.100  ACK
[RTP flows]
10.0.0.50 --> 10.0.0.1   BYE
10.0.0.1  --> 192.168.1.100  BYE
192.168.1.100 --> 10.0.0.1   SIP/2.0 200 OK
10.0.0.1  --> 10.0.0.50  SIP/2.0 200 OK

Every step is here: INVITE, 100, 180, 200, ACK, conversation, BYE, 200. This is what you're comparing against when something goes wrong.

Trace 2: Call with no audio (NAT problem)

10.0.0.50 --> 10.0.0.1   INVITE sip:[email protected]
                          [SDP: c=IN IP4 10.0.0.50, m=audio 49170]
10.0.0.1  --> 10.0.0.50  SIP/2.0 100 Trying
10.0.0.1  --> 198.51.100.10  INVITE sip:[email protected]
                              [SDP: c=IN IP4 10.0.0.50, m=audio 49170]
198.51.100.10 --> 10.0.0.1   SIP/2.0 200 OK
                              [SDP: c=IN IP4 198.51.100.10, m=audio 3456]
10.0.0.1  --> 10.0.0.50  SIP/2.0 200 OK
10.0.0.50 --> 198.51.100.10  ACK

The call connected. Both sides sent 200 OK and ACK. But look at the SDP. Alice's INVITE has c=IN IP4 10.0.0.50, which is a private address. Bob's phone at 198.51.100.10 is on a different network. When Bob tries to send RTP to 10.0.0.50, that address is unreachable from his network. Result: Bob can't hear Alice. Meanwhile, Alice's SDP port 49170 might receive audio from Bob because Alice's NAT device might map incoming RTP to the right internal port (if the outbound RTP from Alice created a NAT mapping), or it might not. This is classic one way or no audio, and the problem is visible right there in the SDP.

Trace 3: Failed registration (bad credentials)

10.0.0.50 --> 10.0.0.1   REGISTER sip:example.com
10.0.0.1  --> 10.0.0.50  SIP/2.0 401 Unauthorized
                          [WWW-Authenticate: Digest realm="example.com" nonce="abc123"]
10.0.0.50 --> 10.0.0.1   REGISTER sip:example.com
                          [Authorization: Digest username="alice" response="def456"]
10.0.0.1  --> 10.0.0.50  SIP/2.0 401 Unauthorized
                          [WWW-Authenticate: Digest realm="example.com" nonce="ghi789"]
10.0.0.50 --> 10.0.0.1   REGISTER sip:example.com
                          [Authorization: Digest username="alice" response="jkl012"]
10.0.0.1  --> 10.0.0.50  SIP/2.0 401 Unauthorized

The pattern is clear: the phone sends REGISTER, gets challenged, responds with credentials, and gets challenged again instead of getting a 200 OK. The credentials are wrong. The phone keeps trying because it doesn't distinguish between "you didn't authenticate" (the first 401) and "your authentication failed" (the subsequent 401s). The username "alice" is visible in the Authorization header, so you can verify it's what you expect. The password isn't visible, but you know it's wrong because the server keeps rejecting it.

Tips for efficient trace reading

Always start by finding the Call-ID. Once you have it, you can filter everything else away and focus on the specific call.

Check timestamps. The time between an INVITE and a 100 Trying should be milliseconds. If it's seconds, there's a network delay. The time between 180 Ringing and 200 OK tells you how long the phone rang before someone answered.

Look at both sides when possible. A capture from only one side of the conversation shows you what that side sent and received, but doesn't show you what happened at the other end. If possible, capture at both the caller and callee simultaneously. This reveals problems in the middle, like messages being modified by a proxy or SBC.

Save your captures. When you're troubleshooting a call issue, start the capture before reproducing the problem and stop it after. Save the capture file. If you need to escalate to a vendor or provider, the capture file is the single most useful thing you can give them.


Next up: Common SIP Problems and What They Look Like, a symptom based troubleshooting reference for the problems you'll encounter most often.

sipwiresharksngreppacket-capturetroubleshootingvoip

Share

Opens your messaging app. We do not collect or store any phone numbers.
Opens your email client. We do not collect or store any email addresses through sharing.

Want to know when we publish new articles? Sign up for updates