Hi,
have a look at the uac module and its uac_replace_to function (https://kamailio.org/docs/modules/6.0.x/modules/uac.html#uac.f.uac_replace_to_uri).

Regards,

Federico

On Wed, Jun 4, 2025 at 10:04 AM disa_369--- via sr-users <sr-users@lists.kamailio.org> wrote:
Hello to everyone.
I deployed Kamailio on Debian system. Install was successfull.
I have the task to use Kamailio as proxy between Avaya PBX and Videoconference System.
Outgoing calls only from
IPPhone ----- Avaya PBX  ---sip----> Kamailio -----sip----> Video System-IVR
IVR number is 3000.
Avaya Prefix for routing to Kamailio is 1234.
When we dial number 12343000 the call goes to Video system with Header "TO" 12343000@ip_of_PBXAvaya and call drops.
How to replace ip-address of Avaya to ip-address of Video_System? What to add in kamailio.cfg?


ip video_system - *.*.60.3
ip avaya *.*.20.10

My route config


####### Routing Logic ########
/* Main SIP request routing logic
 * - processing of any incoming SIP request starts with this route
 * - note: this is the same as route { ... } */
request_route {
        # per request initial checks
        route(REQINIT);

        # NAT detection
        route(NATDETECT);

        # CANCEL processing
        if (is_method("CANCEL")) {
                if (t_check_trans()) {
                        route(RELAY);
                }
                exit;
        }

        # handle retransmissions
        if (!is_method("ACK")) {
                if(t_precheck_trans()) {
                        t_check_trans();
                        exit;
                }
                t_check_trans();
        }

        # handle requests within SIP dialogs
        route(WITHINDLG);


        ### only initial requests (no To tag)

        # authentication
        route(AUTH);

        # record routing for dialog forming requests (in case they are routed)
        # - remove preloaded route headers
        remove_hf("Route");
        if (is_method("INVITE|SUBSCRIBE")) {
                record_route();
        }

        # account only INVITEs
        if (is_method("INVITE")) {
                setflag(FLT_ACC); # do accounting
        }

if ($rU==$null) {
 sl_send_reply("484", "Address Incomplete");
 exit;

 }

$du = "sip:*.*.60.3:5060";
route(RELAY);
exit;

}

# Wrapper for relaying requests
route[RELAY] {

        # enable additional event routes for forwarded requests
        # - serial forking, RTP relaying handling, a.s.o.
        if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
                if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
        }
        if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
                if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
        }
        if (is_method("INVITE")) {
                if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
        }

        if (!t_relay()) {
                sl_reply_error();
        }
        exit;
}

# Per SIP request initial checks
route[REQINIT] {
        # no connect for sending replies
        set_reply_no_connect();
        # enforce symmetric signaling
        # - send back replies to the source address of request
        force_rport();

#!ifdef WITH_ANTIFLOOD
        # flood detection from same IP and traffic ban for a while
        # be sure you exclude checking trusted peers, such as pstn gateways
        # - local host excluded (e.g., loop to self)
        if(src_ip!=myself) {
                if($sht(ipban=>$si)!=$null) {
                        # ip is already blocked
                        xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
                        exit;
                }
                if (!pike_check_req()) {
                        xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");
                        $sht(ipban=>$si) = 1;
                        exit;
                }
        }
#!endif
        if($ua =~ "friendly|scanner|sipcli|sipvicious|VaxSIPUserAgent|pplsip") {
                # silent drop for scanners - uncomment next line if want to reply
                # sl_send_reply("200", "OK");
                exit;
        }

        if (!mf_process_maxfwd_header("10")) {
                sl_send_reply("483","Too Many Hops");
                exit;
        }

        if(is_method("OPTIONS") && uri==myself && $rU==$null) {
                sl_send_reply("200","Keepalive");
                exit;
        }

        if(!sanity_check("17895", "7")) {
                xlog("Malformed SIP request from $si:$sp\n");
                exit;
        }
}

# Handle requests within SIP dialogs
route[WITHINDLG] {
        if (!has_totag()) return;

        # sequential request withing a dialog should
        # take the path determined by record-routing
        if (loose_route()) {
                route(DLGURI);
                if (is_method("BYE")) {
                        setflag(FLT_ACC); # do accounting ...
                        setflag(FLT_ACCFAILED); # ... even if the transaction fails
                } else if ( is_method("ACK") ) {
                        # ACK is forwarded statelessly
                        route(NATMANAGE);
                } else if ( is_method("NOTIFY") ) {
                        # Add Record-Route for in-dialog NOTIFY as per RFC 6665.
                        record_route();
                }
                route(RELAY);
                exit;
        }

        if (is_method("SUBSCRIBE") && uri == myself) {
                # in-dialog subscribe requests
                route(PRESENCE);
                exit;
        }
        if ( is_method("ACK") ) {
                if ( t_check_trans() ) {
                        # no loose-route, but stateful ACK;
                        # must be an ACK after a 487
                        # or e.g. 404 from upstream server
                        route(RELAY);
                        exit;
                } else {
                        # ACK without matching transaction ... ignore and discard
                        exit;
                }
        }
        sl_send_reply("404","Not here");
        exit;
}

