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