1254219Scy/*
2254219Scy * Copyright (C) 2012 by Darren Reed.
3254219Scy *
4254219Scy * See the IPFILTER.LICENCE file for details on licencing.
5254219Scy *
6254219Scy * $Id: parsewhoisline.c,v 1.2.2.5 2012/07/22 08:04:24 darren_r Exp $
7254219Scy */
8254219Scy#include "ipf.h"
9254219Scy
10254219Scy/*
11254219ScyMicrosoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255
12254219ScyMicrosoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47
13254219Scy */
14254219Scyint
15254219Scyparsewhoisline(line, addrp, maskp)
16254219Scy	char *line;
17254219Scy	addrfamily_t *addrp;
18254219Scy	addrfamily_t *maskp;
19254219Scy{
20254219Scy	struct in_addr a1, a2;
21254219Scy	char *src = line;
22254219Scy	char *s = NULL;
23254219Scy
24254219Scy	if (line == NULL)
25254219Scy		return -1;
26254219Scy
27254219Scy	while (*src != '\0') {
28254219Scy		s = strchr(src, '(');
29254219Scy		if (s == NULL)
30254219Scy			break;
31254219Scy
32254219Scy		if (strncmp(s, "(NET", 4)) {
33254219Scy			src = s + 1;
34254219Scy		}
35254219Scy		break;
36254219Scy	}
37254219Scy
38254219Scy	if (s == NULL)
39254219Scy		return -1;
40254219Scy
41254219Scy	memset(addrp, 0x00, sizeof(*maskp));
42254219Scy	memset(maskp, 0x00, sizeof(*maskp));
43254219Scy
44254219Scy	if (*(s + 4) == '6') {
45254219Scy#ifdef USE_INET6
46254219Scy		i6addr_t a61, a62;
47254219Scy
48254219Scy		s = strchr(s, ')');
49254219Scy		if (s == NULL || *++s != ' ')
50254219Scy			return -1;
51254219Scy		/*
52254219Scy		 * Parse the IPv6
53254219Scy		 */
54254219Scy		if (inet_pton(AF_INET6, s, &a61.in6) != 1)
55254219Scy			return -1;
56254219Scy
57254219Scy		s = strchr(s, ' ');
58254219Scy		if (s == NULL || strncmp(s, " - ", 3))
59254219Scy			return -1;
60254219Scy
61254219Scy		s += 3;
62254219Scy		if (inet_pton(AF_INET6, s, &a62) != 1)
63254219Scy			return -1;
64254219Scy
65254219Scy		addrp->adf_addr = a61;
66254219Scy		addrp->adf_family = AF_INET6;
67254219Scy		addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
68254219Scy				 sizeof(struct in6_addr);
69254219Scy
70254219Scy		maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]);
71254219Scy		maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]);
72254219Scy		maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]);
73254219Scy		maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]);
74254219Scy
75254219Scy		/*
76254219Scy		 * If the mask that's been generated isn't a consecutive mask
77254219Scy		 * then we can't add it into a pool.
78254219Scy		 */
79254219Scy		if (count6bits(maskp->adf_addr.i6) == -1)
80254219Scy			return -1;
81254219Scy
82254219Scy		maskp->adf_family = AF_INET6;
83254219Scy		maskp->adf_len = addrp->adf_len;
84254219Scy
85254219Scy		if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6,
86254219Scy				&addrp->adf_addr.in6)) {
87254219Scy			return -1;
88254219Scy		}
89254219Scy		return 0;
90254219Scy#else
91254219Scy		return -1;
92254219Scy#endif
93254219Scy	}
94254219Scy
95254219Scy	s = strchr(s, ')');
96254219Scy	if (s == NULL || *++s != ' ')
97254219Scy		return -1;
98254219Scy
99254219Scy	s++;
100254219Scy
101254219Scy	if (inet_aton(s, &a1) != 1)
102254219Scy		return -1;
103254219Scy
104254219Scy	s = strchr(s, ' ');
105254219Scy	if (s == NULL || strncmp(s, " - ", 3))
106254219Scy		return -1;
107254219Scy
108254219Scy	s += 3;
109254219Scy	if (inet_aton(s, &a2) != 1)
110254219Scy		return -1;
111254219Scy
112254219Scy	addrp->adf_addr.in4 = a1;
113254219Scy	addrp->adf_family = AF_INET;
114254219Scy	addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
115254219Scy			 sizeof(struct in_addr);
116254219Scy	maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr);
117254219Scy
118254219Scy	/*
119254219Scy	 * If the mask that's been generated isn't a consecutive mask then
120254219Scy	 * we can't add it into a pool.
121254219Scy	 */
122254219Scy	if (count4bits(maskp->adf_addr.in4.s_addr) == -1)
123254219Scy		return -1;
124254219Scy
125254219Scy	maskp->adf_family = AF_INET;
126254219Scy	maskp->adf_len = addrp->adf_len;
127254219Scy	bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len);
128254219Scy	if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) !=
129254219Scy	    addrp->adf_addr.in4.s_addr)
130254219Scy		return -1;
131254219Scy	return 0;
132254219Scy}
133