]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/ipf/libipf/parsewhoisline.c
ipfilter userland: Remove trailing whitespace
[FreeBSD/FreeBSD.git] / sbin / ipf / libipf / 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(char *line, addrfamily_t *addrp, addrfamily_t *maskp)
16 {
17         struct in_addr a1, a2;
18         char *src = line;
19         char *s = NULL;
20
21         if (line == NULL)
22                 return(-1);
23
24         while (*src != '\0') {
25                 s = strchr(src, '(');
26                 if (s == NULL)
27                         break;
28
29                 if (strncmp(s, "(NET", 4)) {
30                         src = s + 1;
31                 }
32                 break;
33         }
34
35         if (s == NULL)
36                 return(-1);
37
38         memset(addrp, 0x00, sizeof(*maskp));
39         memset(maskp, 0x00, sizeof(*maskp));
40
41         if (*(s + 4) == '6') {
42 #ifdef USE_INET6
43                 i6addr_t a61, a62;
44
45                 s = strchr(s, ')');
46                 if (s == NULL || *++s != ' ')
47                         return(-1);
48                 /*
49                  * Parse the IPv6
50                  */
51                 if (inet_pton(AF_INET6, s, &a61.in6) != 1)
52                         return(-1);
53
54                 s = strchr(s, ' ');
55                 if (s == NULL || strncmp(s, " - ", 3))
56                         return(-1);
57
58                 s += 3;
59                 if (inet_pton(AF_INET6, s, &a62) != 1)
60                         return(-1);
61
62                 addrp->adf_addr = a61;
63                 addrp->adf_family = AF_INET6;
64                 addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
65                                  sizeof(struct in6_addr);
66
67                 maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]);
68                 maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]);
69                 maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]);
70                 maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]);
71
72                 /*
73                  * If the mask that's been generated isn't a consecutive mask
74                  * then we can't add it into a pool.
75                  */
76                 if (count6bits(maskp->adf_addr.i6) == -1)
77                         return(-1);
78
79                 maskp->adf_family = AF_INET6;
80                 maskp->adf_len = addrp->adf_len;
81
82                 if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6,
83                                 &addrp->adf_addr.in6)) {
84                         return(-1);
85                 }
86                 return(0);
87 #else
88                 return(-1);
89 #endif
90         }
91
92         s = strchr(s, ')');
93         if (s == NULL || *++s != ' ')
94                 return(-1);
95
96         s++;
97
98         if (inet_aton(s, &a1) != 1)
99                 return(-1);
100
101         s = strchr(s, ' ');
102         if (s == NULL || strncmp(s, " - ", 3))
103                 return(-1);
104
105         s += 3;
106         if (inet_aton(s, &a2) != 1)
107                 return(-1);
108
109         addrp->adf_addr.in4 = a1;
110         addrp->adf_family = AF_INET;
111         addrp->adf_len = offsetof(addrfamily_t, adf_addr) +
112                          sizeof(struct in_addr);
113         maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr);
114
115         /*
116          * If the mask that's been generated isn't a consecutive mask then
117          * we can't add it into a pool.
118          */
119         if (count4bits(maskp->adf_addr.in4.s_addr) == -1)
120                 return(-1);
121
122         maskp->adf_family = AF_INET;
123         maskp->adf_len = addrp->adf_len;
124         bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len);
125         if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) !=
126             addrp->adf_addr.in4.s_addr)
127                 return(-1);
128         return(0);
129 }