]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ipfilter/lib/parsewhoisline.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ipfilter / lib / parsewhoisline.c
1 /*
2  * Copyright (C) 2012 by Darren Reed.
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  *
6  * $Id: parsewhoisline.c,v 1.2.2.5 2012/07/22 08:04:24 darren_r Exp $
7  */
8 #include "ipf.h"
9
10 /*
11 Microsoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255
12 Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47
13  */
14 int
15 parsewhoisline(line, addrp, maskp)
16         char *line;
17         addrfamily_t *addrp;
18         addrfamily_t *maskp;
19 {
20         struct in_addr a1, a2;
21         char *src = line;
22         char *s = NULL;
23
24         if (line == NULL)
25                 return -1;
26
27         while (*src != '\0') {
28                 s = strchr(src, '(');
29                 if (s == NULL)
30                         break;
31
32                 if (strncmp(s, "(NET", 4)) {
33                         src = s + 1;
34                 }
35                 break;
36         }
37
38         if (s == NULL)
39                 return -1;
40
41         memset(addrp, 0x00, sizeof(*maskp));
42         memset(maskp, 0x00, sizeof(*maskp));
43
44         if (*(s + 4) == '6') {
45 #ifdef USE_INET6
46                 i6addr_t a61, a62;
47
48                 s = strchr(s, ')');
49                 if (s == NULL || *++s != ' ')
50                         return -1;
51                 /*
52                  * Parse the IPv6
53                  */
54                 if (inet_pton(AF_INET6, s, &a61.in6) != 1)
55                         return -1;
56
57                 s = strchr(s, ' ');
58                 if (s == NULL || strncmp(s, " - ", 3))
59                         return -1;
60
61                 s += 3;
62                 if (inet_pton(AF_INET6, s, &a62) != 1)
63                         return -1;
64
65                 addrp->adf_addr = a61;
66                 addrp->adf_family = AF_INET6;
67                 addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
68                                  sizeof(struct in6_addr);
69
70                 maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]);
71                 maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]);
72                 maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]);
73                 maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]);
74
75                 /*
76                  * If the mask that's been generated isn't a consecutive mask
77                  * then we can't add it into a pool.
78                  */
79                 if (count6bits(maskp->adf_addr.i6) == -1)
80                         return -1;
81
82                 maskp->adf_family = AF_INET6;
83                 maskp->adf_len = addrp->adf_len;
84
85                 if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6,
86                                 &addrp->adf_addr.in6)) {
87                         return -1;
88                 }
89                 return 0;
90 #else
91                 return -1;
92 #endif
93         }
94
95         s = strchr(s, ')');
96         if (s == NULL || *++s != ' ')
97                 return -1;
98
99         s++;
100
101         if (inet_aton(s, &a1) != 1)
102                 return -1;
103
104         s = strchr(s, ' ');
105         if (s == NULL || strncmp(s, " - ", 3))
106                 return -1;
107
108         s += 3;
109         if (inet_aton(s, &a2) != 1)
110                 return -1;
111
112         addrp->adf_addr.in4 = a1;
113         addrp->adf_family = AF_INET;
114         addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
115                          sizeof(struct in_addr);
116         maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr);
117
118         /*
119          * If the mask that's been generated isn't a consecutive mask then
120          * we can't add it into a pool.
121          */
122         if (count4bits(maskp->adf_addr.in4.s_addr) == -1)
123                 return -1;
124
125         maskp->adf_family = AF_INET;
126         maskp->adf_len = addrp->adf_len;
127         bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len);
128         if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) !=
129             addrp->adf_addr.in4.s_addr)
130                 return -1;
131         return 0;
132 }