Today, I’m goint to
share my SIPP project that I have worked on it during last one month. Before begin this case,
checking call performance on our voice network was my first goal. It can be said that being
continuous of this project offers our team being awake against fail calls. Let
me tell you requirements before start;
> Linux
server
> SIPP Tool
> Also, we
will use python, bash and stored procedure
In first, I’ll
need to give some informations about SIPP. It can be called SIP performance
tool that is a free open sources testing tool. It lets you to
generate sip traffic. In addition, you are able to create varied scenarios whatever you want, even there is
default scenario in SIPP tool. For more technical infos, please check SIPPofficial website.
In this case, I
tryed to explain how we can check sip calls performance and report results. You
can fallow below lines to download and install SIPp tool properly;
wget
http://sourceforge.net/projects/sipp/files/sipp/3.3/sipp-3.3.tar.gz/
apt-get or Yum intsall sipp-XXX-tar.gz
cd Sipp-XX
ls -l
apt-get install openssl
apt-get install libssl-dev
apt-get install libssl1.0.0
apt-get install libssl0.9.8
apt-get install pcaputils
apt-get install libssl-dev
apt-get install libncursesw5-dev
apt-get install libncurses5-dev
apt-get install libcap-dev
make pcapplay_ossl or make pcap
./sipp XXX.XX.XX.XXX -sf
REGISTER_client.xml -inf Register_client.csv -m 1
I think, you
will encounter many errors when you try to install it but “google” will help you for all errors. (My installation took one day :) )
You may start
with creating your own xml scenario that depends according to the your sip
server. Let’s begin to execute ‘vim sample.xml’ on your linux server. Here is
my xml file;
<?xml version="1.0"
encoding="ISO-8859-1" ?>
>>>> be sure your first two lines must be like these.
<!DOCTYPE scenario SYSTEM
"sipp.dtd">
<scenario name="UAC REGISTER
+ INVITE">
<send retrans="500">
>>> First, send register packet with using retrans(for UDP,
timer:500 ms ).
<![CDATA[
REGISTER sip:[remote_ip] SIP/2.0
Via: SIP/2.0/[transport]
[local_ip]:[local_port];rport;branch=[branch]
From:
<sip:[field0]@[field1]>;tag=[call_number]
To: <sip:[field0]@[field1]> >>> these fields should be
defined in .csv file
Call-ID: [call_id]
CSeq: [cseq] REGISTER
Contact:
sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 100
Expires: 120
User-Agent: SIPp/Win32
Content-Length: 0
]]>
</send>
<recv
response="100" optional="true"> >>> it means that options of
response against sent packet.
</recv>
<recv response="200"> >>> SIPp will wait until get 200
OK.
</recv>
<send retrans="500">
>>> Secondly, send invite packet and be sure for branch
parameters like below.
<![CDATA[
INVITE sip:[field3]@[remote_ip] SIP/2.0
Via: SIP/2.0/[transport]
[local_ip]:5062;rport;branch=z9hG4bK-[call_number]-01
From: sipp
<sip:[field0]@[field1]>;tag=[call_number]
To: <sip:[field3]@[field1]>
Call-ID: [call_id]
CSeq: [cseq] INVITE
Contact:
sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 100
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 8
a=rtpmap:8 PCMA/8000
]]>
</send>
<recv response="100" optional="true">
</recv>
<recv response="407" auth="true"> >>> it is used to build the ‘authentication’
keyword.
</recv>
<send>
<![CDATA[
ACK sip:[field3]@[remote_ip] SIP/2.0
Via: SIP/2.0/[transport]
[local_ip]:5062;rport;branch=z9hG4bK-[call_number]-01
From:
<sip:[field0]@[field1]>;tag=[call_number]
[last_To:]
Call-ID: [call_id]
CSeq: [cseq] ACK
Contact:
sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 100
Content-Length: 0
]]>
</send>
<send retrans="500">
>>> send invite again, but now with sip credentials.
<![CDATA[
INVITE sip:[field3]@[remote_ip] SIP/2.0
Via: SIP/2.0/[transport]
[local_ip]:5062;rport;branch=z9hG4bK-[call_number]-02
From: sipp
<sip:[field0]@[field1]>;tag=[call_number]
To: <sip:[field3]@[field1]>
Call-ID: [call_id]
CSeq: [cseq] INVITE
Contact:
<sip:[field0]@[local_ip]:5062>
[field2] >>> It contains SIP credentials in
.csv file
Max-Forwards: 100
Supported: replaces
Allow-Events:
talk,hold,conference,refer,check-sync
Content-Type: application/sdp
Allow: INVITE, INFO, PRACK, ACK, BYE,
CANCEL, OPTIONS, NOTIFY, REGISTER, SUBSCRIBE, REFER, PUBLISH, UPDATE, MESSAGE
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN
IP[local_ip_type] [local_ip]
s=SDP data
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [media_port] RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:9 G722/8000
a=fmtp:101 0-15
a=rtpmap:101 telephone-event/8000
a=ptime:20
a=sendrecv
]]>
</send>
<recv response="100" optional="true">
</recv>
<recv response="180" optional="true">
</recv>
<recv response="183" optional="true">
</recv>
<recv response="480" optional="true">
</recv>
<recv response="200" rrs="true">
</recv>
<send>
<![CDATA[
ACK [next_url] SIP/2.0
Via: SIP/2.0/[transport]
[local_ip]:5062;branch=z9hG4bK-[call_number]-03
From:
<sip:[field0]@[field1]>;tag=[call_number]
[last_To:]
[routes]
Call-ID: [call_id]
CSeq: [cseq] ACK
Contact:
sip:[field0]@[local_ip]:[local_port]
Max-Forwards: 100
Content-Length: 0
]]>
</send>
<pause milliseconds="5000"/> >>> Duration after the setup
call.
<send retrans="500">
<![CDATA[
BYE [next_url] SIP/2.0
Via: SIP/2.0/[transport]
[local_ip]:5062;branch=z9hG4bK-[call_number]-04
From:
<sip:[field0]@[field1]>;tag=[call_number]
[last_To:]
[routes]
Call-ID: [call_id]
CSeq: [cseq] BYE
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 100
Content-Length: 0
]]>
</send>
<recv response="200" crlf="true">
</recv>
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150,
200"/>
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000,
10000"/>
</scenario>
Also, you can see
.csv file to fill fields in .xml file below;
SEQUENTIAL
<username>;<remote_server>;[authentication
username=xxx password=xxx];<called_number>;
After this
configurations, execute this command on your linux server;
./sipp <remote_server>
-sf sample.xml -inf sample.csv -m 1
SIPp can be launched in background mode (-bg command
line option). But to run in background, I used "export TERM=vt100" in bash script.
Also, in command line, there are many features to offer more effective sip testing. You can determine port number, username, transport mode, local ip address, duration etc. More features check this link.
Also, in command line, there are many features to offer more effective sip testing. You can determine port number, username, transport mode, local ip address, duration etc. More features check this link.
Let’s start to
create python code to get CDRs from db server. In this case, we need to a stored
procedure that created from db admin, then we can send request to db server
with python. In addition, you can send your CDRs any e-mail address by python.
That is my
python code to get CDRs:
import pandas as pd
import smtplib
import logging
import time
from email.mime.multipart import
MIMEMultipart
from email.mime.text import
MIMEText
import pyodbc
import json
import argparse
import cgi, cgitb
def getCdr(conn, anumber, bnumber):
oCursor = conn.cursor()
sql = """\
EXEC cdr_list @anumber=?, @bnumber=?
"""
params = (anumber,bnumber)
oCursor.execute(sql, params)
result = "0"
for row in oCursor:
result = row[0]
return (result)
def send_email(text):
sender = "source@domain_address"
recipient = "egemenu@domain_address"
subj = "CDR"
msg = MIMEMultipart('alternative')
msg['Subject'] = subj
msg['From'] = sender
msg['To'] = recipient
msg.attach(MIMEText(text, 'plain'))
try:
a = msg.as_string()
s = smtplib.SMTP('1.1.1.1)
s.sendmail(sender, recipient, a )
s.quit()
return True
except:
return False
def main():
#connectin to the db with SQL Authentification
try:
conn = pyodbc.connect(driver =
'/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so', server = 1.1.1.1, TDS_Version =
'7.0', PORT = "xxxx",
database = 'db_name', uid = ‘username’,
pwd = 'password’)
true_or_false0 = getCdr(conn,
"anumber", "bnumber")
true_or_false1 = getCdr(conn,
"anumber", "bnumber")
true_or_false2 = getCdr(conn,
"anumber", "bnumber")
true_or_false3 = getCdr(conn,
"anumber", "bnumber")
true_or_false4 = getCdr(conn,
"anumber", "bnumber")
results={}
results['CDR RESULTS >> 1: Successful, 0: Fail, -1: Not Found'] =
[true_or_false,true_or_false2,true_or_false3,true_or_false4,true_or_false6]
return send_email(json.dumps(results, indent = 4,
sort_keys=True).replace('\\r\\n', '\n"'))
conn.close()
except Exception as e: print(e)
if __name__ ==
"__main__":
res=main()
Now, we’re done to create main basic bash script;
#!/bin/bash
export TERM=vt100
./sipp remote_server -sf sample.xml -inf sample_1.csv -m 1
sleep 20
./sipp remote_server -sf sample.xml -inf sample_2.csv -m 1
sleep 20
./sipp remote_server -sf sample.xml -inf sample_3.csv -m 1
sleep 20
./sipp remote_server -sf sample.xml -inf sample_4.csv -m 1
sleep 20
./sipp remote_server -sf sample.xml -inf sample_5.csv -m 1
sleep 20
python test_getting_cdr.py
With this
script, it’ll make 5 calls and then get CDRs in order to check their results.
If you add
this main script your crontab, It can run every day or when you want so you
find opportunity to check your network.
The informations appeared in e-mail like this;
{
"CDR RESULTS >> 1: Successful, 0: Fail, -1: Not Found": [
"a_number >> b0_number # 1 ",
"a_number >> b1_number # 1 ",
"a_number >> b2_number # 1 ",
"a_number >> b3_number # 0 ",
"a_number >> b4_number # 0 "
]
}
The informations appeared in e-mail like this;
{
"CDR RESULTS >> 1: Successful, 0: Fail, -1: Not Found": [
"a_number >> b0_number # 1 ",
"a_number >> b1_number # 1 ",
"a_number >> b2_number # 1 ",
"a_number >> b3_number # 0 ",
"a_number >> b4_number # 0 "
]
}
But pay attention when you edit crontab. If you execute ‘crontab -l’ before edit it, that will be better, because you may run ‘crontab -r’ instead of ‘crontab -e’ by mistake. :)
Please do not hesitate to ask any question about this case via e-mail...
No comments:
Post a Comment