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