Call Detail Record - CDR

From VoIPmonitor.org


This guide covers the Call Detail Record (CDR) interface in VoIPmonitor GUI - searching, filtering, and analyzing captured calls.

What is a CDR?

A Call Detail Record (CDR) contains information about a single telephone call:

  • Call timing (start time, duration, connect time)
  • Participant information (caller/called numbers, IP addresses, SIP agents)
  • Signaling details (SIP messages, final response codes)
  • Quality metrics (MOS scores, packet loss, jitter/delay)
  • Media information (codecs, RTP stream data)

How CDR Fields Are Populated

VoIPmonitor populates CDR fields from the SIP INVITE packet:

Field Source
Calling Number From header
Called Number To header (default) or Request-URI
Caller IP Source IP of INVITE packet
Called IP Destination IP of INVITE packet

Call Duration vs Connect Duration

A CDR has two durations. Use the right one – only Connect duration says whether the call was answered.

GUI name Column Measured from → to Meaning
Call duration duration first INVITE → end of call Whole call including ringing. Greater than 0 for every call, also for unanswered and failed calls.
Connect duration connect_duration 200 OK to the INVITE → end of call Connected (talk) time. 0 = the call was not answered. This is the value to compare with carrier billing.

Ringing time = Call duration − Connect duration. The end of the call is the last captured packet (normally the BYE); see Call Termination Codes for calls closed by a timeout. In the CDR filter form, both are available in the Duration section as Call duration [s] and Connect duration [s].

Configuring Destination Number Source

Control where the called number is extracted from using destination_number_mode in voipmonitor.conf:

Value Behavior
1 (default) From To header
2 From INVITE Request-URI

ℹ️ Note: If caller/called numbers appear "inverted", verify the SIP flow in the SIP History tab - this often indicates callback scenarios where the PBX initiates the call.

Understanding the Main CDR View

The CDR view has three main sections:

The CDR List

Title Bar & Timezone

The title bar displays the current time range. Click dates to quickly change the filter.

Timezone hierarchy (check in this order if times appear incorrect):

  1. Storage (Sniffer): utc and timezone in voipmonitor.conf
  2. GUI Settings: Settings > System Configuration > National > Timezone
  3. Display (CDR View): Timezone selector in top-right corner (user-specific)

Button Panel

Filter Form

The most powerful feature for finding specific calls.

Common Tab

  • Participant Filters: Search by Number, IP, or Domain
    • Use % as wildcard (e.g., 222% for numbers starting with 222)
    • Use , for multiple values, ! for negation
  • Email-formatted SIP addresses: For addresses like anonymous@anonymous.invalid:
    • Enter user part (anonymous) in the Number field
    • Enter domain part (anonymous.invalid) in the Domain field
  • Regular Expressions: Use R() syntax:
    • R(^500[0-9]{4}$) - matches 7-digit numbers starting with 500
    • !R(^[+]?[0-9]+$) - find non-numeric caller numbers
    • R(17145787[2-9]) - number ranges
  • IP Address Include Proxy: Check this box to include proxy chain IPs (from cdrproxy) in the filter
  • SIP Filters:
    • Last SIP Response Code - e.g., 487 or 4% for all 4xx
    • SIP requests - filter by method and count (e.g., INVITE count >= 3 for retransmissions)
    • SIP responses - search full response text

⚠️ Warning: SIP requests filter requires save_sip_history = all or requests. SIP responses filter requires save_sip_history = responses or save_sip_responses = yes.

  • DTMF Filters: (requires dtmf2db = yes in sniffer config)
    • DTMF char - search for specific DTMF digit or sequence (e.g., 1 to find calls containing digit "1")
    • DTMF count - filter by number of DTMF digits. Available operators: >= and <
      • >= 1 - find calls with at least one DTMF digit
      • < 1 - find calls with no DTMF digits

ℹ️ Note: The DTMF count filter does not support the = operator. Use < 1 to find calls without DTMF (not = 0).

Finding re-INVITE Calls

Method 1: SIP Requests Count

  • Filter Form > Common > SIP requests: INVITE >= 3

Method 2: Custom Headers (more precise)

  • Configure CDR Custom Headers to capture To header tag
  • Filter by ToTag = % (present = re-INVITE) or ToTag = NULL (absent)

