Read a SIP call and see why it failed. SIP is the signaling protocol that sets up and tears down voice calls.
- sipnab reads that signaling from one of these sources:
- a live network interface,
- a pcap (packet capture) file,
- a HEP feed that your SIP proxies send. HEP copies each SIP message to a collector over the network.
- From an interface or a file, it also reads the RTP audio packets underneath. It grades their quality.
- It shows you:
- the call flow,
- the audio quality,
- the security signals around each call.
sipnab is one binary with no database and no web UI to run.
- You can point it at one box's traffic.
- Or you can have every proxy in a cluster send it HEP. Then one listener sees calls across many nodes, without anything installed on the production hosts.
- It keeps what it sees in memory.
- It answers through its terminal view, a command line, a REST API, and an MCP server.
You can try it without installing anything. sipnab.com/analyze reads a pcap in your browser without uploading it.
The full documentation lives at sipnab.com and in docs/. The Glossary defines the terms these pages use.
On Linux (x86_64 or aarch64) or macOS:
curl -fsSL https://sipnab.com/install.sh | shThe script does three things:
- It picks the build for your OS, CPU and glibc.
- It checks the build against the release's
.sha256file. - It installs the build to
/usr/local/bin. It usessudoonly if that directory is not writable.
You can read the script first. To confirm the
install, run sipnab --version. It prints the version and the features
compiled in.
Other ways in:
| You want | Do this |
|---|---|
| Homebrew on macOS | brew install NormB/tap/sipnab |
A .deb or .rpm, including -noaudio builds for headless servers |
Install with your package manager |
| A static Linux binary with no libpcap dependency (musl) | Release artifacts |
| To prove a download is genuine (checksums, build provenance, SBOM) | Verify a download is genuine |
| To build it yourself | Build from source, below |
Here are four common starting points. Each one ends with a link to the page that goes further.
Reading a file needs no root and no network interface. So it is the easiest place to start. This sample holds one completed call and four failed ones:
curl -LO https://github.com/NormB/sipnab/raw/main/tests/pcap-samples/sip-problem-call.pcapOpen it in the TUI (text user interface), the interactive full-screen view.
- Press
F1for the keys each view accepts. - To quit, press
qand thenyto confirm. - Or press
Ctrl-Cto quit at once.
sipnab -I sip-problem-call.pcapOr stay on the command line. -N skips the TUI and prints to the terminal.
List every call in the file, with its final status code, as a report table:
sipnab -N -I sip-problem-call.pcap --report --no-cli-printPrint only the messages of calls that failed or sounded poor. The output is
JSON that you can pipe into jq:
sipnab -N --json -I sip-problem-call.pcap --problemsExplain one call. A Call-ID is the SIP header that names a call. The report table above lists them:
sipnab -N -I sip-problem-call.pcap --call-report 'busy-3a2b1c@192.0.2.30' --no-cli-printNext:
- Triage a capture from the command line walks through these commands with their output.
- Your first analysis in the TUI does the same interactively.
Live capture on Linux needs raw-socket access. Instead of running sipnab as root, grant the binary the two capabilities once. Then run it as yourself:
sudo sipnab --setup-capsThen capture on an interface. Replace eth0 with your interface. ip link
lists them:
sipnab -d eth0For a stream of JSON, one SIP message per line, add -N --json:
sipnab -N -d eth0 --json- Re-run
--setup-capsafter each upgrade. Replacing the binary clears its capabilities. - On macOS, run live capture with
sudoinstead. - Capture live traffic without root explains the privilege model.
- Tune capture on a busy server covers packet loss.
Kamailio, OpenSIPS and Asterisk can each mirror their SIP traffic over HEP. Then one sipnab listener sees the calls of every node. You install nothing on the production hosts.
A listener on a routable address must do one of two things:
- name the senders it accepts (
--hep-allow), - or share a secret with them (
--hep-auth-file).
Otherwise sipnab refuses to start it:
sipnab -N -L 0.0.0.0:9060 --hep-allow 192.0.2.10To try it on one machine, bind to loopback. Then replay a capture into it from a
second terminal with -H (HEP send):
sipnab -N -L 127.0.0.1:9060sipnab -N -I sip-problem-call.pcap -H 127.0.0.1:9060A proxy's HEP feed carries its SIP signaling, not the call audio. For audio quality, run sipnab where the media flows as well.
These guides set this up end to end, TLS transport included:
sipnab can answer other programs while it captures. Choose an API key and keep
it in the environment. sipnab reads it there, and ps cannot see it there:
export SIPNAB_API_KEY="$(openssl rand -hex 32)"Serve the REST API and Prometheus metrics on loopback. The process keeps
serving until you press Ctrl-C:
sipnab -N -I sip-problem-call.pcap --api 127.0.0.1:8080 --metrics 127.0.0.1:9100curl -H "Authorization: Bearer $SIPNAB_API_KEY" http://127.0.0.1:8080/v1/dialogsMCP (Model Context Protocol) lets an AI agent, such as Claude Code, call sipnab's analysis as tools.
- Over stdio, the default transport, the agent starts sipnab itself. So this is the command you register with your MCP client.
--mcp-transport httpserves remote agents instead.
sipnab --mcp -N -I sip-problem-call.pcap --mcp-tools coreThe server offers 74 tools. Every tool costs the agent context before it asks anything.
--mcp-tools coreloads a small set that still answers a whole call.- Named bundles such as
signalingandmediaload other sets. - Bundles of your own in the config file also load other sets.
- See Choosing which tools load.
Next:
- Privileges. Reading files needs none.
- For live capture, prefer
sudo sipnab --setup-capsto running as root. - Started as root, sipnab opens the capture device. Then it drops to an
unprivileged user (
nobody, or--user). --chrootconfines it further.
- For live capture, prefer
- Listeners bind to loopback by default. On a routable address, these
refuse to start without an option:
- the REST API, without
--api-keyor--api-signing-key, - MCP over HTTP, without
--mcp-tokenor--mcp-signing-key, - the metrics endpoint, without
--metrics-auth. - Set up authentication covers signed tokens, rotation and revocation.
- the REST API, without
- TLS. The REST API, MCP over HTTP and the metrics endpoint each serve
HTTPS themselves when given a certificate and key:
--api-tls-cert/--api-tls-key(API TLS),--mcp-tls-cert/--mcp-tls-key(MCP TLS),--metrics-tls-cert/--metrics-tls-key(Metrics TLS),- or the matching
tls_cert/tls_keykeys insipnab.toml. - HEP can use TLS in both directions (
--hep-listen-transport tls,--hep-send-transport tls). The sender does one of two things:- it trusts only a named CA (
--hep-tls-ca), - or it adds one to the host's bundle (
--hep-tls-extra-ca).
- it trusts only a named CA (
- Sending. Capture is passive. The features that send are off until you
ask for them. For example:
- HEP forwarding (
-H), - reverse DNS (
--reverse-dns), --kill-scannerand-K. On a live interface, these answer scanners with SIP responses.- When sipnab reads a capture file, it sends no scanner responses.
- HEP forwarding (
- The threat model. Threat model and security assessment lists the assets, trust boundaries, mitigations and known gaps.
- Several ways to read the results.
- the interactive TUI,
- the non-interactive CLI (
-N), - JSON (
--json, one message per line), - reports,
- the REST API,
- the MCP server.
- Call analysis.
- dialog state,
- PDD (post-dial delay, the wait before ringing),
- SIP header matching (
--from,--toand the rest), - a filter language of 42 fields, 8 operators and boolean logic.
- Diagnostic aliases.
- As flags:
--problems,--slow-setup,--short-calls,--one-wayand--nat-issues. - Through
--filter:codec-asym,ptime-asym,payload-asym,duration-asymandlate-media. For example:sipnab -N -I capture.pcap --filter codec-asym.
- As flags:
- RTP quality.
- jitter,
- loss,
- MOS (mean opinion score). This is an estimate of how the call sounded, from the ITU-T G.107 E-model (where it comes from).
- RTCP XR (RFC 3611) reports,
- one-way audio.
- Security analysis.
- Scanner detection, registration floods, digest credential leaks, STIR/SHAKEN, and fraud heuristics.
- It sends alerts to syslog, JSON or a command of your own (
--alert,--alert-exec). - It can write fail2ban input (
--fail2ban). - It can ask TFPS to ban a source. That action stays
off until
--allow-actionenables it.
- HEP v3 send over UDP, TCP or TLS, and HEP v1/v2/v3 receive.
- TLS and SRTP decryption. It decrypts from these sources:
- an SSLKEYLOGFILE (TLS 1.2 and 1.3),
- an RSA private key (
--tls-key, TLS 1.2 RSA key exchange only), - SRTP keys. These are the SDES
a=cryptokeys in the SDP, or a master-keys file with--srtp-keys. - DTLS-SRTP (
--dtls-keylog, RFC 5764). - Capture SIP over TLS helps you choose.
- TLS capture with uprobes. This does not break TLS.
- It works on a host where you already have root.
- Kernel uprobes read the SIP plaintext inside OpenSSL or wolfSSL, before
the library encrypts it (
--uprobe-tls). - So it needs no key, certificate or restart.
- Every Linux build has it. Its default tracefs backend needs no BTF.
- The eBPF backend also recovers the peer addresses.
- It is in the released Linux gnu tarballs,
.deband.rpm. - It is not in the static musl builds.
- It needs a kernel with BTF.
- It is in the released Linux gnu tarballs,
- SIPREC metadata. Reads the recording metadata (RFC 7866) that a session recording client sends. sipnab is not a recording client or server.
- Relay correlation.
- It ties media on a relay back to its call. The relay can be an rtpengine
relay (rtpengine) or an rtpproxy relay
(
--rtpproxy-control). - It reads rtpengine's own counters over its control port
(
--rtpengine-control). sipnab labels them as the relay's report, not sipnab's measurement.
- It ties media on a relay back to its call. The relay can be an rtpengine
relay (rtpengine) or an rtpproxy relay
(
- vCon export and delivery.
- It writes each observed call as a vCon, a conversation container
(
--export-vcon, Export a call as a vCon). --vcon-forward, a separate process, delivers them to a vCon store. Two examples are vcon.store and a self-hosted conserver.- It is in the gnu and macOS builds. The static musl builds lack the
vconfeature.
- It is in the gnu and macOS builds. The static musl builds lack the
--vcon-forward-kind vcon-storeadds vcon.store's ingest path and header.- It changes only the copy it sends.
- The reason: vcon.store's validator rejects the string-array
extensionsthat both vCon drafts define (Send sipnab's vCons to vcon.store).
- Export rules (
[[vcon.rule]]) pick calls by filter. They write them per leg or per call. - A call can go to your own transcriber first (
[[vcon.enrich]]). - You can follow and hear live calls while they are in progress.
- A rule with
encrypt_towrites the signed and encrypted form.
- It writes each observed call as a vCon, a conversation container
(
- Export formats. pcap and pcapng, TXT, JSON, NDJSON, CSV, an HTML page of the call flow, Markdown, WAV audio, SIPp XML scenarios and RTP JSON.
- Tunnels and transports. It reads SIP in these forms:
- inside VLAN and QinQ tags, MPLS, GRE, GTP-U, VXLAN, GENEVE and other tunnels,
- SIP over WebSocket,
- SIP split across IP fragments or TCP segments.
- Some need an option on a live capture. Encapsulations lists which.
- Ranked analysis and conformance.
--analyzelists every problem in a capture, worst first.--yang-analyzewrites it as RFC 7951 JSON against a published YANG module.--lintchecks RFC conformance. Each finding has a rule ID and RFC section.
- pcap in and out.
- It reads and writes pcap and pcapng, with rotation and splitting.
- It reads directories, tar archives and password-protected ZIP and 7z archives.
- It reads stored vCon containers as the SIP messages they hold.
- vCons with pseudonyms, and a hardened process.
--redactreplaces identities, addresses and hostnames in exported vCons with keyed pseudonyms.--redact-mapwrites the reverse map to a file only you can read.- A capture started as root drops to
--userafter opening its devices. - It can confine itself with a Landlock sandbox (
--sandbox) and a seccomp allowlist (--seccomp).
- MCP server. 74 tools over stdio or HTTP.
- 61 only read.
- The 13 that write each say what they change.
- File writes stay inside
--mcp-file-root. - These stay off until you enable them:
- swapping the capture (
--mcp-allow-open-capture), - shutting the server down (
--mcp-allow-shutdown), - recording findings (
--mcp-allow-save-findings), - asking TFPS to ban a source (
--allow-action).
- swapping the capture (
- MCP server has a first working example.
- Call list with sortable columns, multi-select, inline search and filters
- Call flow ladder with color-coded arrows, SDP codecs, and PDD
- Four timestamp modes: absolute, delta from the previous message, delta from the first, and scaled to time
- Split view: the raw SIP message beside the ladder, resized with
+/- - Message diff: select two messages with
Spaceto compare them - Extended flow: merge the legs of one call through a proxy or B2BUA into
one ladder (
xorF4) - RTP streams with jitter, loss and MOS (
Tab), audio playback, and WAV export (F2) - Quality views: a live MOS dashboard, a loss map and a call timeline; carrier views: ASR, NER and ACD, top talkers and a call-volume histogram
- Operator notes on messages, saved as pcapng packet comments, and names for hosts from hosts files and DNS
Keybindings lists every key, per view.
sipnab is Rust everywhere except the OS boundary.
- It has 111
unsafeblocks, all of them FFI. - The build rejects any block that does not state its own soundness argument.
You need Rust 1.99+ (edition 2024) and the libpcap headers:
- macOS: included with the Xcode Command Line Tools (
xcode-select --install) - Debian/Ubuntu:
apt install libpcap-dev - Fedora/RHEL:
dnf install libpcap-devel
cargo build --releaseThe binary is at target/release/sipnab.
Install with cargo installs the
published crate instead.
At run time, sipnab loads the system libpcap (libpcap.so.1 on Linux). Only
the static musl release binary carries its own.
Audio playback in the TUI also needs libasound (ALSA).
- It loads it only when you press play.
- Playback lives in a separate plugin,
libsipnab_audio.so. - So a binary built with audio starts fine on a host without libasound.
- WAV export still works there.
| Flag | What it adds | Default |
|---|---|---|
native |
Live and file capture, output writers, the CLI. Needed by every feature below except tls, audio and wasm |
yes |
tui |
The interactive terminal UI | yes |
audio |
RTP audio playback in the TUI, through the lazily loaded sipnab-audio plugin, and WAV export |
yes |
metrics |
Standalone Prometheus metrics server (--metrics) |
yes |
tls |
TLS and DTLS decryption, SRTP key extraction | no |
hep |
HEP v3 send, HEP v1/v2/v3 receive | no |
api |
REST API and its Prometheus endpoint, over HTTP or HTTPS | no |
mcp |
MCP server, stdio transport | no |
mcp-http |
MCP server over HTTP (Streamable HTTP). Implies mcp and api |
no |
plugins |
WASM plugin host (--plugin): sandboxed third-party detections |
no |
vcon |
vCon export of one observed call | no |
archive |
Password-protected ZIP and 7z input | no |
bpf |
eBPF TLS capture (--uprobe-backend bpf). Needs a nightly toolchain and bpf-linker to build, and a kernel with BTF to run. Outside full |
no |
wasm |
WebAssembly build for in-browser pcap analysis | no |
full |
native, tui, audio, metrics, tls, hep, api, mcp, mcp-http, plugins, vcon, archive |
no |
Every feature:
cargo build --release --features fullA headless capture host has the HEP listener, REST API and MCP over HTTP. It has no TUI or audio:
cargo build --release --no-default-features --features native,hep,api,mcp,mcp-httpInstallation covers the other builds. That includes cross-compilation.
These are step-by-step guides.
-
Each guide installs your SIP server: OpenSIPS, Kamailio, Asterisk or FreeSWITCH.
-
It installs each piece beside it.
-
Then it connects sipnab to it.
-
Every command in each guide ran on fresh virtual machines. Each page names them.
-
SIP proxy. OpenSIPS and Kamailio carry your calls. Every other guide builds on them.
-
PBX. Asterisk answers calls and places them on to the callee, as two legs.
-
Softswitch. FreeSWITCH answers each call. It bridges the call to the callee as a second call. The audio of both passes through it.
-
Call records. A vCon server keeps every call as a vCon.
- OpenSIPS records calls into it over SIPREC.
- sipnab can send its own vCons, built from what it saw on the wire.
- The command
sipnab --vcon-forwarddelivers them, to the server or to vcon.store. It is in the gnu and macOS builds, which carry thevconfeature. - Use a vCon server, run sipnab beside it, send to vcon.store
-
Attack blocking. TFPS stops SIP scanners and fraud in the kernel with XDP. fail2ban bans them with an nftables rule.
-
Media relay. rtpengine or rtpproxy anchors every call's audio. sipnab matches the media on the relay with the call it belongs to.
-
Call history. Homer keeps a searchable history of every call your proxy sends it over HEP. sipnab can join the same feed.
-
Metrics. Prometheus and Grafana graph your SIP proxy's statistics. sipnab adds its own call and media series beside them.
docs/README.md indexes every page by what you are trying to do. Here are the ones most people need:
| When you want to | Read |
|---|---|
| Find out why calls fail, drop, or carry one-way audio | Troubleshooting |
| Copy a recipe for a common task | Examples and recipes |
| Narrow to the calls that matter | Filter DSL |
| Look up a flag | CLI reference |
| Write a config file | Config reference, starting from contrib/sipnabrc.example |
| Parse sipnab's JSON or export pcap | Output formats |
| Use sipnab as a Rust library | Library API |
| Understand how it works inside | Architecture and Fault model |
- Ask usage questions in Discussions.
- Report bugs in Issues.
- SUPPORT.md explains which is which.
- MAINTAINERS.md says who answers and how fast.
We welcome contributions.
- CONTRIBUTING.md covers the build and test workflow, the git hooks, and the pull request checklist.
- Before we can merge a pull request, you sign the Contributor License Agreement once.
- A pull request cannot merge until the
license/clacheck passes. - If your change adds a dependency, read Dependencies first.
- This project follows the Contributor Covenant Code of Conduct.
- ROADMAP.md says what we intend to work on over the next year. It also says what we have decided not to build.
Found a vulnerability? Do not open a public issue. SECURITY.md gives:
- the private reporting address,
- the response timeline,
- what is in scope. Examples:
- parser crashes,
- key-material leaks,
- privilege-drop and chroot escapes,
- API and MCP authentication bypass,
- command injection through the
--alert-execfamily.
Licensed under either of
at your option.
Copyright 2024-2026 Norm Brandinger
