|
|
1.1 root 1: /*
2: *******************************************************************************
3: *
4: * debug.c --
5: *
6: * Routines to print out packets received from a name server query.
7: *
8: * Modified version of 4.3BSD BIND res_debug.c 5.6 9/14/85
9: *
10: * Copyright (c) 1985 Regents of the University of California.
11: * All rights reserved. The Berkeley software License Agreement
12: * specifies the terms and conditions for redistribution.
13: *
14: *******************************************************************************
15: */
16:
17: #ifndef lint
18: static char sccsid[] = "@(#)debug.c 5.3 (Berkeley) 3/31/86";
19: #endif not lint
20:
21: #include <sys/types.h>
22: #include <netinet/in.h>
23: #include <stdio.h>
24: #include <arpa/nameser.h>
25: #include <resolv.h>
26: #include "res.h"
27:
28: extern char ctime();
29:
30: /*
31: * Imported from res_debug.c
32: */
33: extern char *rcodes[];
34: extern char *opcodes[];
35:
36: /*
37: * Used to highlight the start of a record when printing it.
38: */
39: #define INDENT "-> "
40:
41:
42:
43: /*
44: * Print the contents of a query.
45: * This is intended to be primarily a debugging routine.
46: */
47:
48: Print_query(msg, eom, printHeader)
49: char *msg, *eom;
50: int printHeader;
51: {
52: Fprint_query(msg, eom, printHeader,stdout);
53: }
54:
55: Fprint_query(msg, eom, printHeader,file)
56: char *msg, *eom;
57: int printHeader;
58: FILE *file;
59: {
60: register char *cp;
61: register HEADER *hp;
62: register int n;
63: short class;
64: short type;
65:
66: /*
67: * Print header fields.
68: */
69: hp = (HEADER *)msg;
70: cp = msg + sizeof(HEADER);
71: if (printHeader || (_res.options & RES_DEBUG2)) {
72: fprintf(file,"HEADER:\n");
73: fprintf(file,"\topcode = %s", opcodes[hp->opcode]);
74: fprintf(file,", id = %d", ntohs(hp->id));
75: fprintf(file,", rcode = %s\n", rcodes[hp->rcode]);
76: fprintf(file,"\theader flags: ");
77: if (hp->qr) {
78: fprintf(file," response");
79: } else {
80: fprintf(file," query");
81: }
82: if (hp->aa)
83: fprintf(file,", auth. answer");
84: if (hp->tc)
85: fprintf(file,", truncation");
86: if (hp->rd)
87: fprintf(file,", want recursion");
88: if (hp->ra)
89: fprintf(file,", recursion avail.");
90: if (hp->pr)
91: fprintf(file,", primary");
92: fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
93: fprintf(file,", answers = %d", ntohs(hp->ancount));
94: fprintf(file,", n.s. = %d", ntohs(hp->nscount));
95: fprintf(file,", additional = %d\n\n", ntohs(hp->arcount));
96: }
97:
98: /*
99: * Print question records.
100: */
101: if (n = ntohs(hp->qdcount)) {
102: fprintf(file,"QUESTIONS:\n");
103: while (--n >= 0) {
104: fprintf(file,"\t");
105: cp = Print_cdname(cp, msg, eom, file);
106: if (cp == NULL)
107: return;
108: type = getshort(cp);
109: cp += sizeof(u_short);
110: class = getshort(cp);
111: cp += sizeof(u_short);
112: fprintf(file,", type = %s", p_type(type));
113: fprintf(file,", class = %s\n", p_class(class));
114: }
115: }
116: /*
117: * Print authoritative answer records
118: */
119: if (n = ntohs(hp->ancount)) {
120: fprintf(file,"ANSWERS:\n");
121: while (--n >= 0) {
122: fprintf(file, INDENT);
123: cp = Print_rr(cp, msg, eom, file);
124: if (cp == NULL)
125: return;
126: }
127: }
128: /*
129: * print name server records
130: */
131: if (n = ntohs(hp->nscount)) {
132: fprintf(file,"NAME SERVERS:\n");
133: while (--n >= 0) {
134: fprintf(file, INDENT);
135: cp = Print_rr(cp, msg, eom, file);
136: if (cp == NULL)
137: return;
138: }
139: }
140: /*
141: * print additional records
142: */
143: if (n = ntohs(hp->arcount)) {
144: fprintf(file,"ADDITIONAL RECORDS:\n");
145: while (--n >= 0) {
146: fprintf(file, INDENT);
147: cp = Print_rr(cp, msg, eom, file);
148: if (cp == NULL)
149: return;
150: }
151: }
152: fprintf(file,"\n");
153:
154: }
155:
156:
157: char *
158: Print_cdname_sub(cp, msg, eom, file, format)
159: char *cp, *msg, *eom;
160: FILE *file;
161: int format;
162: {
163: int n;
164: char name[MAXDNAME];
165: extern char *strcpy();
166:
167: if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
168: return (NULL);
169: if (name[0] == '\0') {
170: (void) strcpy(name, "(root)");
171: }
172: if (format) {
173: fprintf(file, "%-30s", name);
174: } else {
175: fputs(name, file);
176: }
177: return (cp + n);
178: }
179:
180: char *
181: Print_cdname(cp, msg, eom, file)
182: char *cp, *msg, *eom;
183: FILE *file;
184: {
185: return(Print_cdname_sub(cp, msg, eom, file, 0));
186: }
187:
188: char *
189: Print_cdname2(cp, msg, eom, file)
190: char *cp, *msg, *eom;
191: FILE *file;
192: {
193: return(Print_cdname_sub(cp, msg, eom, file, 1));
194: }
195:
196: /*
197: * Print resource record fields in human readable form.
198: */
199: char *
200: Print_rr(cp, msg, eom, file)
201: char *cp, *msg, *eom;
202: FILE *file;
203: {
204: int type, class, dlen, n, c;
205: long ttl;
206: struct in_addr inaddr;
207: char *cp1;
208:
209: if ((cp = Print_cdname(cp, msg, eom, file)) == NULL)
210: return (NULL); /* compression error */
211:
212: type = getshort(cp);
213: cp += sizeof(u_short);
214: class = getshort(cp);
215: cp += sizeof(u_short);
216: ttl = getlong(cp);
217: cp += sizeof(u_long);
218: dlen = getshort(cp);
219: cp += sizeof(u_short);
220:
221: if (_res.options & RES_DEBUG2) {
222: fprintf(file,"\n\ttype = %s, class = %s, ttl = %u, dlen = %d",
223: p_type(type), p_class(class), ttl, dlen);
224: fprintf(file,"\n");
225: }
226:
227: cp1 = cp;
228:
229: /*
230: * Print type specific data, if appropriate
231: */
232: switch (type) {
233: case T_A:
234: switch (class) {
235: case C_IN:
236: bcopy(cp, (char *)&inaddr, sizeof(inaddr));
237: if (dlen == 4) {
238: fprintf(file,"\tinet address = %s\n",
239: inet_ntoa(inaddr));
240: cp += dlen;
241: } else if (dlen == 7) {
242: fprintf(file,"\tinet address = %s",
243: inet_ntoa(inaddr));
244: fprintf(file,", protocol = %d", cp[4]);
245: fprintf(file,", port = %d\n",
246: (cp[5] << 8) + cp[6]);
247: cp += dlen;
248: }
249: break;
250: }
251: break;
252:
253: case T_CNAME:
254: fprintf(file,"\tcanonical name = ");
255: cp = Print_cdname(cp, msg, eom, file);
256: fprintf(file,"\n");
257: break;
258:
259: case T_MX:
260: fprintf(file,"\tpreference = %d",getshort(cp));
261: cp += sizeof(u_short);
262: fprintf(file,", mail exchanger = ");
263: cp = Print_cdname(cp,msg, eom, file);
264: fprintf(file,"\n");
265: break;
266:
267: case T_MG:
268: case T_MB:
269: case T_MR:
270: case T_NS:
271: case T_PTR:
272: fprintf(file,"\tserver name = ");
273: cp = Print_cdname(cp, msg, eom, file);
274: fprintf(file,"\n");
275: break;
276:
277: case T_HINFO:
278: if (n = *cp++) {
279: fprintf(file,"\tCPU=%.*s", n, cp);
280: cp += n;
281: }
282: if (n = *cp++) {
283: fprintf(file,"\tOS=%.*s\n", n, cp);
284: cp += n;
285: }
286: break;
287:
288: case T_SOA:
289: fprintf(file,"\torigin = ");
290: cp = Print_cdname(cp, msg, eom, file);
291: fprintf(file,"\n\tmail addr = ");
292: cp = Print_cdname(cp, msg, eom, file);
293: fprintf(file,"\n\tserial=%ld", getlong(cp));
294: cp += sizeof(u_long);
295: fprintf(file,", refresh=%ld", getlong(cp));
296: cp += sizeof(u_long);
297: fprintf(file,", retry=%ld", getlong(cp));
298: cp += sizeof(u_long);
299: fprintf(file,", expire=%ld", getlong(cp));
300: cp += sizeof(u_long);
301: fprintf(file,", min=%ld\n", getlong(cp));
302: cp += sizeof(u_long);
303: break;
304:
305: case T_MINFO:
306: fprintf(file,"\trequests = ");
307: cp = Print_cdname(cp, msg, eom, file);
308: fprintf(file,"\n\terrors = ");
309: cp = Print_cdname(cp, msg, eom, file);
310: break;
311:
312: case T_UINFO:
313: fprintf(file,"\t%s\n", cp);
314: cp += dlen;
315: break;
316:
317: case T_UID:
318: case T_GID:
319: if (dlen == 4) {
320: fprintf(file,"\t%ld\n", getlong(cp));
321: cp += sizeof(int);
322: }
323: break;
324:
325: case T_WKS:
326: if (dlen < sizeof(u_long) + 1)
327: break;
328: bcopy(cp, (char *)&inaddr, sizeof(inaddr));
329: cp += sizeof(u_long);
330: fprintf(file,"\tinet address = %s, protocol = %d\n\t",
331: inet_ntoa(inaddr), *cp++);
332: n = 0;
333: while (cp < cp1 + dlen) {
334: c = *cp++;
335: do {
336: if (c & 0200)
337: fprintf(file," %d", n);
338: c <<= 1;
339: } while (++n & 07);
340: }
341: putc('\n',file);
342: break;
343:
344: case T_NULL:
345: break;
346:
347: default:
348: fprintf(file,"\t???\n");
349: cp += dlen;
350: }
351: if (cp != cp1 + dlen)
352: fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
353: return (cp);
354: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.