/** initializes a net structure from a string. * @param dst - net structure that will be filled * @param s - string of the form "ip", "ip/mask_len" or "ip/ip_mak". * @return -1 on error, 0 on succes */ int mk_net_str(struct net* dst, str* s) { struct ip_addr* t; char* p; struct ip_addr ip; str addr; str mask; unsigned int bitlen; /* test for ip only */ t = str2ip(s); if (unlikely(t == 0)) t = str2ip6(s); if (likely(t)) return mk_net_bitlen(dst, t, t->len*8); /* not a simple ip, maybe an ip/netmask pair */ p = q_memchr(s->s, '/', s->len); if (likely(p)) { addr.s = s->s; addr.len = (int)(long)(p - s->s); mask.s = p + 1; mask.len = s->len - (addr.len + 1); /* allow '/' enclosed by whitespace */ trim_trailing(&addr); trim_leading(&mask); t = str2ip(&addr); if (likely(t)) { /* it can be a number */ if (str2int(&mask, &bitlen) == 0) return mk_net_bitlen(dst, t, bitlen); ip = *t; t = str2ip(&mask); if (likely(t)) return mk_net(dst, &ip, t); /* error */ return -1; } else { t = str2ip6(&addr); if (likely(t)) { /* it can be a number */ if (str2int(&mask, &bitlen) == 0) return mk_net_bitlen(dst, t, bitlen); ip = *t; t = str2ip6(&mask); if (likely(t)) return mk_net(dst, &ip, t); /* error */ return -1; } } } return -1; }
int populate_ds_bls( ds_set_t *sets) { unsigned int i,k; struct ds_bl *dsbl; ds_set_p set; ds_dest_p dst; struct bl_rule *dsbl_first; struct bl_rule *dsbl_last; struct net *set_net; LM_DBG("Updating ds blacklists...\n"); /* each bl list at a time */ for(dsbl = dsbl_lists; dsbl; dsbl = dsbl->next) { dsbl_first = dsbl_last = NULL; /* each blacklisted set at a time */ for (i = 0; i < dsbl->no_sets; i++) { /* search if any set matches the one above */ for( set=sets ; set ; set = set->next) { if (set->id == dsbl->sets[i]) { LM_DBG("Set [%d] matches. Adding all destinations:\n", set->id); for (dst = set->dlist; dst; dst = dst->next) { /* and add all IPs for each destination */ for( k=0 ; k<dst->ips_cnt ; k++ ) { //print_ip(NULL, &dst->ips[k], "\n"); set_net = mk_net_bitlen( &dst->ips[k], dst->ips[k].len*8); if (set_net == NULL) { LM_ERR("BUILD netmask failed.\n"); continue; } /* add this destination to the BL */ add_rule_to_list( &dsbl_first, &dsbl_last, set_net, NULL/*body*/, 0/*port*/, PROTO_NONE/*proto*/, 0/*flags*/); pkg_free(set_net); } } } } } /* the new content for the BL */ if (dsbl->bl && add_list_to_head( dsbl->bl, dsbl_first, dsbl_last, 1, 0) != 0) { LM_ERR("UPDATE blacklist failed.\n"); return -1; } } return 0; }
/* * Reload address table to new hash table and when done, make new hash table * current one. */ int reload_address_table(struct pm_part_struct *part_struct) { db_key_t cols[8]; db_res_t* res = NULL; db_row_t* row; db_val_t* val; struct address_list **new_hash_table; struct subnet *new_subnet_table; int i, mask, proto, group, port, id; struct ip_addr *ip_addr; struct net *subnet; str str_pattern = {NULL,0}, str_info={NULL,0}; str str_src_ip, str_proto; UNUSED(id); cols[0] = &ip_col; cols[1] = &grp_col; cols[2] = &mask_col; cols[3] = &port_col; cols[4] = &proto_col; cols[5] = &pattern_col; cols[6] = &info_col; cols[7] = &id_col; if (part_struct->perm_dbf.use_table(part_struct->db_handle, &part_struct->table) < 0) { LM_ERR("failed to use address table\n"); return -1; } if (part_struct->perm_dbf.query(part_struct->db_handle, NULL, 0, NULL, cols, 0, 8, 0, &res) < 0) { LM_ERR("failed to query database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*part_struct->hash_table == part_struct->hash_table_1) { empty_hash(part_struct->hash_table_2); new_hash_table = part_struct->hash_table_2; } else { empty_hash(part_struct->hash_table_1); new_hash_table = part_struct->hash_table_1; } /* Choose new subnet table */ if (*part_struct->subnet_table == part_struct->subnet_table_1) { empty_subnet_table(part_struct->subnet_table_2); new_subnet_table = part_struct->subnet_table_2; } else { empty_subnet_table(part_struct->subnet_table_1); new_subnet_table = part_struct->subnet_table_1; } row = RES_ROWS(res); LM_DBG("number of rows in address table: %d\n", RES_ROW_N(res)); if (RES_COL_N(res) != 8) { LM_ERR("too many columns\n"); goto error; } for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); if ((VAL_TYPE(val)!=DB_STRING && VAL_TYPE(val)!=DB_STR) || VAL_NULL(val)) { LM_ERR("invalid IP column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 1) != DB_INT || VAL_NULL(val + 1) || VAL_INT(val + 1) < 0) { LM_ERR("invalid group column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 2) != DB_INT || VAL_NULL(val + 2) || VAL_INT(val + 2) < 0 || VAL_INT(val + 2) > 32) { LM_ERR("invalid mask column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 3) != DB_INT || VAL_NULL(val + 3)) { LM_ERR("invalid port column type on row %d, skipping..\n", i); continue; } if ((VAL_TYPE(val + 4) != DB_STRING && VAL_TYPE(val + 4) != DB_STR) || VAL_NULL(val + 4)) { LM_ERR("invalid protocol column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 5) != DB_STRING && VAL_TYPE(val + 5) != DB_STR) { LM_ERR("invalid pattern column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 6) != DB_STRING && VAL_TYPE(val + 6) != DB_STR) { LM_ERR("invalid info column type on row %d, skipping..\n", i); goto error; } id = (unsigned int) VAL_INT(val + 7); /* IP string */ if (VAL_TYPE(val)==DB_STRING) { str_src_ip.s = (char*)VAL_STRING(val); str_src_ip.len = strlen(str_src_ip.s); } else { str_src_ip = VAL_STR(val); } if (str_src_ip.len==0) { LM_DBG("empty ip field in address table, ignoring entry" " number %d\n", i); continue; } ip_addr = str2ip(&str_src_ip); if (!ip_addr) { LM_DBG("invalid ip field in address table, ignoring entry " "with id %d\n", id); continue; } /* proto string */ if (VAL_TYPE(val+4)==DB_STRING) { str_proto.s = (char*)VAL_STRING(val+4); str_proto.len = strlen(str_proto.s); } else { str_proto = VAL_STR(val+4); } if (str_proto.len==4 && !strncasecmp(str_proto.s, "none",4)) { LM_DBG("protocol field is \"none\" in address table, ignoring" " entry with id %d\n", id); continue; } proto = proto_char2int(&str_proto); if (proto == -1) { LM_DBG("unknown protocol field in address table, ignoring" " entry with id %d\n", id); continue; } /* pattern string */ if (!VAL_NULL(val + 5)) { if (VAL_TYPE(val+5)==DB_STRING) { str_pattern.s = (char*)VAL_STRING(val+5); str_pattern.len = strlen(str_pattern.s); } else { str_pattern = VAL_STR(val+5); } } else { str_pattern.len = 0; str_pattern.s = 0; } /* info string */ if (!VAL_NULL(val + 6)) { if (VAL_TYPE(val+6)==DB_STRING) { str_info.s = (char*)VAL_STRING(val+6); str_info.len = strlen(str_info.s); } else { str_info = VAL_STR(val+6); } } else { str_info.len = 0; str_info.s = 0; } group = (unsigned int) VAL_INT(val + 1); port = (unsigned int) VAL_INT(val + 3); mask = (unsigned int) VAL_INT(val + 2); if (mask == 32) { if (hash_insert(new_hash_table, ip_addr, group, port, proto, &str_pattern, &str_info) == -1) { LM_ERR("hash table insert error\n"); goto error; } LM_DBG("Tuple <%.*s, %u, %u, %u, %.*s, %.*s> inserted into " "address hash table\n", str_src_ip.len, str_src_ip.s, group, port, proto, str_pattern.len, str_pattern.s, str_info.len,str_info.s); } else { subnet = mk_net_bitlen(ip_addr, mask); if (subnet_table_insert(new_subnet_table, group, subnet, port, proto, &str_pattern, &str_info) == -1) { LM_ERR("subnet table problem\n"); if (subnet) { pkg_free(subnet); } goto error; } LM_DBG("Tuple <%.*s, %u, %u, %u> inserted into subnet table\n", str_src_ip.len, str_src_ip.s, group, mask, port); /* subnet in pkg; needs to be freed since was copied to shm */ if (subnet) { pkg_free(subnet); } } } part_struct->perm_dbf.free_result(part_struct->db_handle, res); *part_struct->hash_table = new_hash_table; *part_struct->subnet_table = new_subnet_table; LM_DBG("address table reloaded successfully.\n"); return 1; error: part_struct->perm_dbf.free_result(part_struct->db_handle, res); return -1; }