1- Install Ser with Radius Authentication and Accounting Support
2- Install Radius-Client-NG. Make sure you appended dictionary.sip dictionary.cisco and dictionary.ser to dictionary file


Note: When call connection times out, no start and stop accounting is generated by ser after authorization request.
      The call will be online for 2 minutes(2 online checking intervals) and then automatically ends by ibs
      and no credit is deducted from user.

TODO: Clean the ser cfg and put some comments



#############################################################################33




#
# $Id: ser.cfg,v 1.25.2.1 2005/02/18 14:30:44 andrei Exp $
#
# simple quick-start config script
#

# ----------- global configuration parameters ------------------------

#debug=3         # debug level (cmd line: -dddddddddd)
#fork=yes
#log_stderror=no        # (cmd line: -E)

/* Uncomment these lines to enter debugging mode
fork=yes
log_stderror=yes
*/

check_via = no
# (cmd. line: -v)
  dns = no
# (cmd. line: -r)
  rev_dns = no
# (cmd. line: -R)
#port=5060
#children=4
  fifo = "/tmp/ser_fifo"
#mhomed=1
  alias = "192.168.1.10"
  alias = "192.168.1.11"
  alias = "sip.parspooyesh.com"
# ------------------ module loading ----------------------------------
  loadmodule "/usr/local/lib/ser/modules/sl.so"
  loadmodule "/usr/local/lib/ser/modules/tm.so"
  loadmodule "/usr/local/lib/ser/modules/rr.so"
  loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
  loadmodule "/usr/local/lib/ser/modules/usrloc.so"
  loadmodule "/usr/local/lib/ser/modules/registrar.so"
  loadmodule "/usr/local/lib/ser/modules/textops.so"
  loadmodule "/usr/local/lib/ser/modules/auth.so"
  loadmodule "/usr/local/lib/ser/modules/auth_radius.so"
  loadmodule "/usr/local/lib/ser/modules/acc.so"
  loadmodule "/usr/local/lib/ser/modules/nathelper.so"


# ----------------- setting module-specific parameters ---------------
# -- usrloc params --
modparam ("usrloc", "db_mode", 0)

# -- auth params --
modparam ("auth_radius", "radius_config",
          "/usr/local/etc/radiusclient-ng/radiusclient.conf")
modparam ("acc", "radius_config",
          "/usr/local/etc/radiusclient-ng/radiusclient.conf")
modparam ("acc", "report_cancels", 1)
modparam ("acc", "radius_flag", 1)
modparam ("acc", "radius_missed_flag", 2)



# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam ("rr", "enable_full_lr", 1)




# We will you flag 6 to mark NATed contacts
modparam("registrar", "nat_flag", 6)

# Enable NAT pinging
modparam("nathelper", "natping_interval", 60)

# Ping only contacts that are known to be
# behind NAT
modparam("nathelper", "ping_nated_only", 1)




# -------------------------  request routing logic -------------------
# main routing logic
route
{

# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
  if (!mf_process_maxfwd_header ("10"))
    {
      sl_send_reply ("483", "Too Many Hops");
      break;
    };
if (msg:len >= 2048)
    {
      sl_send_reply ("513", "Message too big");
      break;
    };


if (nat_uac_test("3")) {
    # allow RR-ed requests, as these may indicate that
    # a NAT-enabled proxy takes care of it; unless it is
    # a REGISTER

    if (method == "REGISTER" || ! search("^Record-Route:")) {
        log(1, "LOG: Someone trying to register from private IP, rewriting\n");

        # This will work only for user agents that support symmetric
        # communication. We tested quite many of them and majority is
        # smart smart enough to be symmetric. In some phones, like
        # it takes a configuration option. With Cisco 7960, it is
        # called NAT_Enable=Yes, with kphone it is called
        # "symmetric media" and "symmetric signaling". (The latter
        # not part of public released yet.)

        fix_nated_contact(); # Rewrite contact with source IP of signalling
        if (method == "INVITE") {
            fix_nated_sdp("1");  # Add direction=active to SDP
        };
        force_rport();  # Add rport parameter to topmost Via
        setflag(6);     # Mark as NATed
    };
};

        if(method=="NOTIFY")
        {
                sl_send_reply("200", "I dont like notify");
                break;

        };



  setflag (1);

# we record-route all messages -- to make sure that
# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
  if (!method == "REGISTER")
    record_route ();

# subsequent messages withing a dialog should take the
# path determined by record-routing
  if (loose_route ())
    {
# mark routing logic in request
      append_hf ("P-hint: rr-enforced\r\n");
      route (1);
      break;
    };

  if (uri == myself)
    {

      if (method == "REGISTER")
        {

          if (!radius_www_authorize (""))
            {
              www_challenge ("", "0");
              break;
            };
          save ("location");
          break;
        };

      if (method == "INVITE")
        {
          if (!radius_proxy_authorize (""))
            {
              proxy_challenge ("", "0");
              break;
            };

          if (uri =~ "^sip:008801")
            {
              strip (2);
              prefix ("4433");
              rewritehost ("192.168.1.12");
              t_on_failure ("1");
            };

#         if (uri =~ "^sip:1")
#           {
#             rewritehost ("192.168.2.10");
#           };

        };

    };

  route (1);
}

route[1]
{

    if (uri=~"[@:](192\.168\.|10\.|172\.16)" && !search("^Route:")){
        sl_send_reply("479", "We don't forward to private IP addresses");
        break;
    };


    if (isflagset(6)) {
        force_rtp_proxy();
        append_hf("P-Behind-NAT: Yes\r\n");
        log(1,"Forcing rtp proxy on route\n");
    };

    t_on_reply("1");


# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
  if (!t_relay ())
    {
      sl_reply_error ();
    };
}

failure_route[1]
{
  rewritehost ("192.168.1.16");
  append_branch ();
  route (1);
}

#onreply_route[1] {
#    if (status =~ "(183)|2[0-9][0-9]") {
#        fix_nated_contact();
#        force_rtp_proxy();
#    };
#}

onreply_route[1] {
    # NATed transaction ?
    if (isflagset(6) && status =~ "(180)|(183)|2[0-9][0-9]") {

        log(1,"Forcing rtp proxy on replyroute\n");

        fix_nated_contact();
        force_rtp_proxy();
    # otherwise, is it a transaction behind a NAT and we did not
    # know at time of request processing ? (RFC1918 contacts)
    } else if (nat_uac_test("1")) {
        fix_nated_contact();
    };
}
