nathelper: new parameter nat_addr_mode
[sip-router] / src / modules / nathelper / nathelper.c
1 /*
2  * Copyright (C) 2003-2008 Sippy Software, Inc., http://www.sippysoft.com
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/time.h>
25 #include <netinet/in.h>
26 #include <netinet/in_systm.h>
27 #ifndef __USE_BSD
28 #define __USE_BSD
29 #endif
30 #include <netinet/ip.h>
31 #ifndef __FAVOR_BSD
32 #define __FAVOR_BSD
33 #endif
34 #include <netinet/udp.h>
35 #include <arpa/inet.h>
36 #include <sys/uio.h>
37 #include <sys/un.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <netdb.h>
41 #include <poll.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include "../../core/flags.h"
48 #include "../../core/sr_module.h"
49 #include "../../core/dprint.h"
50 #include "../../core/data_lump.h"
51 #include "../../core/data_lump_rpl.h"
52 #include "../../core/error.h"
53 #include "../../core/forward.h"
54 #include "../../core/ip_addr.h"
55 #include "../../core/mem/mem.h"
56 #include "../../core/parser/parse_from.h"
57 #include "../../core/parser/parse_to.h"
58 #include "../../core/parser/parse_uri.h"
59 #include "../../core/parser/parser_f.h"
60 #include "../../core/parser/parse_methods.h"
61 #include "../../core/parser/sdp/sdp.h"
62 #include "../../core/resolve.h"
63 #include "../../core/timer.h"
64 #include "../../core/trim.h"
65 #include "../../core/ut.h"
66 #include "../../core/pt.h"
67 #include "../../core/timer_proc.h"
68 #include "../../core/pvar.h"
69 #include "../../core/lvalue.h"
70 #include "../../core/msg_translator.h"
71 #include "../../core/usr_avp.h"
72 #include "../../core/socket_info.h"
73 #include "../../core/mod_fix.h"
74 #include "../../core/dset.h"
75 #include "../../core/select.h"
76 #include "../../core/kemi.h"
77 #include "../../core/rpc.h"
78 #include "../../core/rpc_lookup.h"
79 #include "../registrar/sip_msg.h"
80 #include "../usrloc/usrloc.h"
81 #include "nathelper.h"
82 #include "nhelpr_funcs.h"
83 #include "sip_pinger.h"
84
85 MODULE_VERSION
86
87 #if !defined(AF_LOCAL)
88 #define AF_LOCAL AF_UNIX
89 #endif
90 #if !defined(PF_LOCAL)
91 #define PF_LOCAL PF_UNIX
92 #endif
93
94 /* NAT UAC test constants */
95 #define NAT_UAC_TEST_C_1918 0x01
96 #define NAT_UAC_TEST_RCVD 0x02
97 #define NAT_UAC_TEST_V_1918 0x04
98 #define NAT_UAC_TEST_S_1918 0x08
99 #define NAT_UAC_TEST_RPORT 0x10
100 #define NAT_UAC_TEST_O_1918 0x20
101 #define NAT_UAC_TEST_WS 0x40
102 #define NAT_UAC_TEST_C_PORT 0x80
103 #define NAT_UAC_TEST_SDP_CLINE 0x100
104
105 #define DEFAULT_NATPING_STATE 1
106
107
108 static int nat_uac_test_f(struct sip_msg *msg, char *str1, char *str2);
109 static int fix_nated_contact_f(struct sip_msg *, char *, char *);
110 static int add_contact_alias_0_f(struct sip_msg *, char *, char *);
111 static int add_contact_alias_3_f(struct sip_msg *, char *, char *, char *);
112 static int set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2);
113 static int handle_ruri_alias_f(struct sip_msg *, char *, char *);
114 static int pv_get_rr_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
115 static int pv_get_rr_top_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
116 static int fix_nated_sdp_f(struct sip_msg *, char *, char *);
117 static int is_rfc1918_f(struct sip_msg *, char *, char *);
118 static int extract_mediaip(str *, str *, int *, char *);
119 static int alter_mediaip(struct sip_msg *, str *, str *, int, str *, int, int);
120 static int fix_nated_register_f(struct sip_msg *, char *, char *);
121 static int fixup_fix_nated_register(void **param, int param_no);
122 static int fixup_fix_sdp(void **param, int param_no);
123 static int fixup_add_contact_alias(void **param, int param_no);
124 static int add_rcv_param_f(struct sip_msg *, char *, char *);
125 static int nh_sip_reply_received(sip_msg_t *msg);
126 static int test_sdp_cline(struct sip_msg *msg);
127
128 static int w_set_alias_to_pv(struct sip_msg *msg, char *uri_avp, char *hollow);
129 static int ki_set_alias_to_pv(struct sip_msg *msg, str *uri_avp);
130 static int nh_alias_to_uri(str *contact_header, str *alias_uri);
131 static int nh_write_to_pv(struct sip_msg *msg, str *data, str *pvname);
132
133 static void nh_timer(unsigned int, void *);
134 static int mod_init(void);
135 static int child_init(int);
136 static void mod_destroy(void);
137
138 static int nathelper_rpc_init(void);
139
140 static usrloc_api_t ul;
141
142 static int cblen = 0;
143 static int natping_interval = 0;
144 struct socket_info *force_socket = 0;
145
146 static int nh_nat_addr_mode = 1;
147
148 /* clang-format off */
149 typedef struct nh_netaddr {
150         const char *cnetaddr;
151         uint32_t netaddr;
152         uint32_t mask;
153 } nh_netaddr_t;
154
155 static nh_netaddr_t nh_nets_1918[] = {
156         {"10.0.0.0",    0, 0xffffffffu << 24},
157         {"172.16.0.0",  0, 0xffffffffu << 20},
158         {"192.168.0.0", 0, 0xffffffffu << 16},
159         {"100.64.0.0",  0, 0xffffffffu << 22}, /* rfc6598 - cg-nat */
160         {"192.0.0.0",   0, 0xffffffffu <<  3}, /* rfc7335 - IPv4 Service Continuity Prefix */
161         {NULL, 0, 0}
162 };
163
164 static nh_netaddr_t nh_nets_extra[] = {
165         {"192.0.0.0",   0, 0xffffffffu <<  8}, /* rfc7335 - IETF Protocol Assignments */
166         {NULL, 0, 0}
167 };
168 /* clang-format on */
169
170 /*
171  * If this parameter is set then the natpinger will ping only contacts
172  * that have the NAT flag set in user location database
173  */
174 static int ping_nated_only = 0;
175 static const char sbuf[4] = {0, 0, 0, 0};
176 static str force_socket_str = STR_NULL;
177 static int sipping_flag = -1;
178 static int natping_disable_flag = -1;
179 static int natping_processes = 1;
180
181 static str nortpproxy_str = str_init("a=nortpproxy:yes");
182
183 static char *rcv_avp_param = NULL;
184 static unsigned short rcv_avp_type = 0;
185 static int_str rcv_avp_name;
186
187 static char *natping_socket = NULL;
188 static int udpping_from_path = 0;
189 static int sdp_oldmediaip = 1;
190 static int raw_sock = -1;
191 static unsigned int raw_ip = 0;
192 static unsigned short raw_port = 0;
193 static int nh_keepalive_timeout = 0;
194 static request_method_t sipping_method_id = 0;
195 /* filter contacts by server_id */
196 static int nh_filter_srvid = 0;
197
198 /*0-> disabled, 1 ->enabled*/
199 unsigned int *natping_state = NULL;
200
201 /* clang-format off */
202 static cmd_export_t cmds[] = {
203         {"fix_nated_contact",  (cmd_function)fix_nated_contact_f,    0,
204                 0, 0,
205                 REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
206         {"add_contact_alias",  (cmd_function)add_contact_alias_0_f,  0,
207                 0, 0,
208                 REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
209         {"add_contact_alias",  (cmd_function)add_contact_alias_3_f,  3,
210                 fixup_add_contact_alias, 0,
211                 REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
212         {"set_contact_alias",  (cmd_function)set_contact_alias_f,  0,
213                 0, 0,
214                 REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
215         {"handle_ruri_alias",  (cmd_function)handle_ruri_alias_f,    0,
216                 0, 0,
217                 REQUEST_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
218         {"fix_nated_sdp",      (cmd_function)fix_nated_sdp_f,        1,
219                 fixup_fix_sdp,  0,
220                 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
221         {"fix_nated_sdp",      (cmd_function)fix_nated_sdp_f,        2,
222                 fixup_fix_sdp, 0,
223                 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
224         {"nat_uac_test",       (cmd_function)nat_uac_test_f,         1,
225                 fixup_igp_null, 0,
226                 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
227         {"fix_nated_register", (cmd_function)fix_nated_register_f,   0,
228                 fixup_fix_nated_register, 0,
229                 REQUEST_ROUTE },
230         {"add_rcv_param",      (cmd_function)add_rcv_param_f,        0,
231                 0, 0,
232                 REQUEST_ROUTE },
233         {"add_rcv_param",      (cmd_function)add_rcv_param_f,        1,
234                 fixup_igp_null, 0,
235                 REQUEST_ROUTE },
236         {"is_rfc1918",         (cmd_function)is_rfc1918_f,           1,
237                 fixup_spve_null, 0,
238                 ANY_ROUTE },
239                 {"set_alias_to_pv",   (cmd_function)w_set_alias_to_pv,     1,
240                 0, 0, ANY_ROUTE },
241         {0, 0, 0, 0, 0, 0}
242 };
243
244 static pv_export_t mod_pvs[] = {
245         {{"rr_count", (sizeof("rr_count")-1)}, /* number of records routes */
246                 PVT_CONTEXT, pv_get_rr_count_f, 0, 0, 0, 0, 0},
247         {{"rr_top_count", (sizeof("rr_top_count")-1)}, /* number of topmost rrs */
248                 PVT_CONTEXT, pv_get_rr_top_count_f, 0, 0, 0, 0, 0},
249         {{0, 0}, 0, 0, 0, 0, 0, 0, 0}
250 };
251
252 static param_export_t params[] = {
253         {"natping_interval",      INT_PARAM, &natping_interval      },
254         {"ping_nated_only",       INT_PARAM, &ping_nated_only       },
255         {"nortpproxy_str",        PARAM_STR, &nortpproxy_str      },
256         {"received_avp",          PARAM_STRING, &rcv_avp_param         },
257         {"force_socket",          PARAM_STR, &force_socket_str      },
258         {"sipping_from",          PARAM_STR, &sipping_from        },
259         {"sipping_method",        PARAM_STR, &sipping_method      },
260         {"sipping_bflag",         INT_PARAM, &sipping_flag          },
261         {"natping_disable_bflag", INT_PARAM, &natping_disable_flag  },
262         {"natping_processes",     INT_PARAM, &natping_processes     },
263         {"natping_socket",        PARAM_STRING, &natping_socket        },
264         {"keepalive_timeout",     INT_PARAM, &nh_keepalive_timeout  },
265         {"udpping_from_path",     INT_PARAM, &udpping_from_path     },
266         {"append_sdp_oldmediaip", INT_PARAM, &sdp_oldmediaip        },
267         {"filter_server_id",      INT_PARAM, &nh_filter_srvid },
268         {"nat_addr_mode",         INT_PARAM, &nh_nat_addr_mode },
269
270         {0, 0, 0}
271 };
272
273 struct module_exports exports = {
274         "nathelper",           /* module name */
275         DEFAULT_DLFLAGS,       /* dlopen flags */
276         cmds,                  /* cmd (cfg function) exports */
277         params,                /* param exports */
278         0,                     /* RPC method exports */
279         mod_pvs,               /* pseudo-variables exports */
280         nh_sip_reply_received, /* response handling function */
281         mod_init,              /* module init function */
282         child_init,            /* per-child init function */
283         mod_destroy            /* module destroy function */
284 };
285 /* clang-format on */
286
287
288 static int sel_nathelper(str *res, select_t *s, struct sip_msg *msg)
289 {
290         /* dummy */
291         return 0;
292 }
293
294 static int sel_rewrite_contact(str *res, select_t *s, struct sip_msg *msg);
295
296 SELECT_F(select_any_nameaddr)
297
298 select_row_t sel_declaration[] = {
299                 {NULL, SEL_PARAM_STR, STR_STATIC_INIT("nathelper"), sel_nathelper,
300                                 SEL_PARAM_EXPECTED},
301                 {sel_nathelper, SEL_PARAM_STR, STR_STATIC_INIT("rewrite_contact"),
302                                 sel_rewrite_contact, CONSUME_NEXT_INT},
303
304                 {sel_rewrite_contact, SEL_PARAM_STR, STR_STATIC_INIT("nameaddr"),
305                                 select_any_nameaddr, NESTED | CONSUME_NEXT_STR},
306
307                 {NULL, SEL_PARAM_INT, STR_NULL, NULL, 0}};
308
309 static int fixup_fix_sdp(void **param, int param_no)
310 {
311         if(param_no == 1) {
312                 /* flags */
313                 return fixup_igp_null(param, param_no);
314         }
315         if(param_no == 2) {
316                 /* new IP */
317                 return fixup_spve_all(param, param_no);
318         }
319         LM_ERR("unexpected param no: %d\n", param_no);
320         return -1;
321 }
322
323 static int fixup_fix_nated_register(void **param, int param_no)
324 {
325         if(rcv_avp_name.n == 0) {
326                 LM_ERR("you must set 'received_avp' parameter. Must be same value as"
327                            " parameter 'received_avp' of registrar module\n");
328                 return -1;
329         }
330         return 0;
331 }
332
333 static int fixup_add_contact_alias(void **param, int param_no)
334 {
335         if((param_no >= 1) && (param_no <= 3))
336                 return fixup_spve_null(param, 1);
337
338         LM_ERR("invalid parameter number <%d>\n", param_no);
339         return -1;
340 }
341
342 static void nathelper_rpc_enable_ping(rpc_t *rpc, void *ctx)
343 {
344         int value = 0;
345         if(natping_state == NULL) {
346                 rpc->fault(ctx, 500, "NATping disabled");
347                 return;
348         }
349
350         if(rpc->scan(ctx, "d", &value) < 1) {
351                 rpc->fault(ctx, 500, "No parameter");
352                 return;
353         }
354         (*natping_state) = value ? 1 : 0;
355 }
356
357 static const char *nathelper_rpc_enable_ping_doc[2] = {
358                 "Set (enable/disable) nat ping", 0};
359
360 rpc_export_t nathelper_rpc[] = {
361                 {"nathelper.enable_ping", nathelper_rpc_enable_ping,
362                                 nathelper_rpc_enable_ping_doc, 0},
363                 {0, 0, 0, 0}};
364
365 static int nathelper_rpc_init(void)
366 {
367         if(rpc_register_array(nathelper_rpc) != 0) {
368                 LM_ERR("failed to register RPC commands\n");
369                 return -1;
370         }
371         return 0;
372 }
373
374 static int init_raw_socket(void)
375 {
376         int on = 1;
377
378         raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
379         if(raw_sock == -1) {
380                 LM_ERR("cannot create raw socket\n");
381                 return -1;
382         }
383
384         if(setsockopt(raw_sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1) {
385                 LM_ERR("cannot set socket options\n");
386                 return -1;
387         }
388
389         return raw_sock;
390 }
391
392
393 static int get_natping_socket(
394                 char *socket, unsigned int *ip, unsigned short *port)
395 {
396         struct hostent *he;
397         str host;
398         int lport;
399         int lproto;
400
401         if(parse_phostport(socket, &host.s, &host.len, &lport, &lproto) != 0) {
402                 LM_CRIT("invalid natping_socket parameter <%s>\n", natping_socket);
403                 return -1;
404         }
405
406         if(lproto != PROTO_UDP && lproto != PROTO_NONE) {
407                 LM_CRIT("natping_socket can be only UDP <%s>\n", natping_socket);
408                 return 0;
409         }
410         lproto = PROTO_UDP;
411         *port = lport ? (unsigned short)lport : SIP_PORT;
412
413         he = sip_resolvehost(&host, port, (char *)(void *)&lproto);
414         if(he == 0) {
415                 LM_ERR("could not resolve hostname:\"%.*s\"\n", host.len, host.s);
416                 return -1;
417         }
418         if(he->h_addrtype != AF_INET) {
419                 LM_ERR("only ipv4 addresses allowed in natping_socket\n");
420                 return -1;
421         }
422
423         memcpy(ip, he->h_addr_list[0], he->h_length);
424
425         return 0;
426 }
427
428
429 static int mod_init(void)
430 {
431         int i;
432         bind_usrloc_t bind_usrloc;
433         struct in_addr addr;
434         pv_spec_t avp_spec;
435         str s;
436         int port, proto;
437         str host;
438
439         if(nathelper_rpc_init() < 0) {
440                 LM_ERR("failed to register RPC commands\n");
441                 return -1;
442         }
443
444         if(rcv_avp_param && *rcv_avp_param) {
445                 s.s = rcv_avp_param;
446                 s.len = strlen(s.s);
447                 if(pv_parse_spec(&s, &avp_spec) == 0 || avp_spec.type != PVT_AVP) {
448                         LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param);
449                         return -1;
450                 }
451
452                 if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)
453                                 != 0) {
454                         LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param);
455                         return -1;
456                 }
457         } else {
458                 rcv_avp_name.n = 0;
459                 rcv_avp_type = 0;
460         }
461
462         if(force_socket_str.s && force_socket_str.len > 0) {
463                 if(parse_phostport(force_socket_str.s, &host.s, &host.len, &port, &proto) == 0) {
464                         force_socket = grep_sock_info(&host, port, proto);
465                         if(force_socket == 0) {
466                                 LM_ERR("non-local force_socket <%s>\n", force_socket_str.s);
467                         }
468                 }
469         }
470
471         /* create raw socket? */
472         if((natping_socket && natping_socket[0]) || udpping_from_path) {
473                 if((!udpping_from_path)
474                                 && get_natping_socket(natping_socket, &raw_ip, &raw_port) != 0)
475                         return -1;
476                 if(init_raw_socket() < 0)
477                         return -1;
478         }
479
480         if(nortpproxy_str.s && nortpproxy_str.len > 0) {
481                 while(nortpproxy_str.len > 0
482                                 && (nortpproxy_str.s[nortpproxy_str.len - 1] == '\r'
483                                                    || nortpproxy_str.s[nortpproxy_str.len - 1] == '\n'))
484                         nortpproxy_str.len--;
485         }
486
487         if(natping_interval > 0) {
488                 bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
489                 if(!bind_usrloc) {
490                         LM_ERR("can't find usrloc module\n");
491                         return -1;
492                 }
493
494                 if(bind_usrloc(&ul) < 0) {
495                         return -1;
496                 }
497
498                 natping_state = (unsigned int *)shm_malloc(sizeof(unsigned int));
499                 if(!natping_state) {
500                         LM_ERR("no shmem left\n");
501                         return -1;
502                 }
503                 *natping_state = DEFAULT_NATPING_STATE;
504
505                 if(ping_nated_only && ul.nat_flag == 0) {
506                         LM_ERR("bad config - ping_nated_only enabled, but no nat bflag"
507                                    " set in usrloc module\n");
508                         return -1;
509                 }
510                 if(natping_processes < 0) {
511                         LM_ERR("bad config - natping_processes must be >= 0\n");
512                         return -1;
513                 }
514                 ul.set_max_partition(natping_processes * natping_interval);
515
516                 sipping_flag = (sipping_flag == -1) ? 0 : (1 << sipping_flag);
517                 natping_disable_flag =
518                                 (natping_disable_flag == -1) ? 0 : (1 << natping_disable_flag);
519
520                 /* set reply function if SIP natping is enabled */
521                 if(sipping_flag) {
522                         if(sipping_from.s == 0 || sipping_from.len <= 0) {
523                                 LM_ERR("SIP ping enabled, but SIP ping FROM is empty!\n");
524                                 return -1;
525                         }
526                         if(sipping_method.s == 0 || sipping_method.len <= 0) {
527                                 LM_ERR("SIP ping enabled, but SIP ping method is empty!\n");
528                                 return -1;
529                         }
530                         if(nh_keepalive_timeout > 0 && ul.set_keepalive_timeout != NULL) {
531                                 ul.set_keepalive_timeout(nh_keepalive_timeout);
532                         }
533
534                         if(parse_method_name(&sipping_method, &sipping_method_id) < 0) {
535                                 LM_ERR("invalid SIP ping method [%.*s]!\n", sipping_method.len,
536                                                 sipping_method.s);
537                                 return -1;
538                         }
539                         exports.response_f = sipping_rpl_filter;
540                         init_sip_ping();
541                 }
542
543                 register_dummy_timers(natping_processes);
544         }
545
546         /* Prepare 1918 networks list */
547         for(i = 0; nh_nets_1918[i].cnetaddr != NULL; i++) {
548                 if(inet_aton(nh_nets_1918[i].cnetaddr, &addr) != 1)
549                         abort();
550                 nh_nets_1918[i].netaddr = ntohl(addr.s_addr) & nh_nets_1918[i].mask;
551         }
552
553         /* Prepare reserved/extra networks list */
554         for(i = 0; nh_nets_extra[i].cnetaddr != NULL; i++) {
555                 if(inet_aton(nh_nets_extra[i].cnetaddr, &addr) != 1)
556                         abort();
557                 nh_nets_extra[i].netaddr = ntohl(addr.s_addr) & nh_nets_extra[i].mask;
558         }
559
560         register_select_table(sel_declaration);
561
562         return 0;
563 }
564
565
566 static int child_init(int rank)
567 {
568         int i;
569
570         if(rank == PROC_MAIN && natping_interval > 0) {
571                 for(i = 0; i < natping_processes; i++) {
572                         if(fork_dummy_timer(PROC_TIMER, "TIMER NH", 1 /*socks flag*/,
573                                            nh_timer, (void *)(unsigned long)i, 1 /*sec*/)
574                                         < 0) {
575                                 LM_ERR("failed to register timer routine as process\n");
576                                 return -1;
577                                 /* error */
578                         }
579                 }
580         }
581
582         if(rank <= 0 && rank != PROC_TIMER)
583                 return 0;
584
585         return 0;
586 }
587
588
589 static void mod_destroy(void)
590 {
591         /*free the shared memory*/
592         if(natping_state)
593                 shm_free(natping_state);
594 }
595
596
597 static int isnulladdr(str *sx, int pf)
598 {
599         char *cp;
600
601         if(pf == AF_INET6) {
602                 for(cp = sx->s; cp < sx->s + sx->len; cp++)
603                         if(*cp != '0' && *cp != ':')
604                                 return 0;
605                 return 1;
606         }
607         return (sx->len == 7 && memcmp("0.0.0.0", sx->s, 7) == 0);
608 }
609
610 /*
611  * Replaces ip:port pair in the Contact: field with the source address
612  * of the packet.
613  */
614 static int fix_nated_contact(struct sip_msg *msg)
615 {
616         int offset, len, len1;
617         char *cp, *buf, temp[2];
618         contact_t *c;
619         struct lump *anchor;
620         struct sip_uri uri;
621         str hostport;
622         str params1 = {0};
623         str params2 = {0};
624
625         if(get_contact_uri(msg, &uri, &c) == -1)
626                 return -1;
627         if((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
628                 LM_ERR("you can't call fix_nated_contact twice, "
629                            "check your config!\n");
630                 return -1;
631         }
632
633         offset = c->uri.s - msg->buf;
634         anchor = del_lump(msg, offset, c->uri.len, HDR_CONTACT_T);
635         if(anchor == 0)
636                 return -1;
637
638         hostport = uri.host;
639         if(uri.port.len > 0)
640                 hostport.len = uri.port.s + uri.port.len - uri.host.s;
641
642         cp = ip_addr2a(&msg->rcv.src_ip);
643         len = c->uri.len + strlen(cp) + 6 /* :port */ - hostport.len + 1;
644         if(msg->rcv.src_ip.af == AF_INET6)
645                 len += 2;
646         buf = pkg_malloc(len);
647         if(buf == NULL) {
648                 LM_ERR("out of pkg memory\n");
649                 return -1;
650         }
651         temp[0] = hostport.s[0];
652         temp[1] = c->uri.s[c->uri.len];
653         c->uri.s[c->uri.len] = hostport.s[0] = '\0';
654         if(uri.maddr.len <= 0) {
655                 if(msg->rcv.src_ip.af == AF_INET6) {
656                         len1 = snprintf(buf, len, "%s[%s]:%d%s", c->uri.s, cp,
657                                         msg->rcv.src_port, hostport.s + hostport.len);
658                 } else {
659                         len1 = snprintf(buf, len, "%s%s:%d%s", c->uri.s, cp,
660                                         msg->rcv.src_port, hostport.s + hostport.len);
661                 }
662         } else {
663                 /* skip maddr parameter - makes no sense anymore */
664                 LM_DBG("removing maddr parameter from contact uri: [%.*s]\n",
665                                 uri.maddr.len, uri.maddr.s);
666                 params1.s = hostport.s + hostport.len;
667                 params1.len = uri.maddr.s - params1.s;
668                 while(params1.len > 0 && (params1.s[params1.len - 1] == ' '
669                                                                                  || params1.s[params1.len - 1] == '\t'
670                                                                                  || params1.s[params1.len - 1] == ';'))
671                         params1.len--;
672                 params2.s = uri.maddr.s + uri.maddr.len;
673                 params2.len = c->uri.s + c->uri.len - params2.s;
674                 if(msg->rcv.src_ip.af == AF_INET6) {
675                         len1 = snprintf(buf, len, "%s[%s]:%d%.*s%.*s", c->uri.s, cp,
676                                         msg->rcv.src_port, params1.len, params1.s, params2.len,
677                                         params2.s);
678                 } else {
679                         len1 = snprintf(buf, len, "%s%s:%d%.*s%.*s", c->uri.s, cp,
680                                         msg->rcv.src_port, params1.len, params1.s, params2.len,
681                                         params2.s);
682                 }
683         }
684         if(len1 < len)
685                 len = len1;
686         hostport.s[0] = temp[0];
687         c->uri.s[c->uri.len] = temp[1];
688         if(insert_new_lump_after(anchor, buf, len, HDR_CONTACT_T) == 0) {
689                 pkg_free(buf);
690                 return -1;
691         }
692         c->uri.s = buf;
693         c->uri.len = len;
694
695         return 1;
696 }
697
698 static int fix_nated_contact_f(struct sip_msg *msg, char *str1, char *str2)
699 {
700         return fix_nated_contact(msg);
701 }
702
703 /*
704  * Replaces ip:port pair in the Contact: field with the source address
705  * of the packet.
706  */
707 static int set_contact_alias(struct sip_msg *msg)
708 {
709         char nbuf[MAX_URI_SIZE];
710         str nuri;
711         int br;
712
713         int offset, len;
714         char *buf;
715         contact_t *c;
716         struct lump *anchor;
717         struct sip_uri uri;
718
719         nuri.s = nbuf;
720         nuri.len = MAX_URI_SIZE;
721         if(get_contact_uri(msg, &uri, &c) == -1)
722                 return -1;
723         if((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
724                 LM_ERR("you can't update contact twice, check your config!\n");
725                 return -1;
726         }
727
728         if(uri_add_rcv_alias(msg, &c->uri, &nuri) < 0) {
729                 LM_DBG("cannot add the alias parameter\n");
730                 return -1;
731         }
732
733         br = 1;
734         if(c->uri.s[-1] == '<')
735                 br = 0;
736
737
738         len = nuri.len + 2 * br;
739         buf = pkg_malloc(len + 1);
740         if(buf == NULL) {
741                 LM_ERR("out of pkg memory\n");
742                 return -1;
743         }
744         if(br == 1) {
745                 buf[0] = '<';
746                 strncpy(buf + 1, nuri.s, nuri.len);
747                 buf[len - 1] = '>';
748         } else {
749                 strncpy(buf, nuri.s, nuri.len);
750         }
751         buf[len] = '\0';
752
753         offset = c->uri.s - msg->buf;
754         anchor = del_lump(msg, offset, c->uri.len, HDR_CONTACT_T);
755         if(anchor == 0) {
756                 pkg_free(buf);
757                 return -1;
758         }
759
760         if(insert_new_lump_after(anchor, buf, len, HDR_CONTACT_T) == 0) {
761                 pkg_free(buf);
762                 return -1;
763         }
764         c->uri.s = buf + br;
765         c->uri.len = len - 2 * br;
766
767         return 1;
768 }
769
770 static int set_contact_alias_f(struct sip_msg *msg, char *str1, char *str2)
771 {
772         return set_contact_alias(msg);
773 }
774
775 #define SALIAS ";alias="
776 #define SALIAS_LEN (sizeof(SALIAS) - 1)
777
778 /*
779  * Adds ;alias=ip~port~proto param to contact uri containing received ip,
780  * port, and transport proto if contact uri ip and port do not match
781  * received ip and port.
782  */
783 static int add_contact_alias_0(struct sip_msg *msg)
784 {
785         int len, param_len, ip_len;
786         contact_t *c;
787         struct lump *anchor;
788         struct sip_uri uri;
789         struct ip_addr *ip;
790         char *bracket, *lt, *param, *at, *port, *start;
791
792         /* Do nothing if Contact header does not exist */
793         if(!msg->contact) {
794                 if(parse_headers(msg, HDR_CONTACT_F, 0) == -1) {
795                         LM_ERR("while parsing headers\n");
796                         return -1;
797                 }
798                 if(!msg->contact) {
799                         LM_DBG("no contact header\n");
800                         return 2;
801                 }
802         }
803         if(get_contact_uri(msg, &uri, &c) == -1) {
804                 LM_ERR("failed to get contact uri\n");
805                 return -1;
806         }
807
808         /* Compare source ip and port against contact uri */
809         if(((ip = str2ip(&(uri.host))) == NULL)
810                         && ((ip = str2ip6(&(uri.host))) == NULL)) {
811                 LM_DBG("contact uri host is not an ip address\n");
812         } else {
813                 if (ip_addr_cmp(ip, &(msg->rcv.src_ip)) &&
814                     ((msg->rcv.src_port == uri.port_no) ||
815                      ((uri.port.len == 0) && (msg->rcv.src_port == 5060))) &&
816                     (uri.proto == msg->rcv.proto)) {
817                         LM_DBG("no need to add alias param\n");
818                         return 2;
819                 }
820         }
821
822         /* Check if function has been called already */
823         if((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
824                 LM_ERR("you can't call add_contact_alias twice, check your config!\n");
825                 return -1;
826         }
827
828         /* Check if Contact URI needs to be enclosed in <>s */
829         lt = param = NULL;
830         bracket = memchr(msg->contact->body.s, '<', msg->contact->body.len);
831         if(bracket == NULL) {
832                 /* add opening < */
833                 lt = (char *)pkg_malloc(1);
834                 if(!lt) {
835                         LM_ERR("no pkg memory left for lt sign\n");
836                         goto err;
837                 }
838                 *lt = '<';
839                 anchor = anchor_lump(msg, msg->contact->body.s - msg->buf, 0, 0);
840                 if(anchor == NULL) {
841                         LM_ERR("anchor_lump for beginning of contact body failed\n");
842                         goto err;
843                 }
844                 if(insert_new_lump_before(anchor, lt, 1, 0) == 0) {
845                         LM_ERR("insert_new_lump_before for \"<\" failed\n");
846                         goto err;
847                 }
848         }
849
850         /* Create  ;alias param */
851         param_len = SALIAS_LEN + 1 /* [ */ + IP6_MAX_STR_SIZE
852                                 + 1 /* ] */ + 1 /* ~ */ + 5 /* port */ + 1 /* ~ */
853                                 + 1 /* proto */ + 1 /* > */;
854         param = (char *)pkg_malloc(param_len);
855         if(!param) {
856                 LM_ERR("no pkg memory left for alias param\n");
857                 goto err;
858         }
859         at = param;
860         /* ip address */
861         append_str(at, SALIAS, SALIAS_LEN);
862         if(msg->rcv.src_ip.af == AF_INET6)
863                 append_chr(at, '[');
864         ip_len = ip_addr2sbuf(&(msg->rcv.src_ip), at, param_len - SALIAS_LEN);
865         if(ip_len <= 0) {
866                 LM_ERR("failed to copy source ip\n");
867                 goto err;
868         }
869         at = at + ip_len;
870         if(msg->rcv.src_ip.af == AF_INET6)
871                 append_chr(at, ']');
872         /* port */
873         append_chr(at, '~');
874         port = int2str(msg->rcv.src_port, &len);
875         append_str(at, port, len);
876         /* proto */
877         append_chr(at, '~');
878         if((msg->rcv.proto < PROTO_UDP) || (msg->rcv.proto > PROTO_WSS)) {
879                 LM_ERR("invalid transport protocol\n");
880                 goto err;
881         }
882         append_chr(at, msg->rcv.proto + '0');
883         /* closing > */
884         if(bracket == NULL) {
885                 append_chr(at, '>');
886         }
887         param_len = at - param;
888
889         /* Add  ;alias param */
890         LM_DBG("adding param <%.*s>\n", param_len, param);
891         if(uri.port.len > 0) {
892                 start = uri.port.s + uri.port.len;
893         } else {
894                 start = uri.host.s + uri.host.len;
895         }
896         anchor = anchor_lump(msg, start - msg->buf, 0, 0);
897         if(anchor == NULL) {
898                 LM_ERR("anchor_lump for ;alias param failed\n");
899                 goto err;
900         }
901         if(insert_new_lump_after(anchor, param, param_len, 0) == 0) {
902                 LM_ERR("insert_new_lump_after for ;alias param failed\n");
903                 goto err;
904         }
905         return 1;
906
907 err:
908         if(lt)
909                 pkg_free(lt);
910         if(param)
911                 pkg_free(param);
912         return -1;
913 }
914
915 static int add_contact_alias_0_f(struct sip_msg *msg, char *str1, char *str2)
916 {
917         return add_contact_alias_0(msg);
918 }
919
920 static int proto_type_to_int(char *proto)
921 {
922         if(strcasecmp(proto, "udp") == 0)
923                 return PROTO_UDP;
924         if(strcasecmp(proto, "tcp") == 0)
925                 return PROTO_TCP;
926         if(strcasecmp(proto, "tls") == 0)
927                 return PROTO_TLS;
928         if(strcasecmp(proto, "sctp") == 0)
929                 return PROTO_SCTP;
930         if(strcasecmp(proto, "ws") == 0)
931                 return PROTO_WS;
932         if(strcasecmp(proto, "wss") == 0)
933                 return PROTO_WSS;
934         return PROTO_OTHER;
935 }
936
937
938 /*
939  * Adds ;alias=ip~port~proto param to contact uri containing ip, port,
940  * and encoded proto given as parameters.
941  */
942 static int add_contact_alias_3(
943                 sip_msg_t *msg, str *ip_str, str *port_str, str *proto_str)
944 {
945         int param_len, proto;
946         unsigned int tmp;
947         contact_t *c;
948         struct lump *anchor;
949         struct sip_uri uri;
950         char *bracket, *lt, *param, *at, *start;
951
952         /* Do nothing if Contact header does not exist */
953         if(!msg->contact) {
954                 if(parse_headers(msg, HDR_CONTACT_F, 0) == -1) {
955                         LM_ERR("while parsing headers\n");
956                         return -1;
957                 }
958                 if(!msg->contact) {
959                         LM_DBG("no contact header\n");
960                         return 2;
961                 }
962         }
963         if(get_contact_uri(msg, &uri, &c) == -1) {
964                 LM_ERR("failed to get contact uri\n");
965                 return -1;
966         }
967
968         if((str2ip(ip_str) == NULL) && (str2ip6(ip_str) == NULL)) {
969                 LM_ERR("ip param value %s is not valid IP address\n", ip_str->s);
970                 return -1;
971         }
972         if((str2int(port_str, &tmp) == -1) || (tmp == 0) || (tmp > 65535)) {
973                 LM_ERR("port param value is not valid port\n");
974                 return -1;
975         }
976         proto = proto_type_to_int(proto_str->s);
977         if(proto == PROTO_OTHER) {
978                 LM_ERR("proto param value %s is not a known protocol\n", proto_str->s);
979                 return -1;
980         }
981
982         /* Check if function has been called already */
983         if((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
984                 LM_ERR("you can't call alias_contact twice, check your config!\n");
985                 return -1;
986         }
987
988         /* Check if Contact URI needs to be enclosed in <>s */
989         lt = param = NULL;
990         bracket = memchr(msg->contact->body.s, '<', msg->contact->body.len);
991         if(bracket == NULL) {
992                 /* add opening < */
993                 lt = (char *)pkg_malloc(1);
994                 if(!lt) {
995                         LM_ERR("no pkg memory left for lt sign\n");
996                         goto err;
997                 }
998                 *lt = '<';
999                 anchor = anchor_lump(msg, msg->contact->body.s - msg->buf, 0, 0);
1000                 if(anchor == NULL) {
1001                         LM_ERR("anchor_lump for beginning of contact body failed\n");
1002                         goto err;
1003                 }
1004                 if(insert_new_lump_before(anchor, lt, 1, 0) == 0) {
1005                         LM_ERR("insert_new_lump_before for \"<\" failed\n");
1006                         goto err;
1007                 }
1008         }
1009
1010         /* Create  ;alias param */
1011         param_len = SALIAS_LEN + IP6_MAX_STR_SIZE + 1 /* ~ */ + 5 /* port */
1012                                 + 1 /* ~ */ + 1 /* proto */ + 1 /* closing > */;
1013         param = (char *)pkg_malloc(param_len);
1014         if(!param) {
1015                 LM_ERR("no pkg memory left for alias param\n");
1016                 goto err;
1017         }
1018         at = param;
1019         /* ip address */
1020         append_str(at, SALIAS, SALIAS_LEN);
1021         append_str(at, ip_str->s, ip_str->len);
1022         /* port */
1023         append_chr(at, '~');
1024         append_str(at, port_str->s, port_str->len);
1025         /* proto */
1026         append_chr(at, '~');
1027         append_chr(at, proto + '0');
1028         /* closing > */
1029         if(bracket == NULL) {
1030                 append_chr(at, '>');
1031         }
1032         param_len = at - param;
1033
1034         /* Add  ;alias param */
1035         LM_DBG("adding param <%.*s>\n", param_len, param);
1036         if(uri.port.len > 0) {
1037                 start = uri.port.s + uri.port.len;
1038         } else {
1039                 start = uri.host.s + uri.host.len;
1040         }
1041         anchor = anchor_lump(msg, start - msg->buf, 0, 0);
1042         if(anchor == NULL) {
1043                 LM_ERR("anchor_lump for ;alias param failed\n");
1044                 goto err;
1045         }
1046         if(insert_new_lump_after(anchor, param, param_len, 0) == 0) {
1047                 LM_ERR("insert_new_lump_after for ;alias param failed\n");
1048                 goto err;
1049         }
1050         return 1;
1051
1052 err:
1053         if(lt)
1054                 pkg_free(lt);
1055         if(param)
1056                 pkg_free(param);
1057         return -1;
1058 }
1059
1060 static int add_contact_alias_3_f(
1061                 sip_msg_t *msg, char *_ip, char *_port, char *_proto)
1062 {
1063         str ip_str, port_str, proto_str;
1064
1065         /* Get and check param values */
1066         if(fixup_get_svalue(msg, (gparam_p)_ip, &ip_str) != 0) {
1067                 LM_ERR("cannot get ip param value\n");
1068                 return -1;
1069         }
1070         if(fixup_get_svalue(msg, (gparam_p)_port, &port_str) != 0) {
1071                 LM_ERR("cannot get port param value\n");
1072                 return -1;
1073         }
1074         if(fixup_get_svalue(msg, (gparam_p)_proto, &proto_str) != 0) {
1075                 LM_ERR("cannot get proto param value\n");
1076                 return -1;
1077         }
1078         return add_contact_alias_3(msg, &ip_str, &port_str, &proto_str);
1079 }
1080
1081 #define ALIAS "alias="
1082 #define ALIAS_LEN (sizeof(ALIAS) - 1)
1083
1084 /*
1085  * Checks if r-uri has alias param and if so, removes it and sets $du
1086  * based on its value.
1087  */
1088 static int handle_ruri_alias(struct sip_msg *msg)
1089 {
1090         str uri, proto;
1091         char buf[MAX_URI_SIZE], *val, *sep, *at, *next, *cur_uri, *rest, *port,
1092                         *trans;
1093         unsigned int len, rest_len, val_len, alias_len, proto_type, cur_uri_len,
1094                         ip_port_len;
1095
1096         if(parse_sip_msg_uri(msg) < 0) {
1097                 LM_ERR("while parsing Request-URI\n");
1098                 return -1;
1099         }
1100         rest = msg->parsed_uri.sip_params.s;
1101         rest_len = msg->parsed_uri.sip_params.len;
1102         if(rest_len == 0) {
1103                 LM_DBG("no params\n");
1104                 return 2;
1105         }
1106         while(rest_len >= ALIAS_LEN) {
1107                 if(strncmp(rest, ALIAS, ALIAS_LEN) == 0)
1108                         break;
1109                 sep = memchr(rest, 59 /* ; */, rest_len);
1110                 if(sep == NULL) {
1111                         LM_DBG("no alias param\n");
1112                         return 2;
1113                 } else {
1114                         rest_len = rest_len - (sep - rest + 1);
1115                         rest = sep + 1;
1116                 }
1117         }
1118
1119         if(rest_len < ALIAS_LEN) {
1120                 LM_DBG("no alias param\n");
1121                 return 2;
1122         }
1123
1124         /* set dst uri based on alias param value */
1125         val = rest + ALIAS_LEN;
1126         val_len = rest_len - ALIAS_LEN;
1127         port = memchr(val, 126 /* ~ */, val_len);
1128         if(port == NULL) {
1129                 LM_ERR("no '~' in alias param value\n");
1130                 return -1;
1131         }
1132         *(port++) = ':';
1133         trans = memchr(port, 126 /* ~ */, val_len - (port - val));
1134         if(trans == NULL) {
1135                 LM_ERR("no second '~' in alias param value\n");
1136                 return -1;
1137         }
1138         at = &(buf[0]);
1139         append_str(at, "sip:", 4);
1140         ip_port_len = trans - val;
1141         alias_len = SALIAS_LEN + ip_port_len + 2 /* ~n */;
1142         memcpy(at, val, ip_port_len);
1143         at = at + ip_port_len;
1144         trans = trans + 1;
1145         if((ip_port_len + 2 > val_len) || (*trans == ';') || (*trans == '?')) {
1146                 LM_ERR("no proto in alias param\n");
1147                 return -1;
1148         }
1149         proto_type = *trans - 48 /* char 0 */;
1150         if(proto_type != PROTO_UDP) {
1151                 proto_type_to_str(proto_type, &proto);
1152                 if(proto.len == 0) {
1153                         LM_ERR("unknown proto in alias param\n");
1154                         return -1;
1155                 }
1156                 append_str(at, ";transport=", 11);
1157                 memcpy(at, proto.s, proto.len);
1158                 at = at + proto.len;
1159         }
1160         next = trans + 1;
1161         if((ip_port_len + 2 < val_len) && (*next != ';') && (*next != '?')) {
1162                 LM_ERR("invalid alias param value\n");
1163                 return -1;
1164         }
1165         uri.s = &(buf[0]);
1166         uri.len = at - &(buf[0]);
1167         LM_DBG("setting dst_uri to <%.*s>\n", uri.len, uri.s);
1168         if(set_dst_uri(msg, &uri) == -1) {
1169                 LM_ERR("failed to set dst uri\n");
1170                 return -1;
1171         }
1172
1173         /* remove alias param */
1174         if(msg->new_uri.s) {
1175                 cur_uri = msg->new_uri.s;
1176                 cur_uri_len = msg->new_uri.len;
1177         } else {
1178                 cur_uri = msg->first_line.u.request.uri.s;
1179                 cur_uri_len = msg->first_line.u.request.uri.len;
1180         }
1181         at = &(buf[0]);
1182         len = rest - 1 /* ; */ - cur_uri;
1183         memcpy(at, cur_uri, len);
1184         at = at + len;
1185         len = cur_uri_len - alias_len - len;
1186         memcpy(at, rest + alias_len - 1, len);
1187         uri.s = &(buf[0]);
1188         uri.len = cur_uri_len - alias_len;
1189         LM_DBG("rewriting r-uri to <%.*s>\n", uri.len, uri.s);
1190         return rewrite_uri(msg, &uri);
1191 }
1192
1193 static int handle_ruri_alias_f(struct sip_msg *msg, char *str1, char *str2)
1194 {
1195         return handle_ruri_alias(msg);
1196 }
1197
1198 /*
1199  * Counts and return the number of record routes in rr headers of the message.
1200  */
1201 static int pv_get_rr_count_f(
1202                 struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
1203 {
1204         unsigned int count;
1205         struct hdr_field *header;
1206         rr_t *body;
1207
1208         if(msg == NULL)
1209                 return -1;
1210
1211         if(parse_headers(msg, HDR_EOH_F, 0) == -1) {
1212                 LM_ERR("while parsing message\n");
1213                 return -1;
1214         }
1215
1216         count = 0;
1217         header = msg->record_route;
1218
1219         while(header) {
1220                 if(header->type == HDR_RECORDROUTE_T) {
1221                         if(parse_rr(header) == -1) {
1222                                 LM_ERR("while parsing rr header\n");
1223                                 return -1;
1224                         }
1225                         body = (rr_t *)header->parsed;
1226                         while(body) {
1227                                 count++;
1228                                 body = body->next;
1229                         }
1230                 }
1231                 header = header->next;
1232         }
1233
1234         return pv_get_uintval(msg, param, res, (unsigned int)count);
1235 }
1236
1237 /*
1238  * Return count of topmost record routes in rr headers of the message.
1239  */
1240 static int pv_get_rr_top_count_f(
1241                 struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
1242 {
1243         str uri;
1244         struct sip_uri puri;
1245
1246         if(msg == NULL)
1247                 return -1;
1248
1249         if(!msg->record_route && (parse_headers(msg, HDR_RECORDROUTE_F, 0) == -1)) {
1250                 LM_ERR("while parsing Record-Route header\n");
1251                 return -1;
1252         }
1253
1254         if(!msg->record_route) {
1255                 return pv_get_uintval(msg, param, res, 0);
1256         }
1257
1258         if(parse_rr(msg->record_route) == -1) {
1259                 LM_ERR("while parsing rr header\n");
1260                 return -1;
1261         }
1262
1263         uri = ((rr_t *)msg->record_route->parsed)->nameaddr.uri;
1264         if(parse_uri(uri.s, uri.len, &puri) < 0) {
1265                 LM_ERR("while parsing rr uri\n");
1266                 return -1;
1267         }
1268
1269         if(puri.r2.len > 0) {
1270                 return pv_get_uintval(msg, param, res, 2);
1271         } else {
1272                 return pv_get_uintval(msg, param, res, 1);
1273         }
1274 }
1275
1276 /*
1277  * Test if IP address in netaddr belongs to RFC1918 networks
1278  * netaddr in network byte order
1279  */
1280 static inline int is1918addr_n(uint32_t netaddr)
1281 {
1282         int i;
1283         uint32_t hl;
1284
1285         hl = ntohl(netaddr);
1286         for(i = 0; nh_nets_1918[i].cnetaddr != NULL; i++) {
1287                 if((hl & nh_nets_1918[i].mask) == nh_nets_1918[i].netaddr) {
1288                         return 1;
1289                 }
1290         }
1291         if(nh_nat_addr_mode==1) {
1292                 for(i = 0; nh_nets_extra[i].cnetaddr != NULL; i++) {
1293                         if((hl & nh_nets_extra[i].mask) == nh_nets_extra[i].netaddr) {
1294                                 return 1;
1295                         }
1296                 }
1297         }
1298         return 0;
1299 }
1300
1301 /*
1302  * Test if IP address pointed to by saddr belongs to RFC1918 networks
1303  */
1304 static inline int is1918addr(str *saddr)
1305 {
1306         struct in_addr addr;
1307         int rval;
1308         char backup;
1309
1310         rval = -1;
1311         backup = saddr->s[saddr->len];
1312         saddr->s[saddr->len] = '\0';
1313         if(inet_aton(saddr->s, &addr) != 1)
1314                 goto theend;
1315         rval = is1918addr_n(addr.s_addr);
1316
1317 theend:
1318         saddr->s[saddr->len] = backup;
1319         return rval;
1320 }
1321
1322 /*
1323  * Test if IP address pointed to by ip belongs to RFC1918 networks
1324  */
1325 static inline int is1918addr_ip(struct ip_addr *ip)
1326 {
1327         if(ip->af != AF_INET)
1328                 return 0;
1329         return is1918addr_n(ip->u.addr32[0]);
1330 }
1331
1332 /*
1333  * test for occurrence of RFC1918 IP address in Contact HF
1334  */
1335 static int contact_1918(struct sip_msg *msg)
1336 {
1337         struct sip_uri uri;
1338         contact_t *c;
1339
1340         if(get_contact_uri(msg, &uri, &c) == -1)
1341                 return -1;
1342
1343         return (is1918addr(&(uri.host)) == 1) ? 1 : 0;
1344 }
1345
1346 /*
1347  * test if source port of signaling is different from
1348  * port advertised in Contact
1349  */
1350 static int contact_rport(struct sip_msg *msg)
1351 {
1352         struct sip_uri uri;
1353         contact_t *c;
1354
1355         if(get_contact_uri(msg, &uri, &c) == -1) {
1356                 return -1;
1357         }
1358
1359         if(msg->rcv.src_port != (uri.port_no ? uri.port_no : SIP_PORT)) {
1360                 return 1;
1361         } else {
1362                 return 0;
1363         }
1364 }
1365
1366 /**
1367 * test SDP C line ip address and source IP address match
1368 * if all ip address matches, return 0
1369 * returns unmatched ip address count
1370 * on parse error, returns -1
1371 */
1372 static int test_sdp_cline(struct sip_msg *msg){
1373         sdp_session_cell_t* session;
1374         struct ip_addr cline_addr;
1375         int sdp_session_num = 0;
1376         int result = 0;
1377
1378         if(parse_sdp(msg) < 0) {
1379                 LM_ERR("Unable to parse sdp body\n");
1380                 return -1;
1381         }
1382
1383         for(;;){
1384                 session = get_sdp_session(msg, sdp_session_num);
1385                 if(!session)
1386                         break;
1387
1388                 if(!(session->ip_addr.len > 0 && session->ip_addr.s))
1389                         break;
1390
1391                 if(session->pf==AF_INET){
1392                         if(str2ipbuf(&session->ip_addr,&cline_addr)<0){
1393                                 LM_ERR("Couldn't get sdp c line IP address\n");
1394                                 return -1;
1395                         }
1396                 }else if(session->pf==AF_INET6){
1397                         if(str2ip6buf(&session->ip_addr, &cline_addr)<0){
1398                                 LM_ERR("Couldn't get sdp c line IP address\n");
1399                                 return -1;
1400                         }
1401                 }else{
1402                         LM_ERR("Couldn't get sdp address type\n");
1403                         return -1;
1404                 }
1405
1406                 if(ip_addr_cmp(&msg->rcv.src_ip,&cline_addr)){
1407                         result++;
1408                 }
1409                 sdp_session_num++;
1410         }
1411
1412         return sdp_session_num - result;
1413 }
1414 /*
1415  * test for occurrence of RFC1918 IP address in SDP
1416  */
1417 static int sdp_1918(struct sip_msg *msg)
1418 {
1419         str *ip;
1420         int pf;
1421         int sdp_session_num, sdp_stream_num;
1422         sdp_session_cell_t *sdp_session;
1423         sdp_stream_cell_t *sdp_stream;
1424
1425         if(parse_sdp(msg) < 0) {
1426                 LM_ERR("Unable to parse sdp body\n");
1427                 return -1;
1428         }
1429
1430         sdp_session_num = 0;
1431         for(;;) {
1432                 sdp_session = get_sdp_session(msg, sdp_session_num);
1433                 if(!sdp_session)
1434                         break;
1435                 sdp_stream_num = 0;
1436                 for(;;) {
1437                         sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
1438                         if(!sdp_stream)
1439                                 break;
1440                         if(sdp_stream->ip_addr.s && sdp_stream->ip_addr.len) {
1441                                 ip = &(sdp_stream->ip_addr);
1442                                 pf = sdp_stream->pf;
1443                         } else {
1444                                 ip = &(sdp_session->ip_addr);
1445                                 pf = sdp_session->pf;
1446                         }
1447                         if(pf != AF_INET || isnulladdr(ip, pf))
1448                                 break;
1449                         if(is1918addr(ip) == 1)
1450                                 return 1;
1451                         sdp_stream_num++;
1452                 }
1453                 sdp_session_num++;
1454         }
1455         return 0;
1456 }
1457
1458 /*
1459  * test for occurrence of RFC1918 IP address in top Via
1460  */
1461 static int via_1918(struct sip_msg *msg)
1462 {
1463
1464         return (is1918addr(&(msg->via1->host)) == 1) ? 1 : 0;
1465 }
1466
1467 static int nat_uac_test(struct sip_msg *msg, int tests)
1468 {
1469         /* return true if any of the NAT-UAC tests holds */
1470
1471         /* test if the source port is different from the port in Via */
1472         if((tests & NAT_UAC_TEST_RPORT)
1473                         && (msg->rcv.src_port
1474                                            != (msg->via1->port ? msg->via1->port : SIP_PORT))) {
1475                 return 1;
1476         }
1477         /*
1478          * test if source address of signaling is different from
1479          * address advertised in Via
1480          */
1481         if((tests & NAT_UAC_TEST_RCVD) && received_via_test(msg))
1482                 return 1;
1483         /*
1484          * test for occurrences of RFC1918 addresses in Contact
1485          * header field
1486          */
1487         if((tests & NAT_UAC_TEST_C_1918) && (contact_1918(msg) > 0))
1488                 return 1;
1489         /*
1490          * test for occurrences of RFC1918 addresses in SDP body
1491          */
1492         if((tests & NAT_UAC_TEST_S_1918) && (sdp_1918(msg) > 0))
1493                 return 1;
1494         /*
1495          * test for occurrences of RFC1918 addresses top Via
1496          */
1497         if((tests & NAT_UAC_TEST_V_1918) && via_1918(msg))
1498                 return 1;
1499
1500         /*
1501          * test for occurrences of RFC1918 addresses in source address
1502          */
1503         if((tests & NAT_UAC_TEST_O_1918) && is1918addr_ip(&msg->rcv.src_ip))
1504                 return 1;
1505
1506         /*
1507          * test prototype to check whether the message arrived on a WebSocket
1508          */
1509         if((tests & NAT_UAC_TEST_WS)
1510                         && (msg->rcv.proto == PROTO_WS || msg->rcv.proto == PROTO_WSS))
1511                 return 1;
1512
1513         /*
1514          * test if source port of signaling is different from
1515          * port advertised in Contact
1516          */
1517         if((tests & NAT_UAC_TEST_C_PORT) && (contact_rport(msg) > 0))
1518                 return 1;
1519
1520         /**
1521         * test if sdp c line ip address matches with sip source address
1522         */
1523         if((tests & NAT_UAC_TEST_SDP_CLINE) && (test_sdp_cline(msg) > 0))
1524                 return 1;
1525
1526         /* no test succeeded */
1527         return -1;
1528 }
1529
1530 static int nat_uac_test_f(struct sip_msg *msg, char *str1, char *str2)
1531 {
1532         int tflags = 0;
1533         if(fixup_get_ivalue(msg, (gparam_t*)str1, &tflags)<0) {
1534                 LM_ERR("failed to get the value for flags parameter\n");
1535                 return -1;
1536         }
1537         return nat_uac_test(msg, tflags);
1538 }
1539
1540 static int is_rfc1918(struct sip_msg *msg, str *address)
1541 {
1542         return (is1918addr(address) == 1) ? 1 : -1;
1543 }
1544
1545
1546 static int is_rfc1918_f(struct sip_msg *msg, char *str1, char *str2)
1547 {
1548         str address;
1549
1550         if(fixup_get_svalue(msg, (gparam_p)str1, &address) != 0
1551                         || address.len == 0) {
1552                 LM_ERR("invalid address parameter\n");
1553                 return -2;
1554         }
1555
1556         return is_rfc1918(msg, &address);
1557 }
1558
1559 #define ADD_ADIRECTION 0x01
1560 #define FIX_MEDIP 0x02
1561 #define ADD_ANORTPPROXY 0x04
1562 #define FIX_ORGIP 0x08
1563
1564 #define ADIRECTION "a=direction:active"
1565 #define ADIRECTION_LEN (sizeof(ADIRECTION) - 1)
1566
1567 #define AOLDMEDIP "a=oldmediaip:"
1568 #define AOLDMEDIP_LEN (sizeof(AOLDMEDIP) - 1)
1569
1570 #define AOLDMEDIP6 "a=oldmediaip6:"
1571 #define AOLDMEDIP6_LEN (sizeof(AOLDMEDIP6) - 1)
1572
1573 #define AOLDMEDPRT "a=oldmediaport:"
1574 #define AOLDMEDPRT_LEN (sizeof(AOLDMEDPRT) - 1)
1575
1576
1577 /* replace ip addresses in SDP and return umber of replacements */
1578 static inline int replace_sdp_ip(
1579                 struct sip_msg *msg, str *org_body, char *line, str *ip)
1580 {
1581         str body1, oldip, newip;
1582         str body = *org_body;
1583         unsigned hasreplaced = 0;
1584         int pf, pf1 = 0;
1585         str body2;
1586         char *bodylimit = body.s + body.len;
1587         int ret;
1588         int count = 0;
1589
1590         /* Iterate all lines and replace ips in them. */
1591         if(!ip) {
1592                 newip.s = ip_addr2a(&msg->rcv.src_ip);
1593                 newip.len = strlen(newip.s);
1594         } else {
1595                 newip = *ip;
1596         }
1597         body1 = body;
1598         for(;;) {
1599                 if(extract_mediaip(&body1, &oldip, &pf, line) == -1)
1600                         break;
1601                 if(pf != AF_INET) {
1602                         LM_ERR("not an IPv4 address in '%s' SDP\n", line);
1603                         return -1;
1604                 }
1605                 if(!pf1)
1606                         pf1 = pf;
1607                 else if(pf != pf1) {
1608                         LM_ERR("mismatching address families in '%s' SDP\n", line);
1609                         return -1;
1610                 }
1611                 body2.s = oldip.s + oldip.len;
1612                 body2.len = bodylimit - body2.s;
1613                 ret = alter_mediaip(
1614                                 msg, &body1, &oldip, pf, &newip, pf, sdp_oldmediaip);
1615                 if(ret == -1) {
1616                         LM_ERR("can't alter '%s' IP\n", line);
1617                         return -1;
1618                 }
1619                 count += ret;
1620                 hasreplaced = 1;
1621                 body1 = body2;
1622         }
1623         if(!hasreplaced) {
1624                 LM_ERR("can't extract '%s' IP from the SDP\n", line);
1625                 return -1;
1626         }
1627
1628         return count;
1629 }
1630
1631 static int ki_fix_nated_sdp_ip(sip_msg_t *msg, int level, str *ip)
1632 {
1633         str body;
1634         int rest_len;
1635         char *buf, *m_start, *m_end;
1636         struct lump *anchor;
1637         int ret;
1638         int count = 0;
1639
1640         if(extract_body(msg, &body) == -1) {
1641                 LM_ERR("cannot extract body from msg!\n");
1642                 return -1;
1643         }
1644
1645         if(level & (ADD_ADIRECTION | ADD_ANORTPPROXY)) {
1646
1647                 msg->msg_flags |= FL_FORCE_ACTIVE;
1648
1649                 if(level & ADD_ADIRECTION) {
1650                         m_start = ser_memmem(body.s, "\r\nm=", body.len, 4);
1651                         while(m_start != NULL) {
1652                                 m_start += 4;
1653                                 rest_len = body.len - (m_start - body.s);
1654                                 m_start = m_end = ser_memmem(m_start, "\r\nm=", rest_len, 4);
1655                                 if(!m_end)
1656                                         m_end = body.s + body.len; /* just before the final \r\n */
1657                                 anchor = anchor_lump(msg, m_end - msg->buf, 0, 0);
1658                                 if(anchor == NULL) {
1659                                         LM_ERR("anchor_lump failed\n");
1660                                         return -1;
1661                                 }
1662                                 buf = pkg_malloc((ADIRECTION_LEN + CRLF_LEN) * sizeof(char));
1663                                 if(buf == NULL) {
1664                                         LM_ERR("out of pkg memory\n");
1665                                         return -1;
1666                                 }
1667                                 memcpy(buf, CRLF, CRLF_LEN);
1668                                 memcpy(buf + CRLF_LEN, ADIRECTION, ADIRECTION_LEN);
1669                                 if(insert_new_lump_after(
1670                                                    anchor, buf, ADIRECTION_LEN + CRLF_LEN, 0)
1671                                                 == NULL) {
1672                                         LM_ERR("insert_new_lump_after failed\n");
1673                                         pkg_free(buf);
1674                                         return -1;
1675                                 }
1676                         }
1677                 }
1678
1679                 if((level & ADD_ANORTPPROXY) && nortpproxy_str.len) {
1680                         anchor = anchor_lump(msg, body.s + body.len - msg->buf, 0, 0);
1681                         if(anchor == NULL) {
1682                                 LM_ERR("anchor_lump failed\n");
1683                                 return -1;
1684                         }
1685                         buf = pkg_malloc((nortpproxy_str.len + CRLF_LEN) * sizeof(char));
1686                         if(buf == NULL) {
1687                                 LM_ERR("out of pkg memory\n");
1688                                 return -1;
1689                         }
1690                         memcpy(buf, CRLF, CRLF_LEN);
1691                         memcpy(buf + CRLF_LEN, nortpproxy_str.s, nortpproxy_str.len);
1692                         if(insert_new_lump_after(
1693                                            anchor, buf, nortpproxy_str.len + CRLF_LEN, 0)
1694                                         == NULL) {
1695                                 LM_ERR("insert_new_lump_after failed\n");
1696                                 pkg_free(buf);
1697                                 return -1;
1698                         }
1699                 }
1700         }
1701
1702         if(level & FIX_MEDIP) {
1703                 /* Iterate all c= and replace ips in them. */
1704                 ret = replace_sdp_ip(msg, &body, "c=", (ip && ip->len>0) ? ip : 0);
1705                 if(ret == -1)
1706                         return -1;
1707                 count += ret;
1708         }
1709
1710         if(level & FIX_ORGIP) {
1711                 /* Iterate all o= and replace ips in them. */
1712                 ret = replace_sdp_ip(msg, &body, "o=",  (ip && ip->len>0) ? ip : 0);
1713                 if(ret == -1)
1714                         return -1;
1715                 count += ret;
1716         }
1717
1718         return count > 0 ? 1 : 2;
1719 }
1720
1721 static int ki_fix_nated_sdp(sip_msg_t *msg, int level)
1722 {
1723         return ki_fix_nated_sdp_ip(msg, level, NULL);
1724 }
1725
1726 static int fix_nated_sdp_f(struct sip_msg *msg, char *str1, char *str2)
1727 {
1728         int level;
1729         str ip = {0,0};
1730
1731         if(fixup_get_ivalue(msg, (gparam_t *)str1, &level) != 0) {
1732                 LM_ERR("failed to get value for first parameter\n");
1733                 return -1;
1734         }
1735         if(str2 && fixup_get_svalue(msg, (gparam_t *)str2, &ip) != 0) {
1736                 LM_ERR("failed to get value for second parameter\n");
1737                 return -1;
1738         }
1739
1740         return ki_fix_nated_sdp_ip(msg, level, &ip);
1741 }
1742
1743 static int extract_mediaip(str *body, str *mediaip, int *pf, char *line)
1744 {
1745         char *cp, *cp1;
1746         int len, nextisip;
1747
1748         cp1 = NULL;
1749         for(cp = body->s; (len = body->s + body->len - cp) > 0;) {
1750                 cp1 = ser_memmem(cp, line, len, 2);
1751                 if(cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
1752                         break;
1753                 cp = cp1 + 2;
1754         }
1755         if(cp1 == NULL)
1756                 return -1;
1757
1758         mediaip->s = cp1 + 2;
1759         mediaip->len =
1760                         eat_line(mediaip->s, body->s + body->len - mediaip->s) - mediaip->s;
1761         trim_len(mediaip->len, mediaip->s, *mediaip);
1762
1763         nextisip = 0;
1764         for(cp = mediaip->s; cp < mediaip->s + mediaip->len;) {
1765                 len = eat_token_end(cp, mediaip->s + mediaip->len) - cp;
1766                 if(nextisip == 1) {
1767                         mediaip->s = cp;
1768                         mediaip->len = len;
1769                         nextisip++;
1770                         break;
1771                 }
1772                 if(len == 3 && memcmp(cp, "IP", 2) == 0) {
1773                         switch(cp[2]) {
1774                                 case '4':
1775                                         nextisip = 1;
1776                                         *pf = AF_INET;
1777                                         break;
1778
1779                                 case '6':
1780                                         nextisip = 1;
1781                                         *pf = AF_INET6;
1782                                         break;
1783
1784                                 default:
1785                                         break;
1786                         }
1787                 }
1788                 cp = eat_space_end(cp + len, mediaip->s + mediaip->len);
1789         }
1790         if(nextisip != 2 || mediaip->len == 0) {
1791                 LM_ERR("no `IP[4|6]' in `%s' field\n", line);
1792                 return -1;
1793         }
1794         return 1;
1795 }
1796
1797 static int alter_mediaip(struct sip_msg *msg, str *body, str *oldip, int oldpf,
1798                 str *newip, int newpf, int preserve)
1799 {
1800         char *buf;
1801         int offset;
1802         struct lump *anchor;
1803         str omip, nip, oip;
1804
1805         /* check that updating mediaip is really necessary */
1806         if(oldpf == newpf && isnulladdr(oldip, oldpf))
1807                 return 0;
1808         if(newip->len == oldip->len && memcmp(newip->s, oldip->s, newip->len) == 0)
1809                 return 0;
1810
1811         if(preserve != 0) {
1812                 anchor = anchor_lump(msg, body->s + body->len - msg->buf, 0, 0);
1813                 if(anchor == NULL) {
1814                         LM_ERR("anchor_lump failed\n");
1815                         return -1;
1816                 }
1817                 if(oldpf == AF_INET6) {
1818                         omip.s = AOLDMEDIP6;
1819                         omip.len = AOLDMEDIP6_LEN;
1820                 } else {
1821                         omip.s = AOLDMEDIP;
1822                         omip.len = AOLDMEDIP_LEN;
1823                 }
1824                 buf = pkg_malloc(omip.len + oldip->len + CRLF_LEN);
1825                 if(buf == NULL) {
1826                         LM_ERR("out of pkg memory\n");
1827                         return -1;
1828                 }
1829                 memcpy(buf, CRLF, CRLF_LEN);
1830                 memcpy(buf + CRLF_LEN, omip.s, omip.len);
1831                 memcpy(buf + CRLF_LEN + omip.len, oldip->s, oldip->len);
1832                 if(insert_new_lump_after(
1833                                    anchor, buf, omip.len + oldip->len + CRLF_LEN, 0)
1834                                 == NULL) {
1835                         LM_ERR("insert_new_lump_after failed\n");
1836                         pkg_free(buf);
1837                         return -1;
1838                 }
1839         }
1840
1841         if(oldpf == newpf) {
1842                 nip.len = newip->len;
1843                 nip.s = pkg_malloc(nip.len);
1844                 if(nip.s == NULL) {
1845                         LM_ERR("out of pkg memory\n");
1846                         return -1;
1847                 }
1848                 memcpy(nip.s, newip->s, newip->len);
1849         } else {
1850                 nip.len = newip->len + 2;
1851                 nip.s = pkg_malloc(nip.len);
1852                 if(nip.s == NULL) {
1853                         LM_ERR("out of pkg memory\n");
1854                         return -1;
1855                 }
1856                 memcpy(nip.s + 2, newip->s, newip->len);
1857                 nip.s[0] = (newpf == AF_INET6) ? '6' : '4';
1858                 nip.s[1] = ' ';
1859         }
1860
1861         oip = *oldip;
1862         if(oldpf != newpf) {
1863                 do {
1864                         oip.s--;
1865                         oip.len++;
1866                 } while(*oip.s != '6' && *oip.s != '4');
1867         }
1868         offset = oip.s - msg->buf;
1869         anchor = del_lump(msg, offset, oip.len, 0);
1870         if(anchor == NULL) {
1871                 LM_ERR("del_lump failed\n");
1872                 pkg_free(nip.s);
1873                 return -1;
1874         }
1875
1876         if(insert_new_lump_after(anchor, nip.s, nip.len, 0) == 0) {
1877                 LM_ERR("insert_new_lump_after failed\n");
1878                 pkg_free(nip.s);
1879                 return -1;
1880         }
1881         return 1;
1882 }
1883
1884
1885 static u_short raw_checksum(unsigned char *buffer, int len)
1886 {
1887         u_long sum = 0;
1888
1889         while(len > 1) {
1890                 sum += *buffer << 8;
1891                 buffer++;
1892                 sum += *buffer;
1893                 buffer++;
1894                 len -= 2;
1895         }
1896         if(len) {
1897                 sum += *buffer << 8;
1898         }
1899         sum = (sum >> 16) + (sum & 0xffff);
1900         sum = (sum >> 16) + (sum);
1901
1902         return (u_short)~sum;
1903 }
1904
1905
1906 static int send_raw(const char *buf, int buf_len, union sockaddr_union *to,
1907                 const unsigned int s_ip, const unsigned int s_port)
1908 {
1909         struct ip *ip;
1910         struct udphdr *udp;
1911         unsigned char packet[50];
1912         int len = sizeof(struct ip) + sizeof(struct udphdr) + buf_len;
1913
1914         if(len > sizeof(packet)) {
1915                 LM_ERR("payload too big\n");
1916                 return -1;
1917         }
1918
1919         ip = (struct ip *)packet;
1920         udp = (struct udphdr *)(packet + sizeof(struct ip));
1921         memcpy(packet + sizeof(struct ip) + sizeof(struct udphdr), buf, buf_len);
1922
1923         ip->ip_v = 4;
1924         ip->ip_hl = sizeof(struct ip) / 4; // no options
1925         ip->ip_tos = 0;
1926         ip->ip_len = htons(len);
1927         ip->ip_id = 23;
1928         ip->ip_off = 0;
1929         ip->ip_ttl = 69;
1930         ip->ip_p = 17;
1931         ip->ip_src.s_addr = s_ip;
1932         ip->ip_dst.s_addr = to->sin.sin_addr.s_addr;
1933
1934         ip->ip_sum = raw_checksum((unsigned char *)ip, sizeof(struct ip));
1935
1936         udp->uh_sport = htons(s_port);
1937         udp->uh_dport = to->sin.sin_port;
1938         udp->uh_ulen = htons((unsigned short)sizeof(struct udphdr) + buf_len);
1939         udp->uh_sum = 0;
1940
1941         return sendto(raw_sock, packet, len, 0, (struct sockaddr *)to,
1942                         sizeof(struct sockaddr_in));
1943 }
1944
1945 /**
1946  * quick function to extract ip:port from path
1947  */
1948 static char *extract_last_path_ip(str path)
1949 {
1950         /* used for raw UDP ping which works only on IPv4 */
1951         static char ip[24];
1952         char *start = NULL, *end = NULL, *p;
1953         int i;
1954         int path_depth = 0;
1955         int max_path_depth;
1956
1957         max_path_depth = udpping_from_path - 1;
1958
1959         if(!path.len || !path.s)
1960                 return NULL;
1961
1962         p = path.s;
1963         for(i = 0; i < path.len; i++) {
1964                 if(!strncmp("<sip:", p, 5) && i < path.len - 4) {
1965                         start = p + 5;
1966
1967                         end = NULL;
1968                 }
1969                 if((*p == ';' || *p == '>') && !end) {
1970                         end = p;
1971                         if(max_path_depth) {
1972                                 path_depth++;
1973                                 if(path_depth >= max_path_depth) {
1974                                         break;
1975                                 }
1976                         }
1977                 }
1978                 p++;
1979         }
1980         if(start && end) {
1981                 int len = end - start;
1982                 if(len > sizeof(ip) - 1) {
1983                         return NULL;
1984                 }
1985                 memcpy(ip, start, len);
1986                 ip[len] = '\0';
1987                 return (char *)ip;
1988         } else {
1989                 return NULL;
1990         }
1991 }
1992
1993
1994 static void nh_timer(unsigned int ticks, void *timer_idx)
1995 {
1996         static unsigned int iteration = 0;
1997         int rval;
1998         void *buf, *cp;
1999         str c;
2000         str recv;
2001         str *dst_uri;
2002         str opt;
2003         str path;
2004         str ruid;
2005         unsigned int aorhash;
2006         struct sip_uri curi;
2007         struct hostent *he;
2008         struct socket_info *send_sock;
2009         unsigned int flags;
2010         char proto;
2011         struct dest_info dst;
2012         char *path_ip_str = NULL;
2013         unsigned int path_ip = 0;
2014         unsigned short path_port = 0;
2015         int options = 0;
2016         int send_sip_ping = 0;
2017
2018         if((*natping_state) == 0)
2019                 goto done;
2020
2021         buf = NULL;
2022         if(cblen > 0) {
2023                 buf = pkg_malloc(cblen);
2024                 if(buf == NULL) {
2025                         LM_ERR("out of pkg memory\n");
2026                         goto done;
2027                 }
2028         }
2029         if(nh_filter_srvid)
2030                 options |= GAU_OPT_SERVER_ID;
2031         rval = ul.get_all_ucontacts(buf, cblen, (ping_nated_only ? ul.nat_flag : 0),
2032                         ((unsigned int)(unsigned long)timer_idx) * natping_interval
2033                                         + iteration,
2034                         natping_processes * natping_interval, options);
2035         if(rval < 0) {
2036                 if(buf != NULL)
2037                         pkg_free(buf);
2038                 LM_ERR("failed to fetch contacts\n");
2039                 goto done;
2040         }
2041         if(rval > 0) {
2042                 if(buf != NULL)
2043                         pkg_free(buf);
2044                 cblen = rval * 2;
2045                 buf = pkg_malloc(cblen);
2046                 if(buf == NULL) {
2047                         LM_ERR("out of pkg memory\n");
2048                         goto done;
2049                 }
2050                 rval = ul.get_all_ucontacts(buf, cblen,
2051                                 (ping_nated_only ? ul.nat_flag : 0),
2052                                 ((unsigned int)(unsigned long)timer_idx) * natping_interval
2053                                                 + iteration,
2054                                 natping_processes * natping_interval, options);
2055                 if(rval != 0) {
2056                         pkg_free(buf);
2057                         goto done;
2058                 }
2059         }
2060
2061         if(buf == NULL)
2062                 goto done;
2063
2064         cp = buf;
2065         while(1) {
2066                 memcpy(&(c.len), cp, sizeof(c.len));
2067                 if(c.len == 0)
2068                         break;
2069                 c.s = (char *)cp + sizeof(c.len);
2070                 cp = (char *)cp + sizeof(c.len) + c.len;
2071                 memcpy(&(recv.len), cp, sizeof(recv.len));
2072                 recv.s = (char *)cp + sizeof(recv.len);
2073                 cp = (char *)cp + sizeof(recv.len) + recv.len;
2074                 memcpy(&send_sock, cp, sizeof(send_sock));
2075                 cp = (char *)cp + sizeof(send_sock);
2076                 memcpy(&flags, cp, sizeof(flags));
2077                 cp = (char *)cp + sizeof(flags);
2078                 memcpy(&(path.len), cp, sizeof(path.len));
2079                 path.s = path.len ? ((char *)cp + sizeof(path.len)) : NULL;
2080                 cp = (char *)cp + sizeof(path.len) + path.len;
2081                 memcpy(&(ruid.len), cp, sizeof(ruid.len));
2082                 ruid.s = ruid.len ? ((char *)cp + sizeof(ruid.len)) : NULL;
2083                 cp = (char *)cp + sizeof(ruid.len) + ruid.len;
2084                 memcpy(&aorhash, cp, sizeof(aorhash));
2085                 cp = (char *)cp + sizeof(aorhash);
2086
2087                 if((flags & natping_disable_flag)) /* always 0 if natping_disable_flag not set */
2088                         continue;
2089
2090                 if(recv.len > 0)
2091                         dst_uri = &recv;
2092                 else
2093                         dst_uri = &c;
2094
2095                 /* determin the destination */
2096                 if(path.len && (flags & sipping_flag) != 0) {
2097                         /* send to first URI in path */
2098                         if(get_path_dst_uri(&path, &opt) < 0) {
2099                                 LM_ERR("failed to get dst_uri for Path\n");
2100                                 continue;
2101                         }
2102                         /* send to the contact/received */
2103                         if(parse_uri(opt.s, opt.len, &curi) < 0) {
2104                                 LM_ERR("can't parse contact dst_uri\n");
2105                                 continue;
2106                         }
2107                 } else if(path.len && udpping_from_path) {
2108                         path_ip_str = extract_last_path_ip(path);
2109                         if(path_ip_str == NULL) {
2110                                 LM_ERR("ERROR:nathelper:nh_timer: unable to parse path from "
2111                                            "location\n");
2112                                 continue;
2113                         }
2114                         if(get_natping_socket(path_ip_str, &path_ip, &path_port)) {
2115                                 LM_ERR("could not parse path host for udpping_from_path\n");
2116                                 continue;
2117                         }
2118                         if(parse_uri(dst_uri->s, dst_uri->len, &curi) < 0) {
2119                                 LM_ERR("can't parse contact/received uri\n");
2120                                 continue;
2121                         }
2122                 } else {
2123                         /* send to the contact/received */
2124                         if(parse_uri(dst_uri->s, dst_uri->len, &curi) < 0) {
2125                                 LM_ERR("can't parse contact/received uri\n");
2126                                 continue;
2127                         }
2128                 }
2129                 if(curi.proto != PROTO_UDP && curi.proto != PROTO_NONE)
2130                         continue;
2131                 if(curi.port_no == 0)
2132                         curi.port_no = SIP_PORT;
2133                 proto = curi.proto;
2134                 /* we sholud get rid of this resolve (to ofen and to slow); for the
2135                  * moment we are lucky since the curi is an IP -bogdan */
2136                 he = sip_resolvehost(&curi.host, &curi.port_no, &proto);
2137                 if(he == NULL) {
2138                         LM_ERR("can't resolve_host\n");
2139                         continue;
2140                 }
2141                 init_dest_info(&dst);
2142                 hostent2su(&dst.to, he, 0, curi.port_no);
2143
2144                 if(force_socket) {
2145                         send_sock = force_socket;
2146                 }
2147                 if(send_sock == 0) {
2148                         send_sock = get_send_socket(0, &dst.to, PROTO_UDP);
2149                 }
2150                 if(send_sock == NULL) {
2151                         LM_ERR("can't get sending socket\n");
2152                         continue;
2153                 }
2154                 dst.proto = PROTO_UDP;
2155                 dst.send_sock = send_sock;
2156
2157                 send_sip_ping = ((flags & sipping_flag) != 0)
2158                                                         || (ping_nated_only == 0 && sipping_flag != 0);
2159
2160                 if ( send_sip_ping && (opt.s = build_sipping(&c, send_sock, &path,
2161                                                 &ruid, aorhash, &opt.len)) != 0) {
2162                         if(udp_send(&dst, opt.s, opt.len) < 0) {
2163                                 LM_ERR("sip udp_send failed\n");
2164                         }
2165                 } else if(raw_ip) {
2166                         if(send_raw((char *)sbuf, sizeof(sbuf), &dst.to, raw_ip, raw_port)
2167                                         < 0) {
2168                                 LM_ERR("send_raw failed\n");
2169                         }
2170                 } else if(udpping_from_path) {
2171                         if(send_raw((char *)sbuf, sizeof(sbuf), &dst.to, path_ip, path_port)
2172                                         < 0) {
2173                                 LM_ERR("send_raw from path failed\n");
2174                         }
2175                 } else {
2176                         if(udp_send(&dst, (char *)sbuf, sizeof(sbuf)) < 0) {
2177                                 LM_ERR("udp_send failed\n");
2178                         }
2179                 }
2180         }
2181         pkg_free(buf);
2182 done:
2183         iteration++;
2184         if(iteration == natping_interval)
2185                 iteration = 0;
2186 }
2187
2188
2189 /*
2190  * Create received SIP uri that will be either
2191  * passed to registrar in an AVP or apended
2192  * to Contact header field as a parameter
2193  */
2194 static int create_rcv_uri(str *uri, struct sip_msg *m)
2195 {
2196         return get_src_uri(m, 0, uri);
2197 }
2198
2199
2200 /*
2201  * Add received parameter to Contacts for further
2202  * forwarding of the REGISTER requuest
2203  */
2204 static int ki_add_rcv_param(sip_msg_t *msg, int upos)
2205 {
2206         contact_t *c;
2207         struct lump *anchor;
2208         char *param;
2209         str uri;
2210
2211         if(upos) {
2212                 if(msg->rcv.proto != PROTO_UDP) {
2213                         LM_ERR("adding received parameter to Contact URI works only for UDP\n");
2214                         return -1;
2215                 }
2216         }
2217
2218         if(create_rcv_uri(&uri, msg) < 0) {
2219                 return -1;
2220         }
2221
2222         if(contact_iterator(&c, msg, 0) < 0) {
2223                 return -1;
2224         }
2225
2226         while(c) {
2227                 param = (char *)pkg_malloc(RECEIVED_LEN + 2 + uri.len);
2228                 if(!param) {
2229                         LM_ERR("no pkg memory left\n");
2230                         return -1;
2231                 }
2232                 memcpy(param, RECEIVED, RECEIVED_LEN);
2233                 if(upos) {
2234                         memcpy(param + RECEIVED_LEN, uri.s, uri.len);
2235                 } else {
2236                         param[RECEIVED_LEN] = '\"';
2237                         memcpy(param + RECEIVED_LEN + 1, uri.s, uri.len);
2238                         param[RECEIVED_LEN + 1 + uri.len] = '\"';
2239                 }
2240
2241                 if(upos) {
2242                         /* add the param as uri param */
2243                         anchor = anchor_lump(msg, c->uri.s + c->uri.len - msg->buf, 0, 0);
2244                 } else {
2245                         /* add the param as header param */
2246                         anchor = anchor_lump(msg, c->name.s + c->len - msg->buf, 0, 0);
2247                 }
2248                 if(anchor == NULL) {
2249                         LM_ERR("anchor_lump failed\n");
2250                         pkg_free(param);
2251                         return -1;
2252                 }
2253
2254                 if(insert_new_lump_after(anchor, param,
2255                                         RECEIVED_LEN + 1 + uri.len + 1 - ((upos)?2:0), 0) == 0) {
2256                         LM_ERR("insert_new_lump_after failed\n");
2257                         pkg_free(param);
2258                         return -1;
2259                 }
2260
2261                 if(contact_iterator(&c, msg, c) < 0) {
2262                         return -1;
2263                 }
2264         }
2265
2266         return 1;
2267 }
2268
2269 /*
2270  * Add received parameter to Contacts for further
2271  * forwarding of the REGISTER requuest
2272  */
2273 static int add_rcv_param_f(struct sip_msg *msg, char *str1, char *str2)
2274 {
2275         int hdr_param = 0;
2276
2277         if(str1) {
2278                 if(fixup_get_ivalue(msg, (gparam_t*)str1, &hdr_param)<0) {
2279                         LM_ERR("failed to get flags parameter\n");
2280                         return -1;
2281                 }
2282         }
2283         return ki_add_rcv_param(msg, hdr_param);
2284 }
2285
2286 /*
2287  * Create an AVP to be used by registrar with the source IP and port
2288  * of the REGISTER
2289  */
2290 static int fix_nated_register(struct sip_msg *msg)
2291 {
2292         str uri;
2293         int_str val;
2294
2295         if(rcv_avp_name.n == 0)
2296                 return 1;
2297
2298         if(create_rcv_uri(&uri, msg) < 0) {
2299                 return -1;
2300         }
2301
2302         val.s = uri;
2303
2304         if(add_avp(AVP_VAL_STR | rcv_avp_type, rcv_avp_name, val) < 0) {
2305                 LM_ERR("failed to create AVP\n");
2306                 return -1;
2307         }
2308
2309         return 1;
2310 }
2311
2312 static int fix_nated_register_f(struct sip_msg *msg, char *str1, char *str2)
2313 {
2314         return fix_nated_register(msg);
2315 }
2316
2317 /**
2318  * handle SIP replies
2319  */
2320 static int nh_sip_reply_received(sip_msg_t *msg)
2321 {
2322         to_body_t *fb;
2323         str ruid;
2324         str ah;
2325         unsigned int aorhash;
2326         char *p;
2327
2328         if(nh_keepalive_timeout <= 0)
2329                 return 1;
2330         if(msg->cseq == NULL && ((parse_headers(msg, HDR_CSEQ_F, 0) == -1)
2331                                                                         || (msg->cseq == NULL))) {
2332                 LM_ERR("no CSEQ header\n");
2333                 goto done;
2334         }
2335         if(sipping_method_id != METHOD_UNDEF && sipping_method_id != METHOD_OTHER) {
2336                 if(get_cseq(msg)->method_id != sipping_method_id)
2337                         goto done;
2338         } else {
2339                 if(sipping_method_id == METHOD_OTHER) {
2340                         if(get_cseq(msg)->method.len != sipping_method.len)
2341                                 goto done;
2342                         if(strncmp(get_cseq(msg)->method.s, sipping_method.s,
2343                                            sipping_method.len)
2344                                         != 0)
2345                                 goto done;
2346                 } else {
2347                         goto done;
2348                 }
2349         }
2350         /* there must be no second via */
2351         if(!(parse_headers(msg, HDR_VIA2_F, 0) == -1 || (msg->via2 == 0)
2352                            || (msg->via2->error != PARSE_OK)))
2353                 goto done;
2354
2355         /* from uri check */
2356         if((parse_from_header(msg)) < 0) {
2357                 LM_ERR("cannot parse From header\n");
2358                 goto done;
2359         }
2360
2361         fb = get_from(msg);
2362         if(fb->uri.len != sipping_from.len
2363                         || strncmp(fb->uri.s, sipping_from.s, sipping_from.len) != 0)
2364                 goto done;
2365
2366         /* from-tag is: ruid-aorhash-counter */
2367         if(fb->tag_value.len <= 0)
2368                 goto done;
2369
2370         LM_DBG("checking nathelper keepalive reply [%.*s]\n", fb->tag_value.len,
2371                         fb->tag_value.s);
2372
2373         /* skip counter */
2374         p = q_memrchr(fb->tag_value.s, '-', fb->tag_value.len);
2375         if(p == NULL) {
2376                 LM_DBG("from tag format mismatch [%.*s]\n", fb->tag_value.len,
2377                                 fb->tag_value.s);
2378                 goto done;
2379         }
2380         /* aor hash */
2381         ah.len = p - fb->tag_value.s;
2382         aorhash = 0;
2383         p = q_memrchr(fb->tag_value.s, '-', ah.len);
2384         if(p == NULL) {
2385                 LM_DBG("from tag format mismatch [%.*s]!\n", fb->tag_value.len,
2386                                 fb->tag_value.s);
2387                 goto done;
2388         }
2389         ah.s = p + 1;
2390         ah.len = fb->tag_value.s + ah.len - ah.s;
2391
2392         LM_DBG("aor hash string is [%.*s] (%d)\n", ah.len, ah.s, ah.len);
2393
2394         if(ah.len <= 0 || reverse_hex2int(ah.s, ah.len, &aorhash) < 0) {
2395                 LM_DBG("cannot get aor hash in [%.*s]\n", fb->tag_value.len,
2396                                 fb->tag_value.s);
2397                 goto done;
2398         }
2399         LM_DBG("aor hash is [%u] string [%.*s]\n", aorhash, ah.len, ah.s);
2400
2401         ruid.s = fb->tag_value.s;
2402         ruid.len = ah.s - ruid.s - 1;
2403
2404         if(ruid.len <= 0) {
2405                 LM_DBG("cannot get ruid in [%.*s]\n", fb->tag_value.len,
2406                                 fb->tag_value.s);
2407                 goto done;
2408         }
2409
2410         LM_DBG("reply for keepalive of [%.*s:%u]\n", ruid.len, ruid.s, aorhash);
2411
2412         ul.refresh_keepalive(aorhash, &ruid);
2413 done:
2414         /* let the core handle further the reply */
2415         return 1;
2416 }
2417
2418 static int sel_rewrite_contact(str *res, select_t *s, struct sip_msg *msg)
2419 {
2420         static char buf[500];
2421         contact_t *c;
2422         int n, def_port_fl, len;
2423         char *cp;
2424         str hostport;
2425         struct sip_uri uri;
2426
2427         res->len = 0;
2428         n = s->params[2].v.i;
2429         if(n <= 0) {
2430                 LM_ERR("rewrite contact[%d] - zero or negative index not supported\n",
2431                                 n);
2432                 return -1;
2433         }
2434         c = 0;
2435         do {
2436                 if(contact_iterator(&c, msg, c) < 0 || !c)
2437                         return -1;
2438                 n--;
2439         } while(n > 0);
2440
2441         if(parse_uri(c->uri.s, c->uri.len, &uri) < 0 || uri.host.len <= 0) {
2442                 LM_ERR("rewrite contact[%d] - error while parsing Contact URI\n",
2443                                 s->params[2].v.i);
2444                 return -1;
2445         }
2446         len = c->len - uri.host.len;
2447         if(uri.port.len > 0)
2448                 len -= uri.port.len;
2449         def_port_fl =
2450                         (msg->rcv.proto == PROTO_TLS && msg->rcv.src_port == SIPS_PORT)
2451                         || (msg->rcv.proto != PROTO_TLS && msg->rcv.src_port == SIP_PORT);
2452         if(!def_port_fl)
2453                 len += 1 /*:*/ + 5 /*port*/;
2454         if(len > sizeof(buf)) {
2455                 LM_ERR("rewrite contact[%d] - contact too long\n", s->params[2].v.i);
2456                 return -1;
2457         }
2458         hostport = uri.host;
2459         if(uri.port.len > 0)
2460                 hostport.len = uri.port.s + uri.port.len - uri.host.s;
2461
2462         res->s = buf;
2463         res->len = hostport.s - c->name.s;
2464         memcpy(buf, c->name.s, res->len);
2465         cp = ip_addr2a(&msg->rcv.src_ip);
2466         if(def_port_fl) {
2467                 res->len += snprintf(buf + res->len, sizeof(buf) - res->len, "%s", cp);
2468         } else {
2469                 res->len += snprintf(buf + res->len, sizeof(buf) - res->len, "%s:%d",
2470                                 cp, msg->rcv.src_port);
2471         }
2472         memcpy(buf + res->len, hostport.s + hostport.len,
2473                         c->len - (hostport.s + hostport.len - c->name.s));
2474         res->len += c->len - (hostport.s + hostport.len - c->name.s);
2475
2476         return 0;
2477 }
2478 /*!
2479 * @function w_set_alias_to_pv
2480 * @abstract wrapper of set_alias_to_avp_f
2481 * @param msg sip message
2482 * @param uri_avp given avp name
2483 *
2484 * @result 1 successful  , -1 fail
2485 */
2486 static int w_set_alias_to_pv(struct sip_msg *msg, char *uri_avp, char *hollow)
2487 {
2488         str dest_avp={0,0};
2489
2490         if(!uri_avp)
2491                 return -1;
2492
2493         dest_avp.s=uri_avp;
2494         dest_avp.len=strlen(dest_avp.s);
2495
2496         return ki_set_alias_to_pv(msg,&dest_avp);
2497 }
2498
2499 /*!
2500 * @function ki_set_alias_to_pv
2501 * @abstract reads from  msg then write to given avp uri_avp as sip uri
2502 *
2503 * @param msg sip message
2504 * @param uri_avp given avp name
2505 *
2506 * @result 1 successful  , -1 fail
2507 */
2508 static int ki_set_alias_to_pv(struct sip_msg *msg, str *pvname)
2509 {
2510         str contact;
2511         str alias_uri={0,0};
2512
2513         if(parse_headers(msg,HDR_CONTACT_F,0) < 0 ) {
2514                 LM_ERR("Couldn't find Contact Header\n");
2515                 return -1;
2516         }
2517
2518         if(!msg->contact)
2519                 return -1;
2520
2521         if(parse_contact(msg->contact)<0 || !msg->contact->parsed ||
2522         ((contact_body_t *)msg->contact->parsed)->contacts==NULL ||
2523         ((contact_body_t *)msg->contact->parsed)->contacts->next!=NULL){
2524                 LM_ERR("Couldn't parse Contact Header\n");
2525                 return -1;
2526         }
2527
2528         contact.s = ((contact_body_t *)msg->contact->parsed)->contacts->name.s;
2529         contact.len = ((contact_body_t *)msg->contact->parsed)->contacts->len;
2530
2531         if(nh_alias_to_uri(&contact, &alias_uri)<0)
2532                 return -1;
2533
2534         if(nh_write_to_pv(msg, &alias_uri, pvname)<0)
2535                 goto error;
2536
2537         if(alias_uri.s)
2538                 pkg_free(alias_uri.s);
2539
2540         return 1;
2541
2542         error :
2543                 if(alias_uri.s)
2544                         pkg_free(alias_uri.s);
2545
2546         return -1;
2547 }
2548 /*!
2549 * @function nh_write_to_pv
2550 * @abstract nh_write_to_pv function writes data to given avp
2551 * @param data  source data
2552 * @param uri_avp destination avp name
2553 * @result 1 successful  , -1 fail
2554 */
2555 static int nh_write_to_pv(struct sip_msg *msg, str *data, str *pvname)
2556 {
2557         pv_spec_t *pvresult = NULL;
2558         pv_value_t valx;
2559         pvresult = pv_cache_get(pvname);
2560
2561         if(pvresult == NULL) {
2562                 LM_ERR("Failed to malloc destination pseudo-variable \n");
2563                 return -1;
2564         }
2565
2566         if(pvresult->setf==NULL) {
2567                 LM_ERR("Destination pseudo-variable is not writable: [%.*s] \n",
2568                                 pvname->len, pvname->s);
2569                 return -1;
2570         }
2571         memset(&valx, 0, sizeof(pv_value_t));
2572
2573         if(!data->s){
2574                 LM_ERR("There isn't any data to write to the destination\n");
2575                 return -1;
2576         }
2577
2578         valx.flags      =       PV_VAL_STR;
2579         valx.rs.s       =       data->s;
2580         valx.rs.len     =       data->len;
2581
2582         LM_DBG("result: [%.*s]\n", valx.rs.len, valx.rs.s);
2583         pvresult->setf(msg, &pvresult->pvp, (int)EQ_T, &valx);
2584         return 1;
2585 }
2586 /*!
2587 * @function nh_alias_to_uri
2588 * @abstract select alias paramter from contact_header
2589 *                                       then writes to alias_uri
2590 * @param contact_header  Source contact header
2591 * @param alias_uri Destination string
2592 * @result 1 successful  , -1 fail
2593 */
2594 static int nh_alias_to_uri(str *contact_header, str *alias_uri)
2595 {
2596         int i=0; // index
2597         str host={0,0};
2598         str port={0,0};
2599         str proto={0,0};
2600         char *memchr_pointer=0;
2601
2602         if(!contact_header)
2603                 return -1;
2604
2605         LM_DBG("Contact header [%.*s] \r\n",contact_header->len,contact_header->s);
2606
2607         for(i=0; i<contact_header->len  ;i++){
2608                 if(strncmp(&contact_header->s[i], SALIAS, SALIAS_LEN) == 0){
2609                         i=i+SALIAS_LEN;
2610                         host.s = &contact_header->s[i];
2611                         memchr_pointer = memchr(host.s , 126 /* ~ */,contact_header->len-i);
2612                                 if(memchr_pointer == NULL) {
2613                                         LM_ERR("No alias parameter found for host\n");
2614                                         return -1;
2615                                 } else {
2616                                         host.len = memchr_pointer - &contact_header->s[i];
2617                                         i=i+host.len;
2618                                 }
2619                         break;
2620                         }
2621         }
2622
2623         if(!memchr_pointer){
2624                 LM_ERR("Alias couldn't be found \n");
2625                 return -1;
2626         }
2627         if(&memchr_pointer[1]){
2628                 port.s=&memchr_pointer[1];
2629         }else{
2630                 LM_ERR("Alias sign couldn't be found for port \n");
2631                 return -1;
2632         }
2633
2634         memchr_pointer = memchr(port.s , 126 /* ~ */,contact_header->len-i);
2635         if(memchr_pointer == NULL) {
2636                 LM_ERR("Alias sign couldn't be found for proto \n");
2637                 return -1;
2638         } else {
2639                 port.len = memchr_pointer - port.s;
2640                 i=i+port.len;
2641         }
2642         //last char is proto 0,1,2,3,4..7
2643         proto.s= &port.s[port.len+1];
2644         proto_type_to_str((unsigned short)atoi(proto.s), &proto);
2645
2646         LM_DBG("Host [%.*s][port: %.*s][proto: %.*s] \r\n",host.len,host.s,port.len,port.s,proto.len,proto.s);
2647
2648         //sip:host:port;transport=udp
2649         alias_uri->s =(char *) pkg_malloc(port.len+host.len+proto.len+16);
2650         if(!alias_uri->s){
2651                 LM_ERR("Allocation ERROR\n");
2652                 return -1;
2653         }
2654
2655         memset(alias_uri->s,0,16+port.len+host.len);
2656
2657         memcpy(alias_uri->s,"sip:",4);
2658         memcpy(&alias_uri->s[4],host.s,host.len);
2659
2660         memcpy(&alias_uri->s[4+host.len],":",1);
2661         memcpy(&alias_uri->s[4+host.len+1],port.s,port.len);
2662         memcpy(&alias_uri->s[4+host.len+1+port.len],";transport=",11);
2663         memcpy(&alias_uri->s[4+host.len+1+port.len+11],proto.s,proto.len);
2664
2665         alias_uri->len=port.len+host.len+16+proto.len;
2666         LM_DBG("Alias uri [%.*s][len: %d] \r\n",alias_uri->len,alias_uri->s,alias_uri->len);
2667
2668         return 1;
2669 }
2670
2671 /**
2672  *
2673  */
2674 /* clang-format off */
2675 static sr_kemi_t sr_kemi_nathelper_exports[] = {
2676         { str_init("nathelper"), str_init("nat_uac_test"),
2677                 SR_KEMIP_INT, nat_uac_test,
2678                 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
2679                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2680         },
2681         { str_init("nathelper"), str_init("fix_nated_contact"),
2682                 SR_KEMIP_INT, fix_nated_contact,
2683                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2684                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2685         },
2686         { str_init("nathelper"), str_init("fix_nated_register"),
2687                 SR_KEMIP_INT, fix_nated_register,
2688                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2689                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2690         },
2691         { str_init("nathelper"), str_init("set_contact_alias"),
2692                 SR_KEMIP_INT, set_contact_alias,
2693                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2694                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2695         },
2696         { str_init("nathelper"), str_init("handle_ruri_alias"),
2697                 SR_KEMIP_INT, handle_ruri_alias,
2698                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2699                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2700         },
2701         { str_init("nathelper"), str_init("is_rfc1918"),
2702                 SR_KEMIP_INT, is_rfc1918,
2703                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2704                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2705         },
2706         { str_init("nathelper"), str_init("add_contact_alias"),
2707                 SR_KEMIP_INT, add_contact_alias_0,
2708                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
2709                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2710         },
2711         { str_init("nathelper"), str_init("add_contact_alias_addr"),
2712                 SR_KEMIP_INT, add_contact_alias_3,
2713                 { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
2714                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2715         },
2716         { str_init("nathelper"), str_init("add_rcv_param"),
2717                 SR_KEMIP_INT, ki_add_rcv_param,
2718                 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
2719                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2720         },
2721         { str_init("nathelper"), str_init("fix_nated_sdp"),
2722                 SR_KEMIP_INT, ki_fix_nated_sdp,
2723                 { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
2724                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2725         },
2726         { str_init("nathelper"), str_init("fix_nated_sdp_ip"),
2727                 SR_KEMIP_INT, ki_fix_nated_sdp_ip,
2728                 { SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
2729                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2730         },
2731         { str_init("nathelper"), str_init("set_alias_to_pv"),
2732                 SR_KEMIP_INT, ki_set_alias_to_pv,
2733                 { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
2734                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2735         },
2736
2737         { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
2738 };
2739 /* clang-format on */
2740
2741 /**
2742  *
2743  */
2744 int mod_register(char *path, int *dlflags, void *p1, void *p2)
2745 {
2746         sr_kemi_modules_add(sr_kemi_nathelper_exports);
2747         return 0;
2748 }