RTP Tab

Filter by quality metrics:

  • RTP IP/Port: Filter by media endpoint addresses
  • MOS: Find calls below a threshold
  • PDV (Jitter): Filter by delay events in specific intervals
  • Loss: Filter by consecutive packet loss patterns
  • Last RTP from Last SIP: Find calls where RTP ended before final SIP (early media stops)

Quick Filters

Access shortcuts for common searches and saved filter templates.

Saving filter templates:

  1. Apply filter criteria
  2. Click Save filter template button
  3. Name your template

Editing or deleting filter templates:

  1. Select the filter template you wish to edit/delete from the template name/dropdown field
  2. Two new buttons appear right behind the dropdown: Edit template and Delete template
  3. Click the appropriate button to modify or remove the template

Combining templates (OR logic):

  1. Open Filter Form > Combination subtab
  2. Select multiple saved templates
  3. Results show calls matching ANY selected template

Menu

  • Delete: Remove selected CDRs and files
  • Export CSV: Export all standard CDR columns to a CSV file. Note: The CSV export always includes all standard CDR columns regardless of which columns are currently visible in the CDR list view. Column visibility settings (Show columns) only affect the on-screen display, not the CSV output. For exporting only specific columns, use a direct database query or the Web API.
  • Batch download audio: Download audio for displayed CDRs (limit: 100 records)
  • Create merged PCAP: Combine selected CDRs into one PCAP

💡 Tip: For multi-page exports: create per-page PCAPs, then merge with mergecap -w combined.pcap *.pcap (available at /var/www/html/bin/mergecap-* or via wireshark-common package).

Selecting multiple rows:

  • CTRL+Click - select specific rows
  • SHIFT+Click - select range

CDR List Columns

Key Columns

Column Description
ID Unique record identifier
Sensor ID Capturing sensor name
Datetime Call start time
Duration (PDD) / Codec Call duration (from the first INVITE, includes ringing – see Call Duration vs Connect Duration), Post-Dial Delay, codec
Caller/Called Info Number, Name, IP, Agent. Red flag indicates BYE sender
Last Response Final SIP response code
RTP IP Addresses Source IPs and ports for both legs

Quality Columns

  • MOS Column: Three parametric scores (see Quality Guide):
    • F1: Fixed 50ms jitter buffer
    • F2: Fixed 200ms jitter buffer
    • Adapt: Adaptive jitter buffer (up to 500ms)
  • Delay Column: Color-coded packet delay variation distribution
  • Loss Column: Color-coded consecutive packet loss (red = burst losses)
  • RTCP Column: Endpoint-reported jitter and loss
  • PRICE Column: Billing costs (hidden by default, enable via column selector)

Sniffer Loss vs RTCP Loss

Scenario Likely Cause
RTCP loss > Sniffer loss Network issue after the sniffer (Wi-Fi, last-mile)
Sniffer loss > RTCP loss Monitoring point overload or RTCP reports not captured

Understanding Last SIP Response

ℹ️ Note: If a call shows 200 OK AND an error code (5xx/4xx), check the Connect duration (not Duration – Duration runs from the first INVITE and is always > 0): if it is > 0, the call connected successfully and the error appears in the BYE packet's Reason header (termination reason).

Finding termination reason:

  1. Expand CDR detail > SIP History tab
  2. Find the BYE packet
  3. Click magnifying glass to expand
  4. Look for Reason header

Call Termination Codes (cdr.bye)

Every CDR stores in the cdr.bye column how the call ended: whether the sniffer saw a normal BYE, or had to close the call itself because a timeout expired. In the GUI, the codes 100 and higher are shown as a note in the CDR detail and can be searched with the Timeout calls filter in the CDR filter form.

