sipp 是 linux 上用來產生 SIP traffic 的測試工具,它可以使用 xml 描述一通電話的所有 SIP 封包的內容,並利用 pcap 播放工具,將 pcap 裡面的 RTP 語音直接送到受話端。sipp 安裝後,預設只會有一個 g711a.pcap 也就是 alaw 的 RTP 語音檔,如果要測試其他 codec 的語音檔,就要自己錄製。
tcpdump
首先我們準備好一個 SIP Client 當作發話端,在 SIP server 上先建立一個 conference room,當然 SIP Client 必須要設定只使用我們要錄製的 ilbc codec。
執行 tcpdump 將封包錄製下來。
tcpdump -i eth0 -w audio.pcap
接下來就用 SIP Client 撥打電話到 conference room 裡面,然後就講幾句話之後掛斷電話。
wireshark 處理 audio.pcap
用 wireshark 將 audio.pcap 打開之後,可以看到這一段時間錄製的所有封包,這時候,我們用 filter 將 RTP 封包擷取出來。
在 filter 的地方填寫以下的字串,就可以取出 RTP 的語音封包,192.168.1.11 是發話端的 IP,192.168.1.5 是受話端的 IP。
((ip.src == 192.168.1.11) and (ip.dst == 192.168.1.5)) and rtp
在 File -> Export Specific Packet 的選單中,選擇將 Displayed All Packets 另存到另一個 ilbc.pcap 檔案中。
sipp scenario
準備 sipp call scenario 檔案,內容就是撥打電話進去,接通後,播放 ilbc.pcap 檔案。
SIPP scenario: test.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<scenario name="test">
<send>
<![CDATA[
INVITE sip:[field2]@[remote_ip] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch];rport
Max-Forwards: 70
To: "[field2]" <sip:[field2]@[remote_ip]>
From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]
Call-ID: [call_id]
CSeq: [cseq] INVITE
Contact: <sip:[field0]@[local_ip]:[local_port]>
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]:[local_port]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [auto_media_port] RTP/AVP 97 101
a=rtpmap:97 ILBC/8000
a=rtpmap:97 mode=20
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16
]]>
</send>
<recv response="401" auth="true" />
<send>
<![CDATA[
INVITE sip:[field2]@[remote_ip] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch];rport
Max-Forwards: 70
To: "[field2]" <sip:[field2]@[remote_ip]>
From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]
Call-ID: [call_id]
CSeq: [cseq] INVITE
Contact: <sip:[field0]@[local_ip]:[local_port]>
Content-Type: application/sdp
[field1]
Allow: INVITE,ACK,BYE,CANCEL,OPTIONS,PRACK,REFER,NOTIFY,SUBSCRIBE,INFO,MESSAGE
Supported: replaces,norefersub,100rel
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]:[local_port]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [auto_media_port] RTP/AVP 97 101
a=rtpmap:97 ILBC/8000
a=rtpmap:97 mode=20
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16
]]>
</send>
<recv response="100" optional="true" />
<recv response="180" optional="true" />
<recv response="200" />
<send>
<![CDATA[
ACK sip:[field2]@[remote_ip] SIP/2.0
Via: SIP/2.0/[transport] [local_ip];rport;branch=[branch]
From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]
To: "[field2]" <sip:[field2]@[remote_ip]>[peer_tag_param]
Call-ID: [call_id]
CSeq: [cseq] ACK
Content-Length: 0
]]>
</send>
<pause milliseconds="2000"/>
<nop>
<action>
<exec play_pcap_audio="pcap/dtmf_2833_star.pcap" />
</action>
</nop>
<nop>
<action>
<exec play_pcap_audio="pcap/ilbc.pcap"/>
</action>
</nop>
<pause milliseconds="1000"/>
<send retrans="500">
<![CDATA[
BYE sip:[field2]@[remote_ip] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];rport;branch=[branch]
Max-Forwards: 70
From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]
To: "[field2]" <sip:[field2]@[remote_ip]>[peer_tag_param]
Call-ID: [call_id]
Cseq: 3 BYE
Subject: Performance Test
Content-Length: 0
]]>
</send>
<recv response="200" crlf="true" />
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
</scenario>
準備另一個搭配 test.xml call scenario 的 sip 帳號及密碼的 csv 檔案: test.csv
SEQUENTIAL
2106;[authentication username=2106 password=test];2105
執行 sipp
因為通話是設定讓 sipp 以門號 2106 撥打到 2105,所以我們利用 SIP Client 註冊到 2105 之後,執行以下的 sipp 指令,就可以在 2105 接聽到 sipp 撥打過來的電話,然後聽到剛剛錄製的 ilbc 語音。
sipp -sf test.xml -inf test.csv -r 1 -rp 1 -i 192.168.1.11 -m 1 192.168.1.5