Exemplo n.º 1
0
/**
 * ip_range_split() callback.
 *
 * Insert IP range in database, linking it to the proper country code.
 */
static void
gip_add_cidr(uint32 ip, uint bits, void *udata)
{
	struct range_context *ctx = udata;
	iprange_err_t error;
	uint16 cc;

	if (GNET_PROPERTY(reload_debug) > 4)
		printf("GEO adding %s/%d for \"%s\"\n",
			ip_to_string(ip), bits, ctx->line);

	cc = ctx->country;
	error = iprange_add_cidr(geo_db, ip, bits, cc);

	switch (error) {
	case IPR_ERR_OK:
		break;
		/* FALL THROUGH */
	default:
		g_warning("%s, line %d: rejected entry \"%s\" (%s/%d): %s",
			gip_source[GIP_IPV4].file, ctx->linenum,
			ctx->line, ip_to_string(ip), bits, iprange_strerror(error));
		return;
	}
}
Exemplo n.º 2
0
/**
 * Load bogons data from the supplied FILE.
 *
 * @returns the amount of entries loaded.
 */
static G_GNUC_COLD int
bogons_load(FILE *f)
{
	char line[1024];
	uint32 ip, netmask;
	int linenum = 0;
	int bits;
	iprange_err_t error;
	filestat_t buf;

	bogons_db = iprange_new();
	if (-1 == fstat(fileno(f), &buf)) {
		g_warning("cannot stat %s: %m", bogons_file);
	} else {
		bogons_mtime = buf.st_mtime;
	}

	while (fgets(line, sizeof line, f)) {
		linenum++;

		/*
		 * Remove all trailing spaces in string.
		 * Otherwise, lines which contain only spaces would cause a warning.
		 */

		if (!file_line_chomp_tail(line, sizeof line, NULL)) {
			g_warning("%s, line %d: too long a line", bogons_file, linenum);
			break;
		}

		if (file_line_is_skipable(line))
			continue;

		if (!string_to_ip_and_mask(line, &ip, &netmask)) {
			g_warning("%s, line %d: invalid IP or netmask \"%s\"",
				bogons_file, linenum, line);
			continue;
		}

		bits = netmask_to_cidr(netmask);
		error = iprange_add_cidr(bogons_db, ip, bits, 1);

		switch (error) {
		case IPR_ERR_OK:
			break;
			/* FALL THROUGH */
		default:
			g_warning("%s, line %d: rejected entry \"%s\" (%s/%d): %s",
				bogons_file, linenum, line, ip_to_string(ip), bits,
				iprange_strerror(error));
			continue;
		}
	}

	iprange_sync(bogons_db);

	if (GNET_PROPERTY(reload_debug)) {
		g_debug("loaded %u bogus IP ranges (%u hosts)",
			iprange_get_item_count(bogons_db),
			iprange_get_host_count4(bogons_db));
	}

	return iprange_get_item_count(bogons_db);
}
Exemplo n.º 3
0
/**
 * Parse an IPv6 Geo IP line and record the range in the database.
 */
static void
gip_parse_ipv6(const char *line, int linenum)
{
	const char *end;
	uint16 code;
	int error;
	uint8 ip[16];
	unsigned bits;

	/*
	 * Each line looks like:
	 *
	 *    2a03:be00::/32 nl
	 *
	 * The leading part up to the space is the IPv6 network in CIDR format.
	 * The trailing word is the 2-letter ISO country code.
	 */

	if (!parse_ipv6_addr(line, ip, &end)) {
		g_warning("%s, line %d: bad IPv6 network address \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	if ('/' != *end) {
		g_warning("%s, line %d: missing network separator in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	bits = parse_uint(end + 1, &end, 10, &error);

	if (error) {
		g_warning("%s, line %d: cannot parse network bit amount in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	if (bits > 128) {
		g_warning("%s, line %d: invalid bit amount %u in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, bits, line);
		return;
	}

	if (!is_ascii_space(*end)) {
		g_warning("%s, line %d: missing spaces after network in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	while (is_ascii_space(*end))
		end++;

	if ('\0' == *end) {
		g_warning("%s, line %d: missing country code in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	code = iso3166_encode_cc(end);
	if (ISO3166_INVALID == code) {
		g_warning("%s, line %d: bad country code in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	error = iprange_add_cidr6(geo_db, ip, bits, (code + 1) << 1);

	if (IPR_ERR_OK != error) {
		g_warning("%s, line %d: cannot insert %s/%u: %s",
			gip_source[GIP_IPV6].file, linenum, ipv6_to_string(ip),
			bits, iprange_strerror(error));
	}
}