Commit | Line | Data |
---|---|---|
b423e985 | 1 | /* |
8ea4199d | 2 | * Copyright (c) 1985 Regents of the University of California. |
6b2f9dd0 KB |
3 | * All rights reserved. |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
6 | * provided that this notice is preserved and that due credit is given | |
7 | * to the University of California at Berkeley. The name of the University | |
8 | * may not be used to endorse or promote products derived from this | |
9 | * software without specific prior written permission. This software | |
10 | * is provided ``as is'' without express or implied warranty. | |
b423e985 RC |
11 | */ |
12 | ||
2ce81398 | 13 | #if defined(LIBC_SCCS) && !defined(lint) |
6b2f9dd0 KB |
14 | static char sccsid[] = "@(#)res_debug.c 5.22 (Berkeley) %G%"; |
15 | #endif /* LIBC_SCCS and not lint */ | |
8ea4199d | 16 | |
d1c1ab68 JB |
17 | #if defined(lint) && !defined(DEBUG) |
18 | #define DEBUG | |
19 | #endif | |
20 | ||
0d22afd1 RC |
21 | #include <sys/types.h> |
22 | #include <netinet/in.h> | |
23 | #include <stdio.h> | |
02a51825 | 24 | #include <arpa/nameser.h> |
0d22afd1 RC |
25 | |
26 | extern char *p_cdname(), *p_rr(), *p_type(), *p_class(); | |
27 | extern char *inet_ntoa(); | |
28 | ||
cd43bd6a | 29 | char *_res_opcodes[] = { |
0d22afd1 RC |
30 | "QUERY", |
31 | "IQUERY", | |
32 | "CQUERYM", | |
33 | "CQUERYU", | |
34 | "4", | |
35 | "5", | |
36 | "6", | |
37 | "7", | |
38 | "8", | |
0d22afd1 RC |
39 | "UPDATEA", |
40 | "UPDATED", | |
3e8361d9 | 41 | "UPDATEDA", |
0d22afd1 | 42 | "UPDATEM", |
3e8361d9 | 43 | "UPDATEMA", |
0d22afd1 RC |
44 | "ZONEINIT", |
45 | "ZONEREF", | |
46 | }; | |
47 | ||
cd43bd6a | 48 | char *_res_resultcodes[] = { |
0d22afd1 RC |
49 | "NOERROR", |
50 | "FORMERR", | |
51 | "SERVFAIL", | |
52 | "NXDOMAIN", | |
53 | "NOTIMP", | |
54 | "REFUSED", | |
55 | "6", | |
56 | "7", | |
57 | "8", | |
58 | "9", | |
59 | "10", | |
60 | "11", | |
61 | "12", | |
62 | "13", | |
63 | "14", | |
64 | "NOCHANGE", | |
65 | }; | |
66 | ||
a73d974c KD |
67 | p_query(msg) |
68 | char *msg; | |
69 | { | |
d1c1ab68 | 70 | #ifdef DEBUG |
a73d974c | 71 | fp_query(msg,stdout); |
d1c1ab68 | 72 | #endif |
a73d974c KD |
73 | } |
74 | ||
0d22afd1 RC |
75 | /* |
76 | * Print the contents of a query. | |
77 | * This is intended to be primarily a debugging routine. | |
78 | */ | |
a73d974c | 79 | fp_query(msg,file) |
e515a559 | 80 | char *msg; |
a73d974c | 81 | FILE *file; |
0d22afd1 | 82 | { |
d1c1ab68 | 83 | #ifdef DEBUG |
0d22afd1 RC |
84 | register char *cp; |
85 | register HEADER *hp; | |
86 | register int n; | |
87 | ||
88 | /* | |
89 | * Print header fields. | |
90 | */ | |
e515a559 RC |
91 | hp = (HEADER *)msg; |
92 | cp = msg + sizeof(HEADER); | |
a73d974c | 93 | fprintf(file,"HEADER:\n"); |
d7070d01 | 94 | fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]); |
a73d974c | 95 | fprintf(file,", id = %d", ntohs(hp->id)); |
d7070d01 | 96 | fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]); |
a73d974c | 97 | fprintf(file,"\theader flags: "); |
0d22afd1 | 98 | if (hp->qr) |
a73d974c | 99 | fprintf(file," qr"); |
0d22afd1 | 100 | if (hp->aa) |
a73d974c | 101 | fprintf(file," aa"); |
0d22afd1 | 102 | if (hp->tc) |
a73d974c | 103 | fprintf(file," tc"); |
0d22afd1 | 104 | if (hp->rd) |
a73d974c | 105 | fprintf(file," rd"); |
0d22afd1 | 106 | if (hp->ra) |
a73d974c | 107 | fprintf(file," ra"); |
0d22afd1 | 108 | if (hp->pr) |
a73d974c KD |
109 | fprintf(file," pr"); |
110 | fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount)); | |
111 | fprintf(file,", ancount = %d", ntohs(hp->ancount)); | |
112 | fprintf(file,", nscount = %d", ntohs(hp->nscount)); | |
113 | fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount)); | |
0d22afd1 RC |
114 | /* |
115 | * Print question records. | |
116 | */ | |
117 | if (n = ntohs(hp->qdcount)) { | |
a73d974c | 118 | fprintf(file,"QUESTIONS:\n"); |
0d22afd1 | 119 | while (--n >= 0) { |
a73d974c KD |
120 | fprintf(file,"\t"); |
121 | cp = p_cdname(cp, msg, file); | |
0d22afd1 RC |
122 | if (cp == NULL) |
123 | return; | |
20087cad | 124 | fprintf(file,", type = %s", p_type(_getshort(cp))); |
0d22afd1 | 125 | cp += sizeof(u_short); |
20087cad | 126 | fprintf(file,", class = %s\n\n", p_class(_getshort(cp))); |
0d22afd1 RC |
127 | cp += sizeof(u_short); |
128 | } | |
129 | } | |
130 | /* | |
131 | * Print authoritative answer records | |
132 | */ | |
133 | if (n = ntohs(hp->ancount)) { | |
a73d974c | 134 | fprintf(file,"ANSWERS:\n"); |
0d22afd1 | 135 | while (--n >= 0) { |
a73d974c KD |
136 | fprintf(file,"\t"); |
137 | cp = p_rr(cp, msg, file); | |
0d22afd1 RC |
138 | if (cp == NULL) |
139 | return; | |
140 | } | |
141 | } | |
142 | /* | |
143 | * print name server records | |
144 | */ | |
145 | if (n = ntohs(hp->nscount)) { | |
a73d974c | 146 | fprintf(file,"NAME SERVERS:\n"); |
0d22afd1 | 147 | while (--n >= 0) { |
a73d974c KD |
148 | fprintf(file,"\t"); |
149 | cp = p_rr(cp, msg, file); | |
0d22afd1 RC |
150 | if (cp == NULL) |
151 | return; | |
152 | } | |
153 | } | |
154 | /* | |
155 | * print additional records | |
156 | */ | |
157 | if (n = ntohs(hp->arcount)) { | |
a73d974c | 158 | fprintf(file,"ADDITIONAL RECORDS:\n"); |
0d22afd1 | 159 | while (--n >= 0) { |
a73d974c KD |
160 | fprintf(file,"\t"); |
161 | cp = p_rr(cp, msg, file); | |
0d22afd1 RC |
162 | if (cp == NULL) |
163 | return; | |
164 | } | |
165 | } | |
d1c1ab68 | 166 | #endif |
0d22afd1 RC |
167 | } |
168 | ||
169 | char * | |
a73d974c | 170 | p_cdname(cp, msg, file) |
e515a559 | 171 | char *cp, *msg; |
a73d974c | 172 | FILE *file; |
0d22afd1 | 173 | { |
d1c1ab68 | 174 | #ifdef DEBUG |
0d22afd1 RC |
175 | char name[MAXDNAME]; |
176 | int n; | |
177 | ||
127b68cb | 178 | if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0) |
0d22afd1 RC |
179 | return (NULL); |
180 | if (name[0] == '\0') { | |
181 | name[0] = '.'; | |
182 | name[1] = '\0'; | |
183 | } | |
a73d974c | 184 | fputs(name, file); |
0d22afd1 | 185 | return (cp + n); |
d1c1ab68 | 186 | #endif |
0d22afd1 RC |
187 | } |
188 | ||
189 | /* | |
190 | * Print resource record fields in human readable form. | |
191 | */ | |
192 | char * | |
a73d974c | 193 | p_rr(cp, msg, file) |
e515a559 | 194 | char *cp, *msg; |
a73d974c | 195 | FILE *file; |
0d22afd1 | 196 | { |
d1c1ab68 | 197 | #ifdef DEBUG |
0d22afd1 RC |
198 | int type, class, dlen, n, c; |
199 | struct in_addr inaddr; | |
200 | char *cp1; | |
201 | ||
a73d974c | 202 | if ((cp = p_cdname(cp, msg, file)) == NULL) |
0d22afd1 | 203 | return (NULL); /* compression error */ |
20087cad | 204 | fprintf(file,"\n\ttype = %s", p_type(type = _getshort(cp))); |
0d22afd1 | 205 | cp += sizeof(u_short); |
20087cad | 206 | fprintf(file,", class = %s", p_class(class = _getshort(cp))); |
0d22afd1 | 207 | cp += sizeof(u_short); |
20087cad | 208 | fprintf(file,", ttl = %u", _getlong(cp)); |
0d22afd1 | 209 | cp += sizeof(u_long); |
20087cad | 210 | fprintf(file,", dlen = %d\n", dlen = _getshort(cp)); |
0d22afd1 RC |
211 | cp += sizeof(u_short); |
212 | cp1 = cp; | |
213 | /* | |
214 | * Print type specific data, if appropriate | |
215 | */ | |
216 | switch (type) { | |
217 | case T_A: | |
218 | switch (class) { | |
219 | case C_IN: | |
11e57e73 | 220 | bcopy(cp, (char *)&inaddr, sizeof(inaddr)); |
0d22afd1 | 221 | if (dlen == 4) { |
a73d974c | 222 | fprintf(file,"\tinternet address = %s\n", |
0d22afd1 RC |
223 | inet_ntoa(inaddr)); |
224 | cp += dlen; | |
225 | } else if (dlen == 7) { | |
a73d974c | 226 | fprintf(file,"\tinternet address = %s", |
0d22afd1 | 227 | inet_ntoa(inaddr)); |
a73d974c KD |
228 | fprintf(file,", protocol = %d", cp[4]); |
229 | fprintf(file,", port = %d\n", | |
0d22afd1 RC |
230 | (cp[5] << 8) + cp[6]); |
231 | cp += dlen; | |
232 | } | |
233 | break; | |
e0dd8906 KD |
234 | default: |
235 | cp += dlen; | |
0d22afd1 RC |
236 | } |
237 | break; | |
238 | case T_CNAME: | |
239 | case T_MB: | |
018df4a9 | 240 | #ifdef OLDRR |
0d22afd1 RC |
241 | case T_MD: |
242 | case T_MF: | |
018df4a9 | 243 | #endif /* OLDRR */ |
0d22afd1 RC |
244 | case T_MG: |
245 | case T_MR: | |
246 | case T_NS: | |
247 | case T_PTR: | |
a73d974c KD |
248 | fprintf(file,"\tdomain name = "); |
249 | cp = p_cdname(cp, msg, file); | |
250 | fprintf(file,"\n"); | |
0d22afd1 RC |
251 | break; |
252 | ||
253 | case T_HINFO: | |
254 | if (n = *cp++) { | |
a73d974c | 255 | fprintf(file,"\tCPU=%.*s\n", n, cp); |
0d22afd1 RC |
256 | cp += n; |
257 | } | |
258 | if (n = *cp++) { | |
a73d974c | 259 | fprintf(file,"\tOS=%.*s\n", n, cp); |
0d22afd1 RC |
260 | cp += n; |
261 | } | |
262 | break; | |
263 | ||
264 | case T_SOA: | |
a73d974c KD |
265 | fprintf(file,"\torigin = "); |
266 | cp = p_cdname(cp, msg, file); | |
267 | fprintf(file,"\n\tmail addr = "); | |
268 | cp = p_cdname(cp, msg, file); | |
20087cad | 269 | fprintf(file,"\n\tserial=%ld", _getlong(cp)); |
0d22afd1 | 270 | cp += sizeof(u_long); |
20087cad | 271 | fprintf(file,", refresh=%ld", _getlong(cp)); |
0d22afd1 | 272 | cp += sizeof(u_long); |
20087cad | 273 | fprintf(file,", retry=%ld", _getlong(cp)); |
0d22afd1 | 274 | cp += sizeof(u_long); |
20087cad | 275 | fprintf(file,", expire=%ld", _getlong(cp)); |
0d22afd1 | 276 | cp += sizeof(u_long); |
20087cad | 277 | fprintf(file,", min=%ld\n", _getlong(cp)); |
0d22afd1 RC |
278 | cp += sizeof(u_long); |
279 | break; | |
280 | ||
73546a32 | 281 | case T_MX: |
20087cad | 282 | fprintf(file,"\tpreference = %ld,",_getshort(cp)); |
018df4a9 KD |
283 | cp += sizeof(u_short); |
284 | fprintf(file," name = "); | |
73546a32 | 285 | cp = p_cdname(cp, msg, file); |
73546a32 KD |
286 | break; |
287 | ||
e515a559 | 288 | case T_MINFO: |
a73d974c KD |
289 | fprintf(file,"\trequests = "); |
290 | cp = p_cdname(cp, msg, file); | |
291 | fprintf(file,"\n\terrors = "); | |
292 | cp = p_cdname(cp, msg, file); | |
e515a559 RC |
293 | break; |
294 | ||
0d22afd1 | 295 | case T_UINFO: |
a73d974c | 296 | fprintf(file,"\t%s\n", cp); |
0d22afd1 RC |
297 | cp += dlen; |
298 | break; | |
299 | ||
300 | case T_UID: | |
301 | case T_GID: | |
302 | if (dlen == 4) { | |
20087cad | 303 | fprintf(file,"\t%ld\n", _getlong(cp)); |
0d22afd1 RC |
304 | cp += sizeof(int); |
305 | } | |
306 | break; | |
307 | ||
308 | case T_WKS: | |
309 | if (dlen < sizeof(u_long) + 1) | |
310 | break; | |
11e57e73 | 311 | bcopy(cp, (char *)&inaddr, sizeof(inaddr)); |
0d22afd1 | 312 | cp += sizeof(u_long); |
a73d974c | 313 | fprintf(file,"\tinternet address = %s, protocol = %d\n\t", |
0d22afd1 RC |
314 | inet_ntoa(inaddr), *cp++); |
315 | n = 0; | |
316 | while (cp < cp1 + dlen) { | |
317 | c = *cp++; | |
318 | do { | |
a943feed | 319 | if (c & 0200) |
a73d974c | 320 | fprintf(file," %d", n); |
a943feed | 321 | c <<= 1; |
0d22afd1 RC |
322 | } while (++n & 07); |
323 | } | |
a73d974c | 324 | putc('\n',file); |
0d22afd1 RC |
325 | break; |
326 | ||
3bf25746 | 327 | #ifdef ALLOW_T_UNSPEC |
1e12917d KB |
328 | case T_UNSPEC: |
329 | { | |
330 | int NumBytes = 8; | |
331 | char *DataPtr; | |
332 | int i; | |
3bf25746 | 333 | |
1e12917d KB |
334 | if (dlen < NumBytes) NumBytes = dlen; |
335 | fprintf(file, "\tFirst %d bytes of hex data:", | |
336 | NumBytes); | |
337 | for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) | |
338 | fprintf(file, " %x", *DataPtr); | |
339 | fputs("\n", file); | |
340 | cp += dlen; | |
341 | } | |
342 | break; | |
343 | #endif /* ALLOW_T_UNSPEC */ | |
3bf25746 | 344 | |
0d22afd1 | 345 | default: |
a73d974c | 346 | fprintf(file,"\t???\n"); |
0d22afd1 RC |
347 | cp += dlen; |
348 | } | |
349 | if (cp != cp1 + dlen) | |
a73d974c KD |
350 | fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen); |
351 | fprintf(file,"\n"); | |
0d22afd1 | 352 | return (cp); |
d1c1ab68 | 353 | #endif |
0d22afd1 RC |
354 | } |
355 | ||
356 | static char nbuf[20]; | |
0d22afd1 RC |
357 | |
358 | /* | |
359 | * Return a string for the type | |
360 | */ | |
361 | char * | |
362 | p_type(type) | |
363 | int type; | |
364 | { | |
0d22afd1 RC |
365 | switch (type) { |
366 | case T_A: | |
367 | return("A"); | |
368 | case T_NS: /* authoritative server */ | |
369 | return("NS"); | |
018df4a9 | 370 | #ifdef OLDRR |
0d22afd1 RC |
371 | case T_MD: /* mail destination */ |
372 | return("MD"); | |
373 | case T_MF: /* mail forwarder */ | |
374 | return("MF"); | |
018df4a9 | 375 | #endif /* OLDRR */ |
0d22afd1 RC |
376 | case T_CNAME: /* connonical name */ |
377 | return("CNAME"); | |
378 | case T_SOA: /* start of authority zone */ | |
379 | return("SOA"); | |
380 | case T_MB: /* mailbox domain name */ | |
381 | return("MB"); | |
382 | case T_MG: /* mail group member */ | |
383 | return("MG"); | |
73546a32 KD |
384 | case T_MX: /* mail routing info */ |
385 | return("MX"); | |
0d22afd1 RC |
386 | case T_MR: /* mail rename name */ |
387 | return("MR"); | |
388 | case T_NULL: /* null resource record */ | |
389 | return("NULL"); | |
390 | case T_WKS: /* well known service */ | |
391 | return("WKS"); | |
392 | case T_PTR: /* domain name pointer */ | |
393 | return("PTR"); | |
394 | case T_HINFO: /* host information */ | |
395 | return("HINFO"); | |
396 | case T_MINFO: /* mailbox information */ | |
397 | return("MINFO"); | |
398 | case T_AXFR: /* zone transfer */ | |
399 | return("AXFR"); | |
400 | case T_MAILB: /* mail box */ | |
401 | return("MAILB"); | |
402 | case T_MAILA: /* mail address */ | |
403 | return("MAILA"); | |
404 | case T_ANY: /* matches any type */ | |
405 | return("ANY"); | |
406 | case T_UINFO: | |
407 | return("UINFO"); | |
408 | case T_UID: | |
409 | return("UID"); | |
410 | case T_GID: | |
411 | return("GID"); | |
3bf25746 | 412 | #ifdef ALLOW_T_UNSPEC |
1e12917d KB |
413 | case T_UNSPEC: |
414 | return("UNSPEC"); | |
415 | #endif /* ALLOW_T_UNSPEC */ | |
0d22afd1 | 416 | default: |
06eef7c4 KB |
417 | (void)sprintf(nbuf, "%d", type); |
418 | return(nbuf); | |
0d22afd1 RC |
419 | } |
420 | } | |
421 | ||
422 | /* | |
423 | * Return a mnemonic for class | |
424 | */ | |
425 | char * | |
426 | p_class(class) | |
427 | int class; | |
428 | { | |
429 | ||
430 | switch (class) { | |
431 | case C_IN: /* internet class */ | |
432 | return("IN"); | |
0d22afd1 RC |
433 | case C_ANY: /* matches any class */ |
434 | return("ANY"); | |
435 | default: | |
06eef7c4 KB |
436 | (void)sprintf(nbuf, "%d", class); |
437 | return(nbuf); | |
0d22afd1 RC |
438 | } |
439 | } |