1、sipp的安装
1) 在centos 7.2下安装
yum install make gcc gcc-c++ ncurses ncurses.x86_64 ncurses-devel ncurses-devel.x86_64 openssl lksctp-tools libnet libpcap libpcap-devel libpcap.x86_64 libpcap-devel.x86_64 gsl gsl-devel
cd /root/
wget http://sourceforge.net/projects/sipp/files/sipp/3.4/sipp-3.3.990.tar.gz/download
tar -zxvf sipp-3.3.990.tar.gz
cd sipp-3.3.990/
./configure --with-sctp --with-pcap --with-openssl make && sudo make install
sipp -v
2) 在ubuntu14.04 下有些差异
http://sipp.sourceforge.net/doc3.3/reference.html
http://sipp.sourceforge.net/doc/reference.html
tar xvf sipp-3.5.2.tar.gz
cd sipp-3.5.2
sudo apt-get install libsctp-dev lksctp-tools
sudo apt-get install libncurses5-dev
sudo apt-get install libpcap-dev libssl-dev
sudo apt-get install build-essential
./build.sh --with-pcap --with-sctp --with-openssl
make
make install
2、sipp拨号测试
先在freepbx上创建好两个分机103和104
最好是在linux下创建xml脚本文件,因为windows操作之后文档的编码格式可能会改变,xml对编码格式非常敏感。在windows和linux两边编辑容易出问题。
1) 主叫账户
vi caller.csv
SEQUENTIAL
103;104;[authentication username=103 password=103]
2) 被叫账号
vi callee.csv
SEQUENTIAL
104;;[authentication username=104 password=104]
3) 注册脚本
vi regclient_set_c_port.xml
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> <scenario name="regclient"> <!--本脚本特为持续性测试使用,如单次使用,建议-p 与-set c_port的端口设为相同--> <!--执行命令样例:sipp -sf regc_set_c_port.xml 172.31.231.220:5060 -i 172.31.231.23 -p 5077 -inf caller.csv -m 1 -set c_port 5066--> <Global variables="c_port" /> <nop hide="true"> <action> <!--设置EXP的值为3600--> <assignstr assign_to="EXP" value="3600" /> </action> </nop> <send> <![CDATA[ REGISTER sip:[remote_ip] SIP/2.0 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] From: <sip:[field0]@[remote_ip]>;tag=acknnkkg.[call_number] To: <sip:[field0]@[remote_ip]> Call-ID: [call_id] CSeq: 1 REGISTER Contact: <sip:[field0]@[local_ip]:[$c_port]> Max-Forwards: 70 Subject: Reg Performance Test made by wangwei user-agent: SIPp client Expires: [$EXP] Content-Length: 0 ]]> </send> <recv response="401" optional="true" auth="true" next="auth" > </recv> <recv response="403" optional="true" next="END"> </recv> <recv response="404" optional="true" next="END"> </recv> <recv response="200" next="END" timeout="5000"> </recv> <label id="auth" /> <send> <![CDATA[ REGISTER sip:[remote_ip] SIP/2.0 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] [last_From:] [last_To:] [last_Call-ID:] [last_CSeq:] Contact: <sip:[field0]@[local_ip]:[$c_port]> Max-Forwards: 70 Subject: Reg Performance Test made by wangwei user-agent: SIPp client Expires: [$EXP] [field2] Content-Length: 0 ]]> </send> <recv response="200" next="END" timeout="5000"> </recv> <label id="END"/> <nop hide="true"> </nop> <!--<Reference variables="microseconds,seconds" />--> <!-- Definition of the response time repartition table (unit is ms) --> <ResponseTimeRepartition value="50, 200"/> <!-- Definition of the call length repartition table (unit is ms) --> <CallLengthRepartition value="500, 5000"/> </scenario>
4) 被叫脚本
vi callee_with_bye.xml
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> <scenario name="callee_with_bye"> <!--用于模拟局内被叫侧用户的正常业务流程 媒体类型:PCMU 呼叫挂机:主叫方(60秒超时后主动发BYE拆话)--> <!--执行命令样例:sipp -sf callee_with_bye.xml -p 5068--> <!--定义全局状态机,如果收到OPTIONS消息,则跳转至options标签处--> <recv request="OPTIONS" optional="global" next="options"> </recv> <recv request="INVITE"> <!--参数caller_num、callee_num和caller_tag用于主叫未挂机,BYE接收超时主动发BYE的流程--> <action> <ereg regexp="<sip:(.*)@(.*)>;tag=(.*)" search_in="hdr" header="From: " check_it="true" assign_to="junk,caller_num,domain,caller_tag" /> <ereg regexp="<sip:(.*)@.*>" search_in="hdr" header="To: " check_it="true" assign_to="junk,callee_num" /> </action> </recv> <!--增加间隔20ms,避免偶现系统不发送100响应的问题--> <pause hide="true" milliseconds="20"/> <send> <![CDATA[ SIP/2.0 100 Trying [last_Via:] [last_From:] [last_To:] [last_Call-ID:] [last_CSeq:] Contact: <sip:[local_ip]:[local_port];transport=[transport]> Content-Length: 0 ]]> </send> <!--增加间隔20ms,避免偶现系统不发送180响应的问题--> <pause hide="true" milliseconds="20"/> <send> <![CDATA[ SIP/2.0 180 Ringing [last_Via:] [last_From:] [last_To:];tag=[call_number] [last_Call-ID:] [last_CSeq:] Contact: <sip:[local_ip]:[local_port];transport=[transport]> Content-Length: 0 ]]> </send> <!--设置发送200后等待ACK的重传周期为1秒,如果1秒内收不到ACK则进行200的重传--> <send retrans="1000" start_rtd="ack"> <![CDATA[ SIP/2.0 200 OK [last_Via:] [last_From:] [last_To:];tag=[call_number] [last_Call-ID:] [last_CSeq:] Contact:<sip:[local_ip]:[local_port];transport=[transport]> Content-Type: application/sdp Content-Length: [len] v=0 o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] s=- c=IN IP[media_ip_type] [media_ip] t=0 0 m=audio [media_port] RTP/AVP 0 8 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=ptime:20 ]]> </send> <!--设置等待ACK的超时定时器为30秒,如果30秒内收不到ACK则呼叫超时失败而结束--> <recv request="ACK" rtd="ack" timeout="30000" /> <!--使用rtp_stream循环播放PCMA音频 <nop hide="true"> <action> <exec rtp_stream="pcap/g711a.pcap,-1,0"/> </action> </nop> --> <!--使用rtp_stream循环播放PCMU音频 <nop hide="true"> <action> <exec rtp_stream="pcap/g711u.pcap,-1,0"/> </action> </nop> --> <!--使用play_pcap单次播放PCMA音频--> <nop hide="true"> <action> <exec play_pcap_audio="pcap/g711a.pcap"/> </action> </nop> <!--使用play_pcap单次播放PCMU音频 <nop hide="true"> <action> <exec play_pcap_audio="pcap/g711u.pcap"/> </action> </nop> --> <recv request="BYE" timeout="60000" ontimeout="send_bye"/> <send next="END"> <![CDATA[ SIP/2.0 200 OK [last_Via:] [last_From:] [last_To:] [last_Call-ID:] [last_CSeq:] Contact: <sip:[local_ip]:[local_port];transport=[transport]> Content-Length: 0 ]]> </send> <label id="options"/> <send next="END" > <![CDATA[ SIP/2.0 200 OK [last_Via:] [last_Call-ID:] [last_From:] [last_To:];tag=telpo-options[call_number] [last_CSeq:] [last_Contact:] user-agent: SIPP version [sipp_version] subject: reg performance test made by wangwei link-status: I am alive Content-Length: 0 ]]> </send> <!--主叫未挂机,BYE接收超时,被叫主动发BYE--> <label id="send_bye"/> <send start_rtd="bye"> <![CDATA[ BYE sip:[$caller_num]@[local_ip]:[local_port] SIP/2.0 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] From: "[$caller_num]" <sip:[$caller_num]@[local_ip]>;tag=[call_number] To: "[$callee_num]"<sip:[$callee_num]@[local_ip]>;tag=[$caller_tag] Call-ID: [call_id] CSeq: 2 BYE Max-Forwards: 70 Subject: normal call scenario by wangwei Content-Length: 0 ]]> </send> <recv response="200" rtd="bye"> </recv> <label id="END"/> <Reference variables="junk,domain" /> <!-- definition of the response time repartition table (unit is ms)--> <ResponseTimeRepartition value="50, 200"/> <!-- definition of the call length repartition table (unit is ms)--> <CallLengthRepartition value="500, 1000, 10000"/> </scenario>
5) 主叫脚本
vi caller_with_auth.xml
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> <scenario name="caller_with_auth"> <!--执行命令样例:sipp -sf caller_with_auth.xml 47.106.93.236:5060 -p 5066 -inf caller.csv -m 1 -d 10000 -oocsn ooc_default--> <!--发送INVITE消息,设定重传定时器为1000ms,同时启动定时器invite--> <send retrans="1000" start_rtd="invite"> <![CDATA[ INVITE sip:[field1]@[remote_ip] SIP/2.0 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]zhg8 To: "[field1]"<sip:[field1]@[remote_ip]> Call-ID: [call_id] CSeq: 1 INVITE Contact: <sip:[field0]@[local_ip]:[local_port]> User-Agent: SIPp client mode version [sipp_version] Allow: INVITE,PRACK,ACK,UPDATE,CANCEL,BYE,OPTIONS,INFO,SUBSCRIBE,REFER,NOTIFY Max-Forwards: 70 Content-Type: application/sdp Content-Length: [len] v=0 o=SIPp [pid][call_number] 8[pid][call_number]8 IN IP[local_ip_type] [local_ip] s=SIPp Normal Call Test t=0 0 m=audio [media_port] RTP/AVP 0 8 c=IN IP[media_ip_type] [media_ip] a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=ptime:20 a=sendrecv ]]> </send> <recv response="100" optional="true"> </recv> <recv response="401" auth="true"> </recv> <!--部分呼叫鉴权可能为407 <recv response="401" auth="true"> </recv>--> <send> <![CDATA[ ACK sip:[field1]@[remote_ip]:[remote_port] SIP/2.0 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch-3] From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]zhg8 To: "[field1]"<sip:[field1]@[remote_ip]>[peer_tag_param] Call-ID: [call_id] CSeq: 1 ACK Contact: <sip:[field0]@[local_ip]:[local_port]> Max-Forwards: 70 Subject: normal call scenario by wangwei user-agent: SIPp client mode version [sipp_version] Content-Length: 0 ]]> </send> <send retrans="1000" start_rtd="invite"> <![CDATA[ INVITE sip:[field1]@[remote_ip] SIP/2.0 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]zhg8 To: "[field1]"<sip:[field1]@[remote_ip]> Call-ID: [call_id] CSeq: 2 INVITE [field2] Contact: <sip:[field0]@[local_ip]:[local_port]> User-Agent: SIPp client mode version [sipp_version] Allow: INVITE,PRACK,ACK,UPDATE,CANCEL,BYE,OPTIONS,INFO,SUBSCRIBE,REFER,NOTIFY Max-Forwards: 70 Content-Type: application/sdp Content-Length: [len] v=0 o=SIPp [pid][call_number] 8[pid][call_number]8 IN IP[local_ip_type] [local_ip] s=SIPp Normal Call Test t=0 0 m=audio [media_port] RTP/AVP 0 8 c=IN IP[media_ip_type] [media_ip] a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=sendrecv a=ptime:20 ]]> </send> <!--1xx响应均为可选接收消息,且接收到临时响应后,即可停止invite定时器的计时--> <!--收到4xx/5xx错误响应后,直接进入呼叫失败--> <recv response="100" optional="true" rtd="invite"> </recv> <recv response="183" optional="true" rtd="invite" next="normal"> </recv> <recv response="403" optional="true" rtd="invite" next="err_ack"> </recv> <recv response="480" optional="true" rtd="invite" next="err_ack"> </recv> <recv response="486" optional="true" rtd="invite" next="err_ack"> </recv> <recv response="500" optional="true" rtd="invite" next="err_ack"> </recv> <recv response="503" optional="true" rtd="invite" next="err_ack"> </recv> <recv response="180" optional="true" rtd="invite" next="normal"> </recv> <label id="normal"/> <recv response="200" rtd="invite"> <action> <ereg regexp="m=audio ([0-9]*)" search_in="msg" check_it="true" assign_to="junk,callee_media_port" /> </action> </recv> <nop hide="true"> </nop> <send> <![CDATA[ ACK sip:[field1]@[remote_ip]:[remote_port] SIP/2.0 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]zhg8 To: "[field1]"<sip:[field1]@[remote_ip]>[peer_tag_param] Call-ID: [call_id] CSeq: 2 ACK Contact: <sip:[field0]@[local_ip]:[local_port]> Max-Forwards: 70 Subject: normal call scenario by wangwei user-agent: SIPp client mode version [sipp_version] Content-Length: 0 ]]> </send> <!--使用rtp_stream循环播放PCMA音频 <nop hide="true"> <action> <exec rtp_stream="pcap/g711a.pcap,-1,0"/> </action> </nop> --> <!--使用rtp_stream循环播放PCMU音频 <nop hide="true"> <action> <exec rtp_stream="pcap/g711u.pcap,-1,0"/> </action> </nop> --> <!--使用play_pcap单次播放PCMA音频--> <nop hide="true"> <action> <exec play_pcap_audio="pcap/g711a.pcap"/> </action> </nop> <!--使用play_pcap单次播放PCMU音频 <nop hide="true"> <action> <exec play_pcap_audio="pcap/g711u.pcap"/> </action> </nop> --> <!--媒体流传输完毕后,暂停发送BYE结束呼叫,在执行命令中增加参数-d 指定暂停时间:如-d 10000暂停10秒--> <pause /> <send start_rtd="bye"> <![CDATA[ BYE sip:[field1]@[remote_ip]:[remote_port] SIP/2.0 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]zhg8 To: "[field1]"<sip:[field1]@[remote_ip]>[peer_tag_param] Call-ID: [call_id] CSeq: 3 BYE Max-Forwards: 70 Subject: normal call scenario by wangwei Content-Length: 0 ]]> </send> <recv response="200" rtd="bye" next="END"> </recv> <!--异常结束,复用err_ack流程--> <label id="err_ack"/> <send> <![CDATA[ ACK sip:[field1]@[remote_ip]:[remote_port] SIP/2.0 [last_Via:] From: "[field0]" <sip:[field0]@[remote_ip]>;tag=[call_number]zhg8 To: "[field1]"<sip:[field1]@[remote_ip]>[peer_tag_param] [last_Call-ID:] CSeq: 2 ACK Max-Forwards: 70 Subject: normal call scenario by wangwei user-agent: SIPp client mode version [sipp_version] Content-Length: 0 ]]> </send> <!--正常结束--> <label id="END"/> <nop hide="true"> </nop> <!--如果存在定义了但未被使用的变量,可以在下面语句的双引号中增加,避免运行时报错--> <Reference variables="junk,callee_media_port" /> <!--definition of the response time repartition table (unit is ms) --> <ResponseTimeRepartition value="50, 200,1000,2000,4000,10000"/> <!--definition of the call length repartition table (unit is ms) --> <CallLengthRepartition value="500, 1000, 10000"/> </scenario>
6) 按以下步骤运行
#主叫注册
sipp -sf regclient_set_c_port.xml 47.106.xx.xxx:5060 -i 192.168.247.152 -p 5066 -inf caller.csv -set c_port 5066 -m 1
#被叫注册
sipp -sf regclient_set_c_port.xml 47.106.xx.xxx:5060 -i 192.168.247.152 -p 5088 -inf callee.csv -set c_port 5088 -m 1
#被叫
sipp -sf callee_with_bye.xml -i 192.168.247.152 -p 5088 -trace_err
#主叫
sudo sipp -sf caller_with_auth.xml 47.106.xx.xxx:5060 -i 192.168.247.152 -p 5066 -inf caller.csv -m 1 -d 10000 -oocsn ooc_default -trace_err
7) 登陆会议室
我在freepbx上创建的会议室号是2018,没有密码,直接拨号就能登进去
所以将主叫账户caller.csv改成登陆会议室就行
SEQUENTIAL
103;2018;[authentication username=103 password=103]
3、其他拓展应用
具体应用看手册 SIPp3.4中文参考手册.pdf https://files.cnblogs.com/files/dong1/SIPp3.4%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C.pdf
1) SIPP通过next指定id实现循环
https://blog.csdn.net/voip3261/article/details/10335925
参考 https://blog.csdn.net/netluoriver/article/details/21786301