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.15 (Berkeley) 11/10/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 "UPDATEA", 34 "UPDATED", 35 "UPDATEM", 36 "ZONEINIT", 37 "ZONEREF", 38 }; 39 40 char *rcodes[] = { 41 "NOERROR", 42 "FORMERR", 43 "SERVFAIL", 44 "NXDOMAIN", 45 "NOTIMP", 46 "REFUSED", 47 "6", 48 "7", 49 "8", 50 "9", 51 "10", 52 "11", 53 "12", 54 "13", 55 "14", 56 "NOCHANGE", 57 }; 58 59 p_query(msg) 60 char *msg; 61 { 62 #ifdef DEBUG 63 fp_query(msg,stdout); 64 #endif 65 } 66 67 /* 68 * Print the contents of a query. 69 * This is intended to be primarily a debugging routine. 70 */ 71 fp_query(msg,file) 72 char *msg; 73 FILE *file; 74 { 75 #ifdef DEBUG 76 register char *cp; 77 register HEADER *hp; 78 register int n; 79 80 /* 81 * Print header fields. 82 */ 83 hp = (HEADER *)msg; 84 cp = msg + sizeof(HEADER); 85 fprintf(file,"HEADER:\n"); 86 fprintf(file,"\topcode = %s", opcodes[hp->opcode]); 87 fprintf(file,", id = %d", ntohs(hp->id)); 88 fprintf(file,", rcode = %s\n", rcodes[hp->rcode]); 89 fprintf(file,"\theader flags: "); 90 if (hp->qr) 91 fprintf(file," qr"); 92 if (hp->aa) 93 fprintf(file," aa"); 94 if (hp->tc) 95 fprintf(file," tc"); 96 if (hp->rd) 97 fprintf(file," rd"); 98 if (hp->ra) 99 fprintf(file," ra"); 100 if (hp->pr) 101 fprintf(file," pr"); 102 fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount)); 103 fprintf(file,", ancount = %d", ntohs(hp->ancount)); 104 fprintf(file,", nscount = %d", ntohs(hp->nscount)); 105 fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount)); 106 /* 107 * Print question records. 108 */ 109 if (n = ntohs(hp->qdcount)) { 110 fprintf(file,"QUESTIONS:\n"); 111 while (--n >= 0) { 112 fprintf(file,"\t"); 113 cp = p_cdname(cp, msg, file); 114 if (cp == NULL) 115 return; 116 fprintf(file,", type = %s", p_type(getshort(cp))); 117 cp += sizeof(u_short); 118 fprintf(file,", class = %s\n\n", p_class(getshort(cp))); 119 cp += sizeof(u_short); 120 } 121 } 122 /* 123 * Print authoritative answer records 124 */ 125 if (n = ntohs(hp->ancount)) { 126 fprintf(file,"ANSWERS:\n"); 127 while (--n >= 0) { 128 fprintf(file,"\t"); 129 cp = p_rr(cp, msg, file); 130 if (cp == NULL) 131 return; 132 } 133 } 134 /* 135 * print name server records 136 */ 137 if (n = ntohs(hp->nscount)) { 138 fprintf(file,"NAME SERVERS:\n"); 139 while (--n >= 0) { 140 fprintf(file,"\t"); 141 cp = p_rr(cp, msg, file); 142 if (cp == NULL) 143 return; 144 } 145 } 146 /* 147 * print additional records 148 */ 149 if (n = ntohs(hp->arcount)) { 150 fprintf(file,"ADDITIONAL RECORDS:\n"); 151 while (--n >= 0) { 152 fprintf(file,"\t"); 153 cp = p_rr(cp, msg, file); 154 if (cp == NULL) 155 return; 156 } 157 } 158 #endif 159 } 160 161 char * 162 p_cdname(cp, msg, file) 163 char *cp, *msg; 164 FILE *file; 165 { 166 #ifdef DEBUG 167 char name[MAXDNAME]; 168 int n; 169 170 if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0) 171 return (NULL); 172 if (name[0] == '\0') { 173 name[0] = '.'; 174 name[1] = '\0'; 175 } 176 fputs(name, file); 177 return (cp + n); 178 #endif 179 } 180 181 /* 182 * Print resource record fields in human readable form. 183 */ 184 char * 185 p_rr(cp, msg, file) 186 char *cp, *msg; 187 FILE *file; 188 { 189 #ifdef DEBUG 190 int type, class, dlen, n, c; 191 struct in_addr inaddr; 192 char *cp1; 193 194 if ((cp = p_cdname(cp, msg, file)) == NULL) 195 return (NULL); /* compression error */ 196 fprintf(file,"\n\ttype = %s", p_type(type = getshort(cp))); 197 cp += sizeof(u_short); 198 fprintf(file,", class = %s", p_class(class = getshort(cp))); 199 cp += sizeof(u_short); 200 fprintf(file,", ttl = %u", getlong(cp)); 201 cp += sizeof(u_long); 202 fprintf(file,", dlen = %d\n", dlen = getshort(cp)); 203 cp += sizeof(u_short); 204 cp1 = cp; 205 /* 206 * Print type specific data, if appropriate 207 */ 208 switch (type) { 209 case T_A: 210 switch (class) { 211 case C_IN: 212 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 213 if (dlen == 4) { 214 fprintf(file,"\tinternet address = %s\n", 215 inet_ntoa(inaddr)); 216 cp += dlen; 217 } else if (dlen == 7) { 218 fprintf(file,"\tinternet address = %s", 219 inet_ntoa(inaddr)); 220 fprintf(file,", protocol = %d", cp[4]); 221 fprintf(file,", port = %d\n", 222 (cp[5] << 8) + cp[6]); 223 cp += dlen; 224 } 225 break; 226 default: 227 cp += dlen; 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 #ifdef ALLOW_T_UNSPEC 320 case T_UNSPEC: 321 { 322 int NumBytes = 8; 323 char *DataPtr; 324 int i; 325 326 if (dlen < NumBytes) NumBytes = dlen; 327 fprintf(file, "\tFirst %d bytes of hex data:", 328 NumBytes); 329 for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) 330 fprintf(file, " %x", *DataPtr); 331 fputs("\n", file); 332 cp += dlen; 333 } 334 break; 335 #endif ALLOW_T_UNSPEC 336 337 default: 338 fprintf(file,"\t???\n"); 339 cp += dlen; 340 } 341 if (cp != cp1 + dlen) 342 fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen); 343 fprintf(file,"\n"); 344 return (cp); 345 #endif 346 } 347 348 static char nbuf[20]; 349 extern char *sprintf(); 350 351 /* 352 * Return a string for the type 353 */ 354 char * 355 p_type(type) 356 int type; 357 { 358 switch (type) { 359 case T_A: 360 return("A"); 361 case T_NS: /* authoritative server */ 362 return("NS"); 363 #ifdef OLDRR 364 case T_MD: /* mail destination */ 365 return("MD"); 366 case T_MF: /* mail forwarder */ 367 return("MF"); 368 #endif /* OLDRR */ 369 case T_CNAME: /* connonical name */ 370 return("CNAME"); 371 case T_SOA: /* start of authority zone */ 372 return("SOA"); 373 case T_MB: /* mailbox domain name */ 374 return("MB"); 375 case T_MG: /* mail group member */ 376 return("MG"); 377 case T_MX: /* mail routing info */ 378 return("MX"); 379 case T_MR: /* mail rename name */ 380 return("MR"); 381 case T_NULL: /* null resource record */ 382 return("NULL"); 383 case T_WKS: /* well known service */ 384 return("WKS"); 385 case T_PTR: /* domain name pointer */ 386 return("PTR"); 387 case T_HINFO: /* host information */ 388 return("HINFO"); 389 case T_MINFO: /* mailbox information */ 390 return("MINFO"); 391 case T_AXFR: /* zone transfer */ 392 return("AXFR"); 393 case T_MAILB: /* mail box */ 394 return("MAILB"); 395 case T_MAILA: /* mail address */ 396 return("MAILA"); 397 case T_ANY: /* matches any type */ 398 return("ANY"); 399 case T_UINFO: 400 return("UINFO"); 401 case T_UID: 402 return("UID"); 403 case T_GID: 404 return("GID"); 405 #ifdef ALLOW_T_UNSPEC 406 case T_UNSPEC: 407 return("UNSPEC"); 408 #endif ALLOW_T_UNSPEC 409 default: 410 return (sprintf(nbuf, "%d", type)); 411 } 412 } 413 414 /* 415 * Return a mnemonic for class 416 */ 417 char * 418 p_class(class) 419 int class; 420 { 421 422 switch (class) { 423 case C_IN: /* internet class */ 424 return("IN"); 425 case C_ANY: /* matches any class */ 426 return("ANY"); 427 default: 428 return (sprintf(nbuf, "%d", class)); 429 } 430 } 431