Code GUI label Meaning Related parameter (default)
0 – The call was not answered (no 200 OK to the INVITE) –
1 – Answered, but no BYE was seen –
2 missing BYE confirmation BYE seen, but not confirmed by 200 OK –
3 – Normal end: BYE and its 200 OK seen –
100 packet loss The sniffer lost packets between the kernel and the application; the CDR may be incomplete –
101 one way signalization SIP was seen in one direction only, without any reply –
102 absolute timeout Closed after the maximum call length absolute_timeout (14400 s = 4 h)
103 BYE timeout BYE was sent, but the call still had traffic until the BYE timer expired bye_timeout (1200 s), bye_confirmed_timeout (600 s)
104 RTP timeout RTP stopped in the middle of the call and no BYE came rtptimeout (300 s)
105 one way timeout No reply to the INVITE initiator's requests onewaytimeout (15 s)
106 early BYE BYE without any 18x or 2xx response –
107 zombie No 18x/2xx and no RTP within 300 s after the INVITE – (fixed 300 s)
108 sip without rtp The call never had any RTP and no BYE came sipwithoutrtptimeout (3600 s = 1 h)
109 maximum sip/invite packets exceeded Too many SIP / INVITE packets in one call max_sip_packets_in_call (20000), max_invite_packets_in_call (10000)
110 closed during closing sniffer The call was still open when the sniffer was stopped or restarted –

If several reasons apply, the code is chosen in this order: 110, 102, 103, 104, 105, 107, 108, 109, 101, 100, 106, then 0–3.

⚠️ Warning: Duration of calls closed by a timeout. The timeout only decides when the sniffer closes the call. callend, duration and connect_duration always end at the last captured packet of the call (SIP, RTP or RTCP), not at the moment the timeout expired. For a call without RTP whose BYE was not captured (code 108), connect_duration therefore ends at the last SIP packet seen (for example the ACK or a session-timer re-INVITE) and is shorter than the real call. Such calls are the usual reason why the sum of connect_duration is lower than the carrier's invoice. The real fix is to capture the missing traffic (RTP and BYE of these calls) – see Sniffer_troubleshooting.

Example – connected time per termination code:

SELECT bye, COUNT(*) AS calls, ROUND(SUM(connect_duration) / 60) AS connect_minutes
FROM cdr
WHERE calldate >= '2026-07-01' AND calldate < '2026-08-01' AND connect_duration > 0
GROUP BY bye
ORDER BY bye;

The CDR Detail View

Click the [+] icon on any CDR row to expand the detail view.

Summary Tab

Call Quality Graph

  • Each vertical line = packet group
  • Colored dot = median delay (jitter)
  • Red lines at top = packet loss
  • Clock drift: A steadily climbing/descending graph indicates clock issues, not necessarily network problems

Why high delay causes loss: When packets arrive later than the jitter buffer capacity (typically 50-200ms), they're skipped during playback - detected as packet loss.

Received Packets

Shows packets VoIPmonitor received FROM each endpoint:

Field Meaning
Caller > Received Packets Packets from caller (A-leg)
Called > Received Packets Packets from called party (B-leg)

Empty value indicates one-way stream (no packets captured from that endpoint).

If the call has more than two RTP streams (SBC, RTP proxy, NAT), these values – like all caller/called quality metrics of the CDR – come from the one stream selected for each direction. See How the caller (A) and called (B) streams are selected and the RTP Legs tab.

DTMF Section

Shows DTMF digits when capture is enabled:

  • dtmf2db = yes - SIP INFO and RFC 2833
  • inbanddtmf = yes - In-band G.711 (CPU intensive)

DTMF data is stored in the cdr_dtmf database table (columns: cdr_ID, dtmf). The DTMF column in CDR view is displayed automatically when DTMF data exists for a call — there is no manual column visibility toggle for DTMF.

⚠️ Warning: DTMF is NOT included in CSV export. The Export CSV function exports only standard CDR columns. To export DTMF data, query the cdr_dtmf table directly:

SELECT c.ID, c.calldate, c.caller, c.called, d.dtmf
FROM cdr c
JOIN cdr_dtmf d ON c.ID = d.cdr_ID
WHERE c.calldate >= '2024-01-01';

RTP Stream Used in Another Call

This informational message indicates the RTP IP:port combination was reused across sessions. Common with aggressive port reuse by PBXs. Not an error.

SIP History Tab

Wireshark-like view of call signaling:

  • Sequence Diagram: Visual SIP message flow
  • Message Table: Text list of all messages
  • Packet Detail: Click magnifying glass for decoded packet tree

