Example #1
0
/** 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;
}
Example #2
0
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;
}
Example #3
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;
}