1: /* 2: ******************************************************************************* 3: * 4: * debug.c -- 5: * 6: * Routines to print out packets received from a name server query. 7: * 8: * Modified version of 4.3BSD BIND res_debug.c 5.6 9/14/85 9: * 10: * Copyright (c) 1985 Regents of the University of California. 11: * All rights reserved. The Berkeley software License Agreement 12: * specifies the terms and conditions for redistribution. 13: * 14: ******************************************************************************* 15: */ 16: 17: #ifndef lint 18: static char sccsid[] = "@(#)debug.c 5.3 (Berkeley) 3/31/86"; 19: #endif not lint 20: 21: #include <sys/types.h> 22: #include <netinet/in.h> 23: #include <stdio.h> 24: #include <arpa/nameser.h> 25: #include <resolv.h> 26: #include "res.h" 27: 28: extern char ctime(); 29: 30: /* 31: * Imported from res_debug.c 32: */ 33: extern char *rcodes[]; 34: extern char *opcodes[]; 35: 36: /* 37: * Used to highlight the start of a record when printing it. 38: */ 39: #define INDENT "-> " 40: 41: 42: 43: /* 44: * Print the contents of a query. 45: * This is intended to be primarily a debugging routine. 46: */ 47: 48: Print_query(msg, eom, printHeader) 49: char *msg, *eom; 50: int printHeader; 51: { 52: Fprint_query(msg, eom, printHeader,stdout); 53: } 54: 55: Fprint_query(msg, eom, printHeader,file) 56: char *msg, *eom; 57: int printHeader; 58: FILE *file; 59: { 60: register char *cp; 61: register HEADER *hp; 62: register int n; 63: short class; 64: short type; 65: 66: /* 67: * Print header fields. 68: */ 69: hp = (HEADER *)msg; 70: cp = msg + sizeof(HEADER); 71: if (printHeader || (_res.options & RES_DEBUG2)) { 72: fprintf(file,"HEADER:\n"); 73: fprintf(file,"\topcode = %s", opcodes[hp->opcode]); 74: fprintf(file,", id = %d", ntohs(hp->id)); 75: fprintf(file,", rcode = %s\n", rcodes[hp->rcode]); 76: fprintf(file,"\theader flags: "); 77: if (hp->qr) { 78: fprintf(file," response"); 79: } else { 80: fprintf(file," query"); 81: } 82: if (hp->aa) 83: fprintf(file,", auth. answer"); 84: if (hp->tc) 85: fprintf(file,", truncation"); 86: if (hp->rd) 87: fprintf(file,", want recursion"); 88: if (hp->ra) 89: fprintf(file,", recursion avail."); 90: if (hp->pr) 91: fprintf(file,", primary"); 92: fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount)); 93: fprintf(file,", answers = %d", ntohs(hp->ancount)); 94: fprintf(file,", n.s. = %d", ntohs(hp->nscount)); 95: fprintf(file,", additional = %d\n\n", ntohs(hp->arcount)); 96: } 97: 98: /* 99: * Print question records. 100: */ 101: if (n = ntohs(hp->qdcount)) { 102: fprintf(file,"QUESTIONS:\n"); 103: while (--n >= 0) { 104: fprintf(file,"\t"); 105: cp = Print_cdname(cp, msg, eom, file); 106: if (cp == NULL) 107: return; 108: type = getshort(cp); 109: cp += sizeof(u_short); 110: class = getshort(cp); 111: cp += sizeof(u_short); 112: fprintf(file,", type = %s", p_type(type)); 113: fprintf(file,", class = %s\n", p_class(class)); 114: } 115: } 116: /* 117: * Print authoritative answer records 118: */ 119: if (n = ntohs(hp->ancount)) { 120: fprintf(file,"ANSWERS:\n"); 121: while (--n >= 0) { 122: fprintf(file, INDENT); 123: cp = Print_rr(cp, msg, eom, file); 124: if (cp == NULL) 125: return; 126: } 127: } 128: /* 129: * print name server records 130: */ 131: if (n = ntohs(hp->nscount)) { 132: fprintf(file,"NAME SERVERS:\n"); 133: while (--n >= 0) { 134: fprintf(file, INDENT); 135: cp = Print_rr(cp, msg, eom, file); 136: if (cp == NULL) 137: return; 138: } 139: } 140: /* 141: * print additional records 142: */ 143: if (n = ntohs(hp->arcount)) { 144: fprintf(file,"ADDITIONAL RECORDS:\n"); 145: while (--n >= 0) { 146: fprintf(file, INDENT); 147: cp = Print_rr(cp, msg, eom, file); 148: if (cp == NULL) 149: return; 150: } 151: } 152: fprintf(file,"\n"); 153: 154: } 155: 156: 157: char * 158: Print_cdname_sub(cp, msg, eom, file, format) 159: char *cp, *msg, *eom; 160: FILE *file; 161: int format; 162: { 163: int n; 164: char name[MAXDNAME]; 165: extern char *strcpy(); 166: 167: if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0) 168: return (NULL); 169: if (name[0] == '\0') { 170: (void) strcpy(name, "(root)"); 171: } 172: if (format) { 173: fprintf(file, "%-30s", name); 174: } else { 175: fputs(name, file); 176: } 177: return (cp + n); 178: } 179: 180: char * 181: Print_cdname(cp, msg, eom, file) 182: char *cp, *msg, *eom; 183: FILE *file; 184: { 185: return(Print_cdname_sub(cp, msg, eom, file, 0)); 186: } 187: 188: char * 189: Print_cdname2(cp, msg, eom, file) 190: char *cp, *msg, *eom; 191: FILE *file; 192: { 193: return(Print_cdname_sub(cp, msg, eom, file, 1)); 194: } 195: 196: /* 197: * Print resource record fields in human readable form. 198: */ 199: char * 200: Print_rr(cp, msg, eom, file) 201: char *cp, *msg, *eom; 202: FILE *file; 203: { 204: int type, class, dlen, n, c; 205: long ttl; 206: struct in_addr inaddr; 207: char *cp1; 208: 209: if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) 210: return (NULL); /* compression error */ 211: 212: type = getshort(cp); 213: cp += sizeof(u_short); 214: class = getshort(cp); 215: cp += sizeof(u_short); 216: ttl = getlong(cp); 217: cp += sizeof(u_long); 218: dlen = getshort(cp); 219: cp += sizeof(u_short); 220: 221: if (_res.options & RES_DEBUG2) { 222: fprintf(file,"\n\ttype = %s, class = %s, ttl = %u, dlen = %d", 223: p_type(type), p_class(class), ttl, dlen); 224: fprintf(file,"\n"); 225: } 226: 227: cp1 = cp; 228: 229: /* 230: * Print type specific data, if appropriate 231: */ 232: switch (type) { 233: case T_A: 234: switch (class) { 235: case C_IN: 236: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 237: if (dlen == 4) { 238: fprintf(file,"\tinet address = %s\n", 239: inet_ntoa(inaddr)); 240: cp += dlen; 241: } else if (dlen == 7) { 242: fprintf(file,"\tinet address = %s", 243: inet_ntoa(inaddr)); 244: fprintf(file,", protocol = %d", cp[4]); 245: fprintf(file,", port = %d\n", 246: (cp[5] << 8) + cp[6]); 247: cp += dlen; 248: } 249: break; 250: } 251: break; 252: 253: case T_CNAME: 254: fprintf(file,"\tcanonical name = "); 255: cp = Print_cdname(cp, msg, eom, file); 256: fprintf(file,"\n"); 257: break; 258: 259: case T_MX: 260: fprintf(file,"\tpreference = %d",getshort(cp)); 261: cp += sizeof(u_short); 262: fprintf(file,", mail exchanger = "); 263: cp = Print_cdname(cp,msg, eom, file); 264: fprintf(file,"\n"); 265: break; 266: 267: case T_MG: 268: case T_MB: 269: case T_MR: 270: case T_NS: 271: case T_PTR: 272: fprintf(file,"\tserver name = "); 273: cp = Print_cdname(cp, msg, eom, file); 274: fprintf(file,"\n"); 275: break; 276: 277: case T_HINFO: 278: if (n = *cp++) { 279: fprintf(file,"\tCPU=%.*s", n, cp); 280: cp += n; 281: } 282: if (n = *cp++) { 283: fprintf(file,"\tOS=%.*s\n", n, cp); 284: cp += n; 285: } 286: break; 287: 288: case T_SOA: 289: fprintf(file,"\torigin = "); 290: cp = Print_cdname(cp, msg, eom, file); 291: fprintf(file,"\n\tmail addr = "); 292: cp = Print_cdname(cp, msg, eom, file); 293: fprintf(file,"\n\tserial=%ld", getlong(cp)); 294: cp += sizeof(u_long); 295: fprintf(file,", refresh=%ld", getlong(cp)); 296: cp += sizeof(u_long); 297: fprintf(file,", retry=%ld", getlong(cp)); 298: cp += sizeof(u_long); 299: fprintf(file,", expire=%ld", getlong(cp)); 300: cp += sizeof(u_long); 301: fprintf(file,", min=%ld\n", getlong(cp)); 302: cp += sizeof(u_long); 303: break; 304: 305: case T_MINFO: 306: fprintf(file,"\trequests = "); 307: cp = Print_cdname(cp, msg, eom, file); 308: fprintf(file,"\n\terrors = "); 309: cp = Print_cdname(cp, msg, eom, file); 310: break; 311: 312: case T_UINFO: 313: fprintf(file,"\t%s\n", cp); 314: cp += dlen; 315: break; 316: 317: case T_UID: 318: case T_GID: 319: if (dlen == 4) { 320: fprintf(file,"\t%ld\n", getlong(cp)); 321: cp += sizeof(int); 322: } 323: break; 324: 325: case T_WKS: 326: if (dlen < sizeof(u_long) + 1) 327: break; 328: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 329: cp += sizeof(u_long); 330: fprintf(file,"\tinet address = %s, protocol = %d\n\t", 331: inet_ntoa(inaddr), *cp++); 332: n = 0; 333: while (cp < cp1 + dlen) { 334: c = *cp++; 335: do { 336: if (c & 0200) 337: fprintf(file," %d", n); 338: c <<= 1; 339: } while (++n & 07); 340: } 341: putc('\n',file); 342: break; 343: 344: case T_NULL: 345: break; 346: 347: default: 348: fprintf(file,"\t???\n"); 349: cp += dlen; 350: } 351: if (cp != cp1 + dlen) 352: fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen); 353: return (cp); 354: }