1 /* $NetBSD: printmsg.c,v 1.4 2014/12/10 04:37:53 christos Exp $ */
2
3 /*
4 * Copyright (C) 2004, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1998-2001 Internet Software Consortium.
6 *
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.
10 *
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.
18 */
19
20 /* Id: printmsg.c,v 1.31 2011/08/25 23:46:42 tbox Exp */
21
22 #include <config.h>
23
24 #include <isc/buffer.h>
25 #include <isc/util.h>
26
27 #include <dns/name.h>
28 #include <dns/rdataset.h>
29
30 #include "printmsg.h"
31
32 static const char *opcodetext[] = {
33 "QUERY",
34 "IQUERY",
35 "STATUS",
36 "RESERVED3",
37 "NOTIFY",
38 "UPDATE",
39 "RESERVED6",
40 "RESERVED7",
41 "RESERVED8",
42 "RESERVED9",
43 "RESERVED10",
44 "RESERVED11",
45 "RESERVED12",
46 "RESERVED13",
47 "RESERVED14",
48 "RESERVED15"
49 };
50
51 static const char *rcodetext[] = {
52 "NOERROR",
53 "FORMERR",
54 "SERVFAIL",
55 "NXDOMAIN",
56 "NOTIMP",
57 "REFUSED",
58 "YXDOMAIN",
59 "YXRRSET",
60 "NXRRSET",
61 "NOTAUTH",
62 "NOTZONE",
63 "RESERVED11",
64 "RESERVED12",
65 "RESERVED13",
66 "RESERVED14",
67 "RESERVED15",
68 "BADVERS"
69 };
70
71 static isc_result_t
printsection(dns_message_t * msg,dns_section_t sectionid,const char * section_name)72 printsection(dns_message_t *msg, dns_section_t sectionid,
73 const char *section_name)
74 {
75 dns_name_t *name, *print_name;
76 dns_rdataset_t *rdataset;
77 isc_buffer_t target;
78 isc_result_t result;
79 isc_region_t r;
80 dns_name_t empty_name;
81 char t[65536];
82 #ifdef USEINITALWS
83 isc_boolean_t first;
84 #endif
85 isc_boolean_t no_rdata;
86
87 if (sectionid == DNS_SECTION_QUESTION)
88 no_rdata = ISC_TRUE;
89 else
90 no_rdata = ISC_FALSE;
91
92 printf(";; %s SECTION:\n", section_name);
93
94 dns_name_init(&empty_name, NULL);
95
96 result = dns_message_firstname(msg, sectionid);
97 if (result == ISC_R_NOMORE)
98 return (ISC_R_SUCCESS);
99 else if (result != ISC_R_SUCCESS)
100 return (result);
101
102 for (;;) {
103 name = NULL;
104 dns_message_currentname(msg, sectionid, &name);
105
106 isc_buffer_init(&target, t, sizeof(t));
107 #ifdef USEINITALWS
108 first = ISC_TRUE;
109 #endif
110 print_name = name;
111
112 for (rdataset = ISC_LIST_HEAD(name->list);
113 rdataset != NULL;
114 rdataset = ISC_LIST_NEXT(rdataset, link)) {
115 result = dns_rdataset_totext(rdataset,
116 print_name,
117 ISC_FALSE,
118 no_rdata,
119 &target);
120 if (result != ISC_R_SUCCESS)
121 return (result);
122 #ifdef USEINITALWS
123 if (first) {
124 print_name = &empty_name;
125 first = ISC_FALSE;
126 }
127 #endif
128 }
129 isc_buffer_usedregion(&target, &r);
130 printf("%.*s", (int)r.length, (char *)r.base);
131
132 result = dns_message_nextname(msg, sectionid);
133 if (result == ISC_R_NOMORE)
134 break;
135 else if (result != ISC_R_SUCCESS)
136 return (result);
137 }
138
139 return (ISC_R_SUCCESS);
140 }
141
142 static isc_result_t
printrdata(dns_message_t * msg,dns_rdataset_t * rdataset,dns_name_t * owner,const char * set_name)143 printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner,
144 const char *set_name)
145 {
146 isc_buffer_t target;
147 isc_result_t result;
148 isc_region_t r;
149 char t[65536];
150
151 UNUSED(msg);
152 printf(";; %s SECTION:\n", set_name);
153
154 isc_buffer_init(&target, t, sizeof(t));
155
156 result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE,
157 &target);
158 if (result != ISC_R_SUCCESS)
159 return (result);
160 isc_buffer_usedregion(&target, &r);
161 printf("%.*s", (int)r.length, (char *)r.base);
162
163 return (ISC_R_SUCCESS);
164 }
165
166 isc_result_t
printmessage(dns_message_t * msg)167 printmessage(dns_message_t *msg) {
168 isc_result_t result;
169 dns_rdataset_t *opt, *tsig;
170 dns_name_t *tsigname;
171
172 result = ISC_R_SUCCESS;
173
174 printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n",
175 opcodetext[msg->opcode], rcodetext[msg->rcode], msg->id);
176
177 printf(";; flags:");
178 if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
179 printf(" qr");
180 if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
181 printf(" aa");
182 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
183 printf(" tc");
184 if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
185 printf(" rd");
186 if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
187 printf(" ra");
188 if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
189 printf(" ad");
190 if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
191 printf(" cd");
192 printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n",
193 msg->counts[DNS_SECTION_QUESTION],
194 msg->counts[DNS_SECTION_ANSWER],
195 msg->counts[DNS_SECTION_AUTHORITY],
196 msg->counts[DNS_SECTION_ADDITIONAL]);
197 opt = dns_message_getopt(msg);
198 if (opt != NULL)
199 printf(";; EDNS: version: %u, udp=%u\n",
200 (unsigned int)((opt->ttl & 0x00ff0000) >> 16),
201 (unsigned int)opt->rdclass);
202
203 tsigname = NULL;
204 tsig = dns_message_gettsig(msg, &tsigname);
205 if (tsig != NULL)
206 printf(";; PSEUDOSECTIONS: TSIG\n");
207 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION])) {
208 printf("\n");
209 result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION");
210 if (result != ISC_R_SUCCESS)
211 return (result);
212 }
213 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) {
214 printf("\n");
215 result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER");
216 if (result != ISC_R_SUCCESS)
217 return (result);
218 }
219 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY])) {
220 printf("\n");
221 result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY");
222 if (result != ISC_R_SUCCESS)
223 return (result);
224 }
225 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL])) {
226 printf("\n");
227 result = printsection(msg, DNS_SECTION_ADDITIONAL,
228 "ADDITIONAL");
229 if (result != ISC_R_SUCCESS)
230 return (result);
231 }
232 if (tsig != NULL) {
233 printf("\n");
234 result = printrdata(msg, tsig, tsigname,
235 "PSEUDOSECTION TSIG");
236 if (result != ISC_R_SUCCESS)
237 return (result);
238 }
239 printf("\n");
240
241 return (result);
242 }
243