|
|
1.1 root 1: /*
2: * Copyright (c) 1985,1989 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:
20: #ifndef lint
21: static char sccsid[] = "@(#)debug.c 5.22 (Berkeley) 6/29/90";
22: #endif /* not lint */
23:
24: /*
25: *******************************************************************************
26: *
27: * debug.c --
28: *
29: * Routines to print out packets received from a name server query.
30: *
31: * Modified version of 4.3BSD BIND res_debug.c 5.30 6/27/90
32: *
33: *******************************************************************************
34: */
35:
36: #include <sys/types.h>
37: #include <netinet/in.h>
38: #include <stdio.h>
39: #include <arpa/nameser.h>
40: #include <arpa/inet.h>
41: #include <resolv.h>
42: #include <netdb.h>
43: #include "res.h"
44:
45: extern char ctime();
46:
47: /*
48: * Imported from res_debug.c
49: */
50: extern char *_res_resultcodes[];
51: extern char *_res_opcodes[];
52:
53: /*
54: * Used to highlight the start of a record when printing it.
55: */
56: #define INDENT " -> "
57:
58:
59:
60: /*
61: * Print the contents of a query.
62: * This is intended to be primarily a debugging routine.
63: */
64:
65: Print_query(msg, eom, printHeader)
66: char *msg, *eom;
67: int printHeader;
68: {
69: Fprint_query(msg, eom, printHeader,stdout);
70: }
71:
72: Fprint_query(msg, eom, printHeader,file)
73: char *msg, *eom;
74: int printHeader;
75: FILE *file;
76: {
77: register char *cp;
78: register HEADER *hp;
79: register int n;
80: short class;
81: short type;
82:
83: /*
84: * Print header fields.
85: */
86: hp = (HEADER *)msg;
87: cp = msg + sizeof(HEADER);
88: if (printHeader || (_res.options & RES_DEBUG2)) {
89: fprintf(file," HEADER:\n");
90: fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
91: fprintf(file,", id = %d", ntohs(hp->id));
92: fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
93: fprintf(file,"\theader flags: ");
94: if (hp->qr) {
95: fprintf(file," response");
96: } else {
97: fprintf(file," query");
98: }
99: if (hp->aa)
100: fprintf(file,", auth. answer");
101: if (hp->tc)
102: fprintf(file,", truncation");
103: if (hp->rd)
104: fprintf(file,", want recursion");
105: if (hp->ra)
106: fprintf(file,", recursion avail.");
107: if (hp->pr)
108: fprintf(file,", primary");
109: fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
110: fprintf(file,", answers = %d", ntohs(hp->ancount));
111: fprintf(file,", authority records = %d", ntohs(hp->nscount));
112: fprintf(file,", additional = %d\n\n", ntohs(hp->arcount));
113: }
114:
115: /*
116: * Print question records.
117: */
118: if (n = ntohs(hp->qdcount)) {
119: fprintf(file," QUESTIONS:\n");
120: while (--n >= 0) {
121: fprintf(file,"\t");
122: cp = Print_cdname(cp, msg, eom, file);
123: if (cp == NULL)
124: return;
125: type = _getshort(cp);
126: cp += sizeof(u_short);
127: class = _getshort(cp);
128: cp += sizeof(u_short);
129: fprintf(file,", type = %s", p_type(type));
130: fprintf(file,", class = %s\n", p_class(class));
131: }
132: }
133: /*
134: * Print authoritative answer records
135: */
136: if (n = ntohs(hp->ancount)) {
137: fprintf(file," ANSWERS:\n");
138: while (--n >= 0) {
139: fprintf(file, INDENT);
140: cp = Print_rr(cp, msg, eom, file);
141: if (cp == NULL)
142: return;
143: }
144: }
145: /*
146: * print name server records
147: */
148: if (n = ntohs(hp->nscount)) {
149: fprintf(file," AUTHORITY RECORDS:\n");
150: while (--n >= 0) {
151: fprintf(file, INDENT);
152: cp = Print_rr(cp, msg, eom, file);
153: if (cp == NULL)
154: return;
155: }
156: }
157: /*
158: * print additional records
159: */
160: if (n = ntohs(hp->arcount)) {
161: fprintf(file," ADDITIONAL RECORDS:\n");
162: while (--n >= 0) {
163: fprintf(file, INDENT);
164: cp = Print_rr(cp, msg, eom, file);
165: if (cp == NULL)
166: return;
167: }
168: }
169: fprintf(file,"\n------------\n");
170: }
171:
172:
173: char *
174: Print_cdname_sub(cp, msg, eom, file, format)
175: char *cp, *msg, *eom;
176: FILE *file;
177: int format;
178: {
179: int n;
180: char name[MAXDNAME];
181: extern char *strcpy();
182:
183: if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
184: return (NULL);
185: if (name[0] == '\0') {
186: (void) strcpy(name, "(root)");
187: }
188: if (format) {
189: fprintf(file, "%-30s", name);
190: } else {
191: fputs(name, file);
192: }
193: return (cp + n);
194: }
195:
196: char *
197: Print_cdname(cp, msg, eom, file)
198: char *cp, *msg, *eom;
199: FILE *file;
200: {
201: return(Print_cdname_sub(cp, msg, eom, file, 0));
202: }
203:
204: char *
205: Print_cdname2(cp, msg, eom, file)
206: char *cp, *msg, *eom;
207: FILE *file;
208: {
209: return(Print_cdname_sub(cp, msg, eom, file, 1));
210: }
211:
212: /*
213: * Print resource record fields in human readable form.
214: */
215: char *
216: Print_rr(cp, msg, eom, file)
217: char *cp, *msg, *eom;
218: FILE *file;
219: {
220: int type, class, dlen, n, c;
221: unsigned long rrttl, ttl;
222: struct in_addr inaddr;
223: char *cp1, *cp2;
224: int debug;
225:
226: if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) {
227: fprintf(file, "(name truncated?)\n");
228: return (NULL); /* compression error */
229: }
230:
231: type = _getshort(cp);
232: cp += sizeof(u_short);
233: class = _getshort(cp);
234: cp += sizeof(u_short);
235: rrttl = _getlong(cp);
236: cp += sizeof(u_long);
237: dlen = _getshort(cp);
238: cp += sizeof(u_short);
239:
240: debug = _res.options & (RES_DEBUG|RES_DEBUG2);
241: if (debug) {
242: if (_res.options & RES_DEBUG2) {
243: fprintf(file,"\n\ttype = %s, class = %s, dlen = %d",
244: p_type(type), p_class(class), dlen);
245: }
246: if (type == T_SOA) {
247: fprintf(file,"\n\tttl = %lu (%s)", rrttl, p_time(rrttl));
248: }
249: (void) putc('\n', file);
250: }
251:
252: cp1 = cp;
253:
254: /*
255: * Print type specific data, if appropriate
256: */
257: switch (type) {
258: case T_A:
259: switch (class) {
260: case C_IN:
261: case C_HS:
262: bcopy(cp, (char *)&inaddr, sizeof(inaddr));
263: if (dlen == 4) {
264: fprintf(file,"\tinternet address = %s\n",
265: inet_ntoa(inaddr));
266: cp += dlen;
267: } else if (dlen == 7) {
268: fprintf(file,"\tinternet address = %s",
269: inet_ntoa(inaddr));
270: fprintf(file,", protocol = %d", cp[4]);
271: fprintf(file,", port = %d\n",
272: (cp[5] << 8) + cp[6]);
273: cp += dlen;
274: }
275: break;
276: default:
277: fprintf(file,"\taddress, class = %d, len = %d\n",
278: class, dlen);
279: cp += dlen;
280: }
281: break;
282:
283: case T_CNAME:
284: fprintf(file,"\tcanonical name = ");
285: goto doname;
286:
287: case T_MG:
288: fprintf(file,"\tmail group member = ");
289: goto doname;
290: case T_MB:
291: fprintf(file,"\tmail box = ");
292: goto doname;
293: case T_MR:
294: fprintf(file,"\tmailbox rename = ");
295: goto doname;
296: case T_MX:
297: fprintf(file,"\tpreference = %u",_getshort(cp));
298: cp += sizeof(u_short);
299: fprintf(file,", mail exchanger = ");
300: goto doname;
301: case T_NS:
302: fprintf(file,"\tnameserver = ");
303: goto doname;
304: case T_PTR:
305: fprintf(file,"\tname = ");
306: doname:
307: cp = Print_cdname(cp, msg, eom, file);
308: (void) putc('\n', file);
309: break;
310:
311: case T_HINFO:
312: if (n = *cp++) {
313: fprintf(file,"\tCPU = %.*s", n, cp);
314: cp += n;
315: }
316: if (n = *cp++) {
317: fprintf(file,"\tOS = %.*s\n", n, cp);
318: cp += n;
319: }
320: break;
321:
322: case T_SOA:
323: if (!debug)
324: (void) putc('\n', file);
325: fprintf(file,"\torigin = ");
326: cp = Print_cdname(cp, msg, eom, file);
327: fprintf(file,"\n\tmail addr = ");
328: cp = Print_cdname(cp, msg, eom, file);
329: fprintf(file,"\n\tserial = %lu", _getlong(cp));
330: cp += sizeof(u_long);
331: ttl = _getlong(cp);
332: fprintf(file,"\n\trefresh = %lu (%s)", ttl, p_time(ttl));
333: cp += sizeof(u_long);
334: ttl = _getlong(cp);
335: fprintf(file,"\n\tretry = %lu (%s)", ttl, p_time(ttl));
336: cp += sizeof(u_long);
337: ttl = _getlong(cp);
338: fprintf(file,"\n\texpire = %lu (%s)", ttl, p_time(ttl));
339: cp += sizeof(u_long);
340: ttl = _getlong(cp);
341: fprintf(file,"\n\tminimum ttl = %lu (%s)\n", ttl, p_time(ttl));
342: cp += sizeof(u_long);
343: break;
344:
345: case T_MINFO:
346: if (!debug)
347: (void) putc('\n', file);
348: fprintf(file,"\trequests = ");
349: cp = Print_cdname(cp, msg, eom, file);
350: fprintf(file,"\n\terrors = ");
351: cp = Print_cdname(cp, msg, eom, file);
352: (void) putc('\n', file);
353: break;
354:
355: case T_TXT:
356: (void) fputs("\ttext = \"", file);
357: cp2 = cp1 + dlen;
358: while (cp < cp2) {
359: if (n = (unsigned char) *cp++) {
360: for (c = n; c > 0 && cp < cp2; c--)
361: if (*cp == '\n') {
362: (void) putc('\\', file);
363: (void) putc(*cp++, file);
364: } else
365: (void) putc(*cp++, file);
366: }
367: }
368: (void) fputs("\"\n", file);
369: break;
370:
371: case T_UINFO:
372: fprintf(file,"\tuser info = %s\n", cp);
373: cp += dlen;
374: break;
375:
376: case T_UID:
377: case T_GID:
378: if (dlen == 4) {
379: fprintf(file,"\t%cid = %lu\n",type == T_UID ? 'u' : 'g',
380: _getlong(cp));
381: cp += sizeof(int);
382: } else {
383: fprintf(file,"\t%cid of length %d?\n",
384: type == T_UID ? 'u' : 'g', dlen);
385: cp += dlen;
386: }
387: break;
388:
389: case T_WKS: {
390: struct protoent *protoPtr;
391:
392: if (dlen < sizeof(u_long) + 1)
393: break;
394: if (!debug)
395: (void) putc('\n', file);
396: bcopy(cp, (char *)&inaddr, sizeof(inaddr));
397: cp += sizeof(u_long);
398: if ((protoPtr = getprotobynumber(*cp)) != NULL) {
399: fprintf(file,"\tinet address = %s, protocol = %s\n\t",
400: inet_ntoa(inaddr), protoPtr->p_name);
401: } else {
402: fprintf(file,"\tinet address = %s, protocol = %d\n\t",
403: inet_ntoa(inaddr), *cp);
404: }
405: cp++;
406: n = 0;
407: while (cp < cp1 + dlen) {
408: c = *cp++;
409: do {
410: struct servent *s;
411:
412: if (c & 0200) {
413: s = getservbyport(n, NULL);
414: if (s != NULL) {
415: fprintf(file," %s", s->s_name);
416: } else {
417: fprintf(file," #%d", n);
418: }
419: }
420: c <<= 1;
421: } while (++n & 07);
422: }
423: putc('\n',file);
424: }
425: break;
426:
427: case T_NULL:
428: fprintf(file, "\tNULL (dlen %d)\n", dlen);
429: cp += dlen;
430: break;
431:
432: default:
433: fprintf(file,"\t??? unknown type %d ???\n", type);
434: cp += dlen;
435: }
436: if (_res.options & RES_DEBUG && type != T_SOA) {
437: fprintf(file,"\tttl = %lu (%s)\n", rrttl, p_time(rrttl));
438: }
439: if (cp != cp1 + dlen) {
440: fprintf(file,
441: "\n*** Error: record size incorrect (%d != %d)\n\n",
442: cp - cp1, dlen);
443: cp = NULL;
444: }
445: return (cp);
446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.