sipmon 0.1.5

Passive SIP/RTP signaling & media quality monitoring (pcap/live, TUI + JSONL export)
sipmon-0.1.5 is not a library.

sipmon

A passive SIP/RTP signaling and media quality monitoring tool. A standalone Rust executable deployed on a mirrored port / packet capture box, with no dependency on a running PBX. Inputs may be a live capture, a pcap file, a stdin stream, or a previously recorded event log; output is a live TUI monitor plus exportable analysis results (JSONL).

sipmon call list

sipmon call detail

Features

  • Inputs: live interface (libpcap + BPF), offline pcap/pcapng, stdin tcpdump -w - stream, event-log replay
  • Modes: live interactive monitoring / record recording with live TUI (--headless = no UI, -d daemonizable) / replay
  • SIP correlation: Call-ID call state machine, transactions, Call-ID / number / IP / SSRC indexes, SIP-over-TCP reassembly
  • Media quality: RFC3550 jitter/loss, RTCP RR RTT, one-way delay estimate, E-model MOS
  • TURN detection: auto-learns TURN servers, labels turn-client / turn-peer relay legs
  • Diagnostics: 20+ rules for Contact reachability, Record-Route, SDP/RTP consistency, one-way media, TURN allocation/refresh
  • TUI: Overview / Search / Call Detail / Heatmap / Streams / Event Log / IP Stats pages
  • Analysis: PDD/setup/ring timing, hangup initiator (BYE, CANCEL, reject), per-IP loss over 1s…1h windows
  • Export: JSONL on exit or via export; query fetches a Call-ID flow for scripting

Quick start

sipmon live -i any                 # live monitoring (TUI)
sipmon live -i eth0 -f "udp port 5060"   # with a BPF filter
sipmon record -i any -w cap.evlog --headless   # record to an event log
sipmon record -i any -w cap.evlog -d --pidfile /run/sipmon.pid --logfile /var/log/sipmon.log
sipmon replay -l cap.evlog         # replay a recording (TUI)
sipmon file -r capture.pcap        # offline pcap analysis
sipmon capture.pcap                # default mode: dispatch by extension
sipmon cap.evlog                   #   *.pcap/.pcapng → file, *.evlog → replay, *.jsonl → snapshot view
sipmon out.jsonl
tcpdump -i eth0 -w - | sipmon -    # read a live tcpdump stream

Commands

Command Description
(none) Default mode: positional FILE dispatched by extension (.pcap/.pcapngfile, .evlogreplay, .jsonl → snapshot view); no FILE starts a live capture. --no-tui for headless output
live Live capture + TUI. -i interface, -f BPF filter, --no-media disables RTP/RTCP analysis, -w also writes an event log
record Live capture → event log (-w required). Live TUI on a tty; --headless disables it. -d daemonizes, --pidfile/--logfile for daemon runs. Flushes gracefully on SIGTERM/SIGINT
- Read a pcap byte stream from stdin
file Offline pcap/pcapng. --rate 1x replay speed multiplier, --no-tui, --print-events
replay Replay an event log (TUI / --no-tui)
query No TUI; exports flow + stream stats + RTT + diagnostics for a Call-ID (script friendly)
export Rebuild a snapshot from an event log → JSONL, with --from/--to time filtering

Common options

--dry-run            In-memory analysis only, writes no files
--max-calls N        Max calls retained in memory (default 100000)
--max-streams N      RTP stream ring cap (default 50000)
--max-diagnostics N  Diagnostics ring cap (default 50000)
--diag-level X       info|warn|critical (default warn)
--turn-servers IP,…  TURN server IP list (auto-learning also supported)
--local-ips IP,…     Local (monitored) machine IPs: Call Detail flow/media pin
                     the local endpoint to the right with ingress/egress arrows
                     (default: this host's own interface addresses)
--raw-truncate N     Truncate stored raw SIP messages to N bytes
--bucket 15m|1h|1d   Heatmap bucket granularity (default 15m)
-w/--evlog PATH      Write the binary event log to PATH
--export-jsonl PATH  Export JSONL on exit

TUI

Pages: Overview 1 · Search 2// · Call Detail 3 · Heatmap 4 · Streams 5 · Event Log 6 · IP Stats 7. Tab/Shift-Tab cycles pages, Space pauses, e exports JSONL, x clears in-memory stats, q/Esc/Ctrl-C quits.

Call Detail uses a fixed four-pane layout: Flow (chronological SIP messages, / selects) · Raw (full bytes of the selected message, PgUp/PgDn scrolls) · Diagnostics · Network (traffic totals + per-stream media table). With a known local IP (--local-ips) the local endpoint is pinned to the right and arrows show the direction — remote -> local is inbound, remote <- local outbound.

IP Stats aggregates per-IP conditions, split by direction (TX = sent by the IP, RX = received): c collapses to a loss-only summary, w cycles the time window, s sorts, Enter drills down to the calls involving an IP.

Event log format

Private binary append-only format. Header holds the SMON magic, version, and timezone; records are ts_delta | ev_type | len | payload. Event types: 1 SipMsgEvt, 2 TxnEvt, 3 CallEvt, 4 StreamSnapEvt (every 5s), 5 RtcpRttEvt, 6 HealthBucketEvt, 7 ErrorEvt, 8 DiagEvt.

No raw RTP payload is stored — only the summaries needed to rebuild the analysis, plus truncated raw SIP messages (--raw-truncate controls the cap). record always writes to disk; live needs an explicit -w.

Diagnostic codes

Code Meaning
CONTACT_UNREACHABLE / CONTACT_PRIVATE_NAT / CONTACT_MCAST Contact address unreachable, private NAT, or multicast
RR_NOT_HONORED / RR_DEPTH_MISMATCH Record-Route not honored / depth mismatch
SDP_HOLD SDP carries hold (sendonly/inactive)
RTP_PT_MISMATCH / RTP_PT_CHANGED / RTP_FLOW_UNEXPECTED Payload type mismatch / changed mid-call / RTP flow disagrees with SDP
ONE_WAY_MEDIA One-way media (only receiving, not sending)
TURN_ALLOC_OK / TURN_ALLOC_FAILED / TURN_REFRESH_FAILED TURN allocation succeeded / failed / refresh failed
TURN_RELAY_MEDIA / TURN_CHANNEL_MEDIA / TURN_SEND_IND_MEDIA Media relayed via TURN Relay / ChannelData / Send-Ind
TURN_LEG_IMBALANCE TURN leg packet imbalance (suspected one-way)

Metric definitions

  • RTT: RTT = arrival_NTP − LSR − DLSR from the RTCP RR
  • One-way delay: RTCP SR NTP↔RTP mapping (when both directions are visible); otherwise an indirect estimate from RTP arrival intervals (labeled "estimate")
  • jitter/loss: RFC3550, 64-packet reorder window
  • MOS: simplified E-model (G.107): R = 93.2 − Id − Ie, labeled "estimate"

Limitations

  • TLS/SRTP encrypted payloads cannot be parsed; capture at the decryption point
  • Absolute one-way delay under one-way passive observation is an estimate; RTCP RTT is the primary metric
  • Capturing without interface permissions requires root / elevated privileges (same as tcpdump)

Tests

cargo test                       # unit + integration tests (pcap fixture)
cargo test --test cli_integration