# Handle SIP registrations
route[REGISTRAR] {
        if (!is_method("REGISTER")) return;

        if(isflagset(FLT_NATS)) {
                setbflag(FLB_NATB);
#!ifdef WITH_NATSIPPING
                # do SIP NAT pinging
                setbflag(FLB_NATSIPPING);
#!endif
        }
        if (!save("location")) {
                sl_reply_error();
        }
        exit;
}

# User location service
route[LOCATION] {

#!ifdef WITH_SPEEDDIAL
        # search for short dialing - 2-digit extension
        if($rU=~"^[0-9][0-9]$") {
                if(sd_lookup("speed_dial")) {
                        route(SIPOUT);
                }
        }
#!endif

#!ifdef WITH_ALIASDB
        # search in DB-based aliases
        if(alias_db_lookup("dbaliases")) {
                route(SIPOUT);
        }
#!endif

        $avp(oexten) = $rU;
        if (!lookup("location")) {
                $var(rc) = $rc;
                route(TOVOICEMAIL);
                t_newtran();
                switch ($var(rc)) {
                        case -1:
                        case -3:
                                send_reply("404", "Not Found");
                                exit;
                        case -2:
                                send_reply("405", "Method Not Allowed");
                                exit;
                }
        }

        # when routing via usrloc, log the missed calls also
        if (is_method("INVITE")) {
                setflag(FLT_ACCMISSED);
        }

        route(RELAY);
        exit;
}

# Presence server processing
route[PRESENCE] {
        if(!is_method("PUBLISH|SUBSCRIBE")) return;

        if(is_method("SUBSCRIBE") && $hdr(Event)=="message-summary") {
                route(TOVOICEMAIL);
                # returns here if no voicemail server is configured
                sl_send_reply("404", "No voicemail service");
                exit;
        }

#!ifdef WITH_PRESENCE
#!ifdef WITH_MSGREBUILD
        # apply changes in case the request headers or body were modified
        msg_apply_changes();
#!endif
        if (!t_newtran()) {
                sl_reply_error();
                exit;
        }

        if(is_method("PUBLISH")) {
                handle_publish();
                t_release();
        } else if(is_method("SUBSCRIBE")) {
                handle_subscribe();
                t_release();
        }
        exit;
#!endif

        # if presence enabled, this part will not be executed
        if (is_method("PUBLISH") || $rU==$null) {
                sl_send_reply("404", "Not here");
                exit;
        }
        return;
}

# IP authorization and user authentication
route[AUTH] {
#!ifdef WITH_AUTH

#!ifdef WITH_IPAUTH
        if((!is_method("REGISTER")) && allow_source_address()) {
                # source IP allowed
                return;
        }
#!endif

        if (is_method("REGISTER") || from_uri==myself) {
                # authenticate requests
                if (!auth_check("$fd", "subscriber", "1")) {
                        auth_challenge("$fd", "0");
                        exit;
                }
                # user authenticated - remove auth header
                if(!is_method("REGISTER|PUBLISH"))
                        consume_credentials();
        }
        # if caller is not local subscriber, then check if it calls
        # a local destination, otherwise deny, not an open relay here
        if (from_uri!=myself && uri!=myself) {
                sl_send_reply("403","Not relaying");
                exit;
        }

#!else

        # authentication not enabled - do not relay at all to foreign networks
        if(uri!=myself) {
                sl_send_reply("403","Not relaying");
                exit;
        }

#!endif
        return;
}

# Caller NAT detection
route[NATDETECT] {
#!ifdef WITH_NAT
        if (nat_uac_test("19")) {
                if (is_method("REGISTER")) {
                        fix_nated_register();
                } else {
                        if(is_first_hop()) {
                                set_contact_alias();
                        }
                }
                setflag(FLT_NATS);
        }
#!endif
        return;
}

# RTPProxy control and signaling updates for NAT traversal
route[NATMANAGE] {
#!ifdef WITH_NAT
        if (is_request()) {
                if(has_totag()) {
                        if(check_route_param("nat=yes")) {
                                setbflag(FLB_NATB);
                        }
                }
        }
        if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;

#!ifdef WITH_RTPENGINE
        if(nat_uac_test("8")) {
                rtpengine_manage("SIP-source-address replace-origin replace-session-connection");
        } else {
                rtpengine_manage("replace-origin replace-session-connection");
        }
#!else
        if(nat_uac_test("8")) {
                rtpproxy_manage("co");
        } else {
                rtpproxy_manage("cor");
        }
#!endif

        if (is_request()) {
                if (!has_totag()) {
                        if(t_is_branch_route()) {
                                add_rr_param(";nat=yes");
                        }
                }
        }
        if (is_reply()) {
                if(isbflagset(FLB_NATB)) {
                        if(is_first_hop())
                                set_contact_alias();
                }
        }

        if(isbflagset(FLB_NATB)) {
                # no connect message in a dialog involving NAT traversal
                if (is_request()) {
                        if(has_totag()) {
                                set_forward_no_connect();
                        }
                }
        }
#!endif
        return;
}