Viewing SDP Data

ℹ️ Note: Basic RTP IP/port information is displayed by default in CDR columns - no configuration required. Only advanced SDP inspection requires save_sip_history = all.

To view detailed SDP:

  1. SIP History tab > click INVITE packet
  2. Click magnifying glass to expand
  3. Scroll to SDP section

SDP shows:

  • c= - connection lines (media IPs)
  • m= - media description (ports)
  • a= - attributes (codecs, encryption)

RTP Legs Tab

Available with sniffer 2026.09.0 and GUI 2026.9.0 or newer; the tab appears only for calls that have media leg information.

Shows all RTP streams of the call grouped by media leg – a physical segment of the media path, such as caller ↔ SBC or SBC ↔ carrier:

  • Leg rows: the SDP addresses negotiated on that segment, marked as caller or called SDP (stored when save_sdp_ipport is enabled, which is the default).
  • View rows: shown when the same leg was seen under more than one address pair, e.g. before and after NAT.
  • Stream rows: direction (caller → called or called → caller), SSRC, source/destination, codec, packets and per-stream quality (loss, MOS, jitter, RTCP, delay).

The two streams whose quality is stored in the CDR (the Caller and Called values) are marked [A] and [B]. The selection rules are described in How the caller (A) and called (B) streams are selected.

Legs by CID / Legs by Header Tabs

For correlating related call legs. See Merging_or_correlating_multiple_call_legs for details.

  • Legs by CID: Finds calls sharing last 6 digits of From header within seconds
  • Legs by Header: Correlates by custom SIP header (configured via match_header)

💡 Tip: When investigating 487 "Request Cancelled" responses, use Legs by CID to see all related legs - the answered leg shows 200 OK, cancelled legs show 487 (normal forking behavior).

Charts Tab

Displays charts in context of the selected call (e.g., trends for that caller number).

Map Tab

Geolocates source/destination SIP IPs using GeoIP service.

Dashboard Panels

Bottom panels provide aggregated views:

  • Group By: Last SIP Response, Codec, SIP IP, or IP Groups
  • Charts: Pie chart of grouped data
  • Filters: Click any item to apply as filter

Trend Analysis: Group by SIP IP to visualize call volume trends for capacity planning. See Alerts for trend-based alerting.

Limitations

Media Encryption Filtering

Type Support Verification
SRTP/DTLS-SRTP Supported (can decrypt) Check SDP for a=crypto or a=fingerprint
ZRTP Not supported Cannot monitor ZRTP calls

⚠️ Warning: There is no filter for media encryption type. Verify manually via SDP in SIP History tab.

See Also






AI Summary for RAG

Summary: CDR View is the primary VoIPmonitor GUI interface for analyzing calls. Main sections: CDR List (paginated records), Button Panel (filter/export tools), Dashboard (aggregated stats). Filter Form has Common tab (participant info, SIP filters with % wildcard, R() regex) and RTP tab (quality metrics). RTP IP/port shown by default without configuration. SIP request filters require save_sip_history config. Menu provides Delete, Export CSV, Batch download audio (100 limit), Create merged PCAP. Detail View includes Summary tab (quality graph, DTMF), SIP History tab (packet inspection, SDP viewing), Legs tabs (call correlation). 487 responses often indicate normal forking - check Legs by CID. ZRTP not supported.

Keywords: CDR, call detail record, filter, search, MOS, jitter, packet loss, SIP history, call legs, correlation, RTCP, trend analysis, re-INVITE, filter template, batch download, DTMF, SIP retransmissions, SRTP, DTLS, ZRTP, mergecap, RTP IP, RTP port, SDP

Key Questions:

  • How do I filter calls by quality metrics (MOS, jitter, loss)?
  • How do I view SIP message flow for a call?
  • What is the difference between sniffer loss and RTCP loss?
  • How do I detect SIP retransmissions?
  • How do I investigate 487 "Request Cancelled" responses?
  • How do I view RTP ports? (displayed by default, no config needed)
  • How do I create merged PCAP from multiple calls?
  • How do I view SDP data in SIP History?
  • Does VoIPmonitor support ZRTP? (No)
  • How do I save and combine filter templates?