Keybindings - NormB/sipnab GitHub Wiki
Complete keyboard shortcut reference for sipnab's interactive TUI.
You can remap keys marked (configurable) in the [keybindings] config section. See config-reference.md for details. All other keys are hardcoded.
Annotated screenshots of every view are in the TUI visual tour at the bottom of this page.
Quick start:
j/kfor vim-style up/down.Enterto drill into a call.Escto go back.Tabto switch between Call List and RTP Streams.
| Key | Action | Views |
|---|---|---|
j / k
|
Navigate down / up | All list and scroll views |
Enter |
Drill in (call flow, raw message, stream detail) | Call List, Call Flow, RTP Streams |
Esc |
Back to the previous view (asks to quit from the Call List) | All views |
Tab |
Switch between Call List and RTP Streams | Call List, RTP Streams |
/ |
Search | Call List, Raw Message, RTP Streams |
F7 |
Open filter dialog | Call List, Call Flow, RTP Streams |
F2 |
Save capture (or the selected stream's audio) | Call List, Call Flow, Raw Message, RTP Streams, Stream Detail |
Space |
Star dialogs for multi-select β save them, or open them as one merged flow | Call List |
t |
Cycle timestamp mode | Call List, Call Flow |
F1 |
Help | Call List, Call Flow, Raw Message, Message Diff, Combined Detail, RTP Streams, Stream Detail |
| Key | Action |
|---|---|
| Ctrl+C | Force quit (skips the confirmation) |
| Ctrl+L | Clear calls β Call List only, same as F5 there |
| v | Show version (with git commit) in the status line |
| n | Cycle name resolution (Off / Static / DNS) |
| N | Name the selected address (map IP β host/FQDN) |
| F | Show the filter the F7 dialog built as a summary or in full on status line 3 (configurable: filter_detail)
|
| F12 | Toggle mouse capture β off enables the terminal's native drag-to-select (wheel scrolling pauses until re-enabled) |
| Mouse wheel | Scroll (every view: lists move the selection, text views scroll) |
Esc and the quit key open a confirmation rather than ending the session.
-
Escmeans "go back" in every other view. - It was ending captures that had been running for hours.
| Key | Action |
|---|---|
| Y, Enter | Quit |
| N, Esc, q | Return to the session |
| Ctrl+C | Quit at once, from anywhere, including this dialog |
Any other key leaves the question on screen. A stray keypress must not dismiss the dialog, and it certainly must not answer it.
v, n, and F12 ship as fallbacks.
- A key you explicitly rebind in
[keybindings]always wins over them. - In the Raw Message view with an active search,
n/Nare match navigation instead.
Clipboard copies (y in the Raw Message view, E in the Call Flow view) use
OSC 52. This is an escape sequence the terminal maps to your system
clipboard.
- It travels in-band over the pty. So it works across SSH with no X11 forwarding.
- Your terminal must support it. Most modern ones (kitty, WezTerm, iTerm2, Windows Terminal, foot, recent xterm) do.
On top of OSC 52, sipnab also feeds
pbcopy/xclip silently when one is available.
- Copies stop at 72 KiB (terminals limit OSC 52 payloads).
- The status line reports how much it copied.
To select arbitrary screen text with the mouse:
- Press
F12to turn mouse capture off. - Drag as usual.
- Press
F12again to get wheel scrolling back.
In many terminals, holding Shift while dragging bypasses mouse capture
without toggling anything.
To start every session with capture off, set mouse_capture = false under
[display] in the config file.
| Key | Action |
|---|---|
| Up / k | Navigate up |
| Down / j | Navigate down |
| PgUp | Page up |
| PgDn | Page down |
| Home | Jump to first dialog |
| End | Jump to last dialog |
| Enter | Open call flow for the selected dialog β with two or more starred rows, opens one chronologically merged flow of all of them |
| Space | Star/unstar dialog ([*]) for multi-select: F2 saves all starred dialogs, Enter opens them as one merged flow |
| Esc / q | Quit, after a confirmation (configurable: quit)
|
| < | Sort by previous column |
| > | Sort by next column |
| Z | Reverse sort direction |
| A | Toggle autoscroll (configurable: autoscroll)
|
| p | Pause/resume capture (configurable: pause)
|
| / | Activate search (configurable: search) β while typing, β/β/PgUp/PgDn/Home/End move the highlight in the narrowed list, Space stars rows, and Enter commits the query and opens the selection in one press |
| i | Clear non-matching dialogs |
| I | Clear matching dialogs |
| t | Cycle timestamp mode (absolute / delta from previous / delta from first / scaled) |
| u | Cycle From/To column display (default / host:port / user / user@host:port) |
| r / F6 | Show raw SIP message for selected dialog |
| s | Switch to Statistics view |
| h | Open the Capture health panel: drops, undecodable frames, and on a -L run the HEP listener's senders |
| g | Open Top talkers: every source IP ranked by the dialogs it took part in |
| m | Open Carrier metrics: ASR, NER and ACD per destination IP |
| c | Open Compare two calls for the two starred dialogs (star exactly two with Space first; any other count leaves a hint on the status line) |
| e | Open the Endpoint rollup for the selected dialog's source address |
| b | Open the Call volume histogram: calls per 60-second bucket |
| o | Open the SDP offer/answer timeline of the selected dialog |
| f | Open the RFC conformance findings of the selected dialog |
| x | Open TFPS observe: the sources an enforcing TFPS peer bans, and its drop counters |
| a | Open Security findings: the alerts of the armed detectors |
| B | Open the Capture filter editor to append an expression to the BPF capture filter |
| N | Name the selected dialog's addresses (map IP β host/FQDN; Tab switches between source and destination) |
| S | Open the Relay statistics view β asks the live relay for its own counters (s asks what this capture saw, S asks what the relay says). See Relay statistics
|
| D | Open the Quality Dashboard (live MOS/jitter/loss) |
| T | Open the call timeline for the selected dialog (Esc / q closes it) |
| O | Open pcap file (File Open dialog) |
| F8 | Open Settings popup (configurable: settings)
|
| Tab | Switch to RTP Streams view |
| F1 / ? | Help (configurable: help)
|
| F2 | Save capture (configurable: save)
|
| F3 | Search (same as /) β matches Call-ID, method, From/To user, addresses, dialog state, and the full raw message text (headers and bodies, including SDP and multipart payloads) |
| F4 | Open extended multi-leg flow for the selected dialog (configurable: extended_flow)
|
| F5 / Ctrl+L | Clear calls (configurable: clear_calls) β the starred dialogs when any carry a star, otherwise all of them. Ctrl+L is a fixed alias |
| F7 | Open filter dialog (configurable: filter)
|
| F9 | Clear filter: drops the view filter and the persisted search |
| F10 | Column selector (configurable: column_selector) β a popup to show/hide any of the eleven Call List columns (#, Method, From, To, Source, Destination, State, Msgs, Date, PDD, Duration) |
A search committed with Enter keeps narrowing the list. It appears on the
status line as Search: /query (F9 clears). F9 clears it together with any
active filter.
Gotcha: the
clear_callsaction bindsF5in both views.
- In the Call List it clears calls.
- In the Call Flow it resets a pending message-compare selection.
- Rebinding
clear_callsmoves both.
| Key | Action |
|---|---|
| Tab / Shift+Tab | Switch focus between the ladder (left) and detail (right) panes |
| Up / k | Previous message or RTP row β or scroll detail up when the detail pane has focus |
| Down / j | Next message or RTP row β or scroll detail down when the detail pane has focus |
| PgUp | Page up (ladder, or detail when focused) |
| PgDn | Page down (ladder, or detail when focused) |
| Home | Jump to first message (or top of detail when focused) |
| End | Jump to last message (or bottom of detail when focused) |
| Enter | Open full-screen raw message view β or, with the cursor on an RTP stream's row, that stream's Stream Detail view (MOS, jitter, quality intervals, burst/gap analysis, silence detection, sparklines) |
| Space | Select message for diff (press on two messages to compare) |
| q | Quit, after a confirmation (configurable: quit)
|
| Esc | Back to call list |
| d | Cycle SDP display mode (hidden / summary / full) |
| t | Cycle timestamp mode (absolute / delta from previous / delta from first / scaled) |
| c | Cycle color scheme (method / Call-ID / CSeq) |
| h | Cycle header-name display (as captured / expanded / compact) β visual only, rewrites From: β f: etc. in the message text views |
| R | Show or hide the detail pane |
| + / = / 0 / Left | Widen the detail pane, narrowing the ladder (with the detail pane off, shows a hint instead) |
| - / 9 / Right | Narrow the detail pane, widening the ladder (with the detail pane off, shows a hint instead) |
| w | Toggle line wrapping in the detail pane (off = long lines truncate and a scrollbar appears along the bottom edge) |
| β / β | Scroll the detail pane horizontally when it has focus with wrap off |
| [ | Scroll the detail pane up |
| ] | Scroll the detail pane down |
| e | Expand/collapse the selected fold header (retransmissions, auth retries) |
| f | Filter the ladder to the selected message's transaction (toggle) |
| a | Open combined detail for the selected message's transaction |
| A | Open combined detail for the whole dialog |
| m | Set mark at current message β navigate to another message and sipnab shows the delta between the mark and the cursor, for measuring the delay between two specific SIP messages |
| M | Clear mark |
| E | Export Mermaid sequence diagram to clipboard |
| y | Copy the selected message's raw text to the clipboard, as the raw message view shows it (see Copying text) |
| C | Write, amend or remove your note on the selected message. The note is yours, never sipnab's analysis: sipnab shows it in a pane titled so, marks the row with β, writes it as a packet comment when you save PCAP-NG, and saves it to a notes file with the NOTES save format. See Operator notes
|
| x / F4 | Toggle extended multi-leg flow (configurable: extended_flow) β shows related B2BUA/SBC call legs together, for tracing a call through proxies and back-to-back user agents |
| r | Open RTP Streams narrowed to this call's streams (in a merged or extended flow, every call the flow shows). a there switches to every stream and back, and Esc returns here with the selected message kept |
| N | Name endpoints (map IP β host/FQDN, and Tab/Shift+Tab switch between the offered participants) |
| F1 / ? | Help (configurable: help)
|
| F2 | Save (configurable: save)
|
| F5 | Reset message-compare selection (configurable: clear_calls)
|
| F6 / Ctrl+R | Toggle the call's RTP streams in the ladder: one arrow per stream, from sender to receiver, with codec, packet count and a one-way mark (see Follow each RTP stream in the call flow). Ctrl+R is an alias for front-ends that cannot send F-keys |
| F7 | Open filter dialog (configurable: filter)
|
| F9 | Clear filter: drops the view filter and the persisted search |
While the detail pane shows, Tab moves keyboard focus between the two panes.
- The status line names the focused pane (
Focus: Ladder/Focus: Detail). - That pane gets a highlighted border.
- When either pane has more rows than fit, a vertical scrollbar appears on its right edge.
-
[and]always scroll the detail pane regardless of focus.
C opens a one-line editor on the selected message.
- Enter keeps the note.
- An empty note removes it.
- Esc leaves it as it was.
sipnab refuses a note over 4096 bytes, or one holding:
- a control character,
- an SDES
inline:key, - a TLS key-log line,
- or a digest
response=value.
It says why on the status line without repeating it. A message sipnab read from no frame takes no note.
The note goes three places:
- The pane under the flow, titled "operator note β not sipnab analysis".
- A PCAP-NG save, as the packet comment on that message's frame. A line names the frame you typed it on.
- The NOTES format of the save dialog (
F2, Tab to NOTES). It writes the file--notesresumes from.
A classic PCAP save refuses rather than drop the notes. sipnab never reads a packet comment back.
Quitting with notes you have not saved to a notes file says so in the quit confirmation. Opening another capture asks first. The notes are about this capture's frames, and opening another drops them.
| Key | Action |
|---|---|
| Up / k | Scroll up |
| Down / j | Scroll down |
| PgUp | Page up |
| PgDn | Page down |
| Home / End | Jump to top/bottom |
| / | Search within message |
| n / N | Jump to the next / previous search-match line (wraps) |
| s | Toggle syntax highlighting |
| c | Cycle color scheme |
| h | Cycle header-name display (as captured / expanded / compact) |
| y | Copy the displayed message's raw text to the clipboard (OSC 52, works over SSH β see Copying text) |
| C | Write, amend or remove your note on this message β see Operator notes |
| F1 / ? | Help (configurable: help)
|
| F2 | Save (configurable: save)
|
| q | Quit, after a confirmation (configurable: quit)
|
| Esc | Back to the view you came from (call flow or call list) |
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| h | Cycle header-name display (as captured / expanded / compact) |
| q | Quit, after a confirmation (configurable: quit)
|
| Esc | Back to call flow |
| F1 / ? | Help (configurable: help)
|
Opened from the call flow with a (transaction) or A (whole dialog). It
renders every message of the selection as one scrollable document.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| h | Cycle header-name display (as captured / expanded / compact) |
| F1 / ? | Help (configurable: help)
|
| q | Quit, after a confirmation (configurable: quit)
|
| Esc | Back to call flow |
| Key | Action |
|---|---|
| Up / k | Navigate up |
| Down / j | Navigate down |
| PgUp / PgDn | Page scroll |
| Home | Jump to first stream |
| End | Jump to last stream |
| / | Search streams (SSRC, codec, addresses, dialog) (configurable: search) β while typing, β/β/PgUp/PgDn/Home/End move the highlight in the narrowed list and Enter commits the query and opens the highlighted stream |
| Enter | Open the Stream Detail view for the selected stream |
| D | Open the Quality Dashboard (live MOS/jitter/loss) |
| Tab | Switch to Call List |
| a | After r from a call flow: switch between that call's streams and every stream. Status line 3 says which the list shows, and how many streams sipnab linked to no call |
| Esc | Back to the call flow when r opened the list from one, otherwise to the Call List |
| q | Quit, after a confirmation (configurable: quit)
|
| N | Name the selected stream's source address (map IP β host/FQDN) |
| F1 / ? | Help (configurable: help)
|
| F2 | Save the selected stream's audio as WAV (configurable: save)
|
| F7 | Open filter dialog (configurable: filter)
|
| Key | Action |
|---|---|
| Up / k | Scroll up |
| Down / j | Scroll down |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Shift+P | Play / stop the stream's audio (G.711; requires the audio build) |
| L | Open the packet loss map (RTP loss pattern) β a single screen with nothing to scroll, so Esc or q is the only key it takes, and either returns here |
| F1 / ? | Help (configurable: help)
|
| F2 | Save the stream's audio as WAV (configurable: save)
|
| q | Quit, after a confirmation (configurable: quit)
|
| Esc | Back to the view you came from (RTP Streams, Call Flow, or Quality Dashboard) |
The Stream Detail view shows comprehensive per-stream quality data:
- MOS score,
- jitter statistics,
- quality intervals,
- burst/gap analysis (RFC 3611),
- silence detection,
- sparkline graphs for MOS and jitter trends over the stream's lifetime.
Live call-quality overview:
- aggregate MOS/jitter/loss,
- the worst streams ranked first,
- per-stream trend sparklines.
Open with D from the Call List or RTP Streams view.
| Key | Action |
|---|---|
| Up / k, Down / j | Select stream (worst first) |
| PgUp / PgDn | Page through streams |
| Home / End | Jump to best/worst |
| Enter | Open stream detail for the selection |
| L | Open the packet loss map (RTP loss pattern) for the selection |
| Esc / q / D | Close (returns to the opening view) |
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / s | Back to Call List |
Every source IP in the capture, ranked by the number of dialogs it took part in, then by messages.
- Each row counts the participant's dialogs, messages, INVITEs, and how many of those INVITEs got an answer or failed.
- The view credits a participant for every dialog it took part in. So the shares overlap.
Open with g from the Call List.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / g | Back to Call List |
Answer-seizure ratio (ASR), network effectiveness ratio (NER) and average call duration (ACD) for each destination IP. That is the address each call went to.
- A call attempt is an INVITE that got a final response.
- A group with no call attempt shows
βrather than a zero. - The figures come from the same calculation as
GET /v1/dialogs/rates.
Open with m from the Call List.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / m | Back to Call List |
Two dialogs side by side: Call-ID, state, final status, message count and the methods each carried. The view:
- marks each field that differs
(differs), - lists the differences by name,
- shows a failed call's diagnosis hints.
Star exactly two dialogs with Space in the Call List, then press c.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / c | Back to Call List |
Everything the selected dialog's source address did in the capture:
- its dialogs,
- messages sent and received,
- counts by method and by state,
- INVITE outcomes,
- registrations,
- the User-Agent and Server values it sent,
- its RTP streams with codecs, loss and jitter,
- its most recent Call-IDs.
The same report as GET /v1/endpoints. Open with e from the Call List.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / e | Back to Call List |
The capture's own health:
- the loss, decode and media-path counters,
- on a run with a HEP listener (
-L), one line counting its senders.
Open with h from the Call List.
| Key | Action |
|---|---|
| s | Open HEP senders |
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / h | Back to Call List |
Who is feeding the -L listener:
- each sender (the capture id it claims and the address it sends from),
- its packet count,
- when it was last heard and whether it went silent,
- then every address the listener refused, with the reasons.
The same table --hep-senders prints at the end of a headless run.
A session with no listener says so. Open with s from Capture health.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / s | Back to Capture health |
Calls per 60-second bucket across the capture, one bar per bucket. The view
scales the bars against the busiest bucket. Open with b from the Call List.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / b | Back to Call List |
Each SDP offer and answer of the selected dialog in order:
- its time,
- the codecs,
- the media address and port,
- the direction attribute (
sendrecv,sendonlyand so on).
The row of a mid-call change names it:
- on hold,
- resumed,
- codec change,
- switched to T.38 fax,
- media anchor moved,
- or a transfer.
Open with o from the Call List.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / o | Back to Call List |
The selected dialog's RFC conformance findings. They are the same ones
GET /v1/dialogs/:call_id/lint returns. Each names:
- its severity,
- the RFC section,
- the message it came from,
- the rule ID,
- what sipnab observed,
- what the RFC expects,
- and why it matters.
Open with f from the Call List.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / f | Back to Call List |
What an enforcing TFPS peer reports, read by running its
tfps_ctl command:
- the sources it bans now,
- or its per-source drop counters.
The view only reads; it bans and unbans nothing. Without tfps_ctl on the
PATH (or named by --tfps-ctl or [tfps] ctl) the view says so. Open with
x from the Call List.
| Key | Action |
|---|---|
| b | Show the banned sources (the view opens on these) |
| d | Show the drop counters |
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / x | Back to Call List |
The detectors armed on this run and the alerts they raised. For each finding: rule, source address, detail and time.
- It shows 200 findings and gives the total when more matched.
- With no detector armed, the view says that nothing was watching. So an empty list is not a clean bill.
- The same report as
GET /v1/security/findings. - Arm a detector with
--kill-scanner,--fraud-detect,--digest-leakor--reg-flood.
Open with a from the Call List.
| Key | Action |
|---|---|
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / q / a | Back to Call List |
Appends an expression to the BPF capture filter.
- The upper pane previews the filter in force.
- The lower pane takes the expression.
-
Entercompiles the combined filter first. It refuses one libpcap rejects, with the reason on the status line. - A live capture then applies it to the running capture.
- sipnab reads a single capture file again under it.
- With several input files, or none, it reports that the filter compiles and applies nothing.
Open with B from the Call List.
| Key | Action |
|---|---|
| Tab | Switch between AND (narrow the current filter) and OR (widen it) |
| Enter | Check the combined filter and apply it |
| Backspace | Delete the last character |
| Up / Down | Scroll the preview |
| PgUp / PgDn | Page the preview |
| Home / End | Jump to top/bottom of the preview |
| Esc | Discard the edit and return to the Call List |
The live relay's own view of media, asked over its control socket. This is
distinct from the Statistics view above, which is about what this capture
saw. Open with S:
- From the Call List it asks the relay's global counters.
- From a call's flow view it scopes them to that call.
It needs a relay control address and a live capture. A run reading a file reports that it may not ask. The ask runs in the background. So the view never freezes waiting on a slow relay.
| Key | Action |
|---|---|
| ? | Show the names the relay knows (what you can ask for) |
| K | Compare the relay's per-call count against this capture's (per-call view only) |
| H | Show what the relay holds now: the Call-IDs of up to 32 calls (press again to return to the counters) |
| Up / k, Down / j | Scroll |
| PgUp / PgDn | Page scroll |
| Home / End | Jump to top/bottom |
| Esc / S | Close |
The help text can run past the screen, so it scrolls.
| Key | Action |
|---|---|
| Esc / F1 / q | Close help |
| Up / k, Down / j | Scroll one line |
| PgUp / PgDn | Scroll ten lines |
| Home / End | Jump to top/bottom |
| Key | Action |
|---|---|
| Esc | Cancel and close |
| Enter | Save to the specified path |
| Tab | Cycle format forward (PCAP -> PCAP-NG -> TXT -> JSON -> NDJSON -> CSV -> Mermaid/HTML -> Markdown -> WAV -> SIPp XML -> RTP JSON) |
| Shift+Tab | Cycle format backward |
| Left / Right | Move cursor in filename |
| Home / End | Jump to start/end of filename |
| Backspace | Delete character before cursor |
| (any char) | Insert character |
Save formats: PCAP, PCAP-NG, TXT, JSON, NDJSON, CSV, Mermaid/HTML, Markdown, WAV, SIPp XML, RTP JSON
| Key | Action |
|---|---|
| Esc | Cancel without applying |
| Enter | Apply filter (or cancel if Cancel button focused) |
| Tab | Focus next field |
| Shift+Tab / BackTab | Focus previous field |
| Down | Next field (or checkbox down) |
| Up | Previous field (or checkbox up) |
| Left / Right | Move within checkboxes or text cursor |
| Space | Toggle checkbox / activate button |
| F9 | Clear all fields and active filter, close popup |
| Backspace / Delete | Text editing in focused text field |
| Home / End | Jump to start/end of text field |
| (any char) | Insert character in focused text field |
The SIP-method grid starts with an All master checkbox. Space on it checks or unchecks every method at once.
| Key | Action |
|---|---|
| Esc | Close settings |
| Up / k | Previous setting |
| Down / j | Next setting |
| Enter / Space | Toggle or cycle the focused setting |
Settings items: Colors, Timestamps, Autoscroll, Detail pane, SDP, Syntax colors.
Values read as the rest of the TUI spells them: Delta from previous, Call-ID, Hidden, On and Off.
The popup opens on the file browser. Tab switches to typing a path instead,
and Tab again returns to the browser.
| Key | Action |
|---|---|
| Esc | Cancel and close |
| Tab | Switch between the browser and typing a path, in either direction |
| Up / Down | Browser: move the selection |
| PgUp / PgDn | Browser: page through the listing |
| Home / End | Browser: jump to the first or last entry |
| Enter | Browser: descend into the selected directory, or load the selected capture. Typed path: load that path |
| (any char) | Browser: extend the name filter, which narrows the listing. Typed path: insert the character |
| Backspace | Browser: trim the name filter, then climb to the parent directory once the filter is empty. Typed path: delete the character before the cursor |
| Left / Right | Typed path: move the cursor |
| Home / End (typed path) | Jump to the start or end of the path |
| Delete | Typed path: delete the character under the cursor |
The browser lists:
-
.pcap,.pcapng, and.capfiles, - their gzip-compressed forms (
*.pcap.gz, β¦), - archives of captures (
.tar,.tgz,.tar.gz, and.zipin builds with thearchivefeature).
sipnab decompresses on the fly. It loads an archive as the set of captures it holds, member by member into one view. The status line says how many captures came out of the archive and how many members it did not read.
If sipnab cannot read the directory, the dialog shows the reason instead of a blank list.
- The most common cause: sipnab started with
sudoand dropped privileges to an unprivileged user that can't read your home directory. - Run sipnab without
sudoto browse your own files. See install.md for capabilities.
A capture load that meets an encrypted archive member asks here when no password you configured opens it (see Archives).
- The load waits for the answer.
- The popup names the archive, the member and the attempt.
- Each archive gets three attempts.
| Key | Action |
|---|---|
| Enter | Try the password. A wrong one reopens the popup, masked, saying so |
| Esc | Skip this archive's locked members and load the rest |
| Ctrl-R | Show or hide what you typed. The popup always opens masked, one dot per character, and masks again after every attempt. While shown, the title says "password visible" |
| Ctrl-U | Clear the entry |
| Backspace | Delete the last character |
A paste arrives as one entry. So a password manager works, and no character of the password acts as a key.
- The session remembers the password that opened an archive for that archive only. It forgets it when another capture opens.
- The action trail says
archive_password_acceptedorarchive_locked_members_skippedwith the archive's name. It never says the password or its length. - The status line counts locked members. It marks an archive that uses ZipCrypto, which protects nothing.
| Key | Action |
|---|---|
| Up / k | Move selection up |
| Down / j | Move selection down |
| Space | Toggle column visibility |
| s | Save the current layout to [display] visible_columns in the config file this run loaded, or the user config file ($XDG_CONFIG_HOME/sipnab/sipnab.toml, by default ~/.config/sipnab/sipnab.toml) when none was (persists across runs). Refused, with a message, when the settings came from /etc/sipnab/sipnab.toml
|
| Enter / Esc | Close selector |
Press t in the Call List or Call Flow to cycle through the timestamp modes. Both views share the mode:
-
Absolute --
HH:MM:SS.mmmwall-clock time -
Delta from previous (default) --
+N.NNNstime since previous entry. Color-coded in call flow:- Green: < 100 ms
- Yellow: 100 ms - 1 s
- Red: 1 s - 5 s
- Bold red: > 5 s
-
Delta from first --
+N.NNNscumulative time from first entry - Scaled -- delta-from-previous timestamps plus time-proportional spacer rows. So quiet gaps are visible in the ladder. The set of visible messages is identical in every mode. Only the presentation changes.
In the Call List, the timing column's header names the mode. The column shows different data in each:
-
Start in Absolute (the dialog's start time,
HH:MM:SS). - +Prev in Delta from previous (time since the dialog above it, in the list's current sort order).
- +First in Delta from first (time since the first dialog).
- The spacer rows of Scaled belong to the ladder. So the Call List shows Scaled as +Prev.
The F10 column selector and the visible_columns setting still call this
column Date.
Absolute: Delta from previous: Delta from first: 14:23:01.000 INVITE +0.000s INVITE +0.000s INVITE 14:23:01.003 100 +0.003s 100 +0.003s 100 14:23:01.847 180 +0.844s 180 +0.847s 180 14:23:03.134 200 +1.287s 200 +2.134s 200 14:23:03.137 ACK +0.003s ACK +2.137s ACK 14:24:08.320 BYE +65.18s BYE +67.32s BYE
Tip: Delta from previous is ideal for spotting latency spikes in call setup. Delta from first is useful for measuring total elapsed time from the first message.
sipnab can display host names instead of raw IP addresses (Wireshark-style). It does so in:
- the call list Source/Destination columns,
- call-flow participant labels,
- the RTP stream views.
Press n to cycle the mode (shown briefly in the status line):
-
Off (default) -- raw
ip:port -
Static -- operator mappings + the system
/etc/hosts. No network traffic - DNS -- additionally resolves via reverse DNS (PTR). A background worker looks names up and caches them (so the UI never blocks)
Names come from four sources, highest priority first:
- operator-entered mappings,
- then
/etc/hosts(or a--names/[names] hosts_file), - then any Name Resolution Block in the capture you opened,
- then reverse DNS.
Substitution touches only the IP. The :port stays (sbc-edge:5060).
To name an address in context, select a call-list row, stream row, or
call-flow message and press N.
- A popup opens with the endpoints of that row or message. A call-list row offers its source and its destination.
- Each endpoint is pre-filled with the name it has now.
-
TabandShift+Tabmove between the endpoints. - Type a host/FQDN and press Enter to apply every endpoint. An empty name clears that mapping.
-
Esccloses the popup without applying.
Naming an address turns resolution on automatically. sipnab saves the mapping
to $XDG_CONFIG_HOME/sipnab/hosts (~/.config/sipnab/hosts) so it persists
across runs.
Mappings can also persist into your config file.
- Set
[names] persist_to_config = true.N-dialog edits then land in the[names.manual]table of:- the file this run loaded (
~/.sipnabrc, a--configfile, whichever it was), - or the user config file (
$XDG_CONFIG_HOME/sipnab/sipnab.toml, by default~/.config/sipnab/sipnab.toml) when none was.
- the file this run loaded (
- The edits leave comments and other sections intact.
- When the settings came from
/etc/sipnab/sipnab.toml, edits are not written there. The status line says so when the session opens.
You can also pre-declare mappings there by hand:
[names.manual]
"192.0.2.1" = "sbc-edge"When saving a capture as PCAP-NG with resolution active, sipnab embeds the mappings as a Name Resolution Block. It reads them back when you reopen the file.
Related flags:
-
--resolve(start with resolution on), -
--reverse-dns(enable PTR lookups, which implies--resolve), -
--names <FILE>(preload an/etc/hosts-format mapping file, repeatable).
See cli-reference.md and the [names]
section of config-reference.md.
The call list is the main view when sipnab starts. It shows all tracked SIP dialogs with their state, timing, and quality metrics.
Live capture: eth0 Dialogs: 47 shown of 47 Autoscroll: on Capture filter (BPF): port 5060 View filter: none # Method From To Src IP Dst IP State Msgs +Prev PDD βΈ 1 INVITE alice bob 192.0.2.1 192.0.2.2 InCall 12 +0.000s 847ms 2 INVITE charlie dave 192.0.2.3 192.0.2.4 Ringing 6 +1.234s -- 3 REGISTER admin -- 192.0.2.5 192.0.2.1 Registered 4 +0.012s -- 4 INVITE +15551234 +15559876 192.0.2.6 192.0.2.7 Failed 8 +3.456s -- 5 INVITE 1005 1006 192.0.2.1 192.0.2.2 Completed 14 +0.003s 923ms 6 OPTIONS monitor -- 192.0.2.8 192.0.2.1 Completed 2 +0.001s -- 7 INVITE 1010 +441234567 192.0.2.9 192.0.2.7 InCall 10 +0.215s 1.2s Esc Quit F1 Help Enter Open call Tab Streams F2 Save F7 Filter
The three lines above the list say what you are looking at.
- Line 1 names:
- the source (
Live capture: eth0orFile: call.pcap), - how many dialogs the list shows out of how many sipnab holds,
- whether autoscroll is on.
- the source (
- Line 2 is the capture (BPF) filter the kernel applies. It is
nonewhen sipnab compiled no filter.- The filter can belong to a different source from the one line 1 names.
Then line 2 says which after the filter:
-
[live capture]when a file opened withOreplaced the screen while the live capture keeps running behind it, -
[file re-scan]whenBre-read a capture file under the filter.
-
- The filter can belong to a different source from the one line 1 names.
Then line 2 says which after the filter:
- Line 3 is the view filter from
F7and any search you kept with Enter.- It also carries status messages, with errors in red.
- A line wider than the terminal ends in
β¦.
The key bar
at the bottom lists the keys of the view you are in, F1 Help first after the
way out, and fewer of them on a narrow terminal.
Tip:
- Press
Spaceto star dialogs. A starred row shows[*]in the#column (theβΈabove is just the cursor).F2then saves only the starred dialogs.Enteropens two or more of them as a single merged flow.- Use
</>to sort by different columns andZto reverse sort direction.
The call flow shows a ladder diagram for a selected dialog, with timing, SDP, and RTP quality indicators.
192.0.2.1:5060 192.0.2.3:5060 192.0.2.2:5060 (alice UAC) (OpenSIPS proxy) (bob UAS) | | | +0.000s |------- INVITE -------->| | +0.003s |<--------- 100 ---------| | +0.005s | |------- INVITE -------->| +0.008s | |<--------- 100 ---------| +0.847s | |<--------- 180 ---------| +839ms +0.850s |<--------- 180 ---------| | +2.134s | |<--------- 200 ---------| +1.28s +2.137s |<--------- 200 ---------| | +2.140s |--------- ACK --------->| | +2.143s | |--------- ACK --------->| | ββ RTP PCMU MOS 4.2 ββ | | | | ββ RTP PCMU MOS 4.1 ββ | +65.320s | |<--------- BYE ---------| +65.323s |<--------- BYE ---------| | +65.326s |------- 200 OK -------->| | | | | Esc Back F1 Help ββ Move Enter Raw d SDP t Time c Color R Detail
Tip:
- Press
mto set a mark at any message. Then navigate to another message to see the delta badge showing elapsed time between them.- Press
Mto clear the mark.- Use
dto cycle through SDP display modes (none / summary / full).
Full SIP message with optional syntax highlighting, searchable.
INVITE sip:[email protected]:5060 SIP/2.0 Via: SIP/2.0/UDP 192.0.2.1:5060;branch=z9hG4bK-524287-1 Max-Forwards: 70 From: "alice" <sip:[email protected]>;tag=as6e4f2c8b To: <sip:[email protected]> Contact: <sip:[email protected]:5060> Call-ID: [email protected] CSeq: 102 INVITE User-Agent: Olle/1.0 Content-Type: application/sdp Content-Length: 263v=0 o=alice 2890844526 2890844526 IN IP4 192.0.2.1 s=- c=IN IP4 192.0.2.1 t=0 0 m=audio 10000 RTP/AVP 0 8 101 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-16 Esc Back F1 Help s Highlight c Color / Search y Copy F2 Save
Shows all tracked RTP streams with quality metrics. Switch here from the Call List with Tab.
RTP Streams: 14 tracked # SSRC Src IP:Port Dst IP:Port Codec Pkts Jitter Loss% MOS βΈ 1 0x1a2b3c4d 192.0.2.1:10000 192.0.2.2:20000 PCMU 4820 2.1ms 0.0% 4.2 2 0x5e6f7a8b 192.0.2.2:20000 192.0.2.1:10000 PCMU 4815 1.8ms 0.0% 4.3 3 0x9c0d1e2f 192.0.2.6:12000 192.0.2.7:22000 PCMA 1205 18.3ms 1.2% 3.4 4 0xa1b2c3d4 192.0.2.7:22000 192.0.2.6:12000 PCMA 1198 45.7ms 3.8% 2.1 5 0xe5f60718 192.0.2.9:14000 192.0.2.7:24000 opus 9612 3.2ms 0.1% 4.1 6 0x29304150 192.0.2.7:24000 192.0.2.9:14000 opus 9608 2.9ms 0.0% 4.2 7 0xdeadbeef 192.0.2.3:16000 -- PCMU 340 -- -- orphan Esc Back F1 Help Enter Detail Tab Calls F2 Save WAV F7 Filter a All/Call
Tip: Streams marked
orphanhave no matching SIP dialog. This often indicates:
- RTP arriving on unexpected ports (check your NAT/ALG config),
- or calls that started before capture began.
The filter popup lets you build filter expressions with text fields and checkboxes for common options.
β Filter βββββββββββββββββββββββββββββββββββββββββββββββ β From user: [alice ] β β To user: [ ] β β Source IP: [ ] β β Destination IP: [ ] β β Text in message: [ ] β β Header: [Name: text ] β β After: [2026-07-07T08:00:00Z ] β β Before: [2026-07-07T09:00:00Z ] β β Named filter: [sales, support ] β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β All [*] β β REGISTER [*] OPTIONS [*] β β INVITE [*] PUBLISH [*] β β [ Filter ] [ Cancel ] β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Tab Next Space Toggle Enter Apply Esc Cancel F9 Clear
Each label says what its field matches:
- From user and To user match the user part of the URI.
- Source IP and Destination IP match the addresses.
- Text in message searches every SIP message of the call.
- Header takes
Name: text, or a bare header name to find the calls that carry it. - After and Before take an RFC 3339 timestamp.
- The empty fields show an example in gray.
- Named filter takes the names of
[filters]entries, separated by spaces, with or without the leading@. While it is empty, it lists the names the config defines.
Tip: Press
F9to clear every field and the method boxes at once. For anything the fields cannot say, the Filter DSL takes the full expression.
Status line 3 shows the applied selections as a summary, one short item per field:
-
7 methodscounts the checked methods. One checked method shows its name, as inINVITE. -
From~alicenames the field and the text it matches. -
@salesnames a[filters]entry. -
after 2026-07-07T08:00:00Zrepeats a time bound.
For example, F7: 7 methods, From~alice, To~bob Β· F full.
- Press
Fin any view to show the full expression instead, and again to return to the summary.- The key is
filter_detailin[keybindings]. - Set
view_filter_detail = "full"under[display]to start with the full expression.
- The key is
Save captured data in multiple formats. Use Tab to cycle through formats.
β Save capture βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β Save to: /tmp/sipnab_20240615_120000.pcap β β Dialogs: 47 (3 checked) Β· Messages: 212 β β β β Packet capture β β βΈ PCAP Universal baseline (Wireshark, tcpdump, Homer) β β PCAP-NG Modern format with metadata and annotations β β Reporting β β HTML Ladder diagram page (Mermaid), no dependencies β β Markdown Call summary for tickets and incidents β β β¦ β β [Enter] Save [Tab/β§Tab] Format [Esc] Cancel β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Enter Save Tab Format Esc Cancel
The path and the dialog count stay at the top on any terminal height. The keys
stay at the bottom. Only the format list scrolls. With no dialog checked, the
count line says none checked, so all are saved.
Tip:
- Select specific dialogs in the Call List with
Spacebefore pressingF2. The save dialog shows the count and saves only those.- HTML writes a ladder diagram page drawn with Mermaid that you can open in any browser.
Toggle display options without leaving the TUI.
β Settings βββββββββββββββββββββββββββββββββββββββ β β β Colors: [Method] β β Timestamps: [Delta from previous] β β Autoscroll: [On] β β Detail pane: [On] β β SDP: [Hidden] β β Syntax colors: [On] β β β β β/β move Β· Enter toggle Β· Esc close β ββββββββββββββββββββββββββββββββββββββββββββββββββ ββ Move Enter Toggle Esc Close
-
theme-guide.md β recolor every TUI element via
[theme] -
config-reference.md β rebind the 12 configurable keys
via
[keybindings] -
filter-dsl.md β the expression language the F7 filter
dialog compiles down to (and the
--filterflag exposes directly)