2019年1月16日 星期三

pcapsipdump

pcapsipdump 基於 libpcap,將網路界面或 pcap 檔的封包以每個 SIP session (包括 RTP 或 T38 media) 儲存成不同的檔案。封包除了用 BPF 先行過濾外,可以用正規表示式過濾出需要的電話號碼或 SIP Method。另外,在每個 session 開始或結束時可以指定執行 shell 指令。

編譯

需要 libpcap-dev、libbsd-dev 等。
git svn clone --stdlayout https://svn.code.sf.net/p/pcapsipdump/code pcapsipdump
cd pcapsipdump
make
sudo make install

指令格式

pcapsipdump [-fpU] [-i interface | -r file] [-d output_directory] [-P pid_file]
            [-v level] [-R filter] [-m filter] [-n filter] [-l filter]
            [-B size] [-T limit] [-t trigger:action:param] [expression]
參數
  • -f:不 fork,也就是不成為 daemon
  • -p
  • -U
  • -i interface 或 -r file:必須指定網路界面或檔案
  • -d:指定輸出目錄和檔名,不然預設是 ... 
    • %f %t %i
  • -P:
  • -v:
  • -R:
  • -m filter:Method 過濾,預設是「^(INVITE|OPTIONS|REGISTER)$」。
  • -n:電話號碼過濾 (正規表示式)
  • -l:
  • -B:
  • -T:
  • -t:
  • expression:BPF 過濾表示式

使用範例

pcapsipdump ; 顯示使用說明
pcapsipdump -f -r test.pcapng -m '^INVIT$' -d ./%Y%m%d-%H%M%S-%f-%t.pcap

程式

main() @pcapsipdump.cpp
  1. 取得參數,剩下的部份是額外的 BPF 表示式。
  2. ...
  3. 使用 pcap_create() 或 pcap_open_offline() 取得網路界面或 pcap 檔的 pcap_t handle。
  4. 用 pcap_compile() 和 pcap_setfilter() 編譯和設定 BPF 過濾。預設過濾式「udp or vlan」,指令參數之外剩餘的部份就是 BPF 表示式。
  5. pcap_datalink() 查看 datalink 類型,換算出 IP 信頭位置。
  6. 可以 fork() 為 daemon。
  7. pcap_next_ex() 處理每個封包
    1. 每封包時間 15 秒檢查是否 session 過長應該結束
    2. fragment 封包:看是否需要儲存,然後處理下個封包。
    3. 如果是要儲存的 RTP 封包,儲存然後處理下個封包。
    4. 如果是 SIP 封包的話
      1. 檢查號碼是否符合儲存然後處理下個封包。
      2. 新 callid:檢查 Method 符合後產生輸出檔名。
      3. BYE
      4. 解析 SDP
      5. 是否有 fragment
    5. 其它封包:可開顯示
  8. 結束所有 session
  9. 結束 pcap_t
  10. 等候子行程
讀取封包需要取得 pcap_t
  • 從網路界面:pcap_create() → 設定選項 → pcap_activate()。pcap_findalldevs() 列出界面,然後 pcap_freealldevs() 釋出。pcap_lookupdev() 取得第一個非「loopback」的界面。
  • 從檔案:pcap_open_offline() 或 pcap_fopen_offline()。
  • 「假」的:pcap_open_dead()
  • 讀取封包:pcap_dispatch(), pacp_loop(), pcap_next(), pcap_next_ex()。
  • 結束取得封包:pcap_close()
過濾:pcap_compile() ...
寫 pcap 檔:pcap_dump_open() -> pcap_dump() -> pcap_dump_close()。
送出封包:pcap_inject()、pcap_sendpacket()

參考

沒有留言:

張貼留言

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...