1 /* $NetBSD: wire_test.c,v 1.6 2014/12/10 04:37:53 christos Exp $ */
4 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: wire_test.c,v 1.67 2007/06/19 23:46:59 tbox Exp */
26 #include <isc/buffer.h>
27 #include <isc/commandline.h>
29 #include <isc/string.h>
32 #include <dns/result.h>
38 isc_boolean_t printmemstats
= ISC_FALSE
;
39 isc_boolean_t dorender
= ISC_FALSE
;
42 process_message(isc_buffer_t
*source
);
45 CHECKRESULT(isc_result_t result
, const char *msg
) {
46 if (result
!= ISC_R_SUCCESS
) {
47 printf("%s: %s\n", msg
, dns_result_totext(result
));
55 if (c
>= '0' && c
<= '9')
57 else if (c
>= 'a' && c
<= 'f')
58 return (c
- 'a' + 10);
59 else if (c
>= 'A' && c
<= 'F')
60 return (c
- 'A' + 10);
62 printf("bad input format: %02x\n", c
);
69 fprintf(stderr
, "wire_test [-p] [-b] [-s] [-r]\n");
70 fprintf(stderr
, "\t-p\tPreserve order of the records in messages\n");
71 fprintf(stderr
, "\t-b\tBest-effort parsing (ignore some errors)\n");
72 fprintf(stderr
, "\t-s\tPrint memory statistics\n");
73 fprintf(stderr
, "\t-r\tAfter parsing, re-render the message\n");
74 fprintf(stderr
, "\t-t\tTCP mode - ignore the first 2 bytes\n");
78 main(int argc
, char *argv
[]) {
85 isc_boolean_t need_close
= ISC_FALSE
;
86 unsigned char b
[64 * 1024];
88 isc_boolean_t tcp
= ISC_FALSE
;
92 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx
) == ISC_R_SUCCESS
);
94 while ((ch
= isc_commandline_parse(argc
, argv
, "pbsrt")) != -1) {
97 parseflags
|= DNS_MESSAGEPARSE_PRESERVEORDER
;
100 parseflags
|= DNS_MESSAGEPARSE_BESTEFFORT
;
103 printmemstats
= ISC_TRUE
;
117 argc
-= isc_commandline_index
;
118 argv
+= isc_commandline_index
;
121 f
= fopen(argv
[1], "r");
123 printf("fopen failed\n");
126 need_close
= ISC_TRUE
;
131 while (fgets(s
, sizeof(s
), f
) != NULL
) {
135 while (*rp
!= '\0') {
138 if (*rp
!= ' ' && *rp
!= '\t' &&
139 *rp
!= '\r' && *rp
!= '\n') {
148 printf("bad input format: %lu\n", (unsigned long)len
);
151 if (len
> sizeof(b
) * 2) {
152 printf("input too long\n");
156 for (i
= 0; i
< len
; i
+= 2) {
168 unsigned char *p
= b
;
173 printf("premature end of packet\n");
176 len
= p
[0] << 8 | p
[1];
178 if (p
+ 2 + len
> bp
) {
179 printf("premature end of packet\n");
182 isc_buffer_init(&source
, p
+ 2, len
);
183 isc_buffer_add(&source
, len
);
184 process_message(&source
);
188 isc_buffer_init(&source
, b
, sizeof(b
));
189 isc_buffer_add(&source
, bp
- b
);
190 process_message(&source
);
194 isc_mem_stats(mctx
, stdout
);
195 isc_mem_destroy(&mctx
);
201 process_message(isc_buffer_t
*source
) {
202 dns_message_t
*message
;
207 result
= dns_message_create(mctx
, DNS_MESSAGE_INTENTPARSE
, &message
);
208 CHECKRESULT(result
, "dns_message_create failed");
210 result
= dns_message_parse(message
, source
, parseflags
);
211 if (result
== DNS_R_RECOVERABLE
)
212 result
= ISC_R_SUCCESS
;
213 CHECKRESULT(result
, "dns_message_parse failed");
215 result
= printmessage(message
);
216 CHECKRESULT(result
, "printmessage() failed");
219 isc_mem_stats(mctx
, stdout
);
222 unsigned char b2
[64 * 1024];
226 isc_buffer_init(&buffer
, b2
, sizeof(b2
));
230 * Changing this here is a hack, and should not be done in
231 * reasonable application code, ever.
233 message
->from_to_wire
= DNS_MESSAGE_INTENTRENDER
;
235 for (i
= 0; i
< DNS_SECTION_MAX
; i
++)
236 message
->counts
[i
] = 0; /* Another hack XXX */
238 result
= dns_compress_init(&cctx
, -1, mctx
);
239 CHECKRESULT(result
, "dns_compress_init() failed");
241 result
= dns_message_renderbegin(message
, &cctx
, &buffer
);
242 CHECKRESULT(result
, "dns_message_renderbegin() failed");
244 result
= dns_message_rendersection(message
,
245 DNS_SECTION_QUESTION
, 0);
247 "dns_message_rendersection(QUESTION) failed");
249 result
= dns_message_rendersection(message
,
250 DNS_SECTION_ANSWER
, 0);
252 "dns_message_rendersection(ANSWER) failed");
254 result
= dns_message_rendersection(message
,
255 DNS_SECTION_AUTHORITY
, 0);
257 "dns_message_rendersection(AUTHORITY) failed");
259 result
= dns_message_rendersection(message
,
260 DNS_SECTION_ADDITIONAL
, 0);
262 "dns_message_rendersection(ADDITIONAL) failed");
264 dns_message_renderend(message
);
266 dns_compress_invalidate(&cctx
);
268 message
->from_to_wire
= DNS_MESSAGE_INTENTPARSE
;
269 dns_message_destroy(&message
);
271 printf("Message rendered.\n");
273 isc_mem_stats(mctx
, stdout
);
275 result
= dns_message_create(mctx
, DNS_MESSAGE_INTENTPARSE
,
277 CHECKRESULT(result
, "dns_message_create failed");
279 result
= dns_message_parse(message
, &buffer
, parseflags
);
280 CHECKRESULT(result
, "dns_message_parse failed");
282 result
= printmessage(message
);
283 CHECKRESULT(result
, "printmessage() failed");
285 dns_message_destroy(&message
);