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 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 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 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