|
|
1.1 root 1: /*-
2: * Copyright (c) 1985, 1990 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: *
19: * @(#)res_debug.c 5.30 (Berkeley) 6/27/90
20: */
21:
22: #if defined(LIBC_SCCS) && !defined(lint)
23: static char sccsid[] = "@(#)res_debug.c 5.30 (Berkeley) 6/27/90";
24: #endif /* LIBC_SCCS and not lint */
25:
26: #include <sys/types.h>
27: #include <netinet/in.h>
28: #include <stdio.h>
29: #include <arpa/nameser.h>
30:
31: extern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time();
32: extern char *inet_ntoa();
33:
34: char *_res_opcodes[] = {
35: "QUERY",
36: "IQUERY",
37: "CQUERYM",
38: "CQUERYU",
39: "4",
40: "5",
41: "6",
42: "7",
43: "8",
44: "UPDATEA",
45: "UPDATED",
46: "UPDATEDA",
47: "UPDATEM",
48: "UPDATEMA",
49: "ZONEINIT",
50: "ZONEREF",
51: };
52:
53: char *_res_resultcodes[] = {
54: "NOERROR",
55: "FORMERR",
56: "SERVFAIL",
57: "NXDOMAIN",
58: "NOTIMP",
59: "REFUSED",
60: "6",
61: "7",
62: "8",
63: "9",
64: "10",
65: "11",
66: "12",
67: "13",
68: "14",
69: "NOCHANGE",
70: };
71:
72: p_query(msg)
73: char *msg;
74: {
75: fp_query(msg,stdout);
76: }
77:
78: /*
79: * Print the contents of a query.
80: * This is intended to be primarily a debugging routine.
81: */
82: fp_query(msg,file)
83: char *msg;
84: FILE *file;
85: {
86: register char *cp;
87: register HEADER *hp;
88: register int n;
89:
90: /*
91: * Print header fields.
92: */
93: hp = (HEADER *)msg;
94: cp = msg + sizeof(HEADER);
95: fprintf(file,"HEADER:\n");
96: fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
97: fprintf(file,", id = %d", ntohs(hp->id));
98: fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
99: fprintf(file,"\theader flags: ");
100: if (hp->qr)
101: fprintf(file," qr");
102: if (hp->aa)
103: fprintf(file," aa");
104: if (hp->tc)
105: fprintf(file," tc");
106: if (hp->rd)
107: fprintf(file," rd");
108: if (hp->ra)
109: fprintf(file," ra");
110: if (hp->pr)
111: fprintf(file," pr");
112: fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount));
113: fprintf(file,", ancount = %d", ntohs(hp->ancount));
114: fprintf(file,", nscount = %d", ntohs(hp->nscount));
115: fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount));
116: /*
117: * Print question records.
118: */
119: if (n = ntohs(hp->qdcount)) {
120: fprintf(file,"QUESTIONS:\n");
121: while (--n >= 0) {
122: fprintf(file,"\t");
123: cp = p_cdname(cp, msg, file);
124: if (cp == NULL)
125: return;
126: fprintf(file,", type = %s", p_type(_getshort(cp)));
127: cp += sizeof(u_short);
128: fprintf(file,", class = %s\n\n", p_class(_getshort(cp)));
129: cp += sizeof(u_short);
130: }
131: }
132: /*
133: * Print authoritative answer records
134: */
135: if (n = ntohs(hp->ancount)) {
136: fprintf(file,"ANSWERS:\n");
137: while (--n >= 0) {
138: fprintf(file,"\t");
139: cp = p_rr(cp, msg, file);
140: if (cp == NULL)
141: return;
142: }
143: }
144: /*
145: * print name server records
146: */
147: if (n = ntohs(hp->nscount)) {
148: fprintf(file,"NAME SERVERS:\n");
149: while (--n >= 0) {
150: fprintf(file,"\t");
151: cp = p_rr(cp, msg, file);
152: if (cp == NULL)
153: return;
154: }
155: }
156: /*
157: * print additional records
158: */
159: if (n = ntohs(hp->arcount)) {
160: fprintf(file,"ADDITIONAL RECORDS:\n");
161: while (--n >= 0) {
162: fprintf(file,"\t");
163: cp = p_rr(cp, msg, file);
164: if (cp == NULL)
165: return;
166: }
167: }
168: }
169:
170: char *
171: p_cdname(cp, msg, file)
172: char *cp, *msg;
173: FILE *file;
174: {
175: char name[MAXDNAME];
176: int n;
177:
178: if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0)
179: return (NULL);
180: if (name[0] == '\0') {
181: name[0] = '.';
182: name[1] = '\0';
183: }
184: fputs(name, file);
185: return (cp + n);
186: }
187:
188: /*
189: * Print resource record fields in human readable form.
190: */
191: char *
192: p_rr(cp, msg, file)
193: char *cp, *msg;
194: FILE *file;
195: {
196: int type, class, dlen, n, c;
197: struct in_addr inaddr;
198: char *cp1, *cp2;
199:
200: if ((cp = p_cdname(cp, msg, file)) == NULL)
201: return (NULL); /* compression error */
202: fprintf(file,"\n\ttype = %s", p_type(type = _getshort(cp)));
203: cp += sizeof(u_short);
204: fprintf(file,", class = %s", p_class(class = _getshort(cp)));
205: cp += sizeof(u_short);
206: fprintf(file,", ttl = %s", p_time(_getlong(cp)));
207: cp += sizeof(u_long);
208: fprintf(file,", dlen = %d\n", dlen = _getshort(cp));
209: cp += sizeof(u_short);
210: cp1 = cp;
211: /*
212: * Print type specific data, if appropriate
213: */
214: switch (type) {
215: case T_A:
216: switch (class) {
217: case C_IN:
218: case C_HS:
219: bcopy(cp, (char *)&inaddr, sizeof(inaddr));
220: if (dlen == 4) {
221: fprintf(file,"\tinternet address = %s\n",
222: inet_ntoa(inaddr));
223: cp += dlen;
224: } else if (dlen == 7) {
225: fprintf(file,"\tinternet address = %s",
226: inet_ntoa(inaddr));
227: fprintf(file,", protocol = %d", cp[4]);
228: fprintf(file,", port = %d\n",
229: (cp[5] << 8) + cp[6]);
230: cp += dlen;
231: }
232: break;
233: default:
234: cp += dlen;
235: }
236: break;
237: case T_CNAME:
238: case T_MB:
239: case T_MG:
240: case T_MR:
241: case T_NS:
242: case T_PTR:
243: fprintf(file,"\tdomain name = ");
244: cp = p_cdname(cp, msg, file);
245: fprintf(file,"\n");
246: break;
247:
248: case T_HINFO:
249: if (n = *cp++) {
250: fprintf(file,"\tCPU=%.*s\n", n, cp);
251: cp += n;
252: }
253: if (n = *cp++) {
254: fprintf(file,"\tOS=%.*s\n", n, cp);
255: cp += n;
256: }
257: break;
258:
259: case T_SOA:
260: fprintf(file,"\torigin = ");
261: cp = p_cdname(cp, msg, file);
262: fprintf(file,"\n\tmail addr = ");
263: cp = p_cdname(cp, msg, file);
264: fprintf(file,"\n\tserial = %ld", _getlong(cp));
265: cp += sizeof(u_long);
266: fprintf(file,"\n\trefresh = %s", p_time(_getlong(cp)));
267: cp += sizeof(u_long);
268: fprintf(file,"\n\tretry = %s", p_time(_getlong(cp)));
269: cp += sizeof(u_long);
270: fprintf(file,"\n\texpire = %s", p_time(_getlong(cp)));
271: cp += sizeof(u_long);
272: fprintf(file,"\n\tmin = %s\n", p_time(_getlong(cp)));
273: cp += sizeof(u_long);
274: break;
275:
276: case T_MX:
277: fprintf(file,"\tpreference = %ld,",_getshort(cp));
278: cp += sizeof(u_short);
279: fprintf(file," name = ");
280: cp = p_cdname(cp, msg, file);
281: break;
282:
283: case T_TXT:
284: (void) fputs("\t\"", file);
285: cp2 = cp1 + dlen;
286: while (cp < cp2) {
287: if (n = (unsigned char) *cp++) {
288: for (c = n; c > 0 && cp < cp2; c--)
289: if (*cp == '\n') {
290: (void) putc('\\', file);
291: (void) putc(*cp++, file);
292: } else
293: (void) putc(*cp++, file);
294: }
295: }
296: (void) fputs("\"\n", file);
297: break;
298:
299: case T_MINFO:
300: fprintf(file,"\trequests = ");
301: cp = p_cdname(cp, msg, file);
302: fprintf(file,"\n\terrors = ");
303: cp = p_cdname(cp, msg, file);
304: break;
305:
306: case T_UINFO:
307: fprintf(file,"\t%s\n", cp);
308: cp += dlen;
309: break;
310:
311: case T_UID:
312: case T_GID:
313: if (dlen == 4) {
314: fprintf(file,"\t%ld\n", _getlong(cp));
315: cp += sizeof(int);
316: }
317: break;
318:
319: case T_WKS:
320: if (dlen < sizeof(u_long) + 1)
321: break;
322: bcopy(cp, (char *)&inaddr, sizeof(inaddr));
323: cp += sizeof(u_long);
324: fprintf(file,"\tinternet address = %s, protocol = %d\n\t",
325: inet_ntoa(inaddr), *cp++);
326: n = 0;
327: while (cp < cp1 + dlen) {
328: c = *cp++;
329: do {
330: if (c & 0200)
331: fprintf(file," %d", n);
332: c <<= 1;
333: } while (++n & 07);
334: }
335: putc('\n',file);
336: break;
337:
338: #ifdef ALLOW_T_UNSPEC
339: case T_UNSPEC:
340: {
341: int NumBytes = 8;
342: char *DataPtr;
343: int i;
344:
345: if (dlen < NumBytes) NumBytes = dlen;
346: fprintf(file, "\tFirst %d bytes of hex data:",
347: NumBytes);
348: for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
349: fprintf(file, " %x", *DataPtr);
350: fputs("\n", file);
351: cp += dlen;
352: }
353: break;
354: #endif /* ALLOW_T_UNSPEC */
355:
356: default:
357: fprintf(file,"\t???\n");
358: cp += dlen;
359: }
360: if (cp != cp1 + dlen) {
361: fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
362: cp = NULL;
363: }
364: fprintf(file,"\n");
365: return (cp);
366: }
367:
368: static char nbuf[40];
369:
370: /*
371: * Return a string for the type
372: */
373: char *
374: p_type(type)
375: int type;
376: {
377: switch (type) {
378: case T_A:
379: return("A");
380: case T_NS: /* authoritative server */
381: return("NS");
382: case T_CNAME: /* canonical name */
383: return("CNAME");
384: case T_SOA: /* start of authority zone */
385: return("SOA");
386: case T_MB: /* mailbox domain name */
387: return("MB");
388: case T_MG: /* mail group member */
389: return("MG");
390: case T_MR: /* mail rename name */
391: return("MR");
392: case T_NULL: /* null resource record */
393: return("NULL");
394: case T_WKS: /* well known service */
395: return("WKS");
396: case T_PTR: /* domain name pointer */
397: return("PTR");
398: case T_HINFO: /* host information */
399: return("HINFO");
400: case T_MINFO: /* mailbox information */
401: return("MINFO");
402: case T_MX: /* mail routing info */
403: return("MX");
404: case T_TXT: /* text */
405: return("TXT");
406: case T_AXFR: /* zone transfer */
407: return("AXFR");
408: case T_MAILB: /* mail box */
409: return("MAILB");
410: case T_MAILA: /* mail address */
411: return("MAILA");
412: case T_ANY: /* matches any type */
413: return("ANY");
414: case T_UINFO:
415: return("UINFO");
416: case T_UID:
417: return("UID");
418: case T_GID:
419: return("GID");
420: #ifdef ALLOW_T_UNSPEC
421: case T_UNSPEC:
422: return("UNSPEC");
423: #endif /* ALLOW_T_UNSPEC */
424: default:
425: (void)sprintf(nbuf, "%d", type);
426: return(nbuf);
427: }
428: }
429:
430: /*
431: * Return a mnemonic for class
432: */
433: char *
434: p_class(class)
435: int class;
436: {
437:
438: switch (class) {
439: case C_IN: /* internet class */
440: return("IN");
441: case C_HS: /* hesiod class */
442: return("HS");
443: case C_ANY: /* matches any class */
444: return("ANY");
445: default:
446: (void)sprintf(nbuf, "%d", class);
447: return(nbuf);
448: }
449: }
450:
451: /*
452: * Return a mnemonic for a time to live
453: */
454: char *
455: p_time(value)
456: u_long value;
457: {
458: int secs, mins, hours;
459: register char *p;
460:
461: if (value == 0) {
462: strcpy(nbuf, "0 secs");
463: return(nbuf);
464: }
465:
466: secs = value % 60;
467: value /= 60;
468: mins = value % 60;
469: value /= 60;
470: hours = value % 24;
471: value /= 24;
472:
473: #define PLURALIZE(x) x, (x == 1) ? "" : "s"
474: p = nbuf;
475: if (value) {
476: (void)sprintf(p, "%d day%s", PLURALIZE(value));
477: while (*++p);
478: }
479: if (hours) {
480: if (value)
481: *p++ = ' ';
482: (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
483: while (*++p);
484: }
485: if (mins) {
486: if (value || hours)
487: *p++ = ' ';
488: (void)sprintf(p, "%d min%s", PLURALIZE(mins));
489: while (*++p);
490: }
491: if (secs || ! (value || hours || mins)) {
492: if (value || hours || mins)
493: *p++ = ' ';
494: (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
495: }
496: return(nbuf);
497: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.