SIP Call Flow Visualizer

Paste a SIP log and get a ladder diagram, a list of detected problems and a summary of the SDP offer/answer. The tool runs in your browser: its own code makes no network requests and stores nothing, so the tool does not upload your log. This page also loads Google’s advertising script, which makes its own requests. If a trace must not share a page with any third-party script, run npm run build on the source below and open dist/sip-flow-visualizer.html, a single file that works offline.

Try a sample:

SIP 로그를 붙여 넣으면 호 흐름을 사다리 그림(래더 다이어그램)으로 그리고, 찾아낸 문제와 SDP 코덱 협상 결과를 함께 보여 주는 도구입니다. 화면과 안내는 영어로 되어 있습니다. 도구 코드는 로그를 어디에도 보내거나 저장하지 않지만, 이 페이지는 Google 광고 스크립트를 불러오고 그 스크립트는 따로 요청을 보냅니다. 민감한 로그는 아래 소스 코드에서 npm run build로 만든 dist/sip-flow-visualizer.html 파일에서 보세요. 이 파일은 인터넷 연결 없이도 열립니다.

How to use it

  1. Get a SIP trace as text (see below), or click one of the Try a sample buttons.
  2. Paste it into the box, or click Open file / drop a .txt or .log file (up to 5 MB).
  3. Click Visualize. If the log contains several calls, pick one in the Calls list (the red and amber counters show errors and warnings).
  4. Click any arrow in the diagram, or any item under Problems found, to see the full SIP message.
  5. Check SDP negotiation for the codecs each side offered and the codecs they have in common.

Getting a trace

Any of these works. Run capture commands only on systems you are allowed to monitor.

# ngrep: prints a "U date time src -> dst" line before each message
sudo ngrep -d any -q -t -W byline port 5060 > trace.txt

# tcpdump + sngrep: capture, then open in sngrep and save the dialog as text
sudo tcpdump -i any -s 0 -w trace.pcap port 5060

Server logs that print YYYY-MM-DD hh:mm:ss.mmm src -> dst before each message are read as-is. Logs with only the raw SIP messages also work; the tool then guesses addresses from the Via header and marks them as guessed.

Example: what the broken-call sample shows

SIP Call Flow Visualizer result for the broken sample: ladder diagram of call codec-2@example.com between 198.51.100.60:5060 and example.com:5060 with five arrows, red markers on the 200 OK and the second INVITE, an amber marker on OPTIONS, a list of five problems and the SDP offer/answer table with no common codec
Screenshot of the broken-call sample with call codec-2@example.com selected; each marker has the colour of the most severe problem on that message.

To get this view, click the sample Missing ACK, codec mismatch, hold (raw), then the second call in the Calls list. The counters and the list do not add up, and that is expected. A counter shows only the errors and warnings of its own call, so codec-2 shows 2 and 1 while Problems found lists five items. The hold notice is only info, and the unreadable line belongs to no call, so it is listed under every call. In the ladder, the red marker on the 200 OK comes from the codec check, not from signalling: this INVITE did get its ACK. The second INVITE is red for the missing response, although it also carries the hold notice.

The two columns are guesses. These are raw SIP messages with no address lines, so the right-hand column example.com:5060 is the domain from the Request-URI, not a device. The media address is in the SDP table: the SDP in the 200 OK puts the answering side’s media at 192.0.2.50:7000. Click any arrow and the detail line says addresses guessed from Via. The time column is empty because the log has no timestamps.

What the tool printedWhy it mattersCheck first
ERROR INVITE (CSeq 2) never got a final response.This is a re-INVITE inside an established call (its To header already has a tag). If a re-INVITE gets no response at all, RFC 3261 section 14.1 says the caller ends the dialog, so an attempt to put the call on hold can end the call.The rule only asks whether the log contains a final response, and this log ends one message later. Check that the capture ran at least 32 s (64 × T1) past the request, then look for INVITE retransmissions over UDP or a BYE.
ERROR No common codec: offer [G729] vs answer [PCMU].With nothing in common, the answerer must reject the stream by setting its port to 0, and when no stream has a codec in common the whole offer is rejected (RFC 3264 section 6.1); a UAS that rejects an offer should reply 488 (RFC 3261 section 13.3.1.3). Here a 200 OK accepted it with PCMU on port 7000.Look at the answer’s m= line. Port 0 is a correct rejection; a non-zero port with no codec from the offer means the answer itself is wrong. The tool compares codec names only, so a shared telephone-event entry hides a mismatch.
WARN OPTIONS (CSeq 3) got no response.This OPTIONS is also sent inside the call. When a request inside a dialog gets no response, RFC 3261 section 12.2.1.2 says the caller should end the dialog, which for a call means a BYE.Same checks as for the re-INVITE. OPTIONS is the last message in the log, so the tool cannot tell a missing answer from a capture that stopped early.
WARN Line 38: could not read as SIP: "this line is not SIP and should be reported"This is about the input, not the call. A skipped line can hide a real message: when a bracketed prefix was added in front of this sample’s ACK line in a separate check (not one of the tests), that ACK became a second warning of this kind and call codec-2 also got a missing-ACK error.Fix the input first, for example by removing log prefixes, and only then trust the other findings. The line number counts lines in the pasted text.
INFO SDP puts the call on hold (sendonly / inactive / 0.0.0.0).Hold itself is normal. Here it is only requested: the re-INVITE has no answer, so nothing shows that the other side accepted it with recvonly or inactive (RFC 3264 section 6.1).Read it together with the error on the same arrow. Also compare the o= version: this re-INVITE changes codec and direction but keeps the version of the first offer, which RFC 3264 section 8 does not allow. The tool does not read o= lines.

