I used the routing logic that comes with the homer package to accommodate some of the new features included in v3.6
This is what my kamailio.cfg looks like (the file included in /homer/configs/kamailio.cfg):
# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route
route {
if($sht(a=>method::all) == $null) $sht(a=>method::all) = 0;
$sht(a=>method::all) = $sht(a=>method::all) + 1;
if($sht(b=>$rm::$cs::$ci) != $null) {
$var(a) = "sip_capture";
sip_capture("$var(a)");
drop;
}
$sht(b=>$rm::$cs::$ci) = 1;
if (is_method("INVITE|REGISTER")) {
if($ua =~ "(friendly-scanner|sipvicious)") {
sql_query("cb", "INSERT INTO alarm_data_mem (create_date, type, total, source_ip, description) VALUES(NOW(), 'scanner', 1, '$si', 'Friendly scanner alarm!') ON DUPLICATE KEY UPDATE total=total+1");
}
#IP Method
sql_query("cb", "INSERT INTO stats_ip_mem ( method, source_ip, total) VALUES('$rm', '$si', 1) ON DUPLICATE KEY UPDATE total=total+1");
if($au != $null) $var(anumber) = $au;
else $var(anumber) = $fU;
#hostname in contact
if($sel(contact.uri.host) =~ "^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$") {
if($sht(a=>alarm::dns) == $null) $sht(a=>alarm::dns) = 0;
$sht(a=>alarm::dns) = $sht(a=>alarm::dns) + 1;
}
if($sel(contact.uri.host) != $si) {
if($sht(a=>alarm::spoofing) == $null) $sht(a=>alarm::spoofing) = 0;
$sht(a=>alarm::spoofing) = $sht(a=>alarm::spoofing) + 1;
}
if($au =~ "(\=)|(\-\-)|(\')|(\#)|(\%27)|(\%24)") {
if($sht(a=>alarm::sqlinjection) == $null) $sht(a=>alarm::sqlinjection) = 0;
$sht(a=>alarm::sqlinjection) = $sht(a=>alarm::sqlijnection) + 1;
}
if($(hdr(Record-Route)[0]{nameaddr.uri}) != $si) {
if($sht(a=>alarm::spoofing) == $null) $sht(a=>alarm::spoofing) = 0;
$sht(a=>alarm::spoofing) = $sht(a=>alarm::spoofing) + 1;
}
if (is_method("INVITE")) {
if (has_totag()) {
if($sht(a=>method::reinvite) == $null) $sht(a=>method::reinvite) = 0;
$sht(a=>method::reinvite) = $sht(a=>method::reinvite) + 1;
}
else {
if($sht(a=>method::invite) == $null) $sht(a=>method::invite) = 0;
$sht(a=>method::invite) = $sht(a=>method::invite) + 1;
if($adu != $null) {
if($sht(a=>method::invite::auth) == $null) $sht(a=>method::invite::auth) = 0;
$sht(a=>method::invite::auth) = $sht(a=>method::invite::auth) + 1;
}
if($ua != $null) {
sql_query("cb", "INSERT INTO stats_useragent_mem (useragent, method, total) VALUES('$ua', 'INVITE', 1) ON DUPLICATE KEY UPDATE total=total+1");
}
}
}
else {
if($sht(a=>method::register) == $null) $sht(a=>method::register) = 0;
$sht(a=>method::register) = $sht(a=>method::register) + 1;
if($adu != $null) {
if($sht(a=>method::register::auth) == $null) $sht(a=>method::register::auth) = 0;
$sht(a=>method::register::auth) = $sht(a=>method::register::auth) + 1;
}
if($ua != $null) {
sql_query("cb", "INSERT INTO stats_useragent_mem (useragent, method, total) VALUES('$ua', 'REGISTER', 1) ON DUPLICATE KEY UPDATE total=total+1");
}
}
}
else if(is_method("BYE")) {
if($sht(a=>method::bye) == $null) $sht(a=>method::bye) = 0;
$sht(a=>method::bye) = $sht(a=>method::bye) + 1;
if(is_present_hf("Reason") && $(hdr(Reason){param.value,cause}{
s.int}) != "" ) {
$var(cause) = $(hdr(Reason){param.value,cause}{
s.int});
if($var(cause) != 16 && $var(cause) !=17) {
if($sht(a=>stats::sdf) == $null) $sht(a=>stats::sdf) = 0;
$sht(a=>stats::sdf) = $sht(a=>stats::sdf) + 1;
}
}
}
else if(is_method("CANCEL")) {
if($sht(a=>method::cancel) == $null) $sht(a=>method::cancel) = 0;
$sht(a=>method::cancel) = $sht(a=>method::cancel) + 1;
}
else if(is_method("OPTIONS")) {
if($sht(a=>method::options) == $null) $sht(a=>method::options) = 0;
$sht(a=>method::options) = $sht(a=>method::options) + 1;
}
else if(is_method("REFER")) {
if($sht(a=>method::refer) == $null) $sht(a=>method::refer) = 0;
$sht(a=>method::refer) = $sht(a=>method::refer) + 1;
}
else if(is_method("UPDATE")) {
if($sht(a=>method::update) == $null) $sht(a=>method::update) = 0;
$sht(a=>method::update) = $sht(a=>method::update) + 1;
}
$var(a) = "sip_capture";
# Kamailio 4.1 only
#sip_capture("$var(a)");
sip_capture();
drop;
}
onreply_route {
if($sht(a=>method::all) == $null) $sht(a=>method::all) = 0;
$sht(a=>method::all) = $sht(a=>method::all) + 1;
if($sht(b=>$rs::$cs::$rm::$ci) != $null) {
$var(a) = "sip_capture";
sip_capture("$var(a)");
drop;
}
$sht(b=>$rs::$cs::$rm::$ci) = 1;
#413 Too large
if(status == "413") {
if($sht(a=>alarm::413) == $null) $sht(a=>alarm::413) = 0;
$sht(a=>alarm::413) = $sht(a=>alarm::413) + 1;
}
# Too many hops
else if(status == "483") {
if($sht(a=>alarm::483) == $null) $sht(a=>alarm::483) = 0;
$sht(a=>alarm::483) = $sht(a=>alarm::483) + 1;
}
# loops
else if(status == "482") {
if($sht(a=>alarm::482) == $null) $sht(a=>alarm::482) = 0;
$sht(a=>alarm::482) = $sht(a=>alarm::482) + 1;
}
# 400
else if(status == "400") {
if($sht(a=>alarm::400) == $null) $sht(a=>alarm::400) = 0;
$sht(a=>alarm::400) = $sht(a=>alarm::400) + 1;
}
# 500
else if(status == "500") {
if($sht(a=>alarm::500) == $null) $sht(a=>alarm::500) = 0;
$sht(a=>alarm::500) = $sht(a=>alarm::500) + 1;
}
# 503
else if(status == "503") {
if($sht(a=>alarm::503) == $null) $sht(a=>alarm::503) = 0;
$sht(a=>alarm::503) = $sht(a=>alarm::503) + 1;
}
# 403
else if(status == "403") {
if($sht(a=>alarm::403) == $null) $sht(a=>alarm::403) = 0;
$sht(a=>alarm::403) = $sht(a=>alarm::403) + 1;
}
# MOVED
else if(status =~ "^(30[012])$") {
if($sht(a=>response::300) == $null) $sht(a=>response::300) = 0;
$sht(a=>response::300) = $sht(a=>response::300) + 1;
}
if($rm == "INVITE") {
#ISA
if(status =~ "^(408|50[03])$") {
if($sht(a=>stats::isa) == $null) $sht(a=>stats::isa) = 0;
$sht(a=>stats::isa) = $sht(a=>stats::isa) + 1;
}
#Bad486
if(status =~ "^(486|487|603)$") {
if($sht(a=>stats::bad::invite) == $null) $sht(a=>stats::bad::invite) = 0;
$sht(a=>stats::bad::invite) = $sht(a=>stats::bad::invite) + 1;
}
#SD
if(status =~ "^(50[034])$") {
if($sht(a=>stats::sd) == $null) $sht(a=>stats::sd) = 0;
$sht(a=>stats::sd) = $sht(a=>stats::sd) + 1;
}
if(status == "407") {
if($sht(a=>response::407::invite) == $null) $sht(a=>response::407::invite)= 0;
$sht(a=>response::407::invite) = $sht(a=>response::407::invite) + 1;
}
else if(status == "401") {
if($sht(a=>response::401::invite) == $null) $sht(a=>response::401::invite)= 0;
$sht(a=>response::401::invite) = $sht(a=>response::401::invite) + 1;
}
else if(status == "200") {
if($sht(a=>response::200::invite) == $null) $sht(a=>response::200::invite)= 0;
$sht(a=>response::200::invite) = $sht(a=>response::200::invite) + 1;
}
}
else if($rm == "BYE") {
if(status == "407") {
if($sht(a=>response::407::bye) == $null) $sht(a=>response::407::bye) = 0;
$sht(a=>response::407::bye) = $sht(a=>response::407::bye) + 1;
}
else if(status == "401") {
if($sht(a=>response::401::bye) == $null) $sht(a=>response::401::bye) = 0;
$sht(a=>response::401::bye) = $sht(a=>response::401::bye) + 1;
}
else if(status == "200") {
if($sht(a=>response::200::bye) == $null) $sht(a=>response::200::bye) = 0;
$sht(a=>response::200::bye) = $sht(a=>response::200::bye) + 1;
}
}
sip_capture();
drop;
}
route[TIMER_STATS] {
xlog("timer routine: time is $TS\n");
#ALARM SCANNERS
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, source_ip, description) SELECT create_date, type, total, source_ip, description FROM alarm_data_mem;");
sql_query("cb", "TRUNCATE TABLE alarm_data_mem");
#413
if($sht(a=>alarm::413) > 0) {
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 413', $sht(a=>alarm::413), 'Too many big messages')");
}
$sht(a=>alarm::413) = 0;
#483
if($sht(a=>alarm::483) > 0) {
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 483', $sht(a=>alarm::483), 'Too many hops messages')");
}
$sht(a=>alarm::483) = 0;
#482
if($sht(a=>alarm::482) > 0) {
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 482', $sht(a=>alarm::482), 'Too many loops messages')");
}
$sht(a=>alarm::482) = 0;
#403
if($sht(a=>alarm::403) > 0) {
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 403', $sht(a=>alarm::403), 'fraud alarm')");
}
$sht(a=>alarm::403) = 0;
#503
if($sht(a=>alarm::503) > 0) {
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 503', $sht(a=>alarm::503), 'service unavailable')");
}
$sht(a=>alarm::503) = 0;
#500
if($sht(a=>alarm::500) > 0) {
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 500', $sht(a=>alarm::500), 'server errors')");
}
$sht(a=>alarm::500) = 0;
#408
if($sht(a=>alarm::408) > 0) {
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 408', $sht(a=>alarm::408), 'Timeout')");
}
$sht(a=>alarm::408) = 0;
#400
if($sht(a=>alarm::400) > 0) {
sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 400', $sht(a=>alarm::400), 'Too many bad request')");
}
$sht(a=>alarm::400) = 0;
#delete old alarms
sql_query("cb", "DELETE FROM alarm_data WHERE create_date < DATE_SUB(NOW(), INTERVAL 5 DAY)");
#SQL STATS
$var(tm) = ($time(min) mod 10);
if($var(tm) != 0 && $var(tm) != 5) return;
$var(t1) = $TS;
$var(t2) = $var(t1) - 300;
xlog("TIME : $var(tm)\n");
$var(t_date) = "FROM_UNIXTIME(" + $var(t1) + ", '%Y-%m-%d %H:%i:00')";
$var(f_date) = "FROM_UNIXTIME(" + $var(t2) + ", '%Y-%m-%d %H:%i:00')";
#STATS Useragent
sql_query("cb", "INSERT INTO stats_useragent (from_date, to_date, useragent, method, total) SELECT $var(f_date) as from_date, $var(t_date) as to_date, useragent, method, total FROM stats_useragent_mem;");
sql_query("cb", "TRUNCATE TABLE stats_useragent_mem");
#STATS IP
sql_query("cb", "INSERT INTO stats_ip (from_date, to_date, method, source_ip, total) SELECT $var(f_date) as from_date, $var(t_date) as to_date, method, source_ip, total FROM stats_ip_mem;");
sql_query("cb", "TRUNCATE TABLE stats_ip_mem");
#INSERT SQL STATS
#SDF
if($sht(a=>stats::sdf) != $null && $sht(a=>stats::sdf) > 0) {
sql_query("cb", "INSERT INTO stats_data (from_date, to_date, type, total) VALUES($var(f_date), $var(t_date), 'sdf', $sht(a=>stats::sdf))");
$sht(a=>stats::sdf) = 0;
}
#ISA
if($sht(a=>stats::isa) != $null && $sht(a=>stats::isa) > 0) {
sql_query("cb", "INSERT INTO stats_data (from_date, to_date, type, total) VALUES($var(f_date), $var(t_date), 'isa', $sht(a=>stats::isa))");
$sht(a=>stats::isa) = 0;
}
#SD
if($sht(a=>stats::sd) != $null && $sht(a=>stats::sd) > 0) {
sql_query("cb", "INSERT INTO stats_data (from_date, to_date, type, total) VALUES($var(f_date), $var(t_date), 'isa', $sht(a=>stats::sd))");
$sht(a=>stats::sd) = 0;
}
#SSR
if($sht(a=>stats::ssr) != $null && $sht(a=>stats::ssr) > 0) {
sql_query("cb", "INSERT INTO stats_data (from_date, to_date, type, total) VALUES($var(f_date), $var(t_date), 'ssr', $sht(a=>stats::ssr))");
$sht(a=>stats::ssr) = 0;
}
#ASR
$var(asr) = 0;
#if($sht(a=>response::200::invite) > 0) {
if($sht(a=>method::invite) > 0) {
if($sht(a=>response::407::invite) == $null) $sht(a=>response::407::invite) = 0;
if($sht(a=>response::200::invite) == $null) $sht(a=>response::200::invite) = 0;
$var(d) = $sht(a=>method::invite) - $sht(a=>response::407::invite);
if($var(d) > 0) {
$var(asr) = $sht(a=>response::200::invite) / $var(d) * 100;
if($var(asr) > 100) $var(asr) = 100;
}
}
#Stats DATA
sql_query("cb", "INSERT INTO stats_data (from_date, to_date, type, total) VALUES($var(f_date), $var(t_date), 'asr', $var(asr))");
#NER
$var(ner) = 0;
#if($sht(a=>response::200::invite) > 0 || $sht(a=>stats::bad::invite) > 0) {
if($sht(a=>method::invite) > 0) {
if($sht(a=>response::200::invite) == $null) $sht(a=>response::200::invite) = 0;
if($sht(a=>response::bad::invite) == $null) $sht(a=>response::bad::invite) = 0;
if($sht(a=>response::407::invite) == $null) $sht(a=>response::407::invite) = 0;
$var(d) = $sht(a=>method::invite) - $sht(a=>response::407::invite);
if($var(d) > 0) {
$var(ner) = ($sht(a=>response::200::invite) + $sht(a=>stats::bad::invite)) / $var(d) * 100;
if($var(ner) > 100) $var(ner) = 100;
}
}
sql_query("cb", "INSERT INTO stats_data (from_date, to_date, type, total) VALUES($var(f_date), $var(t_date), 'ner', $var(ner))");
#INVITE
if($sht(a=>method::reinvite) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, totag, total) VALUES($var(f_date), $var(t_date),'INVITE', 1, $sht(a=>method::reinvite))");
$sht(a=>method::reinvite) = 0;
}
#INVITE
if($sht(a=>method::invite) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), 'INVITE', $sht(a=>method::invite))");
$sht(a=>method::invite) = 0;
}
#INVITE AUTH
if($sht(a=>method::invite::auth) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, auth, total) VALUES($var(f_date), $var(t_date), 'INVITE', 1, $sht(a=>method::invite::auth))");
$sht(a=>method::invite::auth) = 0;
}
#REGISTER
if($sht(a=>method::register) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), 'REGISTER', $sht(a=>method::register))");
$sht(a=>method::register) = 0;
}
#REGISTER AUTH
if($sht(a=>method::register::auth) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, auth, total) VALUES($var(f_date), $var(t_date), 'REGISTER', 1, $sht(a=>method::register::auth))");
$sht(a=>method::register::auth) = 0;
}
#BYE
if($sht(a=>method::bye) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), 'BYE', $sht(a=>method::bye))");
$sht(a=>method::bye) = 0;
}
#CANCEL
if($sht(a=>method::cancel) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), 'CANCEL', $sht(a=>method::cancel))");
$sht(a=>method::cancel) = 0;
}
#OPTIONS
if($sht(a=>method::options) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), 'OPTIONS', $sht(a=>method::options))");
$sht(a=>method::options) = 0;
}
#REFER
if($sht(a=>method::refer) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), 'REFER', $sht(a=>method::refer))");
$sht(a=>method::refer) = 0;
}
#UPDATE
if($sht(a=>method::update) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), 'UPDATE', $sht(a=>method::update))");
$sht(a=>method::update) = 0;
}
#RESPONSE
#300
if($sht(a=>response::300) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), '300', $sht(a=>response::300))");
$sht(a=>response::300) = 0;
}
#407 INVITE
if($sht(a=>response::407::invite) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, cseq, total) VALUES($var(f_date), $var(t_date), '407', 'INVITE', $sht(a=>response::407::invite))");
$sht(a=>response::407::invite) = 0;
}
#401 INVITE
if($sht(a=>response::401::invite) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, cseq, total) VALUES($var(f_date), $var(t_date), '401', 'INVITE', $sht(a=>response::401::invite))");
$sht(a=>response::401::invite) = 0;
}
#200 INVITE
if($sht(a=>response::200::invite) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, cseq, total) VALUES($var(f_date), $var(t_date), '200', 'INVITE', $sht(a=>response::200::invite))");
$sht(a=>response::200::invite) = 0;
}
#407 BYE
if($sht(a=>response::407::bye) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, cseq, total) VALUES($var(f_date), $var(t_date), '407', 'BYE', $sht(a=>response::407::bye))");
$sht(a=>response::407::bye) = 0;
}
#401 BYE
if($sht(a=>response::401::bye) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, cseq, total) VALUES($var(f_date), $var(t_date), '401', 'BYE', $sht(a=>response::401::bye))");
$sht(a=>response::401::bye) = 0;
}
#200 BYE
if($sht(a=>response::200::bye) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, cseq, total) VALUES($var(f_date), $var(t_date), '200', 'BYE', $sht(a=>response::200::bye))");
$sht(a=>response::200::bye) = 0;
}
#ALL MESSAGES
if($sht(a=>method::all) > 0) {
sql_query("cb", "INSERT INTO stats_method (from_date, to_date, method, total) VALUES($var(f_date), $var(t_date), 'ALL', $sht(a=>method::all))");
$sht(a=>method::all) = 0;
}
}
However, Kamailio's routing logic syntax is different and I'm having a hard time parsing through it. This is what the RTCP-XR collection logic looks like in the Opensips routing logic:
# main request routing logic
route{
#For example, you can capture only needed methods...
if (method =~ "^(INVITE|ACK|CANCEL|BYE|REFER|PRACK|UPDATE)") {
sip_capture();
}
else if (method =~ "^PUBLISH" && !$ct =~ "x-sipX-nonat" && $rd = "
domain.com" ) {
#xlog("$rd=================================");
perl_exec("messagedump");
t_reply("200","PUBLISH RECORDED");
}
exit;
}
onreply_route {
#And only needed reply or needed requests method
if(status =~ "^(1[0-9][0-9]|[3[0-9][0-9]|4[0-9]|[56][0-9][0-9])") {
if($rm =~ "^(INVITE|ACK|CANCEL|BYE|REFER|PRACK|UPDATE)") {
sip_capture();
}
exit;
}
}
Any help would be appreciated.
--
Ashlin Jones-Acosta
Telephony Systems Engineer
Infrastructure Technology
Direct: (805) 222-0934
PennyMac