1 #ifndef lint 2 static char sccsid[] = "@(#)res_debug.c 4.1 (Berkeley) 03/01/85"; 3 #endif 4 5 #include <sys/types.h> 6 #include <netinet/in.h> 7 #include <stdio.h> 8 #include <nameser.h> 9 10 extern char *p_cdname(), *p_rr(), *p_type(), *p_class(); 11 extern char *inet_ntoa(); 12 13 char *opcodes[] = { 14 "QUERY", 15 "IQUERY", 16 "CQUERYM", 17 "CQUERYU", 18 "4", 19 "5", 20 "6", 21 "7", 22 "8", 23 "9", 24 "10", 25 "UPDATEA", 26 "UPDATED", 27 "UPDATEM", 28 "ZONEINIT", 29 "ZONEREF", 30 }; 31 32 char *rcodes[] = { 33 "NOERROR", 34 "FORMERR", 35 "SERVFAIL", 36 "NXDOMAIN", 37 "NOTIMP", 38 "REFUSED", 39 "6", 40 "7", 41 "8", 42 "9", 43 "10", 44 "11", 45 "12", 46 "13", 47 "14", 48 "NOCHANGE", 49 }; 50 51 /* 52 * Print the contents of a query. 53 * This is intended to be primarily a debugging routine. 54 */ 55 p_query(buf) 56 char *buf; 57 { 58 register char *cp; 59 register HEADER *hp; 60 register int n; 61 62 /* 63 * Print header fields. 64 */ 65 hp = (HEADER *)buf; 66 cp = buf + sizeof(HEADER); 67 printf("HEADER:\n"); 68 printf("\topcode = %s", opcodes[hp->opcode]); 69 printf(", id = %d", ntohs(hp->id)); 70 printf(", rcode = %s\n", rcodes[hp->rcode]); 71 printf("\theader flags: "); 72 if (hp->qr) 73 printf(" qr"); 74 if (hp->aa) 75 printf(" aa"); 76 if (hp->tc) 77 printf(" tc"); 78 if (hp->rd) 79 printf(" rd"); 80 if (hp->ra) 81 printf(" ra"); 82 if (hp->pr) 83 printf(" pr"); 84 printf("\n\tqdcount = %d", ntohs(hp->qdcount)); 85 printf(", ancount = %d", ntohs(hp->ancount)); 86 printf(", nscount = %d", ntohs(hp->nscount)); 87 printf(", arcount = %d\n\n", ntohs(hp->arcount)); 88 /* 89 * Print question records. 90 */ 91 if (n = ntohs(hp->qdcount)) { 92 printf("QUESTIONS:\n"); 93 while (--n >= 0) { 94 printf("\t"); 95 cp = p_cdname(cp, buf); 96 if (cp == NULL) 97 return; 98 printf(", type = %s", p_type(ntohs(*(u_short *)cp))); 99 cp += sizeof(u_short); 100 printf(", class = %s\n\n", p_class(ntohs(*(u_short *)cp))); 101 cp += sizeof(u_short); 102 } 103 } 104 /* 105 * Print authoritative answer records 106 */ 107 if (n = ntohs(hp->ancount)) { 108 printf("ANSWERS:\n"); 109 while (--n >= 0) { 110 printf("\t"); 111 cp = p_rr(cp, buf); 112 if (cp == NULL) 113 return; 114 } 115 } 116 /* 117 * print name server records 118 */ 119 if (n = ntohs(hp->nscount)) { 120 printf("NAME SERVERS:\n"); 121 while (--n >= 0) { 122 printf("\t"); 123 cp = p_rr(cp, buf); 124 if (cp == NULL) 125 return; 126 } 127 } 128 /* 129 * print additional records 130 */ 131 if (n = ntohs(hp->arcount)) { 132 printf("ADDITIONAL RECORDS:\n"); 133 while (--n >= 0) { 134 printf("\t"); 135 cp = p_rr(cp, buf); 136 if (cp == NULL) 137 return; 138 } 139 } 140 } 141 142 char * 143 p_cdname(cp, buf) 144 char *cp, *buf; 145 { 146 char name[MAXDNAME]; 147 int n; 148 149 if ((n = dn_expand(buf, cp, name, sizeof(name))) < 0) 150 return (NULL); 151 if (name[0] == '\0') { 152 name[0] = '.'; 153 name[1] = '\0'; 154 } 155 fputs(name, stdout); 156 return (cp + n); 157 } 158 159 /* 160 * Print resource record fields in human readable form. 161 */ 162 char * 163 p_rr(cp, buf) 164 char *cp, *buf; 165 { 166 int type, class, dlen, n, c; 167 struct in_addr inaddr; 168 char *cp1; 169 170 if ((cp = p_cdname(cp, buf)) == NULL) 171 return (NULL); /* compression error */ 172 printf("\n\ttype = %s", p_type(type = ntohs(*(u_short *)cp))); 173 cp += sizeof(u_short); 174 printf(", class = %s", p_class(class = ntohs(*(u_short *)cp))); 175 cp += sizeof(u_short); 176 printf(", ttl = %d", ntohl(*(u_int *)cp)); 177 cp += sizeof(u_long); 178 printf(", dlen = %d\n", dlen = ntohs(*(u_short *)cp)); 179 cp += sizeof(u_short); 180 cp1 = cp; 181 /* 182 * Print type specific data, if appropriate 183 */ 184 switch (type) { 185 case T_A: 186 switch (class) { 187 case C_IN: 188 inaddr.s_addr = *(u_long *)cp; 189 if (dlen == 4) { 190 printf("\tinternet address = %s\n", 191 inet_ntoa(inaddr)); 192 cp += dlen; 193 } else if (dlen == 7) { 194 printf("\tinternet address = %s", 195 inet_ntoa(inaddr)); 196 printf(", protocol = %d", cp[4]); 197 printf(", port = %d\n", 198 (cp[5] << 8) + cp[6]); 199 cp += dlen; 200 } 201 break; 202 } 203 break; 204 case T_CNAME: 205 case T_MB: 206 case T_MD: 207 case T_MF: 208 case T_MG: 209 case T_MR: 210 case T_NS: 211 case T_PTR: 212 printf("\tdomain name = "); 213 cp = p_cdname(cp, buf); 214 printf("\n"); 215 break; 216 217 case T_HINFO: 218 if (n = *cp++) { 219 printf("\tCPU=%.*s\n", n, cp); 220 cp += n; 221 } 222 if (n = *cp++) { 223 printf("\tOS=%.*s\n", n, cp); 224 cp += n; 225 } 226 break; 227 228 case T_SOA: 229 printf("\torigin = "); 230 cp = p_cdname(cp, buf); 231 printf("\n\tmail addr = "); 232 cp = p_cdname(cp, buf); 233 printf("\n\tserial=%d", ntohl(*(u_long *)cp)); 234 cp += sizeof(u_long); 235 printf(", refresh=%d", ntohl(*(u_long *)cp)); 236 cp += sizeof(u_long); 237 printf(", retry=%d", ntohl(*(u_long *)cp)); 238 cp += sizeof(u_long); 239 printf(", expire=%d", ntohl(*(u_long *)cp)); 240 cp += sizeof(u_long); 241 printf(", min=%d\n", ntohl(*(u_long *)cp)); 242 cp += sizeof(u_long); 243 break; 244 245 case T_UINFO: 246 printf("\t%s\n", cp); 247 cp += dlen; 248 break; 249 250 case T_UID: 251 case T_GID: 252 if (dlen == 4) { 253 printf("\t%d\n", ntohl(*(int *)cp)); 254 cp += sizeof(int); 255 } 256 break; 257 258 case T_WKS: 259 if (dlen < sizeof(u_long) + 1) 260 break; 261 inaddr.s_addr = *(u_long *)cp; 262 cp += sizeof(u_long); 263 printf("\tinternet address = %s, protocol = %d\n\t", 264 inet_ntoa(inaddr), *cp++); 265 n = 0; 266 while (cp < cp1 + dlen) { 267 c = *cp++; 268 do { 269 if (c & 1) 270 printf(" %d", n); 271 c >>= 1; 272 } while (++n & 07); 273 } 274 putchar('\n'); 275 break; 276 277 default: 278 printf("\t???\n"); 279 cp += dlen; 280 } 281 if (cp != cp1 + dlen) 282 printf("packet size error (%#x != %#x)\n", cp, cp1+dlen); 283 printf("\n"); 284 return (cp); 285 } 286 287 static char nbuf[20]; 288 extern char *sprintf(); 289 290 /* 291 * Return a string for the type 292 */ 293 char * 294 p_type(type) 295 int type; 296 { 297 298 switch (type) { 299 case T_A: 300 return("A"); 301 case T_NS: /* authoritative server */ 302 return("NS"); 303 case T_MD: /* mail destination */ 304 return("MD"); 305 case T_MF: /* mail forwarder */ 306 return("MF"); 307 case T_CNAME: /* connonical name */ 308 return("CNAME"); 309 case T_SOA: /* start of authority zone */ 310 return("SOA"); 311 case T_MB: /* mailbox domain name */ 312 return("MB"); 313 case T_MG: /* mail group member */ 314 return("MG"); 315 case T_MR: /* mail rename name */ 316 return("MR"); 317 case T_NULL: /* null resource record */ 318 return("NULL"); 319 case T_WKS: /* well known service */ 320 return("WKS"); 321 case T_PTR: /* domain name pointer */ 322 return("PTR"); 323 case T_HINFO: /* host information */ 324 return("HINFO"); 325 case T_MINFO: /* mailbox information */ 326 return("MINFO"); 327 case T_AXFR: /* zone transfer */ 328 return("AXFR"); 329 case T_MAILB: /* mail box */ 330 return("MAILB"); 331 case T_MAILA: /* mail address */ 332 return("MAILA"); 333 case T_ANY: /* matches any type */ 334 return("ANY"); 335 case T_UINFO: 336 return("UINFO"); 337 case T_UID: 338 return("UID"); 339 case T_GID: 340 return("GID"); 341 default: 342 return (sprintf(nbuf, "%d", type)); 343 } 344 } 345 346 /* 347 * Return a mnemonic for class 348 */ 349 char * 350 p_class(class) 351 int class; 352 { 353 354 switch (class) { 355 case C_IN: /* internet class */ 356 return("IN"); 357 case C_CS: /* csnet class */ 358 return("CS"); 359 case C_ANY: /* matches any class */ 360 return("ANY"); 361 default: 362 return (sprintf(nbuf, "%d", class)); 363 } 364 } 365