1 #ifndef lint 2 static char sccsid[] = "@(#)res_debug.c 4.3 (Berkeley) 03/29/85"; 3 #endif 4 5 #include <sys/types.h> 6 #include <netinet/in.h> 7 #include <stdio.h> 8 #include <nameser.h> 9 10 extern char *p_cdname(), *p_rr(), *p_type(), *p_class(); 11 extern char *inet_ntoa(); 12 13 char *opcodes[] = { 14 "QUERY", 15 "IQUERY", 16 "CQUERYM", 17 "CQUERYU", 18 "4", 19 "5", 20 "6", 21 "7", 22 "8", 23 "9", 24 "10", 25 "UPDATEA", 26 "UPDATED", 27 "UPDATEM", 28 "ZONEINIT", 29 "ZONEREF", 30 }; 31 32 char *rcodes[] = { 33 "NOERROR", 34 "FORMERR", 35 "SERVFAIL", 36 "NXDOMAIN", 37 "NOTIMP", 38 "REFUSED", 39 "6", 40 "7", 41 "8", 42 "9", 43 "10", 44 "11", 45 "12", 46 "13", 47 "14", 48 "NOCHANGE", 49 }; 50 51 /* 52 * Print the contents of a query. 53 * This is intended to be primarily a debugging routine. 54 */ 55 p_query(msg) 56 char *msg; 57 { 58 register char *cp; 59 register HEADER *hp; 60 register int n; 61 62 /* 63 * Print header fields. 64 */ 65 hp = (HEADER *)msg; 66 cp = msg + sizeof(HEADER); 67 printf("HEADER:\n"); 68 printf("\topcode = %s", opcodes[hp->opcode]); 69 printf(", id = %d", ntohs(hp->id)); 70 printf(", rcode = %s\n", rcodes[hp->rcode]); 71 printf("\theader flags: "); 72 if (hp->qr) 73 printf(" qr"); 74 if (hp->aa) 75 printf(" aa"); 76 if (hp->tc) 77 printf(" tc"); 78 if (hp->rd) 79 printf(" rd"); 80 if (hp->ra) 81 printf(" ra"); 82 if (hp->pr) 83 printf(" pr"); 84 printf("\n\tqdcount = %d", ntohs(hp->qdcount)); 85 printf(", ancount = %d", ntohs(hp->ancount)); 86 printf(", nscount = %d", ntohs(hp->nscount)); 87 printf(", arcount = %d\n\n", ntohs(hp->arcount)); 88 /* 89 * Print question records. 90 */ 91 if (n = ntohs(hp->qdcount)) { 92 printf("QUESTIONS:\n"); 93 while (--n >= 0) { 94 printf("\t"); 95 cp = p_cdname(cp, msg); 96 if (cp == NULL) 97 return; 98 printf(", type = %s", p_type(getshort(cp))); 99 cp += sizeof(u_short); 100 printf(", class = %s\n\n", p_class(getshort(cp))); 101 cp += sizeof(u_short); 102 } 103 } 104 /* 105 * Print authoritative answer records 106 */ 107 if (n = ntohs(hp->ancount)) { 108 printf("ANSWERS:\n"); 109 while (--n >= 0) { 110 printf("\t"); 111 cp = p_rr(cp, msg); 112 if (cp == NULL) 113 return; 114 } 115 } 116 /* 117 * print name server records 118 */ 119 if (n = ntohs(hp->nscount)) { 120 printf("NAME SERVERS:\n"); 121 while (--n >= 0) { 122 printf("\t"); 123 cp = p_rr(cp, msg); 124 if (cp == NULL) 125 return; 126 } 127 } 128 /* 129 * print additional records 130 */ 131 if (n = ntohs(hp->arcount)) { 132 printf("ADDITIONAL RECORDS:\n"); 133 while (--n >= 0) { 134 printf("\t"); 135 cp = p_rr(cp, msg); 136 if (cp == NULL) 137 return; 138 } 139 } 140 } 141 142 char * 143 p_cdname(cp, msg) 144 char *cp, *msg; 145 { 146 char name[MAXDNAME]; 147 int n; 148 149 if ((n = dn_expand(msg, cp, name, sizeof(name))) < 0) 150 return (NULL); 151 if (name[0] == '\0') { 152 name[0] = '.'; 153 name[1] = '\0'; 154 } 155 fputs(name, stdout); 156 return (cp + n); 157 } 158 159 /* 160 * Print resource record fields in human readable form. 161 */ 162 char * 163 p_rr(cp, msg) 164 char *cp, *msg; 165 { 166 int type, class, dlen, n, c; 167 struct in_addr inaddr; 168 char *cp1; 169 170 if ((cp = p_cdname(cp, msg)) == NULL) 171 return (NULL); /* compression error */ 172 printf("\n\ttype = %s", p_type(type = getshort(cp))); 173 cp += sizeof(u_short); 174 printf(", class = %s", p_class(class = getshort(cp))); 175 cp += sizeof(u_short); 176 printf(", ttl = %ld", getlong(cp)); 177 cp += sizeof(u_long); 178 printf(", dlen = %d\n", dlen = getshort(cp)); 179 cp += sizeof(u_short); 180 cp1 = cp; 181 /* 182 * Print type specific data, if appropriate 183 */ 184 switch (type) { 185 case T_A: 186 switch (class) { 187 case C_IN: 188 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 189 if (dlen == 4) { 190 printf("\tinternet address = %s\n", 191 inet_ntoa(inaddr)); 192 cp += dlen; 193 } else if (dlen == 7) { 194 printf("\tinternet address = %s", 195 inet_ntoa(inaddr)); 196 printf(", protocol = %d", cp[4]); 197 printf(", port = %d\n", 198 (cp[5] << 8) + cp[6]); 199 cp += dlen; 200 } 201 break; 202 } 203 break; 204 case T_CNAME: 205 case T_MB: 206 case T_MD: 207 case T_MF: 208 case T_MG: 209 case T_MR: 210 case T_NS: 211 case T_PTR: 212 printf("\tdomain name = "); 213 cp = p_cdname(cp, msg); 214 printf("\n"); 215 break; 216 217 case T_HINFO: 218 if (n = *cp++) { 219 printf("\tCPU=%.*s\n", n, cp); 220 cp += n; 221 } 222 if (n = *cp++) { 223 printf("\tOS=%.*s\n", n, cp); 224 cp += n; 225 } 226 break; 227 228 case T_SOA: 229 printf("\torigin = "); 230 cp = p_cdname(cp, msg); 231 printf("\n\tmail addr = "); 232 cp = p_cdname(cp, msg); 233 printf("\n\tserial=%ld", getlong(cp)); 234 cp += sizeof(u_long); 235 printf(", refresh=%ld", getlong(cp)); 236 cp += sizeof(u_long); 237 printf(", retry=%ld", getlong(cp)); 238 cp += sizeof(u_long); 239 printf(", expire=%ld", getlong(cp)); 240 cp += sizeof(u_long); 241 printf(", min=%ld\n", getlong(cp)); 242 cp += sizeof(u_long); 243 break; 244 245 case T_MINFO: 246 printf("\trequests = "); 247 cp = p_cdname(cp, msg); 248 printf("\n\terrors = "); 249 cp = p_cdname(cp, msg); 250 break; 251 252 case T_UINFO: 253 printf("\t%s\n", cp); 254 cp += dlen; 255 break; 256 257 case T_UID: 258 case T_GID: 259 if (dlen == 4) { 260 printf("\t%ld\n", getlong(cp)); 261 cp += sizeof(int); 262 } 263 break; 264 265 case T_WKS: 266 if (dlen < sizeof(u_long) + 1) 267 break; 268 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 269 cp += sizeof(u_long); 270 printf("\tinternet address = %s, protocol = %d\n\t", 271 inet_ntoa(inaddr), *cp++); 272 n = 0; 273 while (cp < cp1 + dlen) { 274 c = *cp++; 275 do { 276 if (c & 1) 277 printf(" %d", n); 278 c >>= 1; 279 } while (++n & 07); 280 } 281 putchar('\n'); 282 break; 283 284 default: 285 printf("\t???\n"); 286 cp += dlen; 287 } 288 if (cp != cp1 + dlen) 289 printf("packet size error (%#x != %#x)\n", cp, cp1+dlen); 290 printf("\n"); 291 return (cp); 292 } 293 294 static char nbuf[20]; 295 extern char *sprintf(); 296 297 /* 298 * Return a string for the type 299 */ 300 char * 301 p_type(type) 302 int type; 303 { 304 305 switch (type) { 306 case T_A: 307 return("A"); 308 case T_NS: /* authoritative server */ 309 return("NS"); 310 case T_MD: /* mail destination */ 311 return("MD"); 312 case T_MF: /* mail forwarder */ 313 return("MF"); 314 case T_CNAME: /* connonical name */ 315 return("CNAME"); 316 case T_SOA: /* start of authority zone */ 317 return("SOA"); 318 case T_MB: /* mailbox domain name */ 319 return("MB"); 320 case T_MG: /* mail group member */ 321 return("MG"); 322 case T_MR: /* mail rename name */ 323 return("MR"); 324 case T_NULL: /* null resource record */ 325 return("NULL"); 326 case T_WKS: /* well known service */ 327 return("WKS"); 328 case T_PTR: /* domain name pointer */ 329 return("PTR"); 330 case T_HINFO: /* host information */ 331 return("HINFO"); 332 case T_MINFO: /* mailbox information */ 333 return("MINFO"); 334 case T_AXFR: /* zone transfer */ 335 return("AXFR"); 336 case T_MAILB: /* mail box */ 337 return("MAILB"); 338 case T_MAILA: /* mail address */ 339 return("MAILA"); 340 case T_ANY: /* matches any type */ 341 return("ANY"); 342 case T_UINFO: 343 return("UINFO"); 344 case T_UID: 345 return("UID"); 346 case T_GID: 347 return("GID"); 348 default: 349 return (sprintf(nbuf, "%d", type)); 350 } 351 } 352 353 /* 354 * Return a mnemonic for class 355 */ 356 char * 357 p_class(class) 358 int class; 359 { 360 361 switch (class) { 362 case C_IN: /* internet class */ 363 return("IN"); 364 case C_CS: /* csnet class */ 365 return("CS"); 366 case C_ANY: /* matches any class */ 367 return("ANY"); 368 default: 369 return (sprintf(nbuf, "%d", class)); 370 } 371 } 372