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