1 /* $NetBSD: rdata_test.c,v 1.4 2014/12/10 04:37:59 christos Exp $ */
2
3 /*
4 * Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /* Id */
20
21 /*! \file */
22
23 #include <config.h>
24
25 #include <atf-c.h>
26
27 #include <unistd.h>
28
29 #include <isc/types.h>
30
31 #include <dns/rdata.h>
32
33 #include "dnstest.h"
34
35
36 /*
37 * Individual unit tests
38 */
39
40 /* Successful load test */
41 ATF_TC(hip);
ATF_TC_HEAD(hip,tc)42 ATF_TC_HEAD(hip, tc) {
43 atf_tc_set_md_var(tc, "descr", "that a oversized HIP record will "
44 "be rejected");
45 }
ATF_TC_BODY(hip,tc)46 ATF_TC_BODY(hip, tc) {
47 unsigned char hipwire[DNS_RDATA_MAXLENGTH] = {
48 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
49 0x04, 0x41, 0x42, 0x43, 0x44, 0x00 };
50 unsigned char buf[1024*1024];
51 isc_buffer_t source, target;
52 dns_rdata_t rdata;
53 dns_decompress_t dctx;
54 isc_result_t result;
55 size_t i;
56
57 UNUSED(tc);
58
59 /*
60 * Fill the rest of input buffer with compression pointers.
61 */
62 for (i = 12; i < sizeof(hipwire) - 2; i += 2) {
63 hipwire[i] = 0xc0;
64 hipwire[i+1] = 0x06;
65 }
66
67 isc_buffer_init(&source, hipwire, sizeof(hipwire));
68 isc_buffer_add(&source, sizeof(hipwire));
69 isc_buffer_setactive(&source, i);
70 isc_buffer_init(&target, buf, sizeof(buf));
71 dns_rdata_init(&rdata);
72 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
73 result = dns_rdata_fromwire(&rdata, dns_rdataclass_in,
74 dns_rdatatype_hip, &source, &dctx,
75 0, &target);
76 dns_decompress_invalidate(&dctx);
77 ATF_REQUIRE_EQ(result, DNS_R_FORMERR);
78 }
79
80 ATF_TC(edns_client_subnet);
ATF_TC_HEAD(edns_client_subnet,tc)81 ATF_TC_HEAD(edns_client_subnet, tc) {
82 atf_tc_set_md_var(tc, "descr",
83 "check EDNS client subnet option parsing");
84 }
ATF_TC_BODY(edns_client_subnet,tc)85 ATF_TC_BODY(edns_client_subnet, tc) {
86 struct {
87 unsigned char data[64];
88 size_t len;
89 isc_boolean_t ok;
90 } test_data[] = {
91 {
92 /* option code with no content */
93 { 0x00, 0x08, 0x0, 0x00 }, 4, ISC_FALSE
94 },
95 {
96 /* Option code family 0, source 0, scope 0 */
97 {
98 0x00, 0x08, 0x00, 0x04,
99 0x00, 0x00, 0x00, 0x00
100 },
101 8, ISC_TRUE
102 },
103 {
104 /* Option code family 1 (ipv4), source 0, scope 0 */
105 {
106 0x00, 0x08, 0x00, 0x04,
107 0x00, 0x01, 0x00, 0x00
108 },
109 8, ISC_TRUE
110 },
111 {
112 /* Option code family 2 (ipv6) , source 0, scope 0 */
113 {
114 0x00, 0x08, 0x00, 0x04,
115 0x00, 0x02, 0x00, 0x00
116 },
117 8, ISC_TRUE
118 },
119 {
120 /* extra octet */
121 {
122 0x00, 0x08, 0x00, 0x05,
123 0x00, 0x00, 0x00, 0x00,
124 0x00
125 },
126 9, ISC_FALSE
127 },
128 {
129 /* source too long for IPv4 */
130 {
131 0x00, 0x08, 0x00, 8,
132 0x00, 0x01, 33, 0x00,
133 0x00, 0x00, 0x00, 0x00
134 },
135 12, ISC_FALSE
136 },
137 {
138 /* source too long for IPv6 */
139 {
140 0x00, 0x08, 0x00, 20,
141 0x00, 0x02, 129, 0x00,
142 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00,
146 },
147 24, ISC_FALSE
148 },
149 {
150 /* scope too long for IPv4 */
151 {
152 0x00, 0x08, 0x00, 8,
153 0x00, 0x01, 0x00, 33,
154 0x00, 0x00, 0x00, 0x00
155 },
156 12, ISC_FALSE
157 },
158 {
159 /* scope too long for IPv6 */
160 {
161 0x00, 0x08, 0x00, 20,
162 0x00, 0x02, 0x00, 129,
163 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00,
167 },
168 24, ISC_FALSE
169 },
170 {
171 /* length too short for source generic */
172 {
173 0x00, 0x08, 0x00, 5,
174 0x00, 0x00, 17, 0x00,
175 0x00, 0x00,
176 },
177 19, ISC_FALSE
178 },
179 {
180 /* length too short for source ipv4 */
181 {
182 0x00, 0x08, 0x00, 7,
183 0x00, 0x01, 32, 0x00,
184 0x00, 0x00, 0x00, 0x00
185 },
186 11, ISC_FALSE
187 },
188 {
189 /* length too short for source ipv6 */
190 {
191 0x00, 0x08, 0x00, 19,
192 0x00, 0x02, 128, 0x00,
193 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00,
197 },
198 23, ISC_FALSE
199 },
200 {
201 /* sentinal */
202 { 0x00 }, 0, ISC_FALSE
203 }
204 };
205 unsigned char buf[1024*1024];
206 isc_buffer_t source, target;
207 dns_rdata_t rdata;
208 dns_decompress_t dctx;
209 isc_result_t result;
210 size_t i;
211
212 UNUSED(tc);
213
214 for (i = 0; test_data[i].len != 0; i++) {
215 isc_buffer_init(&source, test_data[i].data, test_data[i].len);
216 isc_buffer_add(&source, test_data[i].len);
217 isc_buffer_setactive(&source, test_data[i].len);
218 isc_buffer_init(&target, buf, sizeof(buf));
219 dns_rdata_init(&rdata);
220 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
221 result = dns_rdata_fromwire(&rdata, dns_rdataclass_in,
222 dns_rdatatype_opt, &source,
223 &dctx, 0, &target);
224 dns_decompress_invalidate(&dctx);
225 if (test_data[i].ok)
226 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
227 else
228 ATF_REQUIRE(result != ISC_R_SUCCESS);
229 }
230 }
231
232 ATF_TC(wks);
ATF_TC_HEAD(wks,tc)233 ATF_TC_HEAD(wks, tc) {
234 atf_tc_set_md_var(tc, "descr", "wks to/from struct");
235 }
ATF_TC_BODY(wks,tc)236 ATF_TC_BODY(wks, tc) {
237 struct {
238 unsigned char data[64];
239 size_t len;
240 isc_boolean_t ok;
241 } test_data[] = {
242 {
243 /* too short */
244 { 0x00, 0x08, 0x0, 0x00 }, 4, ISC_FALSE
245 },
246 {
247 /* minimal TCP */
248 { 0x00, 0x08, 0x0, 0x00, 6 }, 5, ISC_TRUE
249 },
250 {
251 /* minimal UDP */
252 { 0x00, 0x08, 0x0, 0x00, 17 }, 5, ISC_TRUE
253 },
254 {
255 /* minimal other */
256 { 0x00, 0x08, 0x0, 0x00, 1 }, 5, ISC_TRUE
257 },
258 {
259 /* sentinal */
260 { 0x00 }, 0, ISC_FALSE
261 }
262 };
263 unsigned char buf1[1024];
264 unsigned char buf2[1024];
265 isc_buffer_t source, target1, target2;
266 dns_rdata_t rdata;
267 dns_decompress_t dctx;
268 isc_result_t result;
269 size_t i;
270 dns_rdata_in_wks_t wks;
271
272 UNUSED(tc);
273
274 for (i = 0; test_data[i].len != 0; i++) {
275 isc_buffer_init(&source, test_data[i].data, test_data[i].len);
276 isc_buffer_add(&source, test_data[i].len);
277 isc_buffer_setactive(&source, test_data[i].len);
278 isc_buffer_init(&target1, buf1, sizeof(buf1));
279 dns_rdata_init(&rdata);
280 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
281 result = dns_rdata_fromwire(&rdata, dns_rdataclass_in,
282 dns_rdatatype_wks, &source,
283 &dctx, 0, &target1);
284 dns_decompress_invalidate(&dctx);
285 if (test_data[i].ok)
286 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
287 else
288 ATF_REQUIRE(result != ISC_R_SUCCESS);
289 if (result != ISC_R_SUCCESS)
290 continue;
291 result = dns_rdata_tostruct(&rdata, &wks, NULL);
292 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
293 isc_buffer_init(&target2, buf2, sizeof(buf2));
294 dns_rdata_reset(&rdata);
295 result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
296 dns_rdatatype_wks, &wks,
297 &target2);
298 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
299 ATF_REQUIRE_EQ(isc_buffer_usedlength(&target2),
300 test_data[i].len);
301 ATF_REQUIRE_EQ(memcmp(buf2, test_data[i].data,
302 test_data[i].len), 0);
303 }
304 }
305
306 ATF_TC(isdn);
ATF_TC_HEAD(isdn,tc)307 ATF_TC_HEAD(isdn, tc) {
308 atf_tc_set_md_var(tc, "descr", "isdn to/from struct");
309 }
ATF_TC_BODY(isdn,tc)310 ATF_TC_BODY(isdn, tc) {
311 struct {
312 unsigned char data[64];
313 size_t len;
314 isc_boolean_t ok;
315 } test_data[] = {
316 {
317 /* "" */
318 { 0x00 }, 1, ISC_TRUE
319 },
320 {
321 /* "\001" */
322 { 0x1, 0x01 }, 2, ISC_TRUE
323 },
324 {
325 /* "\001" "" */
326 { 0x1, 0x01, 0x00 }, 3, ISC_TRUE
327 },
328 {
329 /* "\000" "\001" */
330 { 0x1, 0x01, 0x01, 0x01 }, 4, ISC_TRUE
331 },
332 {
333 /* sentinal */
334 { 0x00 }, 0, ISC_FALSE
335 }
336 };
337 unsigned char buf1[1024];
338 unsigned char buf2[1024];
339 isc_buffer_t source, target1, target2;
340 dns_rdata_t rdata;
341 dns_decompress_t dctx;
342 isc_result_t result;
343 size_t i;
344 dns_rdata_isdn_t isdn;
345
346 UNUSED(tc);
347
348 for (i = 0; test_data[i].len != 0; i++) {
349 isc_buffer_init(&source, test_data[i].data, test_data[i].len);
350 isc_buffer_add(&source, test_data[i].len);
351 isc_buffer_setactive(&source, test_data[i].len);
352 isc_buffer_init(&target1, buf1, sizeof(buf1));
353 dns_rdata_init(&rdata);
354 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
355 result = dns_rdata_fromwire(&rdata, dns_rdataclass_in,
356 dns_rdatatype_isdn, &source,
357 &dctx, 0, &target1);
358 dns_decompress_invalidate(&dctx);
359 if (test_data[i].ok)
360 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
361 else
362 ATF_REQUIRE(result != ISC_R_SUCCESS);
363 if (result != ISC_R_SUCCESS)
364 continue;
365 result = dns_rdata_tostruct(&rdata, &isdn, NULL);
366 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
367 isc_buffer_init(&target2, buf2, sizeof(buf2));
368 dns_rdata_reset(&rdata);
369 result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
370 dns_rdatatype_isdn, &isdn,
371 &target2);
372 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
373 ATF_REQUIRE_EQ(isc_buffer_usedlength(&target2),
374 test_data[i].len);
375 ATF_REQUIRE_EQ(memcmp(buf2, test_data[i].data,
376 test_data[i].len), 0);
377 }
378 }
379
380 /*
381 * Main
382 */
ATF_TP_ADD_TCS(tp)383 ATF_TP_ADD_TCS(tp) {
384 ATF_TP_ADD_TC(tp, hip);
385 ATF_TP_ADD_TC(tp, edns_client_subnet);
386 ATF_TP_ADD_TC(tp, wks);
387 ATF_TP_ADD_TC(tp, isdn);
388
389 return (atf_no_error());
390 }
391
392