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 
strtoipX(str * ips)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 
reload_address_insert(address_tables_group_t * atg,unsigned int gid,str * ips,unsigned int mask,unsigned int port,str * tagv)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  */
reload_address_db_table(address_tables_group_t * atg)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  */
reload_address_file_table(address_tables_group_t * atg)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  */
reload_address_table(void)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  */
reload_address_table_cmd(void)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  */
init_addresses(void)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  */
clean_addresses(void)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 
allow_address(sip_msg_t * _msg,int addr_group,str * ips,int port)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  */
w_allow_address(struct sip_msg * _msg,char * _addr_group,char * _addr_sp,char * _port_sp)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 
allow_source_address(sip_msg_t * _msg,int addr_group)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  */
w_allow_source_address(struct sip_msg * _msg,char * _addr_group,char * _str2)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  */
ki_allow_source_address_group(sip_msg_t * _msg)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  */
allow_source_address_group(struct sip_msg * _msg,char * _str1,char * _str2)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  */
ki_allow_address_group(sip_msg_t * _msg,str * _addr,int _port)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 
allow_address_group(struct sip_msg * _msg,char * _addr,char * _port)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 }
806