Blame


1 d9a2aaa3 2010-04-07 pbug /*
2 48603f7d 2014-04-13 pjp * Copyright (c) 2010-2014 Peter J. Philipp
3 d9a2aaa3 2010-04-07 pbug * All rights reserved.
4 d9a2aaa3 2010-04-07 pbug *
5 d9a2aaa3 2010-04-07 pbug * Redistribution and use in source and binary forms, with or without
6 d9a2aaa3 2010-04-07 pbug * modification, are permitted provided that the following conditions
7 d9a2aaa3 2010-04-07 pbug * are met:
8 d9a2aaa3 2010-04-07 pbug * 1. Redistributions of source code must retain the above copyright
9 d9a2aaa3 2010-04-07 pbug * notice, this list of conditions and the following disclaimer.
10 d9a2aaa3 2010-04-07 pbug * 2. Redistributions in binary form must reproduce the above copyright
11 d9a2aaa3 2010-04-07 pbug * notice, this list of conditions and the following disclaimer in the
12 d9a2aaa3 2010-04-07 pbug * documentation and/or other materials provided with the distribution.
13 d9a2aaa3 2010-04-07 pbug * 3. The name of the author may not be used to endorse or promote products
14 d9a2aaa3 2010-04-07 pbug * derived from this software without specific prior written permission
15 d9a2aaa3 2010-04-07 pbug *
16 d9a2aaa3 2010-04-07 pbug * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 d9a2aaa3 2010-04-07 pbug * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 d9a2aaa3 2010-04-07 pbug * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 d9a2aaa3 2010-04-07 pbug * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 d9a2aaa3 2010-04-07 pbug * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 d9a2aaa3 2010-04-07 pbug * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 d9a2aaa3 2010-04-07 pbug * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 d9a2aaa3 2010-04-07 pbug * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 d9a2aaa3 2010-04-07 pbug * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 d9a2aaa3 2010-04-07 pbug * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 d9a2aaa3 2010-04-07 pbug *
27 d9a2aaa3 2010-04-07 pbug */
28 d9a2aaa3 2010-04-07 pbug #include "include.h"
29 d9a2aaa3 2010-04-07 pbug #include "dns.h"
30 d9a2aaa3 2010-04-07 pbug #include "db.h"
31 d9a2aaa3 2010-04-07 pbug
32 0e7d94ac 2014-05-18 pjp extern in_addr_t getmask(int);
33 0e7d94ac 2014-05-18 pjp extern int getmask6(int, struct sockaddr_in6 *);
34 d9a2aaa3 2010-04-07 pbug
35 0e7d94ac 2014-05-18 pjp int find_wildcard(struct sockaddr_storage *, int);
36 0e7d94ac 2014-05-18 pjp void init_wildcard(void);
37 0e7d94ac 2014-05-18 pjp int insert_wildcard(char *, char *);
38 0e7d94ac 2014-05-18 pjp
39 d9a2aaa3 2010-04-07 pbug SLIST_HEAD(listhead, wildentry) wildhead;
40 d9a2aaa3 2010-04-07 pbug
41 c0963faf 2014-05-01 pjp static struct wildentry {
42 d9a2aaa3 2010-04-07 pbug char name[INET6_ADDRSTRLEN];
43 d9a2aaa3 2010-04-07 pbug int family;
44 d9a2aaa3 2010-04-07 pbug struct sockaddr_storage hostmask;
45 d9a2aaa3 2010-04-07 pbug struct sockaddr_storage netmask;
46 d9a2aaa3 2010-04-07 pbug u_int8_t prefixlen;
47 c0963faf 2014-05-01 pjp SLIST_ENTRY(wildentry) wildcard_entry;
48 c0963faf 2014-05-01 pjp } *wn2, *wnp;
49 d9a2aaa3 2010-04-07 pbug
50 d9a2aaa3 2010-04-07 pbug
51 0e7d94ac 2014-05-18 pjp static const char rcsid[] = "$Id: wildcard.c,v 1.7 2014/05/18 17:14:05 pjp Exp $";
52 d9a2aaa3 2010-04-07 pbug
53 d9a2aaa3 2010-04-07 pbug /*
54 d9a2aaa3 2010-04-07 pbug * INIT_WILDCARD - initialize the wildcard singly linked list
55 d9a2aaa3 2010-04-07 pbug */
56 d9a2aaa3 2010-04-07 pbug
57 d9a2aaa3 2010-04-07 pbug void
58 d9a2aaa3 2010-04-07 pbug init_wildcard(void)
59 d9a2aaa3 2010-04-07 pbug {
60 d9a2aaa3 2010-04-07 pbug SLIST_INIT(&wildhead);
61 d9a2aaa3 2010-04-07 pbug return;
62 d9a2aaa3 2010-04-07 pbug }
63 d9a2aaa3 2010-04-07 pbug
64 d9a2aaa3 2010-04-07 pbug /*
65 d9a2aaa3 2010-04-07 pbug * INSERT_WILDCARD - insert an address and prefixlen into the wildcard slist
66 d9a2aaa3 2010-04-07 pbug */
67 d9a2aaa3 2010-04-07 pbug
68 d9a2aaa3 2010-04-07 pbug int
69 d9a2aaa3 2010-04-07 pbug insert_wildcard(char *address, char *prefixlen)
70 d9a2aaa3 2010-04-07 pbug {
71 d9a2aaa3 2010-04-07 pbug struct sockaddr_in *sin;
72 d9a2aaa3 2010-04-07 pbug struct sockaddr_in6 *sin6;
73 d9a2aaa3 2010-04-07 pbug int pnum;
74 d9a2aaa3 2010-04-07 pbug int ret;
75 d9a2aaa3 2010-04-07 pbug
76 d9a2aaa3 2010-04-07 pbug pnum = atoi(prefixlen);
77 d9a2aaa3 2010-04-07 pbug wn2 = malloc(sizeof(struct wildentry)); /* Insert after. */
78 d9a2aaa3 2010-04-07 pbug
79 d9a2aaa3 2010-04-07 pbug if (strchr(address, ':') != NULL) {
80 d9a2aaa3 2010-04-07 pbug wn2->family = AF_INET6;
81 d9a2aaa3 2010-04-07 pbug sin6 = (struct sockaddr_in6 *)&wn2->hostmask;
82 d9a2aaa3 2010-04-07 pbug if ((ret = inet_pton(AF_INET6, address, &sin6->sin6_addr.s6_addr)) != 1)
83 d9a2aaa3 2010-04-07 pbug return (-1);
84 d9a2aaa3 2010-04-07 pbug sin6->sin6_family = AF_INET6;
85 d9a2aaa3 2010-04-07 pbug sin6 = (struct sockaddr_in6 *)&wn2->netmask;
86 d9a2aaa3 2010-04-07 pbug sin6->sin6_family = AF_INET6;
87 d9a2aaa3 2010-04-07 pbug if (getmask6(pnum, sin6) < 0)
88 d9a2aaa3 2010-04-07 pbug return(-1);
89 d9a2aaa3 2010-04-07 pbug wn2->prefixlen = pnum;
90 d9a2aaa3 2010-04-07 pbug } else {
91 d9a2aaa3 2010-04-07 pbug
92 d9a2aaa3 2010-04-07 pbug wn2->family = AF_INET;
93 d9a2aaa3 2010-04-07 pbug sin = (struct sockaddr_in *)&wn2->hostmask;
94 d9a2aaa3 2010-04-07 pbug sin->sin_family = AF_INET;
95 d9a2aaa3 2010-04-07 pbug sin->sin_addr.s_addr = inet_addr(address);
96 d9a2aaa3 2010-04-07 pbug sin = (struct sockaddr_in *)&wn2->netmask;
97 d9a2aaa3 2010-04-07 pbug sin->sin_family = AF_INET;
98 d9a2aaa3 2010-04-07 pbug sin->sin_addr.s_addr = getmask(pnum);
99 d9a2aaa3 2010-04-07 pbug wn2->prefixlen = pnum;
100 d9a2aaa3 2010-04-07 pbug
101 d9a2aaa3 2010-04-07 pbug }
102 d9a2aaa3 2010-04-07 pbug
103 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&wildhead, wn2, wildcard_entry);
104 d9a2aaa3 2010-04-07 pbug
105 d9a2aaa3 2010-04-07 pbug return (0);
106 d9a2aaa3 2010-04-07 pbug }
107 d9a2aaa3 2010-04-07 pbug
108 d9a2aaa3 2010-04-07 pbug /*
109 d9a2aaa3 2010-04-07 pbug * FIND_WILDCARD - walk the wildcard list and find the correponding network
110 d9a2aaa3 2010-04-07 pbug * if a network matches return 1, if no match is found return
111 d9a2aaa3 2010-04-07 pbug * 0.
112 d9a2aaa3 2010-04-07 pbug */
113 d9a2aaa3 2010-04-07 pbug
114 d9a2aaa3 2010-04-07 pbug int
115 d9a2aaa3 2010-04-07 pbug find_wildcard(struct sockaddr_storage *sst, int family)
116 d9a2aaa3 2010-04-07 pbug {
117 d9a2aaa3 2010-04-07 pbug struct sockaddr_in *sin, *sin0;
118 d9a2aaa3 2010-04-07 pbug struct sockaddr_in6 *sin6, *sin60, *sin61;
119 d9a2aaa3 2010-04-07 pbug u_int32_t hostmask, netmask;
120 d9a2aaa3 2010-04-07 pbug u_int32_t a;
121 d9a2aaa3 2010-04-07 pbug #ifdef __amd64
122 d9a2aaa3 2010-04-07 pbug u_int64_t *hm[2], *nm[2], *a6[2];
123 d9a2aaa3 2010-04-07 pbug #else
124 d9a2aaa3 2010-04-07 pbug u_int32_t *hm[4], *nm[4], *a6[4];
125 d9a2aaa3 2010-04-07 pbug #endif
126 d9a2aaa3 2010-04-07 pbug
127 c0963faf 2014-05-01 pjp SLIST_FOREACH(wnp, &wildhead, wildcard_entry) {
128 d9a2aaa3 2010-04-07 pbug if (wnp->family == AF_INET) {
129 d9a2aaa3 2010-04-07 pbug if (family != AF_INET)
130 d9a2aaa3 2010-04-07 pbug continue;
131 d9a2aaa3 2010-04-07 pbug sin = (struct sockaddr_in *)sst;
132 d9a2aaa3 2010-04-07 pbug a = sin->sin_addr.s_addr;
133 d9a2aaa3 2010-04-07 pbug sin = (struct sockaddr_in *)&wnp->hostmask;
134 d9a2aaa3 2010-04-07 pbug sin0 = (struct sockaddr_in *)&wnp->netmask;
135 d9a2aaa3 2010-04-07 pbug hostmask = sin->sin_addr.s_addr;
136 d9a2aaa3 2010-04-07 pbug netmask = sin0->sin_addr.s_addr;
137 d9a2aaa3 2010-04-07 pbug if ((hostmask & netmask) == (a & netmask)) {
138 d9a2aaa3 2010-04-07 pbug return (1);
139 d9a2aaa3 2010-04-07 pbug } /* if hostmask */
140 d9a2aaa3 2010-04-07 pbug } else if (wnp->family == AF_INET6) {
141 d9a2aaa3 2010-04-07 pbug if (family != AF_INET6)
142 d9a2aaa3 2010-04-07 pbug continue;
143 d9a2aaa3 2010-04-07 pbug sin6 = (struct sockaddr_in6 *)sst;
144 d9a2aaa3 2010-04-07 pbug sin60 = (struct sockaddr_in6 *)&wnp->hostmask;
145 d9a2aaa3 2010-04-07 pbug sin61 = (struct sockaddr_in6 *)&wnp->netmask;
146 d9a2aaa3 2010-04-07 pbug #ifdef __amd64
147 d9a2aaa3 2010-04-07 pbug /*
148 d9a2aaa3 2010-04-07 pbug * If this is on a 64 bit machine, we'll benefit
149 d9a2aaa3 2010-04-07 pbug * by using 64 bit registers, this should make it
150 d9a2aaa3 2010-04-07 pbug * a tad faster...
151 d9a2aaa3 2010-04-07 pbug */
152 d9a2aaa3 2010-04-07 pbug hm[0] = (u_int64_t *)&sin60->sin6_addr.s6_addr;
153 d9a2aaa3 2010-04-07 pbug hm[1] = (hm[0] + 1);
154 d9a2aaa3 2010-04-07 pbug nm[0] = (u_int64_t *)&sin61->sin6_addr.s6_addr;
155 d9a2aaa3 2010-04-07 pbug nm[1] = (nm[0] + 1);
156 d9a2aaa3 2010-04-07 pbug a6[0] = (u_int64_t *)&sin6->sin6_addr.s6_addr;
157 d9a2aaa3 2010-04-07 pbug a6[1] = (a6[0] + 1);
158 d9a2aaa3 2010-04-07 pbug if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
159 d9a2aaa3 2010-04-07 pbug ((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))) {
160 d9a2aaa3 2010-04-07 pbug #else
161 d9a2aaa3 2010-04-07 pbug hm[0] = (u_int32_t *)&sin60->sin6_addr.s6_addr;
162 d9a2aaa3 2010-04-07 pbug hm[1] = (hm[0] + 1); hm[2] = (hm[1] + 1);
163 d9a2aaa3 2010-04-07 pbug hm[3] = (hm[2] + 1);
164 d9a2aaa3 2010-04-07 pbug nm[0] = (u_int32_t *)&sin61->sin6_addr.s6_addr;
165 d9a2aaa3 2010-04-07 pbug nm[1] = (nm[0] + 1); nm[2] = (nm[1] + 1);
166 d9a2aaa3 2010-04-07 pbug nm[3] = (nm[2] + 1);
167 d9a2aaa3 2010-04-07 pbug a6[0] = (u_int32_t *)&sin6->sin6_addr.s6_addr;
168 d9a2aaa3 2010-04-07 pbug a6[1] = (a6[0] + 1); a6[2] = (a6[1] + 1);
169 d9a2aaa3 2010-04-07 pbug a6[3] = (a6[2] + 1);
170 d9a2aaa3 2010-04-07 pbug
171 d9a2aaa3 2010-04-07 pbug if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
172 d9a2aaa3 2010-04-07 pbug ((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))&&
173 d9a2aaa3 2010-04-07 pbug ((*hm[2] & *nm[2]) == (*a6[2] & *nm[2]))&&
174 d9a2aaa3 2010-04-07 pbug ((*hm[3] & *nm[3]) == (*a6[3] & *nm[3]))) {
175 d9a2aaa3 2010-04-07 pbug #endif
176 d9a2aaa3 2010-04-07 pbug
177 d9a2aaa3 2010-04-07 pbug return (1);
178 d9a2aaa3 2010-04-07 pbug } /* if ip6 address */
179 d9a2aaa3 2010-04-07 pbug
180 d9a2aaa3 2010-04-07 pbug } /* if AF_INET6 */
181 d9a2aaa3 2010-04-07 pbug } /* SLIST */
182 d9a2aaa3 2010-04-07 pbug
183 d9a2aaa3 2010-04-07 pbug return (0);
184 d9a2aaa3 2010-04-07 pbug }