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