Blame


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