etc/services - sync with NetBSD-8
[minix.git] / external / bsd / bind / dist / bin / tests / wire_test.c
blobd4d2f142103d64bf5fe30d1d10f035942a84100e
1 /* $NetBSD: wire_test.c,v 1.6 2014/12/10 04:37:53 christos Exp $ */
3 /*
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 */
22 #include <config.h>
24 #include <stdlib.h>
26 #include <isc/buffer.h>
27 #include <isc/commandline.h>
28 #include <isc/mem.h>
29 #include <isc/string.h>
30 #include <isc/util.h>
32 #include <dns/result.h>
34 #include "printmsg.h"
36 int parseflags = 0;
37 isc_mem_t *mctx;
38 isc_boolean_t printmemstats = ISC_FALSE;
39 isc_boolean_t dorender = ISC_FALSE;
41 static void
42 process_message(isc_buffer_t *source);
44 static inline void
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));
49 exit(1);
53 static int
54 fromhex(char c) {
55 if (c >= '0' && c <= '9')
56 return (c - '0');
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);
63 exit(3);
64 /* NOTREACHED */
67 static void
68 usage(void) {
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");
77 int
78 main(int argc, char *argv[]) {
79 char *rp, *wp;
80 unsigned char *bp;
81 isc_buffer_t source;
82 size_t len, i;
83 int n;
84 FILE *f;
85 isc_boolean_t need_close = ISC_FALSE;
86 unsigned char b[64 * 1024];
87 char s[4000];
88 isc_boolean_t tcp = ISC_FALSE;
89 int ch;
91 mctx = NULL;
92 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
94 while ((ch = isc_commandline_parse(argc, argv, "pbsrt")) != -1) {
95 switch (ch) {
96 case 'p':
97 parseflags |= DNS_MESSAGEPARSE_PRESERVEORDER;
98 break;
99 case 'b':
100 parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
101 break;
102 case 's':
103 printmemstats = ISC_TRUE;
104 break;
105 case 'r':
106 dorender = ISC_TRUE;
107 break;
108 case 't':
109 tcp = ISC_TRUE;
110 break;
111 default:
112 usage();
113 exit(1);
117 argc -= isc_commandline_index;
118 argv += isc_commandline_index;
120 if (argc > 1) {
121 f = fopen(argv[1], "r");
122 if (f == NULL) {
123 printf("fopen failed\n");
124 exit(1);
126 need_close = ISC_TRUE;
127 } else
128 f = stdin;
130 bp = b;
131 while (fgets(s, sizeof(s), f) != NULL) {
132 rp = s;
133 wp = s;
134 len = 0;
135 while (*rp != '\0') {
136 if (*rp == '#')
137 break;
138 if (*rp != ' ' && *rp != '\t' &&
139 *rp != '\r' && *rp != '\n') {
140 *wp++ = *rp;
141 len++;
143 rp++;
145 if (len == 0U)
146 break;
147 if (len % 2 != 0U) {
148 printf("bad input format: %lu\n", (unsigned long)len);
149 exit(1);
151 if (len > sizeof(b) * 2) {
152 printf("input too long\n");
153 exit(2);
155 rp = s;
156 for (i = 0; i < len; i += 2) {
157 n = fromhex(*rp++);
158 n *= 16;
159 n += fromhex(*rp++);
160 *bp++ = n;
164 if (need_close)
165 fclose(f);
167 if (tcp) {
168 unsigned char *p = b;
169 while (p < bp) {
170 unsigned int len;
172 if (p + 2 > bp) {
173 printf("premature end of packet\n");
174 exit(1);
176 len = p[0] << 8 | p[1];
178 if (p + 2 + len > bp) {
179 printf("premature end of packet\n");
180 exit(1);
182 isc_buffer_init(&source, p + 2, len);
183 isc_buffer_add(&source, len);
184 process_message(&source);
185 p += 2 + len;
187 } else {
188 isc_buffer_init(&source, b, sizeof(b));
189 isc_buffer_add(&source, bp - b);
190 process_message(&source);
193 if (printmemstats)
194 isc_mem_stats(mctx, stdout);
195 isc_mem_destroy(&mctx);
197 return (0);
200 static void
201 process_message(isc_buffer_t *source) {
202 dns_message_t *message;
203 isc_result_t result;
204 int i;
206 message = NULL;
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");
218 if (printmemstats)
219 isc_mem_stats(mctx, stdout);
221 if (dorender) {
222 unsigned char b2[64 * 1024];
223 isc_buffer_t buffer;
224 dns_compress_t cctx;
226 isc_buffer_init(&buffer, b2, sizeof(b2));
229 * XXXMLG
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);
246 CHECKRESULT(result,
247 "dns_message_rendersection(QUESTION) failed");
249 result = dns_message_rendersection(message,
250 DNS_SECTION_ANSWER, 0);
251 CHECKRESULT(result,
252 "dns_message_rendersection(ANSWER) failed");
254 result = dns_message_rendersection(message,
255 DNS_SECTION_AUTHORITY, 0);
256 CHECKRESULT(result,
257 "dns_message_rendersection(AUTHORITY) failed");
259 result = dns_message_rendersection(message,
260 DNS_SECTION_ADDITIONAL, 0);
261 CHECKRESULT(result,
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");
272 if (printmemstats)
273 isc_mem_stats(mctx, stdout);
275 result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
276 &message);
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);