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