|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1985, 1990 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: * ! 19: * @(#)res_debug.c 5.30 (Berkeley) 6/27/90 ! 20: */ ! 21: ! 22: #if defined(LIBC_SCCS) && !defined(lint) ! 23: static char sccsid[] = "@(#)res_debug.c 5.30 (Berkeley) 6/27/90"; ! 24: #endif /* LIBC_SCCS and not lint */ ! 25: ! 26: #include <sys/types.h> ! 27: #include <netinet/in.h> ! 28: #include <stdio.h> ! 29: #include <arpa/nameser.h> ! 30: ! 31: extern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time(); ! 32: extern char *inet_ntoa(); ! 33: ! 34: char *_res_opcodes[] = { ! 35: "QUERY", ! 36: "IQUERY", ! 37: "CQUERYM", ! 38: "CQUERYU", ! 39: "4", ! 40: "5", ! 41: "6", ! 42: "7", ! 43: "8", ! 44: "UPDATEA", ! 45: "UPDATED", ! 46: "UPDATEDA", ! 47: "UPDATEM", ! 48: "UPDATEMA", ! 49: "ZONEINIT", ! 50: "ZONEREF", ! 51: }; ! 52: ! 53: char *_res_resultcodes[] = { ! 54: "NOERROR", ! 55: "FORMERR", ! 56: "SERVFAIL", ! 57: "NXDOMAIN", ! 58: "NOTIMP", ! 59: "REFUSED", ! 60: "6", ! 61: "7", ! 62: "8", ! 63: "9", ! 64: "10", ! 65: "11", ! 66: "12", ! 67: "13", ! 68: "14", ! 69: "NOCHANGE", ! 70: }; ! 71: ! 72: p_query(msg) ! 73: char *msg; ! 74: { ! 75: fp_query(msg,stdout); ! 76: } ! 77: ! 78: /* ! 79: * Print the contents of a query. ! 80: * This is intended to be primarily a debugging routine. ! 81: */ ! 82: fp_query(msg,file) ! 83: char *msg; ! 84: FILE *file; ! 85: { ! 86: register char *cp; ! 87: register HEADER *hp; ! 88: register int n; ! 89: ! 90: /* ! 91: * Print header fields. ! 92: */ ! 93: hp = (HEADER *)msg; ! 94: cp = msg + sizeof(HEADER); ! 95: fprintf(file,"HEADER:\n"); ! 96: fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]); ! 97: fprintf(file,", id = %d", ntohs(hp->id)); ! 98: fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]); ! 99: fprintf(file,"\theader flags: "); ! 100: if (hp->qr) ! 101: fprintf(file," qr"); ! 102: if (hp->aa) ! 103: fprintf(file," aa"); ! 104: if (hp->tc) ! 105: fprintf(file," tc"); ! 106: if (hp->rd) ! 107: fprintf(file," rd"); ! 108: if (hp->ra) ! 109: fprintf(file," ra"); ! 110: if (hp->pr) ! 111: fprintf(file," pr"); ! 112: fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount)); ! 113: fprintf(file,", ancount = %d", ntohs(hp->ancount)); ! 114: fprintf(file,", nscount = %d", ntohs(hp->nscount)); ! 115: fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount)); ! 116: /* ! 117: * Print question records. ! 118: */ ! 119: if (n = ntohs(hp->qdcount)) { ! 120: fprintf(file,"QUESTIONS:\n"); ! 121: while (--n >= 0) { ! 122: fprintf(file,"\t"); ! 123: cp = p_cdname(cp, msg, file); ! 124: if (cp == NULL) ! 125: return; ! 126: fprintf(file,", type = %s", p_type(_getshort(cp))); ! 127: cp += sizeof(u_short); ! 128: fprintf(file,", class = %s\n\n", p_class(_getshort(cp))); ! 129: cp += sizeof(u_short); ! 130: } ! 131: } ! 132: /* ! 133: * Print authoritative answer records ! 134: */ ! 135: if (n = ntohs(hp->ancount)) { ! 136: fprintf(file,"ANSWERS:\n"); ! 137: while (--n >= 0) { ! 138: fprintf(file,"\t"); ! 139: cp = p_rr(cp, msg, file); ! 140: if (cp == NULL) ! 141: return; ! 142: } ! 143: } ! 144: /* ! 145: * print name server records ! 146: */ ! 147: if (n = ntohs(hp->nscount)) { ! 148: fprintf(file,"NAME SERVERS:\n"); ! 149: while (--n >= 0) { ! 150: fprintf(file,"\t"); ! 151: cp = p_rr(cp, msg, file); ! 152: if (cp == NULL) ! 153: return; ! 154: } ! 155: } ! 156: /* ! 157: * print additional records ! 158: */ ! 159: if (n = ntohs(hp->arcount)) { ! 160: fprintf(file,"ADDITIONAL RECORDS:\n"); ! 161: while (--n >= 0) { ! 162: fprintf(file,"\t"); ! 163: cp = p_rr(cp, msg, file); ! 164: if (cp == NULL) ! 165: return; ! 166: } ! 167: } ! 168: } ! 169: ! 170: char * ! 171: p_cdname(cp, msg, file) ! 172: char *cp, *msg; ! 173: FILE *file; ! 174: { ! 175: char name[MAXDNAME]; ! 176: int n; ! 177: ! 178: if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0) ! 179: return (NULL); ! 180: if (name[0] == '\0') { ! 181: name[0] = '.'; ! 182: name[1] = '\0'; ! 183: } ! 184: fputs(name, file); ! 185: return (cp + n); ! 186: } ! 187: ! 188: /* ! 189: * Print resource record fields in human readable form. ! 190: */ ! 191: char * ! 192: p_rr(cp, msg, file) ! 193: char *cp, *msg; ! 194: FILE *file; ! 195: { ! 196: int type, class, dlen, n, c; ! 197: struct in_addr inaddr; ! 198: char *cp1, *cp2; ! 199: ! 200: if ((cp = p_cdname(cp, msg, file)) == NULL) ! 201: return (NULL); /* compression error */ ! 202: fprintf(file,"\n\ttype = %s", p_type(type = _getshort(cp))); ! 203: cp += sizeof(u_short); ! 204: fprintf(file,", class = %s", p_class(class = _getshort(cp))); ! 205: cp += sizeof(u_short); ! 206: fprintf(file,", ttl = %s", p_time(_getlong(cp))); ! 207: cp += sizeof(u_long); ! 208: fprintf(file,", dlen = %d\n", dlen = _getshort(cp)); ! 209: cp += sizeof(u_short); ! 210: cp1 = cp; ! 211: /* ! 212: * Print type specific data, if appropriate ! 213: */ ! 214: switch (type) { ! 215: case T_A: ! 216: switch (class) { ! 217: case C_IN: ! 218: case C_HS: ! 219: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); ! 220: if (dlen == 4) { ! 221: fprintf(file,"\tinternet address = %s\n", ! 222: inet_ntoa(inaddr)); ! 223: cp += dlen; ! 224: } else if (dlen == 7) { ! 225: fprintf(file,"\tinternet address = %s", ! 226: inet_ntoa(inaddr)); ! 227: fprintf(file,", protocol = %d", cp[4]); ! 228: fprintf(file,", port = %d\n", ! 229: (cp[5] << 8) + cp[6]); ! 230: cp += dlen; ! 231: } ! 232: break; ! 233: default: ! 234: cp += dlen; ! 235: } ! 236: break; ! 237: case T_CNAME: ! 238: case T_MB: ! 239: case T_MG: ! 240: case T_MR: ! 241: case T_NS: ! 242: case T_PTR: ! 243: fprintf(file,"\tdomain name = "); ! 244: cp = p_cdname(cp, msg, file); ! 245: fprintf(file,"\n"); ! 246: break; ! 247: ! 248: case T_HINFO: ! 249: if (n = *cp++) { ! 250: fprintf(file,"\tCPU=%.*s\n", n, cp); ! 251: cp += n; ! 252: } ! 253: if (n = *cp++) { ! 254: fprintf(file,"\tOS=%.*s\n", n, cp); ! 255: cp += n; ! 256: } ! 257: break; ! 258: ! 259: case T_SOA: ! 260: fprintf(file,"\torigin = "); ! 261: cp = p_cdname(cp, msg, file); ! 262: fprintf(file,"\n\tmail addr = "); ! 263: cp = p_cdname(cp, msg, file); ! 264: fprintf(file,"\n\tserial = %ld", _getlong(cp)); ! 265: cp += sizeof(u_long); ! 266: fprintf(file,"\n\trefresh = %s", p_time(_getlong(cp))); ! 267: cp += sizeof(u_long); ! 268: fprintf(file,"\n\tretry = %s", p_time(_getlong(cp))); ! 269: cp += sizeof(u_long); ! 270: fprintf(file,"\n\texpire = %s", p_time(_getlong(cp))); ! 271: cp += sizeof(u_long); ! 272: fprintf(file,"\n\tmin = %s\n", p_time(_getlong(cp))); ! 273: cp += sizeof(u_long); ! 274: break; ! 275: ! 276: case T_MX: ! 277: fprintf(file,"\tpreference = %ld,",_getshort(cp)); ! 278: cp += sizeof(u_short); ! 279: fprintf(file," name = "); ! 280: cp = p_cdname(cp, msg, file); ! 281: break; ! 282: ! 283: case T_TXT: ! 284: (void) fputs("\t\"", file); ! 285: cp2 = cp1 + dlen; ! 286: while (cp < cp2) { ! 287: if (n = (unsigned char) *cp++) { ! 288: for (c = n; c > 0 && cp < cp2; c--) ! 289: if (*cp == '\n') { ! 290: (void) putc('\\', file); ! 291: (void) putc(*cp++, file); ! 292: } else ! 293: (void) putc(*cp++, file); ! 294: } ! 295: } ! 296: (void) fputs("\"\n", file); ! 297: break; ! 298: ! 299: case T_MINFO: ! 300: fprintf(file,"\trequests = "); ! 301: cp = p_cdname(cp, msg, file); ! 302: fprintf(file,"\n\terrors = "); ! 303: cp = p_cdname(cp, msg, file); ! 304: break; ! 305: ! 306: case T_UINFO: ! 307: fprintf(file,"\t%s\n", cp); ! 308: cp += dlen; ! 309: break; ! 310: ! 311: case T_UID: ! 312: case T_GID: ! 313: if (dlen == 4) { ! 314: fprintf(file,"\t%ld\n", _getlong(cp)); ! 315: cp += sizeof(int); ! 316: } ! 317: break; ! 318: ! 319: case T_WKS: ! 320: if (dlen < sizeof(u_long) + 1) ! 321: break; ! 322: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); ! 323: cp += sizeof(u_long); ! 324: fprintf(file,"\tinternet address = %s, protocol = %d\n\t", ! 325: inet_ntoa(inaddr), *cp++); ! 326: n = 0; ! 327: while (cp < cp1 + dlen) { ! 328: c = *cp++; ! 329: do { ! 330: if (c & 0200) ! 331: fprintf(file," %d", n); ! 332: c <<= 1; ! 333: } while (++n & 07); ! 334: } ! 335: putc('\n',file); ! 336: break; ! 337: ! 338: #ifdef ALLOW_T_UNSPEC ! 339: case T_UNSPEC: ! 340: { ! 341: int NumBytes = 8; ! 342: char *DataPtr; ! 343: int i; ! 344: ! 345: if (dlen < NumBytes) NumBytes = dlen; ! 346: fprintf(file, "\tFirst %d bytes of hex data:", ! 347: NumBytes); ! 348: for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) ! 349: fprintf(file, " %x", *DataPtr); ! 350: fputs("\n", file); ! 351: cp += dlen; ! 352: } ! 353: break; ! 354: #endif /* ALLOW_T_UNSPEC */ ! 355: ! 356: default: ! 357: fprintf(file,"\t???\n"); ! 358: cp += dlen; ! 359: } ! 360: if (cp != cp1 + dlen) { ! 361: fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen); ! 362: cp = NULL; ! 363: } ! 364: fprintf(file,"\n"); ! 365: return (cp); ! 366: } ! 367: ! 368: static char nbuf[40]; ! 369: ! 370: /* ! 371: * Return a string for the type ! 372: */ ! 373: char * ! 374: p_type(type) ! 375: int type; ! 376: { ! 377: switch (type) { ! 378: case T_A: ! 379: return("A"); ! 380: case T_NS: /* authoritative server */ ! 381: return("NS"); ! 382: case T_CNAME: /* canonical name */ ! 383: return("CNAME"); ! 384: case T_SOA: /* start of authority zone */ ! 385: return("SOA"); ! 386: case T_MB: /* mailbox domain name */ ! 387: return("MB"); ! 388: case T_MG: /* mail group member */ ! 389: return("MG"); ! 390: case T_MR: /* mail rename name */ ! 391: return("MR"); ! 392: case T_NULL: /* null resource record */ ! 393: return("NULL"); ! 394: case T_WKS: /* well known service */ ! 395: return("WKS"); ! 396: case T_PTR: /* domain name pointer */ ! 397: return("PTR"); ! 398: case T_HINFO: /* host information */ ! 399: return("HINFO"); ! 400: case T_MINFO: /* mailbox information */ ! 401: return("MINFO"); ! 402: case T_MX: /* mail routing info */ ! 403: return("MX"); ! 404: case T_TXT: /* text */ ! 405: return("TXT"); ! 406: case T_AXFR: /* zone transfer */ ! 407: return("AXFR"); ! 408: case T_MAILB: /* mail box */ ! 409: return("MAILB"); ! 410: case T_MAILA: /* mail address */ ! 411: return("MAILA"); ! 412: case T_ANY: /* matches any type */ ! 413: return("ANY"); ! 414: case T_UINFO: ! 415: return("UINFO"); ! 416: case T_UID: ! 417: return("UID"); ! 418: case T_GID: ! 419: return("GID"); ! 420: #ifdef ALLOW_T_UNSPEC ! 421: case T_UNSPEC: ! 422: return("UNSPEC"); ! 423: #endif /* ALLOW_T_UNSPEC */ ! 424: default: ! 425: (void)sprintf(nbuf, "%d", type); ! 426: return(nbuf); ! 427: } ! 428: } ! 429: ! 430: /* ! 431: * Return a mnemonic for class ! 432: */ ! 433: char * ! 434: p_class(class) ! 435: int class; ! 436: { ! 437: ! 438: switch (class) { ! 439: case C_IN: /* internet class */ ! 440: return("IN"); ! 441: case C_HS: /* hesiod class */ ! 442: return("HS"); ! 443: case C_ANY: /* matches any class */ ! 444: return("ANY"); ! 445: default: ! 446: (void)sprintf(nbuf, "%d", class); ! 447: return(nbuf); ! 448: } ! 449: } ! 450: ! 451: /* ! 452: * Return a mnemonic for a time to live ! 453: */ ! 454: char * ! 455: p_time(value) ! 456: u_long value; ! 457: { ! 458: int secs, mins, hours; ! 459: register char *p; ! 460: ! 461: if (value == 0) { ! 462: strcpy(nbuf, "0 secs"); ! 463: return(nbuf); ! 464: } ! 465: ! 466: secs = value % 60; ! 467: value /= 60; ! 468: mins = value % 60; ! 469: value /= 60; ! 470: hours = value % 24; ! 471: value /= 24; ! 472: ! 473: #define PLURALIZE(x) x, (x == 1) ? "" : "s" ! 474: p = nbuf; ! 475: if (value) { ! 476: (void)sprintf(p, "%d day%s", PLURALIZE(value)); ! 477: while (*++p); ! 478: } ! 479: if (hours) { ! 480: if (value) ! 481: *p++ = ' '; ! 482: (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); ! 483: while (*++p); ! 484: } ! 485: if (mins) { ! 486: if (value || hours) ! 487: *p++ = ' '; ! 488: (void)sprintf(p, "%d min%s", PLURALIZE(mins)); ! 489: while (*++p); ! 490: } ! 491: if (secs || ! (value || hours || mins)) { ! 492: if (value || hours || mins) ! 493: *p++ = ' '; ! 494: (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); ! 495: } ! 496: return(nbuf); ! 497: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.