# URI update for dialog requests
route[DLGURI] {
#!ifdef WITH_NAT
        if(!isdsturiset()) {
                handle_ruri_alias();
        }
#!endif
        return;
}

# Routing to foreign domains
route[SIPOUT] {
        if (uri==myself) return;

        append_hf("P-Hint: outbound\r\n");
        route(RELAY);
        exit;
}

# PSTN GW routing
route[PSTN] {
#!ifdef WITH_PSTN
        # check if PSTN GW IP is defined
        if (strempty($sel(cfg_get.pstn.gw_ip))) {
                xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n");
                return;
        }

        # route to PSTN dialed numbers starting with '+' or '00'
        #     (international format)
        # - update the condition to match your dialing rules for PSTN routing
        if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$")) return;

        # only local users allowed to call
        if(from_uri!=myself) {
                sl_send_reply("403", "Not Allowed");
                exit;
        }

        # normalize target number for pstn gateway
        # - convert leading 00 to +
        if (starts_with("$rU", "00")) {
                strip(2);
                prefix("+");
        }

        if (strempty($sel(cfg_get.pstn.gw_port))) {
                $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
        } else {
                $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip) + ":"
                                        + $sel(cfg_get.pstn.gw_port);
        }

        route(RELAY);
        exit;
#!endif

        return;
}

# JSONRPC over HTTP(S) routing
#!ifdef WITH_JSONRPC
event_route[xhttp:request] {
        set_reply_close();
        set_reply_no_connect();
        if(src_ip!=127.0.0.1) {
                xhttp_reply("403", "Forbidden", "text/html",
                                "<html><body>Not allowed from $si</body></html>");
                exit;
        }
        if ($hu =~ "^/RPC") {
                jsonrpc_dispatch();
                exit;
        }

        xhttp_reply("200", "OK", "text/html",
                                "<html><body>Wrong URL $hu</body></html>");
    exit;
}
#!endif

# Routing to voicemail server
route[TOVOICEMAIL] {
#!ifdef WITH_VOICEMAIL
        if(!is_method("INVITE|SUBSCRIBE")) return;

        # check if VoiceMail server IP is defined
        if (strempty($sel(cfg_get.voicemail.srv_ip))) {
                xlog("SCRIPT: VoiceMail routing enabled but IP not defined\n");
                return;
        }
        if(is_method("INVITE")) {
                if($avp(oexten)==$null) return;

                $ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)
                                + ":" + $sel(cfg_get.voicemail.srv_port);
        } else {
                if($rU==$null) return;

                $ru = "sip:" + $rU + "@" + $sel(cfg_get.voicemail.srv_ip)
                                + ":" + $sel(cfg_get.voicemail.srv_port);
        }
        route(RELAY);
        exit;
#!endif

        return;
}

# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
        xdbg("new branch [$T_branch_idx] to $ru\n");
        route(NATMANAGE);
        return;
}

# Manage incoming replies
reply_route {
        if(!sanity_check("17604", "6")) {
                xlog("Malformed SIP response from $si:$sp\n");
                drop;
        }
        return;
}

# Manage incoming replies in transaction context
onreply_route[MANAGE_REPLY] {
        xdbg("incoming reply\n");
        if(status=~"[12][0-9][0-9]") {
                route(NATMANAGE);
        }
        return;
}

# Manage failure routing cases
failure_route[MANAGE_FAILURE] {
        route(NATMANAGE);

        if (t_is_canceled()) exit;

#!ifdef WITH_BLOCK3XX
        # block call redirect based on 3xx replies.
        if (t_check_status("3[0-9][0-9]")) {
                t_reply("404","Not found");
                exit;
        }
#!endif

#!ifdef WITH_BLOCK401407
        # block call redirect based on 401, 407 replies.
        if (t_check_status("401|407")) {
                t_reply("404","Not found");
                exit;
        }
#!endif

#!ifdef WITH_VOICEMAIL
        # serial forking
        # - route to voicemail on busy or no answer (timeout)
        if (t_check_status("486|408")) {
                $du = $null;
                route(TOVOICEMAIL);
                exit;
        }
#!endif
        return;
__________________________________________________________
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org
To unsubscribe send an email to sr-users-leave@lists.kamailio.org
Important: keep the mailing list in the recipients, do not reply only to the sender!