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