Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

/*	$NetBSD: parsewhoisline.c,v 1.2 2012/07/22 14:27:36 darrenr Exp $	*/

/*
 * Copyright (C) 2012 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 * Id: parsewhoisline.c,v 1.1.1.2 2012/07/22 13:44:40 darrenr Exp $
 */
#include "ipf.h"

/*
Microsoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255
Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47
 */
int
parsewhoisline(line, addrp, maskp)
	char *line;
	addrfamily_t *addrp;
	addrfamily_t *maskp;
{
	struct in_addr a1, a2;
	char *src = line;
	char *s = NULL;

	if (line == NULL)
		return -1;

	while (*src != '\0') {
		s = strchr(src, '(');
		if (s == NULL)
			break;

		if (strncmp(s, "(NET", 4)) {
			src = s + 1;
		}
		break;
	}

	if (s == NULL)
		return -1;

	memset(addrp, 0x00, sizeof(*maskp));
	memset(maskp, 0x00, sizeof(*maskp));

	if (*(s + 4) == '6') {
#ifdef USE_INET6
		i6addr_t a61, a62;

		s = strchr(s, ')');
		if (s == NULL || *++s != ' ')
			return -1;
		/*
		 * Parse the IPv6
		 */
		if (inet_pton(AF_INET6, s, &a61.in6) != 1)
			return -1;

		s = strchr(s, ' ');
		if (s == NULL || strncmp(s, " - ", 3))
			return -1;

		s += 3;
		if (inet_pton(AF_INET6, s, &a62) != 1)
			return -1;

		addrp->adf_addr = a61;
		addrp->adf_family = AF_INET6;
		addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
				 sizeof(struct in6_addr);

		maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]);
		maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]);
		maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]);
		maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]);

		/*
		 * If the mask that's been generated isn't a consecutive mask
		 * then we can't add it into a pool.
		 */
		if (count6bits(maskp->adf_addr.i6) == -1)
			return -1;

		maskp->adf_family = AF_INET6;
		maskp->adf_len = addrp->adf_len;

		if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6,
				&addrp->adf_addr.in6)) {
			return -1;
		}
		return 0;
#else
		return -1;
#endif
	}

	s = strchr(s, ')');
	if (s == NULL || *++s != ' ')
		return -1;

	s++;

	if (inet_aton(s, &a1) != 1)
		return -1;

	s = strchr(s, ' ');
	if (s == NULL || strncmp(s, " - ", 3))
		return -1;

	s += 3;
	if (inet_aton(s, &a2) != 1)
		return -1;

	addrp->adf_addr.in4 = a1;
	addrp->adf_family = AF_INET;
	addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
			 sizeof(struct in_addr);
	maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr);

	/*
	 * If the mask that's been generated isn't a consecutive mask then
	 * we can't add it into a pool.
	 */
	if (count4bits(maskp->adf_addr.in4.s_addr) == -1)
		return -1;

	maskp->adf_family = AF_INET;
	maskp->adf_len = addrp->adf_len;
	bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len);
	if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) !=
	    addrp->adf_addr.in4.s_addr)
		return -1;
	return 0;
}