00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <sys/types.h>
00024 #include <regex.h>
00025 #include "../../mem/shm_mem.h"
00026 #include "../../parser/parse_from.h"
00027 #include "../../ut.h"
00028 #include "../../hash_func.h"
00029 #include "../../usr_avp.h"
00030 #include "../../ip_addr.h"
00031 #include "../../pvar.h"
00032 #include "hash.h"
00033 #include "trusted.h"
00034 #include "address.h"
00035
00036 #define perm_hash(_s) core_hash( &(_s), 0, PERM_HASH_SIZE)
00037
00038
00039
00040 static int tag_avp_type;
00041 static int_str tag_avp;
00042
00043
00044
00045
00046
00047 int init_tag_avp(str *tag_avp_param)
00048 {
00049 pv_spec_t avp_spec;
00050 unsigned short avp_flags;
00051
00052 if (tag_avp_param->s && tag_avp_param->len > 0) {
00053 if (pv_parse_spec(tag_avp_param, &avp_spec)==0
00054 || avp_spec.type != PVT_AVP) {
00055 LM_ERR("malformed or non "
00056 "AVP %.*s peer_tag_avp definition\n", tag_avp_param->len, tag_avp_param->s);
00057 return -1;
00058 }
00059 if(pv_get_avp_name(0, &avp_spec.pvp, &tag_avp, &avp_flags)!=0) {
00060 LM_ERR("[%.*s]- invalid "
00061 "peer_tag_avp AVP definition\n", tag_avp_param->len, tag_avp_param->s);
00062 return -1;
00063 }
00064 tag_avp_type = avp_flags;
00065 } else {
00066 tag_avp.n = 0;
00067 }
00068 return 0;
00069 }
00070
00071
00072
00073
00074
00075 void get_tag_avp(int_str *tag_avp_p, int *tag_avp_type_p)
00076 {
00077 *tag_avp_p = tag_avp;
00078 *tag_avp_type_p = tag_avp_type;
00079 }
00080
00081
00082
00083
00084
00085 struct trusted_list** new_hash_table(void)
00086 {
00087 struct trusted_list** ptr;
00088
00089
00090 ptr = (struct trusted_list **)shm_malloc
00091 (sizeof(struct trusted_list*) * PERM_HASH_SIZE);
00092 if (!ptr) {
00093 LM_ERR("no shm memory for hash table\n");
00094 return 0;
00095 }
00096
00097 memset(ptr, 0, sizeof(struct trusted_list*) * PERM_HASH_SIZE);
00098 return ptr;
00099 }
00100
00101
00102
00103
00104
00105 void free_hash_table(struct trusted_list** table)
00106 {
00107 if (!table)
00108 return;
00109
00110 empty_hash_table(table);
00111 shm_free(table);
00112 }
00113
00114
00115
00116
00117
00118
00119 int hash_table_insert(struct trusted_list** table, char* src_ip,
00120 char* proto, char* pattern, char* tag)
00121 {
00122 struct trusted_list *np;
00123 unsigned int hash_val;
00124
00125 np = (struct trusted_list *) shm_malloc(sizeof(*np));
00126 if (np == NULL) {
00127 LM_ERR("cannot allocate shm memory for table entry\n");
00128 return -1;
00129 }
00130
00131 if (strcasecmp(proto, "any") == 0) {
00132 np->proto = PROTO_NONE;
00133 } else if (strcasecmp(proto, "udp") == 0) {
00134 np->proto = PROTO_UDP;
00135 } else if (strcasecmp(proto, "tcp") == 0) {
00136 np->proto = PROTO_TCP;
00137 } else if (strcasecmp(proto, "tls") == 0) {
00138 np->proto = PROTO_TLS;
00139 } else if (strcasecmp(proto, "sctp") == 0) {
00140 np->proto = PROTO_SCTP;
00141 } else if (strcasecmp(proto, "none") == 0) {
00142 shm_free(np);
00143 return 1;
00144 } else {
00145 LM_CRIT("unknown protocol\n");
00146 shm_free(np);
00147 return -1;
00148 }
00149
00150 np->src_ip.len = strlen(src_ip);
00151 np->src_ip.s = (char *) shm_malloc(np->src_ip.len);
00152
00153 if (np->src_ip.s == NULL) {
00154 LM_CRIT("cannot allocate shm memory for src_ip string\n");
00155 shm_free(np);
00156 return -1;
00157 }
00158
00159 (void) strncpy(np->src_ip.s, src_ip, np->src_ip.len);
00160
00161 if (pattern) {
00162 np->pattern = (char *) shm_malloc(strlen(pattern)+1);
00163 if (np->pattern == NULL) {
00164 LM_CRIT("cannot allocate shm memory for pattern string\n");
00165 shm_free(np->src_ip.s);
00166 shm_free(np);
00167 return -1;
00168 }
00169 (void) strcpy(np->pattern, pattern);
00170 } else {
00171 np->pattern = 0;
00172 }
00173
00174 if (tag) {
00175 np->tag.len = strlen(tag);
00176 np->tag.s = (char *) shm_malloc((np->tag.len) + 1);
00177 if (np->tag.s == NULL) {
00178 LM_CRIT("cannot allocate shm memory for pattern string\n");
00179 shm_free(np->src_ip.s);
00180 shm_free(np->pattern);
00181 shm_free(np);
00182 return -1;
00183 }
00184 (void) strcpy(np->tag.s, tag);
00185 } else {
00186 np->tag.len = 0;
00187 np->tag.s = 0;
00188 }
00189
00190 hash_val = perm_hash(np->src_ip);
00191 np->next = table[hash_val];
00192 table[hash_val] = np;
00193
00194 return 1;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 int match_hash_table(struct trusted_list** table, struct sip_msg* msg,
00204 char *src_ip_c_str, int proto)
00205 {
00206 str uri;
00207 char uri_string[MAX_URI_SIZE + 1];
00208 regex_t preg;
00209 struct trusted_list *np;
00210 str src_ip;
00211 int_str val;
00212
00213 src_ip.s = src_ip_c_str;
00214 src_ip.len = strlen(src_ip.s);
00215
00216 if (parse_from_header(msg) < 0) return -1;
00217 uri = get_from(msg)->uri;
00218 if (uri.len > MAX_URI_SIZE) {
00219 LM_ERR("from URI too large\n");
00220 return -1;
00221 }
00222 memcpy(uri_string, uri.s, uri.len);
00223 uri_string[uri.len] = (char)0;
00224
00225 for (np = table[perm_hash(src_ip)]; np != NULL; np = np->next) {
00226 if ((np->src_ip.len == src_ip.len) &&
00227 (strncmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) &&
00228 ((np->proto == PROTO_NONE) || (np->proto == proto))) {
00229 if (!(np->pattern)) goto found;
00230 if (regcomp(&preg, np->pattern, REG_NOSUB)) {
00231 LM_ERR("invalid regular expression\n");
00232 return -1;
00233 }
00234 if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
00235 regfree(&preg);
00236 } else {
00237 regfree(&preg);
00238 goto found;
00239 }
00240 }
00241 }
00242 return -1;
00243 found:
00244 if (tag_avp.n && np->tag.s) {
00245 val.s = np->tag;
00246 if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) {
00247 LM_ERR("setting of tag_avp failed\n");
00248 return -1;
00249 }
00250 }
00251 return 1;
00252 }
00253
00254
00255
00256
00257
00258 int hash_table_mi_print(struct trusted_list** table, struct mi_node* rpl)
00259 {
00260 int i;
00261 struct trusted_list *np;
00262
00263 for (i = 0; i < PERM_HASH_SIZE; i++) {
00264 np = table[i];
00265 while (np) {
00266 if (addf_mi_node_child(rpl, 0, 0, 0,
00267 "%4d <%.*s, %d, %s, %s>",
00268 i,
00269 np->src_ip.len, ZSW(np->src_ip.s),
00270 np->proto,
00271 np->pattern?np->pattern:"NULL",
00272 np->tag.len?np->tag.s:"NULL") == 0) {
00273 return -1;
00274 }
00275 np = np->next;
00276 }
00277 }
00278 return 0;
00279 }
00280
00281
00282
00283
00284
00285
00286 void empty_hash_table(struct trusted_list **table)
00287 {
00288 int i;
00289 struct trusted_list *np, *next;
00290
00291 for (i = 0; i < PERM_HASH_SIZE; i++) {
00292 np = table[i];
00293 while (np) {
00294 if (np->src_ip.s) shm_free(np->src_ip.s);
00295 if (np->pattern) shm_free(np->pattern);
00296 if (np->tag.s) shm_free(np->tag.s);
00297 next = np->next;
00298 shm_free(np);
00299 np = next;
00300 }
00301 table[i] = 0;
00302 }
00303 }
00304
00305
00306
00307
00308
00309 struct addr_list** new_addr_hash_table(void)
00310 {
00311 struct addr_list** ptr;
00312
00313
00314 ptr = (struct addr_list **)shm_malloc
00315 (sizeof(struct addr_list*) * PERM_HASH_SIZE);
00316 if (!ptr) {
00317 LM_ERR("no shm memory for hash table\n");
00318 return 0;
00319 }
00320
00321 memset(ptr, 0, sizeof(struct addr_list*) * PERM_HASH_SIZE);
00322 return ptr;
00323 }
00324
00325
00326
00327
00328
00329 void free_addr_hash_table(struct addr_list** table)
00330 {
00331 if (!table)
00332 return;
00333
00334 empty_addr_hash_table(table);
00335 shm_free(table);
00336 }
00337
00338
00339
00340
00341
00342 int addr_hash_table_insert(struct addr_list** table, unsigned int grp,
00343 unsigned int ip_addr, unsigned int port)
00344 {
00345 struct addr_list *np;
00346 unsigned int hash_val;
00347 str addr_str;
00348
00349 np = (struct addr_list *) shm_malloc(sizeof(*np));
00350 if (np == NULL) {
00351 LM_ERR("no shm memory for table entry\n");
00352 return -1;
00353 }
00354
00355 np->grp = grp;
00356 np->ip_addr = ip_addr;
00357 np->port = port;
00358
00359 addr_str.s = (char *)(&ip_addr);
00360 addr_str.len = 4;
00361 hash_val = perm_hash(addr_str);
00362 np->next = table[hash_val];
00363 table[hash_val] = np;
00364
00365 return 1;
00366 }
00367
00368
00369
00370
00371
00372
00373 int match_addr_hash_table(struct addr_list** table, unsigned int group,
00374 unsigned int ip_addr, unsigned int port)
00375 {
00376 struct addr_list *np;
00377 str addr_str;
00378
00379 addr_str.s = (char *)(&ip_addr);
00380 addr_str.len = 4;
00381
00382 for (np = table[perm_hash(addr_str)]; np != NULL; np = np->next) {
00383 if ((np->ip_addr == ip_addr) && (np->grp == group) &&
00384 ((np->port == 0) || (np->port == port))) {
00385 return 1;
00386 }
00387 }
00388
00389 return -1;
00390 }
00391
00392
00393
00394
00395
00396
00397
00398 int find_group_in_addr_hash_table(struct addr_list** table,
00399 unsigned int ip_addr, unsigned int port)
00400 {
00401 struct addr_list *np;
00402 str addr_str;
00403
00404 addr_str.s = (char *)(&ip_addr);
00405 addr_str.len = 4;
00406
00407 for (np = table[perm_hash(addr_str)]; np != NULL; np = np->next) {
00408 if ((np->ip_addr == ip_addr) &&
00409 ((np->port == 0) || (np->port == port))) {
00410 return np->grp;
00411 }
00412 }
00413
00414 return -1;
00415 }
00416
00417
00418
00419
00420
00421 int addr_hash_table_mi_print(struct addr_list** table, struct mi_node* rpl)
00422 {
00423 int i;
00424 struct addr_list *np;
00425 struct ip_addr addr;
00426
00427 for (i = 0; i < PERM_HASH_SIZE; i++) {
00428 np = table[i];
00429 while (np) {
00430 addr.af = AF_INET;
00431 addr.len = 4;
00432 addr.u.addr32[0] = np->ip_addr;
00433 if (addf_mi_node_child(rpl, 0, 0, 0,
00434 "%4d <%u, %s, %u>",
00435 i, np->grp, ip_addr2a(&addr),
00436 np->port) == 0)
00437 return -1;
00438 np = np->next;
00439 }
00440 }
00441 return 0;
00442 }
00443
00444
00445
00446
00447
00448
00449 void empty_addr_hash_table(struct addr_list **table)
00450 {
00451 int i;
00452 struct addr_list *np, *next;
00453
00454 for (i = 0; i < PERM_HASH_SIZE; i++) {
00455 np = table[i];
00456 while (np) {
00457 next = np->next;
00458 shm_free(np);
00459 np = next;
00460 }
00461 table[i] = 0;
00462 }
00463 }
00464
00465
00466
00467
00468
00469 struct subnet* new_subnet_table(void)
00470 {
00471 struct subnet* ptr;
00472
00473
00474
00475 ptr = (struct subnet *)shm_malloc
00476 (sizeof(struct subnet) * (PERM_MAX_SUBNETS + 1));
00477 if (!ptr) {
00478 LM_ERR("no shm memory for subnet table\n");
00479 return 0;
00480 }
00481 ptr[PERM_MAX_SUBNETS].grp = 0;
00482 return ptr;
00483 }
00484
00485
00486
00487
00488
00489
00490 int subnet_table_insert(struct subnet* table, unsigned int grp,
00491 unsigned int subnet, unsigned int mask,
00492 unsigned int port)
00493 {
00494 int i;
00495 unsigned int count;
00496
00497 count = table[PERM_MAX_SUBNETS].grp;
00498
00499 if (count == PERM_MAX_SUBNETS) {
00500 LM_CRIT("subnet table is full\n");
00501 return 0;
00502 }
00503
00504 mask = 32 - mask;
00505 subnet = htonl(ntohl(subnet) >> mask);
00506
00507 i = count - 1;
00508
00509 while ((i >= 0) && (table[i].grp > grp)) {
00510 table[i + 1] = table[i];
00511 i--;
00512 }
00513
00514 table[i + 1].grp = grp;
00515 table[i + 1].subnet = subnet;
00516 table[i + 1].port = port;
00517 table[i + 1].mask = mask;
00518
00519 table[PERM_MAX_SUBNETS].grp = count + 1;
00520
00521 return 1;
00522 }
00523
00524
00525
00526
00527
00528
00529 int match_subnet_table(struct subnet* table, unsigned int grp,
00530 unsigned int ip_addr, unsigned int port)
00531 {
00532 unsigned int count, i, subnet;
00533
00534 count = table[PERM_MAX_SUBNETS].grp;
00535
00536 i = 0;
00537 while ((i < count) && (table[i].grp < grp))
00538 i++;
00539
00540 if (i == count) return -1;
00541
00542 while ((i < count) && (table[i].grp == grp)) {
00543 subnet = htonl(ntohl(ip_addr) >> table[i].mask);
00544 if ((table[i].subnet == subnet) &&
00545 ((table[i].port == port) || (table[i].port == 0)))
00546 return 1;
00547 i++;
00548 }
00549
00550 return -1;
00551 }
00552
00553
00554
00555
00556
00557
00558
00559 int find_group_in_subnet_table(struct subnet* table,
00560 unsigned int ip_addr, unsigned int port)
00561 {
00562 unsigned int count, i, subnet;
00563
00564 count = table[PERM_MAX_SUBNETS].grp;
00565
00566 i = 0;
00567 while (i < count) {
00568 subnet = ip_addr << table[i].mask;
00569 if ((table[i].subnet == subnet) &&
00570 ((table[i].port == port) || (table[i].port == 0)))
00571 return table[i].grp;
00572 i++;
00573 }
00574
00575 return -1;
00576 }
00577
00578
00579
00580
00581
00582 int subnet_table_mi_print(struct subnet* table, struct mi_node* rpl)
00583 {
00584 unsigned int count, i;
00585 struct ip_addr addr;
00586
00587 count = table[PERM_MAX_SUBNETS].grp;
00588
00589 for (i = 0; i < count; i++) {
00590 addr.af = AF_INET;
00591 addr.len = 4;
00592 addr.u.addr32[0] = htonl(ntohl(table[i].subnet) << table[i].mask);
00593 if (addf_mi_node_child(rpl, 0, 0, 0,
00594 "%4d <%u, %s, %u, %u>",
00595 i, table[i].grp, ip_addr2a(&addr),
00596 32 - table[i].mask, table[i].port) == 0) {
00597 return -1;
00598 }
00599 }
00600 return 0;
00601 }
00602
00603
00604
00605
00606
00607 void empty_subnet_table(struct subnet *table)
00608 {
00609 table[PERM_MAX_SUBNETS].grp = 0;
00610 }
00611
00612
00613
00614
00615
00616 void free_subnet_table(struct subnet* table)
00617 {
00618 if (!table)
00619 return;
00620
00621 shm_free(table);
00622 }