Skip to content

feat(dpi): add SIP protocol detection and metadata extraction#262

Open
0xghost42 wants to merge 1 commit into
domcyrus:mainfrom
0xghost42:feat/dpi-sip
Open

feat(dpi): add SIP protocol detection and metadata extraction#262
0xghost42 wants to merge 1 commit into
domcyrus:mainfrom
0xghost42:feat/dpi-sip

Conversation

@0xghost42
Copy link
Copy Markdown

Closes #260.

Summary

Adds best-effort Deep Packet Inspection for plaintext SIP (RFC 3261) over TCP and UDP. SIP shares its request grammar with HTTP, so the detector runs before HTTP analysis and rejects payloads whose trailing version token is not SIP/2.0 — this prevents INVITE / OPTIONS / MESSAGE traffic from being misclassified as HTTP.

What it does

Detection

  • Port 5060 (and 5061 hint), plus a cheap start-line signature so non-standard SIP ports are still caught.
  • Request methods: INVITE, ACK, BYE, CANCEL, REGISTER, OPTIONS, PRACK, SUBSCRIBE, NOTIFY, PUBLISH, INFO, REFER, MESSAGE, UPDATE.
  • Responses keyed off the SIP/2.0 <status> prefix.

Extracted metadata (per the issue scope)

  • Request method / response status code + reason phrase.
  • From, To, Call-ID, User-Agent, Server (long form + compact f / t / i / c).
  • CSeq parsed into cseq_number + cseq_method.
  • Content-Type plus a derived has_sdp flag for application/sdp.

Surfaces

  • New ApplicationProtocol::Sip(SipInfo) variant with a Display formatter tuned for the connection-table column (requests show method + Call-ID; responses show status code + reason + CSeq method).
  • DPI details panel in the TUI renders message type, method/status, From, To, Call-ID, CSeq, User-Agent, Server, Content-Type (with an (SDP) tag when has_sdp is set).
  • UDP connection state reports SIP_REQUEST / SIP_RESPONSE.
  • ConnectionFilter general search matches sip, method, Call-ID, From, To, User-Agent, Server — so existing fuzzy search just works.
  • Per-protocol merge keeps stable identity fields and applies latest-wins for message_type / method / status_code / CSeq, mirroring how dialogs evolve across multiple packets in the same connection.
  • get_timeout returns 5 minutes for SIP UDP flows so idle dialogs stay tracked between transactions.

Why detection runs before HTTP

INVITE sip:bob@x SIP/2.0 and OPTIONS / HTTP/1.1 both look like METHOD <uri> <version>. The disambiguator is the trailing version token. sip::is_sip checks for SIP/2.0 in the first line; only then does it consume the payload. HTTP traffic is rejected cheaply by the same check (the OPTIONS method also exists in SIP, so an explicit test for that case is included).

Tests

10 new unit tests in src/network/dpi/sip.rs:

  • Request + response detection.
  • Full INVITE parsing (CSeq, headers, has_sdp).
  • 200 OK parsing (status, reason, Server).
  • REGISTER without body.
  • Compact-form headers (f, t, i, c).
  • HTTP / SIP disambiguation (OPTIONS / HTTP is rejected; OPTIONS sip:… is accepted).
  • Truncated and wrong-version payloads return None.

Full suite locally:

  • cargo test --all-features → 335 passed, 0 failed.
  • cargo clippy --all-features --all-targets -- -D warnings → clean.
  • cargo fmt --all -- --check → clean.
  • cargo build --release → clean.

Test plan

  • Unit tests pass locally on macOS (Apple Silicon).
  • CI green on the PR.
  • Live smoke test against a SIP softphone (recommended for the maintainer; I do not have a SIP endpoint handy on this machine).

Files touched

  • src/network/dpi/sip.rs — new module (~340 lines incl. tests).
  • src/network/dpi/mod.rs — register module, add PORT_SIP / PORT_SIP_TLS, dispatch SIP before HTTP for TCP, after binary protocols for UDP.
  • src/network/types.rsSipInfo, SipMessageType, enum variant, Display arm, sort_key, dist counter, UDP state string, idle timeout.
  • src/network/merge.rsmerge_sip_info (stable fields first-wins, dialog state latest-wins).
  • src/filter.rs — general-search match arm for SIP metadata.
  • src/ui.rs — DPI details panel rendering for SIP.

No changes to ROADMAP / README / CONTRIBUTING — happy to add a roadmap tick if you'd prefer.

Adds best-effort Deep Packet Inspection for plaintext SIP (RFC 3261)
over TCP and UDP. SIP shares its request grammar with HTTP, so the
detector runs before HTTP analysis and rejects payloads whose trailing
version token is not "SIP/2.0" -- this prevents SIP INVITE/OPTIONS/
MESSAGE traffic from being misclassified as HTTP.

Detection
- Port 5060 (and 5061 hint) plus start-line signature.
- Request methods covered: INVITE, ACK, BYE, CANCEL, REGISTER, OPTIONS,
  PRACK, SUBSCRIBE, NOTIFY, PUBLISH, INFO, REFER, MESSAGE, UPDATE.
- Responses keyed off the "SIP/2.0 <status>" prefix.

Extracted metadata
- Request method / response status code + reason phrase.
- From, To, Call-ID, User-Agent, Server headers (both long and compact
  form: f / t / i / c).
- CSeq parsed into cseq_number + cseq_method.
- Content-Type plus a derived has_sdp flag for application/sdp.

Surfaces
- ApplicationProtocol::Sip variant with Display formatter for the
  connection table.
- DPI details panel in the TUI shows message type, method/status,
  From/To/Call-ID/CSeq/User-Agent/Server/Content-Type.
- UDP state string reports SIP_REQUEST / SIP_RESPONSE.
- ConnectionFilter general search matches sip, method, Call-ID, From,
  To, User-Agent, Server.
- Per-protocol merge keeps stable identity fields and latest-wins for
  message_type / method / status / CSeq, mirroring how dialogs evolve.
- get_timeout returns 5 min for SIP UDP flows to track idle dialogs.

Tests
- 10 new unit tests covering request/response parsing, compact headers,
  HTTP-vs-SIP disambiguation (OPTIONS, /, HTTP/1.1), method coverage,
  and rejection of truncated or wrongly-versioned payloads.
- Full suite: cargo test (335 passed), cargo clippy -D warnings, cargo
  fmt --check, cargo build --release all clean.

Closes domcyrus#260
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(dpi): add SIP protocol detection and metadata extraction

1 participant