|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985,1989 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: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)debug.c 5.22 (Berkeley) 6/29/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: ******************************************************************************* ! 26: * ! 27: * debug.c -- ! 28: * ! 29: * Routines to print out packets received from a name server query. ! 30: * ! 31: * Modified version of 4.3BSD BIND res_debug.c 5.30 6/27/90 ! 32: * ! 33: ******************************************************************************* ! 34: */ ! 35: ! 36: #include <sys/types.h> ! 37: #include <netinet/in.h> ! 38: #include <stdio.h> ! 39: #include <arpa/nameser.h> ! 40: #include <arpa/inet.h> ! 41: #include <resolv.h> ! 42: #include <netdb.h> ! 43: #include "res.h" ! 44: ! 45: extern char ctime(); ! 46: ! 47: /* ! 48: * Imported from res_debug.c ! 49: */ ! 50: extern char *_res_resultcodes[]; ! 51: extern char *_res_opcodes[]; ! 52: ! 53: /* ! 54: * Used to highlight the start of a record when printing it. ! 55: */ ! 56: #define INDENT " -> " ! 57: ! 58: ! 59: ! 60: /* ! 61: * Print the contents of a query. ! 62: * This is intended to be primarily a debugging routine. ! 63: */ ! 64: ! 65: Print_query(msg, eom, printHeader) ! 66: char *msg, *eom; ! 67: int printHeader; ! 68: { ! 69: Fprint_query(msg, eom, printHeader,stdout); ! 70: } ! 71: ! 72: Fprint_query(msg, eom, printHeader,file) ! 73: char *msg, *eom; ! 74: int printHeader; ! 75: FILE *file; ! 76: { ! 77: register char *cp; ! 78: register HEADER *hp; ! 79: register int n; ! 80: short class; ! 81: short type; ! 82: ! 83: /* ! 84: * Print header fields. ! 85: */ ! 86: hp = (HEADER *)msg; ! 87: cp = msg + sizeof(HEADER); ! 88: if (printHeader || (_res.options & RES_DEBUG2)) { ! 89: fprintf(file," HEADER:\n"); ! 90: fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]); ! 91: fprintf(file,", id = %d", ntohs(hp->id)); ! 92: fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]); ! 93: fprintf(file,"\theader flags: "); ! 94: if (hp->qr) { ! 95: fprintf(file," response"); ! 96: } else { ! 97: fprintf(file," query"); ! 98: } ! 99: if (hp->aa) ! 100: fprintf(file,", auth. answer"); ! 101: if (hp->tc) ! 102: fprintf(file,", truncation"); ! 103: if (hp->rd) ! 104: fprintf(file,", want recursion"); ! 105: if (hp->ra) ! 106: fprintf(file,", recursion avail."); ! 107: if (hp->pr) ! 108: fprintf(file,", primary"); ! 109: fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount)); ! 110: fprintf(file,", answers = %d", ntohs(hp->ancount)); ! 111: fprintf(file,", authority records = %d", ntohs(hp->nscount)); ! 112: fprintf(file,", additional = %d\n\n", ntohs(hp->arcount)); ! 113: } ! 114: ! 115: /* ! 116: * Print question records. ! 117: */ ! 118: if (n = ntohs(hp->qdcount)) { ! 119: fprintf(file," QUESTIONS:\n"); ! 120: while (--n >= 0) { ! 121: fprintf(file,"\t"); ! 122: cp = Print_cdname(cp, msg, eom, file); ! 123: if (cp == NULL) ! 124: return; ! 125: type = _getshort(cp); ! 126: cp += sizeof(u_short); ! 127: class = _getshort(cp); ! 128: cp += sizeof(u_short); ! 129: fprintf(file,", type = %s", p_type(type)); ! 130: fprintf(file,", class = %s\n", p_class(class)); ! 131: } ! 132: } ! 133: /* ! 134: * Print authoritative answer records ! 135: */ ! 136: if (n = ntohs(hp->ancount)) { ! 137: fprintf(file," ANSWERS:\n"); ! 138: while (--n >= 0) { ! 139: fprintf(file, INDENT); ! 140: cp = Print_rr(cp, msg, eom, file); ! 141: if (cp == NULL) ! 142: return; ! 143: } ! 144: } ! 145: /* ! 146: * print name server records ! 147: */ ! 148: if (n = ntohs(hp->nscount)) { ! 149: fprintf(file," AUTHORITY RECORDS:\n"); ! 150: while (--n >= 0) { ! 151: fprintf(file, INDENT); ! 152: cp = Print_rr(cp, msg, eom, file); ! 153: if (cp == NULL) ! 154: return; ! 155: } ! 156: } ! 157: /* ! 158: * print additional records ! 159: */ ! 160: if (n = ntohs(hp->arcount)) { ! 161: fprintf(file," ADDITIONAL RECORDS:\n"); ! 162: while (--n >= 0) { ! 163: fprintf(file, INDENT); ! 164: cp = Print_rr(cp, msg, eom, file); ! 165: if (cp == NULL) ! 166: return; ! 167: } ! 168: } ! 169: fprintf(file,"\n------------\n"); ! 170: } ! 171: ! 172: ! 173: char * ! 174: Print_cdname_sub(cp, msg, eom, file, format) ! 175: char *cp, *msg, *eom; ! 176: FILE *file; ! 177: int format; ! 178: { ! 179: int n; ! 180: char name[MAXDNAME]; ! 181: extern char *strcpy(); ! 182: ! 183: if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0) ! 184: return (NULL); ! 185: if (name[0] == '\0') { ! 186: (void) strcpy(name, "(root)"); ! 187: } ! 188: if (format) { ! 189: fprintf(file, "%-30s", name); ! 190: } else { ! 191: fputs(name, file); ! 192: } ! 193: return (cp + n); ! 194: } ! 195: ! 196: char * ! 197: Print_cdname(cp, msg, eom, file) ! 198: char *cp, *msg, *eom; ! 199: FILE *file; ! 200: { ! 201: return(Print_cdname_sub(cp, msg, eom, file, 0)); ! 202: } ! 203: ! 204: char * ! 205: Print_cdname2(cp, msg, eom, file) ! 206: char *cp, *msg, *eom; ! 207: FILE *file; ! 208: { ! 209: return(Print_cdname_sub(cp, msg, eom, file, 1)); ! 210: } ! 211: ! 212: /* ! 213: * Print resource record fields in human readable form. ! 214: */ ! 215: char * ! 216: Print_rr(cp, msg, eom, file) ! 217: char *cp, *msg, *eom; ! 218: FILE *file; ! 219: { ! 220: int type, class, dlen, n, c; ! 221: unsigned long rrttl, ttl; ! 222: struct in_addr inaddr; ! 223: char *cp1, *cp2; ! 224: int debug; ! 225: ! 226: if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) { ! 227: fprintf(file, "(name truncated?)\n"); ! 228: return (NULL); /* compression error */ ! 229: } ! 230: ! 231: type = _getshort(cp); ! 232: cp += sizeof(u_short); ! 233: class = _getshort(cp); ! 234: cp += sizeof(u_short); ! 235: rrttl = _getlong(cp); ! 236: cp += sizeof(u_long); ! 237: dlen = _getshort(cp); ! 238: cp += sizeof(u_short); ! 239: ! 240: debug = _res.options & (RES_DEBUG|RES_DEBUG2); ! 241: if (debug) { ! 242: if (_res.options & RES_DEBUG2) { ! 243: fprintf(file,"\n\ttype = %s, class = %s, dlen = %d", ! 244: p_type(type), p_class(class), dlen); ! 245: } ! 246: if (type == T_SOA) { ! 247: fprintf(file,"\n\tttl = %lu (%s)", rrttl, p_time(rrttl)); ! 248: } ! 249: (void) putc('\n', file); ! 250: } ! 251: ! 252: cp1 = cp; ! 253: ! 254: /* ! 255: * Print type specific data, if appropriate ! 256: */ ! 257: switch (type) { ! 258: case T_A: ! 259: switch (class) { ! 260: case C_IN: ! 261: case C_HS: ! 262: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); ! 263: if (dlen == 4) { ! 264: fprintf(file,"\tinternet address = %s\n", ! 265: inet_ntoa(inaddr)); ! 266: cp += dlen; ! 267: } else if (dlen == 7) { ! 268: fprintf(file,"\tinternet address = %s", ! 269: inet_ntoa(inaddr)); ! 270: fprintf(file,", protocol = %d", cp[4]); ! 271: fprintf(file,", port = %d\n", ! 272: (cp[5] << 8) + cp[6]); ! 273: cp += dlen; ! 274: } ! 275: break; ! 276: default: ! 277: fprintf(file,"\taddress, class = %d, len = %d\n", ! 278: class, dlen); ! 279: cp += dlen; ! 280: } ! 281: break; ! 282: ! 283: case T_CNAME: ! 284: fprintf(file,"\tcanonical name = "); ! 285: goto doname; ! 286: ! 287: case T_MG: ! 288: fprintf(file,"\tmail group member = "); ! 289: goto doname; ! 290: case T_MB: ! 291: fprintf(file,"\tmail box = "); ! 292: goto doname; ! 293: case T_MR: ! 294: fprintf(file,"\tmailbox rename = "); ! 295: goto doname; ! 296: case T_MX: ! 297: fprintf(file,"\tpreference = %u",_getshort(cp)); ! 298: cp += sizeof(u_short); ! 299: fprintf(file,", mail exchanger = "); ! 300: goto doname; ! 301: case T_NS: ! 302: fprintf(file,"\tnameserver = "); ! 303: goto doname; ! 304: case T_PTR: ! 305: fprintf(file,"\tname = "); ! 306: doname: ! 307: cp = Print_cdname(cp, msg, eom, file); ! 308: (void) putc('\n', file); ! 309: break; ! 310: ! 311: case T_HINFO: ! 312: if (n = *cp++) { ! 313: fprintf(file,"\tCPU = %.*s", n, cp); ! 314: cp += n; ! 315: } ! 316: if (n = *cp++) { ! 317: fprintf(file,"\tOS = %.*s\n", n, cp); ! 318: cp += n; ! 319: } ! 320: break; ! 321: ! 322: case T_SOA: ! 323: if (!debug) ! 324: (void) putc('\n', file); ! 325: fprintf(file,"\torigin = "); ! 326: cp = Print_cdname(cp, msg, eom, file); ! 327: fprintf(file,"\n\tmail addr = "); ! 328: cp = Print_cdname(cp, msg, eom, file); ! 329: fprintf(file,"\n\tserial = %lu", _getlong(cp)); ! 330: cp += sizeof(u_long); ! 331: ttl = _getlong(cp); ! 332: fprintf(file,"\n\trefresh = %lu (%s)", ttl, p_time(ttl)); ! 333: cp += sizeof(u_long); ! 334: ttl = _getlong(cp); ! 335: fprintf(file,"\n\tretry = %lu (%s)", ttl, p_time(ttl)); ! 336: cp += sizeof(u_long); ! 337: ttl = _getlong(cp); ! 338: fprintf(file,"\n\texpire = %lu (%s)", ttl, p_time(ttl)); ! 339: cp += sizeof(u_long); ! 340: ttl = _getlong(cp); ! 341: fprintf(file,"\n\tminimum ttl = %lu (%s)\n", ttl, p_time(ttl)); ! 342: cp += sizeof(u_long); ! 343: break; ! 344: ! 345: case T_MINFO: ! 346: if (!debug) ! 347: (void) putc('\n', file); ! 348: fprintf(file,"\trequests = "); ! 349: cp = Print_cdname(cp, msg, eom, file); ! 350: fprintf(file,"\n\terrors = "); ! 351: cp = Print_cdname(cp, msg, eom, file); ! 352: (void) putc('\n', file); ! 353: break; ! 354: ! 355: case T_TXT: ! 356: (void) fputs("\ttext = \"", file); ! 357: cp2 = cp1 + dlen; ! 358: while (cp < cp2) { ! 359: if (n = (unsigned char) *cp++) { ! 360: for (c = n; c > 0 && cp < cp2; c--) ! 361: if (*cp == '\n') { ! 362: (void) putc('\\', file); ! 363: (void) putc(*cp++, file); ! 364: } else ! 365: (void) putc(*cp++, file); ! 366: } ! 367: } ! 368: (void) fputs("\"\n", file); ! 369: break; ! 370: ! 371: case T_UINFO: ! 372: fprintf(file,"\tuser info = %s\n", cp); ! 373: cp += dlen; ! 374: break; ! 375: ! 376: case T_UID: ! 377: case T_GID: ! 378: if (dlen == 4) { ! 379: fprintf(file,"\t%cid = %lu\n",type == T_UID ? 'u' : 'g', ! 380: _getlong(cp)); ! 381: cp += sizeof(int); ! 382: } else { ! 383: fprintf(file,"\t%cid of length %d?\n", ! 384: type == T_UID ? 'u' : 'g', dlen); ! 385: cp += dlen; ! 386: } ! 387: break; ! 388: ! 389: case T_WKS: { ! 390: struct protoent *protoPtr; ! 391: ! 392: if (dlen < sizeof(u_long) + 1) ! 393: break; ! 394: if (!debug) ! 395: (void) putc('\n', file); ! 396: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); ! 397: cp += sizeof(u_long); ! 398: if ((protoPtr = getprotobynumber(*cp)) != NULL) { ! 399: fprintf(file,"\tinet address = %s, protocol = %s\n\t", ! 400: inet_ntoa(inaddr), protoPtr->p_name); ! 401: } else { ! 402: fprintf(file,"\tinet address = %s, protocol = %d\n\t", ! 403: inet_ntoa(inaddr), *cp); ! 404: } ! 405: cp++; ! 406: n = 0; ! 407: while (cp < cp1 + dlen) { ! 408: c = *cp++; ! 409: do { ! 410: struct servent *s; ! 411: ! 412: if (c & 0200) { ! 413: s = getservbyport(n, NULL); ! 414: if (s != NULL) { ! 415: fprintf(file," %s", s->s_name); ! 416: } else { ! 417: fprintf(file," #%d", n); ! 418: } ! 419: } ! 420: c <<= 1; ! 421: } while (++n & 07); ! 422: } ! 423: putc('\n',file); ! 424: } ! 425: break; ! 426: ! 427: case T_NULL: ! 428: fprintf(file, "\tNULL (dlen %d)\n", dlen); ! 429: cp += dlen; ! 430: break; ! 431: ! 432: default: ! 433: fprintf(file,"\t??? unknown type %d ???\n", type); ! 434: cp += dlen; ! 435: } ! 436: if (_res.options & RES_DEBUG && type != T_SOA) { ! 437: fprintf(file,"\tttl = %lu (%s)\n", rrttl, p_time(rrttl)); ! 438: } ! 439: if (cp != cp1 + dlen) { ! 440: fprintf(file, ! 441: "\n*** Error: record size incorrect (%d != %d)\n\n", ! 442: cp - cp1, dlen); ! 443: cp = NULL; ! 444: } ! 445: return (cp); ! 446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.