permissions: use perm prefix for global param variables
[sip-router] / src / modules / permissions / address.c
1 /*
2  * allow_address related functions
3  *
4  * Copyright (C) 2006 Juha Heinanen
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include <sys/types.h>
25 #include <regex.h>
26 #include <string.h>
27 #include <arpa/inet.h>
28
29 #include "permissions.h"
30 #include "hash.h"
31 #include "../../core/config.h"
32 #include "../../lib/srdb1/db.h"
33 #include "../../core/ip_addr.h"
34 #include "../../core/resolve.h"
35 #include "../../core/mem/shm_mem.h"
36 #include "../../core/parser/msg_parser.h"
37 #include "../../core/parser/parse_from.h"
38 #include "../../core/usr_avp.h"
39 #include "../../core/mod_fix.h"
40 #include "../../core/ut.h"
41 #include "../../core/resolve.h"
42
43 #define TABLE_VERSION 6
44
45 struct addr_list ***perm_addr_table = NULL; /* Ptr to current address hash table ptr */
46 struct addr_list **perm_addr_table_1 = NULL; /* Pointer to address hash table 1 */
47 struct addr_list **perm_addr_table_2 = NULL; /* Pointer to address hash table 2 */
48
49 struct subnet **perm_subnet_table = NULL;  /* Ptr to current subnet table */
50 struct subnet *perm_subnet_table_1 = NULL; /* Ptr to subnet table 1 */
51 struct subnet *perm_subnet_table_2 = NULL; /* Ptr to subnet table 2 */
52
53 struct domain_name_list ***perm_domain_table = NULL; /* Ptr to current domain name table */
54 static struct domain_name_list **perm_domain_table_1 = NULL; /* Ptr to domain name table 1 */
55 static struct domain_name_list **perm_domain_table_2 = NULL; /* Ptr to domain name table 2 */
56
57 static db1_con_t* perm_db_handle = 0;
58 static db_func_t perm_dbf;
59
60 extern str perm_address_file;
61
62 typedef struct address_tables_group {
63         struct addr_list **address_table;
64         struct subnet *subnet_table;
65         struct domain_name_list **domain_table;
66
67 } address_tables_group_t;
68
69 static inline ip_addr_t *strtoipX(str *ips)
70 {
71         /* try to figure out INET class */
72         if(ips->s[0] == '[' || memchr(ips->s, ':', ips->len)!=NULL)
73         {
74                 /* IPv6 */
75                 return str2ip6(ips);
76         } else {
77                 /* IPv4 */
78                 return str2ip(ips);
79         }
80 }
81
82 int reload_address_insert(address_tables_group_t *atg, unsigned int gid,
83                 str *ips, unsigned int mask, unsigned int port, str *tagv)
84 {
85         ip_addr_t *ipa;
86
87         ipa = strtoipX(ips);
88         if (ipa==NULL) {
89                 LM_DBG("Domain name: %.*s\n", ips->len, ips->s);
90                 /* return -1; */
91         } else {
92                 if(ipa->af == AF_INET6) {
93                         if((int)mask<0 || mask>128) {
94                                 LM_DBG("failure during IP mask check for v6\n");
95                                 return -1;
96                         }
97                         if(mask == 0) {
98                                 mask = 128;
99                         }
100                 } else {
101                         if((int)mask<0 || mask>32) {
102                                 LM_DBG("failure during IP mask check for v4\n");
103                                 return -1;
104                         }
105                         if(mask == 0) {
106                                 mask = 32;
107                         }
108                 }
109         }
110
111         if (ipa!=NULL) {
112                 if ( (ipa->af==AF_INET6 && mask==128) || (ipa->af==AF_INET && mask==32) ) {
113                         if (addr_hash_table_insert(atg->address_table, gid, ipa, port, tagv)
114                                         == -1) {
115                                 LM_ERR("hash table problem\n");
116                                 return -1;
117                         }
118                         LM_DBG("Tuple <%u, %.*s, %u> inserted into address hash table\n",
119                                         gid, ips->len, ips->s, port);
120                 } else {
121                         if (subnet_table_insert(atg->subnet_table, gid, ipa, mask,
122                                                 port, tagv)
123                                         == -1) {
124                                 LM_ERR("subnet table problem\n");
125                                 return -1;
126                         }
127                         LM_DBG("Tuple <%u, %.*s, %u, %u> inserted into subnet table\n",
128                                         gid, ips->len, ips->s, port, mask);
129                 }
130         } else {
131                 if (domain_name_table_insert(atg->domain_table, gid, ips,
132                                         port, tagv)
133                                 == -1) {
134                         LM_ERR("domain name table problem\n");
135                         return -1;
136                 }
137                 LM_DBG("Tuple <%u, %.*s, %u> inserted into domain name table\n",
138                                 gid, ips->len, ips->s, port);
139         }
140         return 0;
141 }
142
143 /*
144  * Reload addr table from database to new hash table and when done, make new hash table
145  * current one.
146  */
147 int reload_address_db_table(address_tables_group_t *atg)
148 {
149         db_key_t cols[5];
150         db1_res_t* res = NULL;
151         db_row_t* row;
152         db_val_t* val;
153
154         int i;
155         unsigned int gid;
156         unsigned int port;
157         unsigned int mask;
158         str ips;
159         str tagv;
160
161         cols[0] = &perm_grp_col;
162         cols[1] = &perm_ip_addr_col;
163         cols[2] = &perm_mask_col;
164         cols[3] = &perm_port_col;
165         cols[4] = &perm_tag_col;
166
167         if (perm_dbf.use_table(perm_db_handle, &perm_address_table) < 0) {
168                 LM_ERR("failed to use table\n");
169                 return -1;
170         }
171
172         if (perm_dbf.query(perm_db_handle, NULL, 0, NULL, cols, 0, 5, 0, &res) < 0) {
173                 LM_ERR("failed to query database\n");
174                 return -1;
175         }
176
177         row = RES_ROWS(res);
178
179         LM_DBG("Number of rows in address table: %d\n", RES_ROW_N(res));
180
181         for (i = 0; i < RES_ROW_N(res); i++) {
182                 val = ROW_VALUES(row + i);
183                 /* basic checks to db values */
184                 if (ROW_N(row + i) != 5)
185                 {
186                         LM_DBG("failure during checks of db address table: Columns %d - expected 5\n", ROW_N(row + i));
187                         goto dberror;
188                 }
189                 if ((VAL_TYPE(val) != DB1_INT) || VAL_NULL(val) || (VAL_INT(val) <= 0))
190                 {
191                         LM_DBG("failure during checks of database value 1 (group) in address table\n");
192                         goto dberror;
193                 }
194                 if ((VAL_TYPE(val + 1) != DB1_STRING) && (VAL_TYPE(val + 1) != DB1_STR))
195                 {
196                         LM_DBG("failure during checks of database value 2 (IP address) in address table - not a string value\n");
197                         goto dberror;
198                 }
199                 if (VAL_NULL(val + 1))
200                 {
201                         LM_DBG("failure during checks of database value 2 (IP address) in address table - NULL value not permitted\n");
202                         goto dberror;
203                 }
204                 if ((VAL_TYPE(val + 2) != DB1_INT) || VAL_NULL(val + 2))
205                 {
206                         LM_DBG("failure during checks of database value 3 (subnet size/CIDR) in address table\n");
207                         goto dberror;
208                 }
209                 if ((VAL_TYPE(val + 3) != DB1_INT) || VAL_NULL(val + 3))
210                 {
211                         LM_DBG("failure during checks of database value 4 (port) in address table\n");
212                         goto dberror;
213                 }
214                 gid = VAL_UINT(val);
215                 ips.s = (char *)VAL_STRING(val + 1);
216                 ips.len = strlen(ips.s);
217                 mask = VAL_UINT(val + 2);
218                 port = VAL_UINT(val + 3);
219                 tagv.s = VAL_NULL(val + 4)?NULL:(char *)VAL_STRING(val + 4);
220                 if(tagv.s!=NULL) {
221                         tagv.len = strlen(tagv.s);
222                 }
223                 if(reload_address_insert(atg, gid, &ips, mask, port, &tagv)<0) {
224                         goto dberror;
225                 }
226         }
227
228         perm_dbf.free_result(perm_db_handle, res);
229
230         return 1;
231
232 dberror:
233         LM_ERR("database problem - invalid record\n");
234         perm_dbf.free_result(perm_db_handle, res);
235         return -1;
236 }
237
238 /**
239  * macros for parsing address file
240  */
241 #define PERM_FADDR_SKIPWS(p) do { \
242                 while(*p && (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')) { \
243                         p++; \
244                 } \
245         } while(0)
246
247 #define PERM_FADDR_PARSESTR(p, vstr) do { \
248                 vstr.s = p; \
249                 while(*p && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n' \
250                                 && *p != '#') { \
251                         p++; \
252                 } \
253                 vstr.len = p - vstr.s; \
254         } while(0)
255
256 #define PERM_FADDR_PARSENUM(p, vnum) do { \
257                 vnum = 0; \
258                 while(*p >= '0' && *p <= '9') { \
259                         vnum = vnum * 10 + (*p - '0'); \
260                         p++; \
261                 } \
262         } while(0)
263
264 /* end-of-data jump at start of comment or end-of-line */
265 #define PERM_FADDR_EODJUMP(p, jumplabel) do { \
266                 if(*p == '\0' || *p == '#') { \
267                         goto jumplabel; \
268                 } \
269         } while(0)
270
271 /*
272  * Reload addr table from file to new hash table and when done, make new hash table
273  * current one.
274  */
275 int reload_address_file_table(address_tables_group_t *atg)
276 {
277         char line[1024], *p;
278         FILE *f = NULL;
279         int i = 0;
280         int n = 0;
281         unsigned int gid;
282         unsigned int mask;
283         unsigned int port;
284         str ips;
285         str tagv;
286
287         f = fopen(perm_address_file.s, "r");
288         if(f == NULL) {
289                 LM_ERR("can't open list file [%s]\n", perm_address_file.s);
290                 return -1;
291         }
292
293         p = fgets(line, 1024, f);
294         while(p) {
295                 i++;
296                 gid = 0;
297                 ips.s = NULL;
298                 ips.len = 0;
299                 mask = 0;
300                 port = 0;
301                 tagv.s = NULL;
302                 tagv.len = 0;
303
304                 /* comment line */
305                 PERM_FADDR_SKIPWS(p);
306                 PERM_FADDR_EODJUMP(p, next_line);
307
308                 /* group id */
309                 PERM_FADDR_PARSENUM(p, gid);
310
311                 PERM_FADDR_SKIPWS(p);
312                 PERM_FADDR_EODJUMP(p, error);
313
314                 /* address - ip/domain */
315                 PERM_FADDR_PARSESTR(p, ips);
316
317                 PERM_FADDR_SKIPWS(p);
318                 PERM_FADDR_EODJUMP(p, add_record);
319
320                 /* mask */
321                 PERM_FADDR_PARSENUM(p, mask);
322
323                 PERM_FADDR_SKIPWS(p);
324                 PERM_FADDR_EODJUMP(p, add_record);
325
326                 /* port */
327                 PERM_FADDR_PARSENUM(p, port);
328
329                 PERM_FADDR_SKIPWS(p);
330                 PERM_FADDR_EODJUMP(p, add_record);
331
332                 /* tag */
333                 PERM_FADDR_PARSESTR(p, tagv);
334
335 add_record:
336                 if(reload_address_insert(atg, gid, &ips, mask, port, &tagv)<0) {
337                         goto error;
338                 }
339                 n++;
340
341 next_line:
342                 p = fgets(line, 1024, f);
343         }
344
345         LM_DBG("processed file: %s (%d lines)- added %d records\n",
346                         perm_address_file.s, i, n);
347
348         fclose(f);
349         return 1;
350
351 error:
352         if(f != NULL) {
353                 fclose(f);
354         }
355         return -1;
356
357 }
358
359 /*
360  * Reload addr table to new hash table and when done, make new hash table
361  * current one.
362  */
363 int reload_address_table(void)
364 {
365         int ret = 0;
366         address_tables_group_t atg;
367
368         /* Choose new hash table and free its old contents */
369         if (*perm_addr_table == perm_addr_table_1) {
370                 empty_addr_hash_table(perm_addr_table_2);
371                 atg.address_table = perm_addr_table_2;
372         } else {
373                 empty_addr_hash_table(perm_addr_table_1);
374                 atg.address_table = perm_addr_table_1;
375         }
376
377         /* Choose new subnet table */
378         if (*perm_subnet_table == perm_subnet_table_1) {
379                 empty_subnet_table(perm_subnet_table_2);
380                 atg.subnet_table = perm_subnet_table_2;
381         } else {
382                 empty_subnet_table(perm_subnet_table_1);
383                 atg.subnet_table = perm_subnet_table_1;
384         }
385
386         /* Choose new domain name table */
387         if (*perm_domain_table == perm_domain_table_1) {
388                 empty_domain_name_table(perm_domain_table_2);
389                 atg.domain_table = perm_domain_table_2;
390         } else {
391                 empty_domain_name_table(perm_domain_table_1);
392                 atg.domain_table = perm_domain_table_1;
393         }
394
395         if(perm_address_file.s==NULL) {
396                 ret = reload_address_db_table(&atg);
397         } else {
398                 ret = reload_address_file_table(&atg);
399         }
400         if(ret!=1) {
401                 return ret;
402         }
403
404         *perm_addr_table = atg.address_table;
405         *perm_subnet_table = atg.subnet_table;
406         *perm_domain_table = atg.domain_table;
407
408         LM_DBG("address table reloaded successfully.\n");
409
410
411         return ret;
412 }
413
414 /*
415  * Wrapper to reload addr table from mi or rpc
416  * we need to open the db_handle
417  */
418 int reload_address_table_cmd(void)
419 {
420         if(perm_address_file.s==NULL) {
421                 if(!perm_db_url.s) {
422                         LM_ERR("db_url not set\n");
423                         return -1;
424                 }
425
426                 if (!perm_db_handle) {
427                         perm_db_handle = perm_dbf.init(&perm_db_url);
428                         if (!perm_db_handle) {
429                                 LM_ERR("unable to connect database\n");
430                                 return -1;
431                         }
432                 }
433         }
434
435         if (reload_address_table () != 1) {
436                 if(perm_address_file.s==NULL) {
437                         perm_dbf.close(perm_db_handle);
438                         perm_db_handle = 0;
439                 }
440                 return -1;
441         }
442
443         if(perm_address_file.s==NULL) {
444                 perm_dbf.close(perm_db_handle);
445                 perm_db_handle = 0;
446         }
447
448         return 1;
449 }
450
451 /*
452  * Initialize data structures
453  */
454 int init_addresses(void)
455 {
456         perm_addr_table_1 = perm_addr_table_2 = 0;
457         perm_addr_table = 0;
458
459         if(perm_address_file.s==NULL) {
460                 if (!perm_db_url.s) {
461                         LM_INFO("db_url parameter of permissions module not set, "
462                                         "disabling allow_address\n");
463                         return 0;
464                 } else {
465                         if (db_bind_mod(&perm_db_url, &perm_dbf) < 0) {
466                                 LM_ERR("load a database support module\n");
467                                 return -1;
468                         }
469
470                         if (!DB_CAPABILITY(perm_dbf, DB_CAP_QUERY)) {
471                                 LM_ERR("database module does not implement 'query' function\n");
472                                 return -1;
473                         }
474                 }
475
476                 perm_db_handle = perm_dbf.init(&perm_db_url);
477                 if (!perm_db_handle) {
478                         LM_ERR("unable to connect database\n");
479                         return -1;
480                 }
481
482                 if(db_check_table_version(&perm_dbf, perm_db_handle, &perm_address_table,
483                                         TABLE_VERSION) < 0) {
484                         DB_TABLE_VERSION_ERROR(perm_address_table);
485                         perm_dbf.close(perm_db_handle);
486                         perm_db_handle = 0;
487                         return -1;
488                 }
489         }
490
491         perm_addr_table_1 = new_addr_hash_table();
492         if (!perm_addr_table_1) return -1;
493
494         perm_addr_table_2  = new_addr_hash_table();
495         if (!perm_addr_table_2) goto error;
496
497         perm_addr_table = (struct addr_list ***)shm_malloc
498                 (sizeof(struct addr_list **));
499         if (!perm_addr_table) {
500                 LM_ERR("no more shm memory for addr_hash_table\n");
501                 goto error;
502         }
503
504         *perm_addr_table = perm_addr_table_1;
505
506         perm_subnet_table_1 = new_subnet_table();
507         if (!perm_subnet_table_1) goto error;
508
509         perm_subnet_table_2 = new_subnet_table();
510         if (!perm_subnet_table_2) goto error;
511
512         perm_subnet_table = (struct subnet **)shm_malloc(sizeof(struct subnet *));
513         if (!perm_subnet_table) {
514                 LM_ERR("no more shm memory for subnet_table\n");
515                 goto error;
516         }
517
518         *perm_subnet_table = perm_subnet_table_1;
519
520         perm_domain_table_1 = new_domain_name_table();
521         if (!perm_domain_table_1) goto error;
522
523         perm_domain_table_2 = new_domain_name_table();
524         if (!perm_domain_table_2) goto error;
525
526         perm_domain_table = (struct domain_name_list ***)shm_malloc(sizeof(struct domain_name_list **));
527         if (!perm_domain_table) {
528                 LM_ERR("no more shm memory for domain name table\n");
529                 goto error;
530         }
531
532         *perm_domain_table = perm_domain_table_1;
533
534
535         if (reload_address_table() == -1) {
536                 LM_CRIT("reload of address table failed\n");
537                 goto error;
538         }
539
540         if(perm_address_file.s==NULL) {
541                 perm_dbf.close(perm_db_handle);
542                 perm_db_handle = 0;
543         }
544
545         return 0;
546
547 error:
548         if (perm_addr_table_1) {
549                 free_addr_hash_table(perm_addr_table_1);
550                 perm_addr_table_1 = 0;
551         }
552         if (perm_addr_table_2) {
553                 free_addr_hash_table(perm_addr_table_2);
554                 perm_addr_table_2 = 0;
555         }
556         if (perm_addr_table) {
557                 shm_free(perm_addr_table);
558                 perm_addr_table = 0;
559         }
560         if (perm_subnet_table_1) {
561                 free_subnet_table(perm_subnet_table_1);
562                 perm_subnet_table_1 = 0;
563         }
564         if (perm_subnet_table_2) {
565                 free_subnet_table(perm_subnet_table_2);
566                 perm_subnet_table_2 = 0;
567         }
568         if (perm_subnet_table) {
569                 shm_free(perm_subnet_table);
570                 perm_subnet_table = 0;
571         }
572
573         if (perm_domain_table_1) {
574                 free_domain_name_table(perm_domain_table_1);
575                 perm_domain_table_1 = 0;
576         }
577         if (perm_domain_table_2) {
578                 free_domain_name_table(perm_domain_table_2);
579                 perm_domain_table_2 = 0;
580         }
581         if (perm_domain_table) {
582                 shm_free(perm_domain_table);
583                 perm_domain_table = 0;
584         }
585
586         if(perm_address_file.s==NULL) {
587                 perm_dbf.close(perm_db_handle);
588                 perm_db_handle = 0;
589         }
590         return -1;
591 }
592
593
594 /*
595  * Close connections and release memory
596  */
597 void clean_addresses(void)
598 {
599         if (perm_addr_table_1) free_addr_hash_table(perm_addr_table_1);
600         if (perm_addr_table_2) free_addr_hash_table(perm_addr_table_2);
601         if (perm_addr_table) shm_free(perm_addr_table);
602         if (perm_subnet_table_1) free_subnet_table(perm_subnet_table_1);
603         if (perm_subnet_table_2) free_subnet_table(perm_subnet_table_2);
604         if (perm_subnet_table) shm_free(perm_subnet_table);
605         if (perm_domain_table_1) free_domain_name_table(perm_domain_table_1);
606         if (perm_domain_table_2) free_domain_name_table(perm_domain_table_2);
607         if (perm_domain_table) shm_free(perm_domain_table);
608 }
609
610
611 int allow_address(sip_msg_t *_msg, int addr_group, str *ips, int port)
612 {
613         struct ip_addr *ipa;
614
615         ipa=strtoipX(ips);
616
617         if ( ipa ) {
618                 if (perm_addr_table
619                                 && match_addr_hash_table(*perm_addr_table, addr_group,
620                                         ipa, (unsigned int)port) == 1) {
621                         return 1;
622                 } else {
623                         if(perm_subnet_table) {
624                                 return match_subnet_table(*perm_subnet_table, addr_group, ipa,
625                                                 (unsigned int)port);
626                         }
627                 }
628         } else {
629                 if(perm_domain_table) {
630                         return match_domain_name_table(*perm_domain_table, addr_group, ips,
631                                         (unsigned int)port);
632                 }
633         }
634         return -1;
635 }
636
637 /*
638  * Checks if an entry exists in cached address table that belongs to a
639  * given address group and has given ip address and port.  Port value
640  * 0 in cached address table matches any port.
641  */
642 int w_allow_address(struct sip_msg* _msg, char* _addr_group, char* _addr_sp,
643                 char* _port_sp)
644 {
645         int port;
646         int addr_group;
647         str ips;
648
649         if(fixup_get_ivalue(_msg, (gparam_p)_addr_group, &addr_group) !=0 ) {
650                 LM_ERR("cannot get group value\n");
651                 return -1;
652         }
653
654         if (_addr_sp==NULL
655                         || (fixup_get_svalue(_msg, (gparam_p)_addr_sp, &ips) < 0)) {
656                 LM_ERR("cannot get value of address pvar\n");
657                 return -1;
658         }
659
660         if (_port_sp==NULL
661                         || (fixup_get_ivalue(_msg, (gparam_p)_port_sp, &port) < 0)) {
662                 LM_ERR("cannot get value of port pvar\n");
663                 return -1;
664         }
665
666         return allow_address(_msg, addr_group, &ips, port);
667 }
668
669 int allow_source_address(sip_msg_t *_msg, int addr_group)
670 {
671         LM_DBG("looking for <%u, %x, %u>\n",
672                         addr_group, _msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
673
674         if (perm_addr_table && match_addr_hash_table(*perm_addr_table, addr_group,
675                                 &_msg->rcv.src_ip, _msg->rcv.src_port) == 1) {
676                 return 1;
677         } else {
678                 if(perm_subnet_table) {
679                         return match_subnet_table(*perm_subnet_table, addr_group,
680                                         &_msg->rcv.src_ip,
681                                         _msg->rcv.src_port);
682                 }
683         }
684         return -1;
685 }
686
687 /*
688  * w_allow_source_address("group") equals to allow_address("group", "$si", "$sp")
689  * but is faster.
690  */
691 int w_allow_source_address(struct sip_msg* _msg, char* _addr_group, char* _str2)
692 {
693         int addr_group = 1;
694
695         if(_addr_group!=NULL
696                         && fixup_get_ivalue(_msg, (gparam_p)_addr_group, &addr_group) !=0 ) {
697                 LM_ERR("cannot get group value\n");
698                 return -1;
699         }
700         return allow_source_address(_msg, addr_group);
701 }
702
703
704 /*
705  * Checks if source address/port is found in cached address or
706  * subnet table in any group. If yes, returns that group. If not returns -1.
707  * Port value 0 in cached address and group table matches any port.
708  */
709 int ki_allow_source_address_group(sip_msg_t* _msg)
710 {
711         int group = -1;
712
713         LM_DBG("looking for <%x, %u> in address table\n",
714                         _msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
715         if(perm_addr_table) {
716                 group = find_group_in_addr_hash_table(*perm_addr_table,
717                                 &_msg->rcv.src_ip, _msg->rcv.src_port);
718                 LM_DBG("Found <%d>\n", group);
719
720                 if (group != -1) return group;
721         }
722
723         LM_DBG("looking for <%x, %u> in subnet table\n",
724                         _msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
725         if(perm_subnet_table) {
726                 group = find_group_in_subnet_table(*perm_subnet_table,
727                                 &_msg->rcv.src_ip, _msg->rcv.src_port);
728         }
729         LM_DBG("Found <%d>\n", group);
730         return group;
731
732 }
733
734 /*
735  * Checks if source address/port is found in cached address or
736  * subnet table in any group. If yes, returns that group. If not returns -1.
737  * Port value 0 in cached address and group table matches any port.
738  */
739 int allow_source_address_group(struct sip_msg* _msg, char* _str1, char* _str2)
740 {
741         return ki_allow_source_address_group(_msg);
742 }
743
744 /*
745  * Checks if address/port is found in cached address or
746  * subnet table in any group. If yes, returns that group. If not returns -1.
747  * Port value 0 in cached address and group table matches any port.
748  */
749 int ki_allow_address_group(sip_msg_t* _msg, str* _addr, int _port)
750 {
751         int group = -1;
752
753         ip_addr_t *ipa;
754
755         ipa=strtoipX(_addr);
756
757         if ( ipa ) {
758                 LM_DBG("looking for <%.*s, %u> in address table\n",
759                                 _addr->len, _addr->s, (unsigned int)_port);
760                 if(perm_addr_table) {
761                         group = find_group_in_addr_hash_table(*perm_addr_table,
762                                         ipa, (unsigned int)_port);
763                         LM_DBG("Found address in group <%d>\n", group);
764
765                         if (group != -1) return group;
766                 }
767                 if(perm_subnet_table) {
768                         LM_DBG("looking for <%.*s, %u> in subnet table\n",
769                                         _addr->len, _addr->s, _port);
770                         group = find_group_in_subnet_table(*perm_subnet_table,
771                                         ipa, (unsigned int)_port);
772                         LM_DBG("Found a match of subnet in group <%d>\n", group);
773                 }
774         } else {
775                 LM_DBG("looking for <%.*s, %u> in domain_name table\n",
776                                 _addr->len, _addr->s, (unsigned int)_port);
777                 if(perm_domain_table) {
778                         group = find_group_in_domain_name_table(*perm_domain_table,
779                                         _addr, (unsigned int)_port);
780                         LM_DBG("Found a match of domain_name in group <%d>\n", group);
781                 }
782         }
783
784         LM_DBG("Found <%d>\n", group);
785         return group;
786 }
787
788 int allow_address_group(struct sip_msg* _msg, char* _addr, char* _port)
789 {
790         int port;
791         str ips;
792
793         if (_addr==NULL
794                         || (fixup_get_svalue(_msg, (gparam_p)_addr, &ips) < 0)) {
795                 LM_ERR("cannot get value of address pvar\n");
796                 return -1;
797         }
798         if (_port==NULL
799                         || (fixup_get_ivalue(_msg, (gparam_p)_port, &port) < 0)) {
800                 LM_ERR("cannot get value of port pvar\n");
801                 return -1;
802         }
803
804         return ki_allow_address_group(_msg, &ips, port);
805 }