How these rules were chosen and tested is in the build post, SIP Call Flow Diagram Tool Built with Claude Code. This sample is a synthetic log written for the tests, and the tool has not yet been checked against real field traces.

What it can and cannot do (v0.1.1)

AreaSupportedNot yet
Inputngrep text, timestamped “src -> dst” logs, raw SIP messages, compact headers (i, f, t, v, m, l…), CRLF or LFpcap files, SIP over TLS (encrypted), vendor-specific log layouts, logs over 5 MB
DiagramOne ladder per Call-ID, hosts in order of appearance, relative timestamps, click for the full messageMerging the legs of one call across different Call-IDs (B2BUA), export to PNG/SVG
ChecksError final responses, INVITE without final response, missing ACK, request without response, retransmissions, late first response to an INVITE (no response within 32 s) or late final response to other requests (> 32 s), no common codec, holdPRACK/100rel rules, session timers, REFER/transfer flows, SIP timer accuracy per transport, RTP quality
SDPOffer/answer per INVITE, codecs, media IP/port, direction, hold detection (c=0.0.0.0 counts only in a re-INVITE)ICE candidates, SRTP crypto, video attributes in detail

Treat the result as a first look, not a verdict: 401/407 challenges and 487 after CANCEL are shown as info because they are normal, and addresses guessed from Via can be wrong behind NAT.

How to extend it for your own logs

The source is small (about 600 lines of plain JavaScript, no dependencies) and split by job, so most changes touch one file.

You want to…Change thisHint
Read your own log layoutsrc/parse.jsAdd a regular expression next to NGREP / STAMP that captures time, source and destination from the line printed before each message.
Add a new checksrc/analyze.jsEach rule is a few lines that call add(code, level, call, message, text). Transactions are grouped by Via branch + CSeq, so “request without X” rules are easy.
Change the drawingsrc/render.js, src/style.cssThe diagram is plain SVG; colours are CSS variables, so light and dark themes follow automatically.
Use it offline or inside your companynpm run buildProduces a single HTML file you can open from disk with no network access.
npm test        # 23 tests on synthetic logs (Node.js 18+)
npm run build   # dist/sip-flow-visualizer.html (single file) and dist/embed.html

Add a test with a sample of the new format before changing the parser. The samples use documentation IP ranges (RFC 5737) and example.com, so never paste real customer data into a test.

Download

Version 0.1.1 · MIT license · source, tests and build script included (25 KB).

Changes in version 0.1.1 (October 8, 2026)

  • A call that rang for more than 32 seconds before it was answered is no longer flagged as slow. For an INVITE the tool now times only the first response, because a provisional response such as 180 Ringing stops the INVITE timeout (Timer B, RFC 3261 section 17.1.1.2). Other requests are still timed to their final response (Timer F, section 17.1.2.2).
  • The address 0.0.0.0 in the first offer or answer of a call is no longer reported as hold. Trickle ICE can put it there as a placeholder before the real addresses are known (RFC 8840 sections 4.1.1 and 4.1.3). In a re-INVITE it still counts as hold, and so do sendonly and inactive.
  • Three display fixes: the empty result area no longer shows before the first run, the 1. SIP log label on this page has its missing space back, and on phones long addresses in the results now wrap instead of running off the right edge of the screen.
  • A To tag written with spaces around = is now recognised, and slow-response times are rounded up so a value just over 32 s no longer reads as 32.0 s. The automated tests grew from 14 to 23 to cover the detection changes.

How it was built

This tool was designed and built with Claude Code as part of the Protocol AI Lab build log. I set the requirements and approved each step; the AI wrote the code and the tests, and checked the results in a browser. The build story, with the real prompts, the dead ends and the time it took: SIP Call Flow Diagram Tool Built with Claude Code.

AI disclosure: built with Claude Code (Claude Opus 5.5). Requirements and approval by J. Kim. Tested with 23 automated tests and in the browser. Not yet validated on real field traces. This revision was drafted with AI assistance. It corrects what the intro said about network requests, updates the title of the linked build post, and adds a short Korean introduction, a worked example of the broken-call sample and a screenshot of its result, captured from the tool’s offline build in an automated browser. J. Kim read and approved this revision on October 8, 2026. Later the same day, at J. Kim’s request, the tool was updated to version 0.1.1; the changes are listed above.

Scroll to Top