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) 03/09/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 } 409