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