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