Blame
Date:
Sat Aug 1 09:01:52 2020 UTC
Message:
move extended RCODE's out of the RCODE section those are only 0x00 through 0x0F make a section that shows extended RCODE's that are added to a EDNS0 tag.
001
2014-11-14
pjp
/*
002
2018-10-19
pjp
* Copyright (c) 2010-2018 Peter J. Philipp
003
2014-11-14
pjp
* All rights reserved.
004
2014-11-14
pjp
*
005
2014-11-14
pjp
* Redistribution and use in source and binary forms, with or without
006
2014-11-14
pjp
* modification, are permitted provided that the following conditions
007
2014-11-14
pjp
* are met:
008
2014-11-14
pjp
* 1. Redistributions of source code must retain the above copyright
009
2014-11-14
pjp
* notice, this list of conditions and the following disclaimer.
010
2014-11-14
pjp
* 2. Redistributions in binary form must reproduce the above copyright
011
2014-11-14
pjp
* notice, this list of conditions and the following disclaimer in the
012
2014-11-14
pjp
* documentation and/or other materials provided with the distribution.
013
2014-11-14
pjp
* 3. The name of the author may not be used to endorse or promote products
014
2014-11-14
pjp
* derived from this software without specific prior written permission
015
2014-11-14
pjp
*
016
2014-11-14
pjp
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
017
2014-11-14
pjp
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
018
2014-11-14
pjp
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
019
2014-11-14
pjp
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
020
2014-11-14
pjp
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
021
2014-11-14
pjp
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
022
2014-11-14
pjp
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
023
2014-11-14
pjp
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
024
2014-11-14
pjp
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
025
2014-11-14
pjp
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
026
2014-11-14
pjp
*
027
2014-11-14
pjp
*/
028
2017-10-26
pjp
029
2017-10-26
pjp
/*
030
2019-06-06
pjp
* $Id: region.c,v 1.7 2019/06/06 14:56:08 pjp Exp $
031
2017-10-26
pjp
*/
032
2017-10-26
pjp
033
2019-06-06
pjp
#include <sys/types.h>
034
2019-06-06
pjp
#include <sys/socket.h>
035
2019-06-06
pjp
036
2019-06-06
pjp
#include <netinet/in.h>
037
2019-06-06
pjp
#include <arpa/inet.h>
038
2019-06-06
pjp
#include <netdb.h>
039
2019-06-06
pjp
040
2019-06-06
pjp
#include <stdio.h>
041
2019-06-06
pjp
#include <stdlib.h>
042
2019-06-06
pjp
#include <string.h>
043
2019-06-06
pjp
#include <errno.h>
044
2019-06-06
pjp
#include <syslog.h>
045
2019-06-06
pjp
046
2019-06-06
pjp
#ifdef __linux__
047
2019-06-06
pjp
#include <grp.h>
048
2019-06-06
pjp
#define __USE_BSD 1
049
2019-06-06
pjp
#include <endian.h>
050
2019-06-06
pjp
#include <bsd/stdlib.h>
051
2019-06-06
pjp
#include <bsd/string.h>
052
2019-06-06
pjp
#include <bsd/sys/queue.h>
053
2019-06-06
pjp
#define __unused
054
2019-06-06
pjp
#include <bsd/sys/tree.h>
055
2019-06-06
pjp
#include <bsd/sys/endian.h>
056
2019-06-06
pjp
#else /* not linux */
057
2019-06-06
pjp
#include <sys/queue.h>
058
2019-06-06
pjp
#include <sys/tree.h>
059
2019-06-06
pjp
#endif /* __linux__ */
060
2019-06-06
pjp
061
2016-07-06
pjp
#include "ddd-dns.h"
062
2016-07-06
pjp
#include "ddd-db.h"
063
2016-07-06
pjp
064
2014-11-14
pjp
u_int8_t find_region(struct sockaddr_storage *, int);
065
2014-11-14
pjp
in_addr_t getmask(int);
066
2014-11-14
pjp
int getmask6(int, struct sockaddr_in6 *);
067
2014-11-14
pjp
void init_region(void);
068
2014-11-14
pjp
int insert_region(char *, char *, u_int8_t);
069
2014-11-14
pjp
070
2017-06-26
pjp
SLIST_HEAD(listhead, regionentry) regionhead;
071
2014-11-14
pjp
072
2017-06-26
pjp
static struct regionentry {
073
2014-11-14
pjp
char name[INET6_ADDRSTRLEN];
074
2014-11-14
pjp
int family;
075
2014-11-14
pjp
struct sockaddr_storage hostmask;
076
2014-11-14
pjp
struct sockaddr_storage netmask;
077
2014-11-14
pjp
u_int8_t region;
078
2014-11-14
pjp
u_int8_t prefixlen;
079
2017-06-26
pjp
SLIST_ENTRY(regionentry) region_entry;
080
2014-11-14
pjp
} *n2, *np;
081
2014-11-14
pjp
082
2014-11-14
pjp
083
2014-11-14
pjp
/*
084
2014-11-14
pjp
* INIT_REGION - initialize the region singly linked list
085
2014-11-14
pjp
*/
086
2014-11-14
pjp
087
2014-11-14
pjp
void
088
2014-11-14
pjp
init_region(void)
089
2014-11-14
pjp
{
090
2017-06-26
pjp
SLIST_INIT(&regionhead);
091
2014-11-14
pjp
return;
092
2014-11-14
pjp
}
093
2014-11-14
pjp
094
2014-11-14
pjp
/*
095
2014-11-14
pjp
* INSERT_REGION - insert particular address and prefix length and region
096
2014-11-14
pjp
* into the
097
2017-06-26
pjp
* singly linked list at "regionhead", if the address
098
2017-06-26
pjp
* contains
099
2014-11-14
pjp
* a colon then it is assumed to be an IPv6 address.
100
2014-11-14
pjp
* return -1 on error, 0 on successful insertion
101
2014-11-14
pjp
*/
102
2014-11-14
pjp
103
2014-11-14
pjp
int
104
2014-11-14
pjp
insert_region(char *address, char *prefixlen, u_int8_t region)
105
2014-11-14
pjp
{
106
2014-11-14
pjp
struct sockaddr_in *sin;
107
2014-11-14
pjp
struct sockaddr_in6 *sin6;
108
2014-11-14
pjp
int pnum;
109
2014-11-14
pjp
int ret;
110
2014-11-14
pjp
111
2014-11-14
pjp
pnum = atoi(prefixlen);
112
2017-06-26
pjp
n2 = malloc(sizeof(struct regionentry)); /* Insert after. */
113
2014-11-14
pjp
114
2014-11-14
pjp
if (strchr(address, ':') != NULL) {
115
2014-11-14
pjp
n2->family = AF_INET6;
116
2014-11-14
pjp
sin6 = (struct sockaddr_in6 *)&n2->hostmask;
117
2014-11-14
pjp
if ((ret = inet_pton(AF_INET6, address, &sin6->sin6_addr.s6_addr)) != 1)
118
2014-11-14
pjp
return (-1);
119
2014-11-14
pjp
sin6->sin6_family = AF_INET6;
120
2014-11-14
pjp
sin6 = (struct sockaddr_in6 *)&n2->netmask;
121
2014-11-14
pjp
sin6->sin6_family = AF_INET6;
122
2014-11-14
pjp
if (getmask6(pnum, sin6) < 0)
123
2014-11-14
pjp
return(-1);
124
2014-11-14
pjp
n2->region = region;
125
2014-11-14
pjp
n2->prefixlen = pnum;
126
2014-11-14
pjp
} else {
127
2014-11-14
pjp
128
2014-11-14
pjp
n2->family = AF_INET;
129
2014-11-14
pjp
sin = (struct sockaddr_in *)&n2->hostmask;
130
2014-11-14
pjp
sin->sin_family = AF_INET;
131
2014-11-14
pjp
sin->sin_addr.s_addr = inet_addr(address);
132
2014-11-14
pjp
sin = (struct sockaddr_in *)&n2->netmask;
133
2014-11-14
pjp
sin->sin_family = AF_INET;
134
2014-11-14
pjp
sin->sin_addr.s_addr = getmask(pnum);
135
2014-11-14
pjp
n2->region = region;
136
2014-11-14
pjp
n2->prefixlen = pnum;
137
2014-11-14
pjp
138
2014-11-14
pjp
}
139
2014-11-14
pjp
140
2017-06-26
pjp
SLIST_INSERT_HEAD(&regionhead, n2, region_entry);
141
2014-11-14
pjp
142
2014-11-14
pjp
return (0);
143
2014-11-14
pjp
}
144
2014-11-14
pjp
145
2014-11-14
pjp
/*
146
2014-11-14
pjp
* FIND_REGION - walk the region list and find the correponding network with
147
2014-11-14
pjp
* the highest prefix length, so that a /24 has more precedence
148
2014-11-14
pjp
* than
149
2014-11-14
pjp
* a /8 for example. IPv6 and IPv4 addresses are kept seperate
150
2014-11-14
pjp
*/
151
2014-11-14
pjp
152
2014-11-14
pjp
u_int8_t
153
2014-11-14
pjp
find_region(struct sockaddr_storage *sst, int family)
154
2014-11-14
pjp
{
155
2014-11-14
pjp
struct sockaddr_in *sin, *sin0;
156
2014-11-14
pjp
struct sockaddr_in6 *sin6, *sin60, *sin61;
157
2014-11-14
pjp
u_int32_t hostmask, netmask;
158
2014-11-14
pjp
u_int32_t a;
159
2014-11-14
pjp
#ifdef __amd64
160
2014-11-14
pjp
u_int64_t *hm[2], *nm[2], *a6[2];
161
2014-11-14
pjp
#else
162
2014-11-14
pjp
u_int32_t *hm[4], *nm[4], *a6[4];
163
2014-11-14
pjp
#endif
164
2014-11-14
pjp
u_int8_t region = 0xff;
165
2014-11-14
pjp
u_int8_t prefixlen = 0;
166
2014-11-14
pjp
167
2017-06-26
pjp
SLIST_FOREACH(np, &regionhead, region_entry) {
168
2014-11-14
pjp
if (np->family == AF_INET) {
169
2014-11-14
pjp
if (family != AF_INET)
170
2014-11-14
pjp
continue;
171
2014-11-14
pjp
sin = (struct sockaddr_in *)sst;
172
2014-11-14
pjp
a = sin->sin_addr.s_addr;
173
2014-11-14
pjp
sin = (struct sockaddr_in *)&np->hostmask;
174
2014-11-14
pjp
sin0 = (struct sockaddr_in *)&np->netmask;
175
2014-11-14
pjp
hostmask = sin->sin_addr.s_addr;
176
2014-11-14
pjp
netmask = sin0->sin_addr.s_addr;
177
2014-11-14
pjp
if ((hostmask & netmask) == (a & netmask)) {
178
2014-11-14
pjp
if (np->prefixlen >= prefixlen) {
179
2014-11-14
pjp
region = np->region;
180
2014-11-14
pjp
prefixlen = np->prefixlen;
181
2014-11-14
pjp
}
182
2014-11-14
pjp
} /* if hostmask */
183
2014-11-14
pjp
} else if (np->family == AF_INET6) {
184
2014-11-14
pjp
if (family != AF_INET6)
185
2014-11-14
pjp
continue;
186
2014-11-14
pjp
sin6 = (struct sockaddr_in6 *)sst;
187
2014-11-14
pjp
sin60 = (struct sockaddr_in6 *)&np->hostmask;
188
2014-11-14
pjp
sin61 = (struct sockaddr_in6 *)&np->netmask;
189
2014-11-14
pjp
#ifdef __amd64
190
2014-11-14
pjp
/*
191
2014-11-14
pjp
* If this is on a 64 bit machine, we'll benefit
192
2014-11-14
pjp
* by using 64 bit registers, this should make it
193
2014-11-14
pjp
* a tad faster...
194
2014-11-14
pjp
*/
195
2014-11-14
pjp
hm[0] = (u_int64_t *)&sin60->sin6_addr.s6_addr;
196
2014-11-14
pjp
hm[1] = (hm[0] + 1);
197
2014-11-14
pjp
nm[0] = (u_int64_t *)&sin61->sin6_addr.s6_addr;
198
2014-11-14
pjp
nm[1] = (nm[0] + 1);
199
2014-11-14
pjp
a6[0] = (u_int64_t *)&sin6->sin6_addr.s6_addr;
200
2014-11-14
pjp
a6[1] = (a6[0] + 1);
201
2014-11-14
pjp
if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
202
2014-11-14
pjp
((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))) {
203
2014-11-14
pjp
#else
204
2014-11-14
pjp
hm[0] = (u_int32_t *)&sin60->sin6_addr.s6_addr;
205
2014-11-14
pjp
hm[1] = (hm[0] + 1); hm[2] = (hm[1] + 1);
206
2014-11-14
pjp
hm[3] = (hm[2] + 1);
207
2014-11-14
pjp
nm[0] = (u_int32_t *)&sin61->sin6_addr.s6_addr;
208
2014-11-14
pjp
nm[1] = (nm[0] + 1); nm[2] = (nm[1] + 1);
209
2014-11-14
pjp
nm[3] = (nm[2] + 1);
210
2014-11-14
pjp
a6[0] = (u_int32_t *)&sin6->sin6_addr.s6_addr;
211
2014-11-14
pjp
a6[1] = (a6[0] + 1); a6[2] = (a6[1] + 1);
212
2014-11-14
pjp
a6[3] = (a6[2] + 1);
213
2014-11-14
pjp
if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
214
2014-11-14
pjp
((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))&&
215
2014-11-14
pjp
((*hm[2] & *nm[2]) == (*a6[2] & *nm[2]))&&
216
2014-11-14
pjp
((*hm[3] & *nm[3]) == (*a6[3] & *nm[3]))) {
217
2014-11-14
pjp
#endif
218
2014-11-14
pjp
219
2014-11-14
pjp
if (np->prefixlen >= prefixlen) {
220
2014-11-14
pjp
region = np->region;
221
2014-11-14
pjp
prefixlen = np->prefixlen;
222
2014-11-14
pjp
}
223
2014-11-14
pjp
} /* if ip6 address */
224
2014-11-14
pjp
225
2014-11-14
pjp
} /* if AF_INET6 */
226
2014-11-14
pjp
} /* SLIST */
227
2014-11-14
pjp
228
2014-11-14
pjp
return (region);
229
2014-11-14
pjp
}
230
2014-11-14
pjp
231
2014-11-14
pjp
/*
232
2014-11-14
pjp
* GETMASK - get the v4 netmask given by prefix length, return netmask in
233
2014-11-14
pjp
* network byte order, function can't fail unless prefix length
234
2014-11-14
pjp
* supplied is > 32
235
2014-11-14
pjp
*/
236
2014-11-14
pjp
237
2014-11-14
pjp
in_addr_t
238
2014-11-14
pjp
getmask(int prefixlen)
239
2014-11-14
pjp
{
240
2014-11-14
pjp
in_addr_t ret = 0xffffffff;
241
2014-11-14
pjp
242
2014-11-14
pjp
/* I know it's cheating */
243
2014-11-14
pjp
if (prefixlen > 31)
244
2014-11-14
pjp
return (htonl(ret));
245
2014-11-14
pjp
246
2014-11-14
pjp
ret >>= prefixlen; /* 0x00ffffff */
247
2014-11-14
pjp
ret = ~ret; /* 0xff000000 */
248
2014-11-14
pjp
249
2014-11-14
pjp
return (htonl(ret));
250
2014-11-14
pjp
}
251
2014-11-14
pjp
252
2014-11-14
pjp
/*
253
2014-11-14
pjp
* GETMASK6 - like getmask() but works on a supplied sockaddr_in6 instead of
254
2014-11-14
pjp
* returning results as return address. Function cannot fail
255
2014-11-14
pjp
* unless prefix length supplied is > 128. At which point a buffer
256
2014-11-14
pjp
* overflow is possible.
257
2014-11-14
pjp
*/
258
2014-11-14
pjp
259
2014-11-14
pjp
int
260
2014-11-14
pjp
getmask6(int prefixlen, struct sockaddr_in6 *sin6)
261
2014-11-14
pjp
{
262
2014-11-14
pjp
int i, j;
263
2014-11-14
pjp
u_int32_t *nm[4];
264
2014-11-14
pjp
265
2014-11-14
pjp
if (prefixlen > 128 || prefixlen < 0)
266
2014-11-14
pjp
return (-1);
267
2014-11-14
pjp
268
2014-11-14
pjp
memset(&sin6->sin6_addr.s6_addr, 0xff, sizeof(sin6->sin6_addr.s6_addr));
269
2014-11-14
pjp
nm[0] = (u_int32_t *)sin6->sin6_addr.s6_addr;
270
2014-11-14
pjp
nm[1] = (nm[0] + 1); nm[2] = (nm[1] + 1);
271
2014-11-14
pjp
nm[3] = (nm[2] + 1);
272
2014-11-14
pjp
273
2014-11-14
pjp
for (i = 0, j = 0; j < prefixlen; j++) {
274
2014-11-14
pjp
if (*nm[i] == 1) {
275
2014-11-14
pjp
*nm[i] = 0;
276
2014-11-14
pjp
i++;
277
2014-11-14
pjp
} else
278
2014-11-14
pjp
*nm[i] >>= 1;
279
2014-11-14
pjp
}
280
2014-11-14
pjp
*nm[0] = htonl(~ *nm[0]);
281
2014-11-14
pjp
*nm[1] = htonl(~ *nm[1]);
282
2014-11-14
pjp
*nm[2] = htonl(~ *nm[2]);
283
2014-11-14
pjp
*nm[3] = htonl(~ *nm[3]);
284
2014-11-14
pjp
285
2014-11-14
pjp
return (0);
286
2014-11-14
pjp
}
repomaster@centroid.eu