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.13 (Berkeley) 3/9/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: "9", 34: "10", 35: "UPDATEA", 36: "UPDATED", 37: "UPDATEM", 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: } 229: break; 230: case T_CNAME: 231: case T_MB: 232: #ifdef OLDRR 233: case T_MD: 234: case T_MF: 235: #endif /* OLDRR */ 236: case T_MG: 237: case T_MR: 238: case T_NS: 239: case T_PTR: 240: fprintf(file,"\tdomain name = "); 241: cp = p_cdname(cp, msg, file); 242: fprintf(file,"\n"); 243: break; 244: 245: case T_HINFO: 246: if (n = *cp++) { 247: fprintf(file,"\tCPU=%.*s\n", n, cp); 248: cp += n; 249: } 250: if (n = *cp++) { 251: fprintf(file,"\tOS=%.*s\n", n, cp); 252: cp += n; 253: } 254: break; 255: 256: case T_SOA: 257: fprintf(file,"\torigin = "); 258: cp = p_cdname(cp, msg, file); 259: fprintf(file,"\n\tmail addr = "); 260: cp = p_cdname(cp, msg, file); 261: fprintf(file,"\n\tserial=%ld", getlong(cp)); 262: cp += sizeof(u_long); 263: fprintf(file,", refresh=%ld", getlong(cp)); 264: cp += sizeof(u_long); 265: fprintf(file,", retry=%ld", getlong(cp)); 266: cp += sizeof(u_long); 267: fprintf(file,", expire=%ld", getlong(cp)); 268: cp += sizeof(u_long); 269: fprintf(file,", min=%ld\n", getlong(cp)); 270: cp += sizeof(u_long); 271: break; 272: 273: case T_MX: 274: fprintf(file,"\tpreference = %ld,",getshort(cp)); 275: cp += sizeof(u_short); 276: fprintf(file," name = "); 277: cp = p_cdname(cp, msg, file); 278: break; 279: 280: case T_MINFO: 281: fprintf(file,"\trequests = "); 282: cp = p_cdname(cp, msg, file); 283: fprintf(file,"\n\terrors = "); 284: cp = p_cdname(cp, msg, file); 285: break; 286: 287: case T_UINFO: 288: fprintf(file,"\t%s\n", cp); 289: cp += dlen; 290: break; 291: 292: case T_UID: 293: case T_GID: 294: if (dlen == 4) { 295: fprintf(file,"\t%ld\n", getlong(cp)); 296: cp += sizeof(int); 297: } 298: break; 299: 300: case T_WKS: 301: if (dlen < sizeof(u_long) + 1) 302: break; 303: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 304: cp += sizeof(u_long); 305: fprintf(file,"\tinternet address = %s, protocol = %d\n\t", 306: inet_ntoa(inaddr), *cp++); 307: n = 0; 308: while (cp < cp1 + dlen) { 309: c = *cp++; 310: do { 311: if (c & 0200) 312: fprintf(file," %d", n); 313: c <<= 1; 314: } while (++n & 07); 315: } 316: putc('\n',file); 317: break; 318: 319: default: 320: fprintf(file,"\t???\n"); 321: cp += dlen; 322: } 323: if (cp != cp1 + dlen) 324: fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen); 325: fprintf(file,"\n"); 326: return (cp); 327: #endif 328: } 329: 330: static char nbuf[20]; 331: extern char *sprintf(); 332: 333: /* 334: * Return a string for the type 335: */ 336: char * 337: p_type(type) 338: int type; 339: { 340: switch (type) { 341: case T_A: 342: return("A"); 343: case T_NS: /* authoritative server */ 344: return("NS"); 345: #ifdef OLDRR 346: case T_MD: /* mail destination */ 347: return("MD"); 348: case T_MF: /* mail forwarder */ 349: return("MF"); 350: #endif /* OLDRR */ 351: case T_CNAME: /* connonical name */ 352: return("CNAME"); 353: case T_SOA: /* start of authority zone */ 354: return("SOA"); 355: case T_MB: /* mailbox domain name */ 356: return("MB"); 357: case T_MG: /* mail group member */ 358: return("MG"); 359: case T_MX: /* mail routing info */ 360: return("MX"); 361: case T_MR: /* mail rename name */ 362: return("MR"); 363: case T_NULL: /* null resource record */ 364: return("NULL"); 365: case T_WKS: /* well known service */ 366: return("WKS"); 367: case T_PTR: /* domain name pointer */ 368: return("PTR"); 369: case T_HINFO: /* host information */ 370: return("HINFO"); 371: case T_MINFO: /* mailbox information */ 372: return("MINFO"); 373: case T_AXFR: /* zone transfer */ 374: return("AXFR"); 375: case T_MAILB: /* mail box */ 376: return("MAILB"); 377: case T_MAILA: /* mail address */ 378: return("MAILA"); 379: case T_ANY: /* matches any type */ 380: return("ANY"); 381: case T_UINFO: 382: return("UINFO"); 383: case T_UID: 384: return("UID"); 385: case T_GID: 386: return("GID"); 387: default: 388: return (sprintf(nbuf, "%d", type)); 389: } 390: } 391: 392: /* 393: * Return a mnemonic for class 394: */ 395: char * 396: p_class(class) 397: int class; 398: { 399: 400: switch (class) { 401: case C_IN: /* internet class */ 402: return("IN"); 403: case C_ANY: /* matches any class */ 404: return("ANY"); 405: default: 406: return (sprintf(nbuf, "%d", class)); 407: } 408: }