#!KAMAILIO
#
# Example configuration file for a sipcapture node
#
####### Global Parameters #########

debug=5
log_stderror=no

memdbg=5
memlog=5

log_facility=LOG_LOCAL0

fork=yes
children=5

/* uncomment the next line to disable TCP (default on) */
disable_tcp=yes

/* IP and port for HEP capturing) */
#listen=udp:<HOST_IP>:9060

#Max loops
max_while_loops=100

mpath="/usr/lib/kamailio/modules"

loadmodule "pv.so"
loadmodule "db_mysql.so"
loadmodule "sipcapture.so"
loadmodule "textops.so"
loadmodule "rtimer.so"
loadmodule "xlog.so"
loadmodule "sqlops.so"
loadmodule "htable.so"
loadmodule "sl.so"
loadmodule "siputils.so"


modparam("htable", "htable", "a=>size=8;autoexpire=400")
modparam("htable", "htable", "b=>size=8;autoexpire=31")

modparam("rtimer", "timer", "name=ta;interval=60;mode=1;")
modparam("rtimer", "exec", "timer=ta;route=TIMER_STATS")

modparam("sqlops","sqlcon","cb=>mysql://<MYSQL_USER>:<MYSQL_PASS>@127.0.0.1/homer_db")

# ----- mi_fifo params -----

####### Routing Logic ########
modparam("sipcapture", "db_url", "mysql://<MYSQL_USER>:<MYSQL_PASS>@localhost/homer_db")
modparam("sipcapture", "capture_on", 1)
/* activate HEP capturing */
modparam("sipcapture", "hep_capture_on", 1)
/* IP to listen. Port/Portrange apply only on mirroring port capturing */
modparam("sipcapture", "raw_socket_listen", "10.0.0.0:5060-5090")
/* Name of interface to bind on raw socket */
modparam("sipcapture", "raw_interface", "eth0")
/* activate IPIP capturing */
modparam("sipcapture", "raw_ipip_capture_on", 0)
/* My table name*/
modparam("sipcapture", "table_name", "sip_capture")
/* children for raw socket */
modparam("sipcapture", "raw_sock_children", 4)
/* insert delayed */
#modparam("sipcapture", "db_insert_mode", 1)
/* activate monitoring/mirroring port capturing. Linux only */
modparam("sipcapture", "raw_moni_capture_on", 1)
/* Promiscious mode RAW socket. Mirroring port. Linux only */
modparam("sipcapture", "promiscious_on", 1)
/* activate Linux Socket Filter (LSF/BPF) on mirroring interface. Linux only */
#modparam("sipcapture", "raw_moni_bpf_on", 1)
/* !!! old schema !!!! */
#modparam("sipcapture", "authorization_column", "authorization")

# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route
route {

	xlog("ANTON: recibido paquete!!");

        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";
                # Kamailio 4.1 only
                #sip_capture("$var(a)"); 
                sip_capture();
                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");
                }

                if($ua =~ "(scanner|bluebox)") {
                        sql_query("cb", "INSERT INTO alarm_data_mem (create_date, type, total, source_ip, description) VALUES(NOW(), 'scanner', 1, '$si', '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")) {
                       $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";
                # Kamailio 4.1 only
                #sip_capture("$var(a)"); 
                sip_capture();
                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;

        }
        # Call Transaction Does not exist
        else if(status == "481") {
                if($sht(a=>alarm::481) == $null) $sht(a=>alarm::481) = 0;
                $sht(a=>alarm::481) = $sht(a=>alarm::481) + 1;
        }
        # 408 Timeout
        else if(status == "408") {
                if($sht(a=>alarm::408) == $null) $sht(a=>alarm::408) = 0;
                $sht(a=>alarm::408) = $sht(a=>alarm::408) + 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;

        }
        # 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(), 'Big messages', $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 hops', $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(), 'Loops detected', $sht(a=>alarm::482), 'Too many loops messages')");
        $sht(a=>alarm::482) = 0;
    }

    #481
    if($sht(a=>alarm::481) > 0) {
        sql_query("cb", "INSERT INTO alarm_data (create_date, type, total, description) VALUES(NOW(), 'Too Many 481', $sht(a=>alarm::481), 'Call transaction does not exist')");
        $sht(a=>alarm::481) = 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(), 'Bad Request detected', $sht(a=>alarm::400), 'Too many bad request')");
        $sht(a=>alarm::400) = 0;
    }

    #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::invite) > 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;
    }

}