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