/* * Check if an entry exists in hash table that has given group, domain_name, and * port. Port 0 in hash table matches any port. */ int match_domain_name_table(struct domain_name_list** table, unsigned int group, str *domain_name, unsigned int port) { struct domain_name_list *np; avp_value_t val; for (np = table[perm_hash(*domain_name)]; np != NULL; np = np->next) { if ( (np->grp == group) && ((np->port == 0) || (np->port == port)) && np->domain.len == domain_name->len && strncmp(np->domain.s, domain_name->s, domain_name->len)==0 ) { if (tag_avp.n && np->tag.s) { val.s = np->tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } return 1; } } return -1; }
/* * Check if an entry exists in hash table that has given src_ip and protocol * value and pattern that matches to From URI. If an entry exists and tag_avp * has been defined, tag of the entry is added as a value to tag_avp. * Returns number of matches or -1 if none matched. */ int match_hash_table(struct trusted_list** table, struct sip_msg* msg, char *src_ip_c_str, int proto) { str uri; char uri_string[MAX_URI_SIZE + 1]; regex_t preg; struct trusted_list *np; str src_ip; int_str val; int count = 0; src_ip.s = src_ip_c_str; src_ip.len = strlen(src_ip.s); if (IS_SIP(msg)) { if (parse_from_header(msg) < 0) return -1; uri = get_from(msg)->uri; if (uri.len > MAX_URI_SIZE) { LM_ERR("from URI too large\n"); return -1; } memcpy(uri_string, uri.s, uri.len); uri_string[uri.len] = (char)0; } for (np = table[perm_hash(src_ip)]; np != NULL; np = np->next) { if ((np->src_ip.len == src_ip.len) && (strncmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) && ((np->proto == PROTO_NONE) || (proto == PROTO_NONE) || (np->proto == proto))) { if (np->pattern && IS_SIP(msg)) { if (regcomp(&preg, np->pattern, REG_NOSUB)) { LM_ERR("invalid regular expression\n"); continue; } if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); continue; } regfree(&preg); } /* Found a match */ if (tag_avp.n && np->tag.s) { val.s = np->tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } if (!peer_tag_mode) return 1; count++; } } if (!count) return -1; else return count; }
/* * Check if an ip_addr/port entry exists in hash table in any group. * Returns first group in which ip_addr/port is found. * Port 0 in hash table matches any port. */ int find_group_in_addr_hash_table(struct addr_list** table, ip_addr_t *addr, unsigned int port) { struct addr_list *np; str addr_str; avp_value_t val; addr_str.s = (char*)addr->u.addr; addr_str.len = 4; for (np = table[perm_hash(addr_str)]; np != NULL; np = np->next) { if (((np->port == 0) || (np->port == port)) && ip_addr_cmp(&np->addr, addr)) { if (tag_avp.n && np->tag.s) { val.s = np->tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } return np->grp; } } return -1; }
/* * Add <grp, ip_addr, port> into hash table */ int addr_hash_table_insert(struct addr_list** table, unsigned int grp, unsigned int ip_addr, unsigned int port) { struct addr_list *np; unsigned int hash_val; str addr_str; np = (struct addr_list *) shm_malloc(sizeof(*np)); if (np == NULL) { LM_ERR("no shm memory for table entry\n"); return -1; } np->grp = grp; np->ip_addr = ip_addr; np->port = port; addr_str.s = (char *)(&ip_addr); addr_str.len = 4; hash_val = perm_hash(addr_str); np->next = table[hash_val]; table[hash_val] = np; return 1; }
/* * Check if an entry exists in hash table that has given src_ip and protocol * value and pattern that matches to From URI. If, assign */ int match_hash_table(struct trusted_list** table, struct sip_msg* msg) { str uri; char uri_string[MAX_URI_SIZE + 1]; regex_t preg; struct trusted_list *np; str src_ip; int_str val; src_ip.s = ip_addr2a(&msg->rcv.src_ip); src_ip.len = strlen(src_ip.s); if (parse_from_header(msg) < 0) return -1; uri = get_from(msg)->uri; if (uri.len > MAX_URI_SIZE) { LM_ERR("from URI too large\n"); return -1; } memcpy(uri_string, uri.s, uri.len); uri_string[uri.len] = (char)0; for (np = table[perm_hash(src_ip)]; np != NULL; np = np->next) { if ((np->src_ip.len == src_ip.len) && (strncasecmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) && ((np->proto == PROTO_NONE) || (np->proto == msg->rcv.proto))) { if (!(np->pattern)) goto found; if (regcomp(&preg, np->pattern, REG_NOSUB)) { LM_ERR("invalid regular expression\n"); return -1; } if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); } else { regfree(&preg); goto found; } } } return -1; found: if (tag_avp.n && np->tag.s) { val.s = np->tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } return 1; }
/* * Check if an domain_name/port entry exists in hash table in any group. * Returns first group in which ip_addr/port is found. * Port 0 in hash table matches any port. */ int find_group_in_domain_name_table(struct domain_name_list** table, str *domain_name, unsigned int port) { struct domain_name_list *np; for (np = table[perm_hash(*domain_name)]; np != NULL; np = np->next) { if ( ((np->port == 0) || (np->port == port)) && np->domain.len == domain_name->len && strncmp(np->domain.s, domain_name->s, domain_name->len)==0 ) { return np->grp; } } return -1; }
/* * Check if an ip_addr/port entry exists in hash table in any group. * Returns first group in which ip_addr/port is found. * Port 0 in hash table matches any port. */ int find_group_in_addr_hash_table(struct addr_list** table, ip_addr_t *addr, unsigned int port) { struct addr_list *np; str addr_str; addr_str.s = (char*)addr->u.addr; addr_str.len = 4; for (np = table[perm_hash(addr_str)]; np != NULL; np = np->next) { if (((np->port == 0) || (np->port == port)) && ip_addr_cmp(&np->addr, addr)) { return np->grp; } } return -1; }
/* * Check if an entry exists in hash table that has given group, ip_addr, and * port. Port 0 in hash table matches any port. */ int match_addr_hash_table(struct addr_list** table, unsigned int group, unsigned int ip_addr, unsigned int port) { struct addr_list *np; str addr_str; addr_str.s = (char *)(&ip_addr); addr_str.len = 4; for (np = table[perm_hash(addr_str)]; np != NULL; np = np->next) { if ((np->ip_addr == ip_addr) && (np->grp == group) && ((np->port == 0) || (np->port == port))) { return 1; } } return -1; }
/* * Add <grp, ip_addr, port> into hash table */ int addr_hash_table_insert(struct addr_list** table, unsigned int grp, ip_addr_t *addr, unsigned int port, char *tagv) { struct addr_list *np; unsigned int hash_val; str addr_str; int len; len = sizeof(struct addr_list); if(tagv!=NULL) len += strlen(tagv) + 1; np = (struct addr_list *) shm_malloc(len); if (np == NULL) { LM_ERR("no shm memory for table entry\n"); return -1; } memset(np, 0, len); np->grp = grp; memcpy(&np->addr, addr, sizeof(ip_addr_t)); np->port = port; if(tagv!=NULL) { np->tag.s = (char*)np + sizeof(struct addr_list); np->tag.len = strlen(tagv); strcpy(np->tag.s, tagv); } addr_str.s = (char*)addr->u.addr; addr_str.len = 4; hash_val = perm_hash(addr_str); np->next = table[hash_val]; table[hash_val] = np; return 1; }
/* * Add <grp, domain_name, port> into hash table */ int domain_name_table_insert(struct domain_name_list** table, unsigned int grp, str *domain_name, unsigned int port, char *tagv) { struct domain_name_list *np; unsigned int hash_val; int len; len = sizeof(struct domain_name_list) + domain_name->len; if(tagv!=NULL) len += strlen(tagv) + 1; np = (struct domain_name_list *) shm_malloc(len); if (np == NULL) { LM_ERR("no shm memory for table entry\n"); return -1; } memset(np, 0, len); np->grp = grp; np->domain.s = (char*)np + sizeof(struct domain_name_list); memcpy(np->domain.s, domain_name->s, domain_name->len); np->domain.len = domain_name->len; np->port = port; if(tagv!=NULL) { np->tag.s = (char*)np + sizeof(struct domain_name_list) + domain_name->len; np->tag.len = strlen(tagv); strcpy(np->tag.s, tagv); } LM_DBG("** Added domain name: %.*s\n", np->domain.len, np->domain.s); hash_val = perm_hash(*domain_name); np->next = table[hash_val]; table[hash_val] = np; return 1; }
/* * Add <src_ip, proto, pattern, ruri_pattern, tag, priority> into hash table, where proto is integer * representation of string argument proto. */ int hash_table_insert(struct trusted_list** table, char* src_ip, char* proto, char* pattern, char* ruri_pattern, char* tag, int priority) { struct trusted_list *np; struct trusted_list *np0 = NULL; struct trusted_list *np1 = NULL; unsigned int hash_val; np = (struct trusted_list *) shm_malloc(sizeof(*np)); if (np == NULL) { LM_ERR("cannot allocate shm memory for table entry\n"); return -1; } if (strcasecmp(proto, "any") == 0) { np->proto = PROTO_NONE; } else if (strcasecmp(proto, "udp") == 0) { np->proto = PROTO_UDP; } else if (strcasecmp(proto, "tcp") == 0) { np->proto = PROTO_TCP; } else if (strcasecmp(proto, "tls") == 0) { np->proto = PROTO_TLS; } else if (strcasecmp(proto, "sctp") == 0) { np->proto = PROTO_SCTP; } else if (strcasecmp(proto, "ws") == 0) { np->proto = PROTO_WS; } else if (strcasecmp(proto, "wss") == 0) { np->proto = PROTO_WSS; } else if (strcasecmp(proto, "none") == 0) { shm_free(np); return 1; } else { LM_CRIT("unknown protocol\n"); shm_free(np); return -1; } np->src_ip.len = strlen(src_ip); np->src_ip.s = (char *) shm_malloc(np->src_ip.len+1); if (np->src_ip.s == NULL) { LM_CRIT("cannot allocate shm memory for src_ip string\n"); shm_free(np); return -1; } (void) strncpy(np->src_ip.s, src_ip, np->src_ip.len); np->src_ip.s[np->src_ip.len] = 0; if (pattern) { np->pattern = (char *) shm_malloc(strlen(pattern)+1); if (np->pattern == NULL) { LM_CRIT("cannot allocate shm memory for pattern string\n"); shm_free(np->src_ip.s); shm_free(np); return -1; } (void) strcpy(np->pattern, pattern); } else { np->pattern = 0; } if (ruri_pattern) { np->ruri_pattern = (char *) shm_malloc(strlen(ruri_pattern)+1); if (np->ruri_pattern == NULL) { LM_CRIT("cannot allocate shm memory for ruri_pattern string\n"); shm_free(np->src_ip.s); shm_free(np); return -1; } (void) strcpy(np->ruri_pattern, ruri_pattern); } else { np->ruri_pattern = 0; } if (tag) { np->tag.len = strlen(tag); np->tag.s = (char *) shm_malloc((np->tag.len) + 1); if (np->tag.s == NULL) { LM_CRIT("cannot allocate shm memory for pattern or ruri_pattern string\n"); shm_free(np->src_ip.s); shm_free(np->pattern); shm_free(np->ruri_pattern); shm_free(np); return -1; } (void) strcpy(np->tag.s, tag); } else { np->tag.len = 0; np->tag.s = 0; } np->priority = priority; hash_val = perm_hash(np->src_ip); if(table[hash_val]==NULL) { np->next = NULL; table[hash_val] = np; } else { np1 = NULL; np0 = table[hash_val]; while(np0) { if(np0->priority < np->priority) break; np1 = np0; np0 = np0->next; } if(np1==NULL) { np->next = table[hash_val]; table[hash_val] = np; } else { np->next = np1->next; np1->next = np; } } return 1; }
/* * Add <src_ip, proto, pattern, tag> into hash table, where proto is integer * representation of string argument proto. */ int hash_table_insert(struct trusted_list** table, char* src_ip, char* proto, char* pattern, char* tag) { struct trusted_list *np; unsigned int hash_val; np = (struct trusted_list *) shm_malloc(sizeof(*np)); if (np == NULL) { LM_ERR("cannot allocate shm memory for table entry\n"); return -1; } if (strcasecmp(proto, "any") == 0) { np->proto = PROTO_NONE; } else if (strcasecmp(proto, "udp") == 0) { np->proto = PROTO_UDP; } else if (strcasecmp(proto, "tcp") == 0) { np->proto = PROTO_TCP; } else if (strcasecmp(proto, "tls") == 0) { np->proto = PROTO_TLS; } else if (strcasecmp(proto, "sctp") == 0) { np->proto = PROTO_SCTP; } else if (strcasecmp(proto, "none") == 0) { shm_free(np); return 1; } else { LM_CRIT("unknown protocol\n"); shm_free(np); return -1; } np->src_ip.len = strlen(src_ip); np->src_ip.s = (char *) shm_malloc(np->src_ip.len); if (np->src_ip.s == NULL) { LM_CRIT("cannot allocate shm memory for src_ip string\n"); shm_free(np); return -1; } (void) strncpy(np->src_ip.s, src_ip, np->src_ip.len); if (pattern) { np->pattern = (char *) shm_malloc(strlen(pattern)+1); if (np->pattern == NULL) { LM_CRIT("cannot allocate shm memory for pattern string\n"); shm_free(np->src_ip.s); shm_free(np); return -1; } (void) strcpy(np->pattern, pattern); } else { np->pattern = 0; } if (tag) { np->tag.len = strlen(tag); np->tag.s = (char *) shm_malloc((np->tag.len) + 1); if (np->tag.s == NULL) { LM_CRIT("cannot allocate shm memory for pattern string\n"); shm_free(np->src_ip.s); shm_free(np->pattern); shm_free(np); return -1; } (void) strcpy(np->tag.s, tag); } else { np->tag.len = 0; np->tag.s = 0; } hash_val = perm_hash(np->src_ip); np->next = table[hash_val]; table[hash_val] = np; return 1; }