1 /*
2 * DNS Reply Tool (drool)
3 *
4 * Copyright (c) 2017-2018, OARC, Inc.
5 * Copyright (c) 2017, Comcast Corporation
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. Neither the name of the copyright holder nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #include "config.h"
39
40 #include "query.h"
41 #include "assert.h"
42
43 #include <string.h>
44 #include <stdlib.h>
45
46 /*
47 * New/Free
48 */
49
query_new(void)50 drool_query_t* query_new(void)
51 {
52 return calloc(1, sizeof(drool_query_t));
53 }
54
query_free(drool_query_t * query)55 void query_free(drool_query_t* query)
56 {
57 drool_assert(query);
58 if (query) {
59 if (query->raw) {
60 free(query->raw);
61 }
62 free(query);
63 }
64 }
65
66 /*
67 * Have functions
68 */
69
query_is_udp(const drool_query_t * query)70 inline int query_is_udp(const drool_query_t* query)
71 {
72 drool_assert(query);
73 return query->is_udp;
74 }
75
query_is_tcp(const drool_query_t * query)76 inline int query_is_tcp(const drool_query_t* query)
77 {
78 drool_assert(query);
79 return query->is_tcp;
80 }
81
query_have_ipv4(const drool_query_t * query)82 inline int query_have_ipv4(const drool_query_t* query)
83 {
84 drool_assert(query);
85 return query->have_ipv4;
86 }
87
query_have_ipv6(const drool_query_t * query)88 inline int query_have_ipv6(const drool_query_t* query)
89 {
90 drool_assert(query);
91 return query->have_ipv6;
92 }
93
query_have_port(const drool_query_t * query)94 inline int query_have_port(const drool_query_t* query)
95 {
96 drool_assert(query);
97 return query->have_port;
98 }
99
query_have_raw(const drool_query_t * query)100 inline int query_have_raw(const drool_query_t* query)
101 {
102 drool_assert(query);
103 return query->have_raw;
104 }
105
106 /*
107 * Get functions
108 */
109
query_ip(const drool_query_t * query)110 inline const struct in_addr* query_ip(const drool_query_t* query)
111 {
112 drool_assert(query);
113
114 if (!query->have_ipv4)
115 return 0;
116
117 return &(query->addr.ip_dst);
118 }
119
query_ip6(const drool_query_t * query)120 inline const struct in6_addr* query_ip6(const drool_query_t* query)
121 {
122 drool_assert(query);
123
124 if (!query->have_ipv6)
125 return 0;
126
127 return &(query->addr.ip6_dst);
128 }
129
query_port(const drool_query_t * query)130 inline uint16_t query_port(const drool_query_t* query)
131 {
132 drool_assert(query);
133 return query->port;
134 }
135
query_length(const drool_query_t * query)136 inline size_t query_length(const drool_query_t* query)
137 {
138 drool_assert(query);
139 return query->length;
140 }
141
query_raw(const drool_query_t * query)142 inline const u_char* query_raw(const drool_query_t* query)
143 {
144 drool_assert(query);
145 return query->raw ? query->raw : query->small;
146 }
147
148 /*
149 * Set functions
150 */
151
query_set_udp(drool_query_t * query)152 int query_set_udp(drool_query_t* query)
153 {
154 drool_assert(query);
155 if (!query) {
156 return 1;
157 }
158 if (query->is_tcp) {
159 return 1;
160 }
161
162 query->is_udp = 1;
163
164 return 0;
165 }
166
query_set_tcp(drool_query_t * query)167 int query_set_tcp(drool_query_t* query)
168 {
169 drool_assert(query);
170 if (!query) {
171 return 1;
172 }
173 if (query->is_udp) {
174 return 1;
175 }
176
177 query->is_tcp = 1;
178
179 return 0;
180 }
181
query_set_ip(drool_query_t * query,const struct in_addr * addr)182 int query_set_ip(drool_query_t* query, const struct in_addr* addr)
183 {
184 drool_assert(query);
185 if (!query) {
186 return 1;
187 }
188 if (!addr) {
189 return 1;
190 }
191 if (query->have_ipv6) {
192 return 1;
193 }
194
195 memcpy(&(query->addr.ip_dst), addr, sizeof(struct in_addr));
196 query->have_ipv4 = 1;
197
198 return 0;
199 }
200
query_set_ip6(drool_query_t * query,const struct in6_addr * addr)201 int query_set_ip6(drool_query_t* query, const struct in6_addr* addr)
202 {
203 drool_assert(query);
204 if (!addr) {
205 return 1;
206 }
207 if (query->have_ipv4) {
208 return 1;
209 }
210
211 memcpy(&(query->addr.ip6_dst), addr, sizeof(struct in6_addr));
212 query->have_ipv6 = 1;
213
214 return 0;
215 }
216
query_set_port(drool_query_t * query,uint16_t port)217 int query_set_port(drool_query_t* query, uint16_t port)
218 {
219 drool_assert(query);
220 if (!query) {
221 return 1;
222 }
223 if (!port) {
224 return 1;
225 }
226
227 query->port = port;
228
229 return 0;
230 }
231
query_set_raw(drool_query_t * query,const u_char * raw,size_t length)232 int query_set_raw(drool_query_t* query, const u_char* raw, size_t length)
233 {
234 drool_assert(query);
235 if (!query) {
236 return 1;
237 }
238 if (!raw) {
239 return 1;
240 }
241 if (!length) {
242 return 1;
243 }
244
245 if (query->raw) {
246 free(query->raw);
247 query->raw = 0;
248 query->length = 0;
249 query->have_raw = 0;
250 }
251 if (length > sizeof(query->small)) {
252 if (!(query->raw = calloc(length, 1))) {
253 return 1;
254 }
255 memcpy(query->raw, raw, length);
256 } else {
257 memcpy(query->small, raw, length);
258 }
259 query->length = length;
260 query->have_raw = 1;
261
262 return 0;
263 }
264