]>
Commit | Line | Data |
---|---|---|
f282cdbe | 1 | /* Test the RES_NOAAAA resolver option. |
dff8da6b | 2 | Copyright (C) 2022-2024 Free Software Foundation, Inc. |
f282cdbe FW |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
17 | <https://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #include <errno.h> | |
20 | #include <netdb.h> | |
21 | #include <resolv.h> | |
22 | #include <stdlib.h> | |
23 | #include <support/check.h> | |
24 | #include <support/check_nss.h> | |
25 | #include <support/resolv_test.h> | |
26 | #include <support/support.h> | |
27 | ||
28 | /* Used to keep track of the number of queries. */ | |
29 | static volatile unsigned int queries; | |
30 | ||
31 | static void | |
32 | response (const struct resolv_response_context *ctx, | |
33 | struct resolv_response_builder *b, | |
34 | const char *qname, uint16_t qclass, uint16_t qtype) | |
35 | { | |
36 | /* Each test should only send one query. */ | |
37 | ++queries; | |
38 | TEST_COMPARE (queries, 1); | |
39 | ||
40 | /* AAAA queries are supposed to be disabled. */ | |
41 | TEST_VERIFY (qtype != T_AAAA); | |
42 | TEST_COMPARE (qclass, C_IN); | |
43 | ||
44 | /* The only other query type besides A is PTR. */ | |
45 | if (qtype != T_A) | |
46 | TEST_COMPARE (qtype, T_PTR); | |
47 | ||
48 | int an, ns, ar; | |
49 | char *tail; | |
50 | if (sscanf (qname, "an%d.ns%d.ar%d.%ms", &an, &ns, &ar, &tail) != 4) | |
51 | FAIL_EXIT1 ("invalid QNAME: %s\n", qname); | |
52 | TEST_COMPARE_STRING (tail, "example"); | |
53 | free (tail); | |
54 | ||
55 | if (an < 0 || ns < 0 || ar < 0) | |
56 | { | |
57 | struct resolv_response_flags flags = { .rcode = NXDOMAIN, }; | |
58 | resolv_response_init (b, flags); | |
59 | resolv_response_add_question (b, qname, qclass, qtype); | |
60 | return; | |
61 | } | |
62 | ||
63 | struct resolv_response_flags flags = {}; | |
64 | resolv_response_init (b, flags); | |
65 | resolv_response_add_question (b, qname, qclass, qtype); | |
66 | ||
67 | resolv_response_section (b, ns_s_an); | |
68 | for (int i = 0; i < an; ++i) | |
69 | { | |
70 | resolv_response_open_record (b, qname, qclass, qtype, 60); | |
71 | switch (qtype) | |
72 | { | |
73 | case T_A: | |
77536da3 FW |
74 | { |
75 | char ipv4[4] = {192, 0, 2, i + 1}; | |
76 | resolv_response_add_data (b, &ipv4, sizeof (ipv4)); | |
77 | } | |
f282cdbe FW |
78 | break; |
79 | ||
80 | case T_PTR: | |
77536da3 FW |
81 | { |
82 | char *name = xasprintf ("ptr-%d", i); | |
83 | resolv_response_add_name (b, name); | |
84 | free (name); | |
85 | } | |
f282cdbe FW |
86 | break; |
87 | } | |
88 | resolv_response_close_record (b); | |
89 | } | |
90 | ||
91 | resolv_response_section (b, ns_s_ns); | |
92 | for (int i = 0; i < ns; ++i) | |
93 | { | |
94 | resolv_response_open_record (b, qname, qclass, T_NS, 60); | |
95 | char *name = xasprintf ("ns%d.example.net", i); | |
96 | resolv_response_add_name (b, name); | |
97 | free (name); | |
98 | resolv_response_close_record (b); | |
99 | } | |
100 | ||
101 | resolv_response_section (b, ns_s_ar); | |
102 | int addr = 1; | |
103 | for (int i = 0; i < ns; ++i) | |
104 | { | |
105 | char *name = xasprintf ("ns%d.example.net", i); | |
106 | for (int j = 0; j < ar; ++j) | |
107 | { | |
108 | resolv_response_open_record (b, name, qclass, T_A, 60); | |
109 | char ipv4[4] = {192, 0, 2, addr}; | |
110 | resolv_response_add_data (b, &ipv4, sizeof (ipv4)); | |
111 | resolv_response_close_record (b); | |
112 | ||
113 | resolv_response_open_record (b, name, qclass, T_AAAA, 60); | |
114 | char ipv6[16] | |
115 | = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, addr}; | |
116 | resolv_response_add_data (b, &ipv6, sizeof (ipv6)); | |
117 | resolv_response_close_record (b); | |
118 | ||
119 | ++addr; | |
120 | } | |
121 | free (name); | |
122 | } | |
123 | } | |
124 | ||
125 | /* Number of modes. Lowest bit encodes *n* function vs implicit _res | |
126 | argument. The mode numbers themselves are arbitrary. */ | |
127 | enum { mode_count = 8 }; | |
128 | ||
129 | /* res_send-like modes do not perform error translation. */ | |
130 | enum { first_send_mode = 6 }; | |
131 | ||
132 | static int | |
133 | libresolv_query (unsigned int mode, const char *qname, uint16_t qtype, | |
134 | unsigned char *buf, size_t buflen) | |
135 | { | |
136 | int saved_errno = errno; | |
137 | ||
138 | TEST_VERIFY_EXIT (mode < mode_count); | |
139 | ||
140 | switch (mode) | |
141 | { | |
142 | case 0: | |
143 | return res_query (qname, C_IN, qtype, buf, buflen); | |
144 | case 1: | |
145 | return res_nquery (&_res, qname, C_IN, qtype, buf, buflen); | |
146 | case 2: | |
147 | return res_search (qname, C_IN, qtype, buf, buflen); | |
148 | case 3: | |
149 | return res_nsearch (&_res, qname, C_IN, qtype, buf, buflen); | |
150 | case 4: | |
151 | return res_querydomain (qname, "", C_IN, qtype, buf, buflen); | |
152 | case 5: | |
153 | return res_nquerydomain (&_res, qname, "", C_IN, qtype, buf, buflen); | |
154 | case 6: | |
155 | { | |
156 | unsigned char querybuf[512]; | |
157 | int ret = res_mkquery (QUERY, qname, C_IN, qtype, | |
158 | NULL, 0, NULL, querybuf, sizeof (querybuf)); | |
159 | TEST_VERIFY_EXIT (ret > 0); | |
160 | errno = saved_errno; | |
161 | return res_send (querybuf, ret, buf, buflen); | |
162 | } | |
163 | case 7: | |
164 | { | |
165 | unsigned char querybuf[512]; | |
166 | int ret = res_nmkquery (&_res, QUERY, qname, C_IN, qtype, | |
167 | NULL, 0, NULL, querybuf, sizeof (querybuf)); | |
168 | TEST_VERIFY_EXIT (ret > 0); | |
169 | errno = saved_errno; | |
170 | return res_nsend (&_res, querybuf, ret, buf, buflen); | |
171 | } | |
172 | } | |
173 | __builtin_unreachable (); | |
174 | } | |
175 | ||
176 | static int | |
177 | do_test (void) | |
178 | { | |
179 | struct resolv_test *obj = resolv_test_start | |
180 | ((struct resolv_redirect_config) | |
181 | { | |
182 | .response_callback = response | |
183 | }); | |
184 | ||
185 | _res.options |= RES_NOAAAA; | |
186 | ||
187 | check_hostent ("an1.ns2.ar1.example", | |
188 | gethostbyname ("an1.ns2.ar1.example"), | |
189 | "name: an1.ns2.ar1.example\n" | |
190 | "address: 192.0.2.1\n"); | |
191 | queries = 0; | |
192 | check_hostent ("an0.ns2.ar1.example", | |
193 | gethostbyname ("an0.ns2.ar1.example"), | |
194 | "error: NO_ADDRESS\n"); | |
195 | queries = 0; | |
196 | check_hostent ("an-1.ns2.ar1.example", | |
197 | gethostbyname ("an-1.ns2.ar1.example"), | |
198 | "error: HOST_NOT_FOUND\n"); | |
199 | queries = 0; | |
200 | ||
201 | check_hostent ("an1.ns2.ar1.example AF_INET", | |
202 | gethostbyname2 ("an1.ns2.ar1.example", AF_INET), | |
203 | "name: an1.ns2.ar1.example\n" | |
204 | "address: 192.0.2.1\n"); | |
205 | queries = 0; | |
206 | check_hostent ("an0.ns2.ar1.example AF_INET", | |
207 | gethostbyname2 ("an0.ns2.ar1.example", AF_INET), | |
208 | "error: NO_ADDRESS\n"); | |
209 | queries = 0; | |
210 | check_hostent ("an-1.ns2.ar1.example AF_INET", | |
211 | gethostbyname2 ("an-1.ns2.ar1.example", AF_INET), | |
212 | "error: HOST_NOT_FOUND\n"); | |
213 | queries = 0; | |
214 | ||
215 | check_hostent ("an1.ns2.ar1.example AF_INET6", | |
216 | gethostbyname2 ("an1.ns2.ar1.example", AF_INET6), | |
217 | "error: NO_ADDRESS\n"); | |
218 | queries = 0; | |
219 | check_hostent ("an0.ns2.ar1.example AF_INET6", | |
220 | gethostbyname2 ("an0.ns2.ar1.example", AF_INET6), | |
221 | "error: NO_ADDRESS\n"); | |
222 | queries = 0; | |
223 | check_hostent ("an-1.ns2.ar1.example AF_INET6", | |
224 | gethostbyname2 ("an-1.ns2.ar1.example", AF_INET6), | |
225 | "error: HOST_NOT_FOUND\n"); | |
226 | queries = 0; | |
227 | ||
228 | /* Multiple addresses. */ | |
229 | check_hostent ("an2.ns0.ar0.example", | |
230 | gethostbyname ("an2.ns0.ar0.example"), | |
231 | "name: an2.ns0.ar0.example\n" | |
232 | "address: 192.0.2.1\n" | |
233 | "address: 192.0.2.2\n"); | |
234 | queries = 0; | |
235 | check_hostent ("an2.ns0.ar0.example AF_INET6", | |
236 | gethostbyname2 ("an2.ns0.ar0.example", AF_INET6), | |
237 | "error: NO_ADDRESS\n"); | |
238 | queries = 0; | |
239 | ||
240 | /* getaddrinfo checks with one address. */ | |
241 | struct addrinfo *ai; | |
242 | int ret; | |
243 | ret = getaddrinfo ("an1.ns2.ar1.example", "80", | |
244 | &(struct addrinfo) | |
245 | { | |
246 | .ai_family = AF_INET, | |
247 | .ai_socktype = SOCK_STREAM, | |
248 | }, &ai); | |
249 | check_addrinfo ("an1.ns2.ar1.example (AF_INET)", ai, ret, | |
250 | "address: STREAM/TCP 192.0.2.1 80\n"); | |
251 | freeaddrinfo (ai); | |
252 | queries = 0; | |
253 | ret = getaddrinfo ("an1.ns2.ar1.example", "80", | |
254 | &(struct addrinfo) | |
255 | { | |
256 | .ai_family = AF_INET6, | |
257 | .ai_socktype = SOCK_STREAM, | |
258 | }, &ai); | |
259 | check_addrinfo ("an1.ns2.ar1.example (AF_INET6)", ai, ret, | |
260 | "error: No address associated with hostname\n"); | |
261 | queries = 0; | |
262 | ret = getaddrinfo ("an1.ns2.ar1.example", "80", | |
263 | &(struct addrinfo) | |
264 | { | |
265 | .ai_family = AF_UNSPEC, | |
266 | .ai_socktype = SOCK_STREAM, | |
267 | }, &ai); | |
268 | check_addrinfo ("an1.ns2.ar1.example (AF_UNSPEC)", ai, ret, | |
269 | "address: STREAM/TCP 192.0.2.1 80\n"); | |
270 | freeaddrinfo (ai); | |
271 | queries = 0; | |
272 | ||
273 | /* getaddrinfo checks with three addresses. */ | |
274 | ret = getaddrinfo ("an3.ns2.ar1.example", "80", | |
275 | &(struct addrinfo) | |
276 | { | |
277 | .ai_family = AF_INET, | |
278 | .ai_socktype = SOCK_STREAM, | |
279 | }, &ai); | |
280 | check_addrinfo ("an3.ns2.ar1.example (AF_INET)", ai, ret, | |
281 | "address: STREAM/TCP 192.0.2.1 80\n" | |
282 | "address: STREAM/TCP 192.0.2.2 80\n" | |
283 | "address: STREAM/TCP 192.0.2.3 80\n"); | |
284 | freeaddrinfo (ai); | |
285 | queries = 0; | |
286 | ret = getaddrinfo ("an3.ns2.ar1.example", "80", | |
287 | &(struct addrinfo) | |
288 | { | |
289 | .ai_family = AF_INET6, | |
290 | .ai_socktype = SOCK_STREAM, | |
291 | }, &ai); | |
292 | check_addrinfo ("an3.ns2.ar1.example (AF_INET6)", ai, ret, | |
293 | "error: No address associated with hostname\n"); | |
294 | queries = 0; | |
295 | ret = getaddrinfo ("an3.ns2.ar1.example", "80", | |
296 | &(struct addrinfo) | |
297 | { | |
298 | .ai_family = AF_UNSPEC, | |
299 | .ai_socktype = SOCK_STREAM, | |
300 | }, &ai); | |
301 | check_addrinfo ("an3.ns2.ar1.example (AF_UNSPEC)", ai, ret, | |
302 | "address: STREAM/TCP 192.0.2.1 80\n" | |
303 | "address: STREAM/TCP 192.0.2.2 80\n" | |
304 | "address: STREAM/TCP 192.0.2.3 80\n"); | |
305 | freeaddrinfo (ai); | |
306 | queries = 0; | |
307 | ||
308 | /* getaddrinfo checks with no address. */ | |
309 | ret = getaddrinfo ("an0.ns2.ar1.example", "80", | |
310 | &(struct addrinfo) | |
311 | { | |
312 | .ai_family = AF_INET, | |
313 | .ai_socktype = SOCK_STREAM, | |
314 | }, &ai); | |
315 | check_addrinfo ("an0.ns2.ar1.example (AF_INET)", ai, ret, | |
316 | "error: No address associated with hostname\n"); | |
317 | queries = 0; | |
318 | ret = getaddrinfo ("an0.ns2.ar1.example", "80", | |
319 | &(struct addrinfo) | |
320 | { | |
321 | .ai_family = AF_INET6, | |
322 | .ai_socktype = SOCK_STREAM, | |
323 | }, &ai); | |
324 | check_addrinfo ("an0.ns2.ar1.example (AF_INET6)", ai, ret, | |
325 | "error: No address associated with hostname\n"); | |
326 | queries = 0; | |
327 | ret = getaddrinfo ("an0.ns2.ar1.example", "80", | |
328 | &(struct addrinfo) | |
329 | { | |
330 | .ai_family = AF_UNSPEC, | |
331 | .ai_socktype = SOCK_STREAM, | |
332 | }, &ai); | |
333 | check_addrinfo ("an-1.ns2.ar1.example (AF_UNSPEC)", ai, ret, | |
334 | "error: No address associated with hostname\n"); | |
335 | queries = 0; | |
336 | ||
337 | /* getaddrinfo checks with NXDOMAIN. */ | |
338 | ret = getaddrinfo ("an-1.ns2.ar1.example", "80", | |
339 | &(struct addrinfo) | |
340 | { | |
341 | .ai_family = AF_INET, | |
342 | .ai_socktype = SOCK_STREAM, | |
343 | }, &ai); | |
344 | check_addrinfo ("an-1.ns2.ar1.example (AF_INET)", ai, ret, | |
345 | "error: Name or service not known\n"); | |
346 | queries = 0; | |
347 | ret = getaddrinfo ("an-1.ns2.ar1.example", "80", | |
348 | &(struct addrinfo) | |
349 | { | |
350 | .ai_family = AF_INET6, | |
351 | .ai_socktype = SOCK_STREAM, | |
352 | }, &ai); | |
353 | check_addrinfo ("an-1.ns2.ar1.example (AF_INET6)", ai, ret, | |
354 | "error: Name or service not known\n"); | |
355 | queries = 0; | |
356 | ret = getaddrinfo ("an-1.ns2.ar1.example", "80", | |
357 | &(struct addrinfo) | |
358 | { | |
359 | .ai_family = AF_UNSPEC, | |
360 | .ai_socktype = SOCK_STREAM, | |
361 | }, &ai); | |
362 | check_addrinfo ("an-1.ns2.ar1.example (AF_UNSPEC)", ai, ret, | |
363 | "error: Name or service not known\n"); | |
364 | queries = 0; | |
365 | ||
366 | for (unsigned int mode = 0; mode < mode_count; ++mode) | |
367 | { | |
368 | unsigned char *buf; | |
369 | int ret; | |
370 | ||
371 | /* Response for A. */ | |
372 | buf = malloc (512); | |
373 | ret = libresolv_query (mode, "an1.ns2.ar1.example", T_A, buf, 512); | |
374 | TEST_VERIFY_EXIT (ret > 0); | |
375 | check_dns_packet ("an1.ns2.ar1.example A", buf, ret, | |
376 | "name: an1.ns2.ar1.example\n" | |
377 | "address: 192.0.2.1\n"); | |
378 | free (buf); | |
379 | queries = 0; | |
380 | ||
381 | /* NODATA response for A. */ | |
382 | buf = malloc (512); | |
383 | errno = 0; | |
384 | ret = libresolv_query (mode, "an0.ns2.ar1.example", T_A, buf, 512); | |
385 | if (mode < first_send_mode) | |
386 | { | |
387 | TEST_COMPARE (ret, -1); | |
388 | TEST_COMPARE (errno, 0); | |
389 | TEST_COMPARE (h_errno, NO_ADDRESS); | |
390 | } | |
391 | else | |
392 | { | |
393 | TEST_VERIFY_EXIT (ret > 0); | |
394 | TEST_COMPARE (((HEADER *)buf)->rcode, 0); | |
395 | check_dns_packet ("an1.ns2.ar1.example A", buf, ret, | |
396 | "name: an0.ns2.ar1.example\n"); | |
397 | } | |
398 | free (buf); | |
399 | queries = 0; | |
400 | ||
401 | /* NXDOMAIN response for A. */ | |
402 | buf = malloc (512); | |
403 | errno = 0; | |
404 | ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_A, buf, 512); | |
405 | if (mode < first_send_mode) | |
406 | { | |
407 | TEST_COMPARE (ret, -1); | |
408 | TEST_COMPARE (errno, 0); | |
409 | TEST_COMPARE (h_errno, HOST_NOT_FOUND); | |
410 | } | |
411 | else | |
412 | { | |
413 | TEST_VERIFY_EXIT (ret > 0); | |
414 | TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN); | |
415 | check_dns_packet ("an1.ns2.ar1.example A", buf, ret, | |
416 | "name: an-1.ns2.ar1.example\n"); | |
417 | } | |
418 | free (buf); | |
419 | queries = 0; | |
420 | ||
421 | /* Response for PTR. */ | |
422 | buf = malloc (512); | |
423 | ret = libresolv_query (mode, "an1.ns2.ar1.example", T_PTR, buf, 512); | |
424 | TEST_VERIFY_EXIT (ret > 0); | |
425 | check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret, | |
426 | "name: an1.ns2.ar1.example\n" | |
427 | "data: an1.ns2.ar1.example PTR ptr-0\n"); | |
428 | free (buf); | |
429 | queries = 0; | |
430 | ||
431 | /* NODATA response for PTR. */ | |
432 | buf = malloc (512); | |
433 | errno = 0; | |
434 | ret = libresolv_query (mode, "an0.ns2.ar1.example", T_PTR, buf, 512); | |
435 | if (mode < first_send_mode) | |
436 | { | |
437 | TEST_COMPARE (ret, -1); | |
438 | TEST_COMPARE (errno, 0); | |
439 | TEST_COMPARE (h_errno, NO_ADDRESS); | |
440 | } | |
441 | else | |
442 | { | |
443 | TEST_VERIFY_EXIT (ret > 0); | |
444 | TEST_COMPARE (((HEADER *)buf)->rcode, 0); | |
445 | check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret, | |
446 | "name: an0.ns2.ar1.example\n"); | |
447 | } | |
448 | free (buf); | |
449 | queries = 0; | |
450 | ||
451 | /* NXDOMAIN response for PTR. */ | |
452 | buf = malloc (512); | |
453 | errno = 0; | |
454 | ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_PTR, buf, 512); | |
455 | if (mode < first_send_mode) | |
456 | { | |
457 | TEST_COMPARE (ret, -1); | |
458 | TEST_COMPARE (errno, 0); | |
459 | TEST_COMPARE (h_errno, HOST_NOT_FOUND); | |
460 | } | |
461 | else | |
462 | { | |
463 | TEST_VERIFY_EXIT (ret > 0); | |
464 | TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN); | |
465 | check_dns_packet ("an1.ns2.ar1.example PTR", buf, ret, | |
466 | "name: an-1.ns2.ar1.example\n"); | |
467 | } | |
468 | free (buf); | |
469 | queries = 0; | |
470 | ||
471 | /* NODATA response for AAAA. */ | |
472 | buf = malloc (512); | |
473 | errno = 0; | |
474 | ret = libresolv_query (mode, "an1.ns2.ar1.example", T_AAAA, buf, 512); | |
475 | if (mode < first_send_mode) | |
476 | { | |
477 | TEST_COMPARE (ret, -1); | |
478 | TEST_COMPARE (errno, 0); | |
479 | TEST_COMPARE (h_errno, NO_ADDRESS); | |
480 | } | |
481 | else | |
482 | { | |
483 | TEST_VERIFY_EXIT (ret > 0); | |
484 | TEST_COMPARE (((HEADER *)buf)->rcode, 0); | |
485 | check_dns_packet ("an1.ns2.ar1.example A", buf, ret, | |
486 | "name: an1.ns2.ar1.example\n"); | |
487 | } | |
488 | free (buf); | |
489 | queries = 0; | |
490 | ||
491 | /* NODATA response for AAAA (original is already NODATA). */ | |
492 | buf = malloc (512); | |
493 | errno = 0; | |
494 | ret = libresolv_query (mode, "an0.ns2.ar1.example", T_AAAA, buf, 512); | |
495 | if (mode < first_send_mode) | |
496 | { | |
497 | TEST_COMPARE (ret, -1); | |
498 | TEST_COMPARE (errno, 0); | |
499 | TEST_COMPARE (h_errno, NO_ADDRESS); | |
500 | } | |
501 | else | |
502 | { | |
503 | TEST_VERIFY_EXIT (ret > 0); | |
504 | TEST_COMPARE (((HEADER *)buf)->rcode, 0); | |
505 | check_dns_packet ("an0.ns2.ar1.example A", buf, ret, | |
506 | "name: an0.ns2.ar1.example\n"); | |
507 | } | |
508 | free (buf); | |
509 | queries = 0; | |
510 | ||
511 | /* NXDOMAIN response. */ | |
512 | buf = malloc (512); | |
513 | errno = 0; | |
514 | ret = libresolv_query (mode, "an-1.ns2.ar1.example", T_AAAA, buf, 512); | |
515 | if (mode < first_send_mode) | |
516 | { | |
517 | TEST_COMPARE (ret, -1); | |
518 | TEST_COMPARE (errno, 0); | |
519 | TEST_COMPARE (h_errno, HOST_NOT_FOUND); | |
520 | } | |
521 | else | |
522 | { | |
523 | TEST_VERIFY_EXIT (ret > 0); | |
524 | TEST_COMPARE (((HEADER *)buf)->rcode, NXDOMAIN); | |
525 | check_dns_packet ("an-1.ns2.ar1.example A", buf, ret, | |
526 | "name: an-1.ns2.ar1.example\n"); | |
527 | } | |
528 | free (buf); | |
529 | queries = 0; | |
530 | } | |
531 | ||
532 | resolv_test_end (obj); | |
533 | ||
534 | return 0; | |
535 | } | |
536 | ||
537 | #include <support/test-driver.c> |