xref: /csrg-svn/lib/libc/net/res_debug.c (revision 18540)
1 #ifndef lint
2 static char sccsid[] = "@(#)res_debug.c	4.3 (Berkeley) 03/29/85";
3 #endif
4 
5 #include <sys/types.h>
6 #include <netinet/in.h>
7 #include <stdio.h>
8 #include <nameser.h>
9 
10 extern char *p_cdname(), *p_rr(), *p_type(), *p_class();
11 extern char *inet_ntoa();
12 
13 char *opcodes[] = {
14 	"QUERY",
15 	"IQUERY",
16 	"CQUERYM",
17 	"CQUERYU",
18 	"4",
19 	"5",
20 	"6",
21 	"7",
22 	"8",
23 	"9",
24 	"10",
25 	"UPDATEA",
26 	"UPDATED",
27 	"UPDATEM",
28 	"ZONEINIT",
29 	"ZONEREF",
30 };
31 
32 char *rcodes[] = {
33 	"NOERROR",
34 	"FORMERR",
35 	"SERVFAIL",
36 	"NXDOMAIN",
37 	"NOTIMP",
38 	"REFUSED",
39 	"6",
40 	"7",
41 	"8",
42 	"9",
43 	"10",
44 	"11",
45 	"12",
46 	"13",
47 	"14",
48 	"NOCHANGE",
49 };
50 
51 /*
52  * Print the contents of a query.
53  * This is intended to be primarily a debugging routine.
54  */
55 p_query(msg)
56 	char *msg;
57 {
58 	register char *cp;
59 	register HEADER *hp;
60 	register int n;
61 
62 	/*
63 	 * Print header fields.
64 	 */
65 	hp = (HEADER *)msg;
66 	cp = msg + sizeof(HEADER);
67 	printf("HEADER:\n");
68 	printf("\topcode = %s", opcodes[hp->opcode]);
69 	printf(", id = %d", ntohs(hp->id));
70 	printf(", rcode = %s\n", rcodes[hp->rcode]);
71 	printf("\theader flags: ");
72 	if (hp->qr)
73 		printf(" qr");
74 	if (hp->aa)
75 		printf(" aa");
76 	if (hp->tc)
77 		printf(" tc");
78 	if (hp->rd)
79 		printf(" rd");
80 	if (hp->ra)
81 		printf(" ra");
82 	if (hp->pr)
83 		printf(" pr");
84 	printf("\n\tqdcount = %d", ntohs(hp->qdcount));
85 	printf(", ancount = %d", ntohs(hp->ancount));
86 	printf(", nscount = %d", ntohs(hp->nscount));
87 	printf(", arcount = %d\n\n", ntohs(hp->arcount));
88 	/*
89 	 * Print question records.
90 	 */
91 	if (n = ntohs(hp->qdcount)) {
92 		printf("QUESTIONS:\n");
93 		while (--n >= 0) {
94 			printf("\t");
95 			cp = p_cdname(cp, msg);
96 			if (cp == NULL)
97 				return;
98 			printf(", type = %s", p_type(getshort(cp)));
99 			cp += sizeof(u_short);
100 			printf(", class = %s\n\n", p_class(getshort(cp)));
101 			cp += sizeof(u_short);
102 		}
103 	}
104 	/*
105 	 * Print authoritative answer records
106 	 */
107 	if (n = ntohs(hp->ancount)) {
108 		printf("ANSWERS:\n");
109 		while (--n >= 0) {
110 			printf("\t");
111 			cp = p_rr(cp, msg);
112 			if (cp == NULL)
113 				return;
114 		}
115 	}
116 	/*
117 	 * print name server records
118 	 */
119 	if (n = ntohs(hp->nscount)) {
120 		printf("NAME SERVERS:\n");
121 		while (--n >= 0) {
122 			printf("\t");
123 			cp = p_rr(cp, msg);
124 			if (cp == NULL)
125 				return;
126 		}
127 	}
128 	/*
129 	 * print additional records
130 	 */
131 	if (n = ntohs(hp->arcount)) {
132 		printf("ADDITIONAL RECORDS:\n");
133 		while (--n >= 0) {
134 			printf("\t");
135 			cp = p_rr(cp, msg);
136 			if (cp == NULL)
137 				return;
138 		}
139 	}
140 }
141 
142 char *
143 p_cdname(cp, msg)
144 	char *cp, *msg;
145 {
146 	char name[MAXDNAME];
147 	int n;
148 
149 	if ((n = dn_expand(msg, cp, name, sizeof(name))) < 0)
150 		return (NULL);
151 	if (name[0] == '\0') {
152 		name[0] = '.';
153 		name[1] = '\0';
154 	}
155 	fputs(name, stdout);
156 	return (cp + n);
157 }
158 
159 /*
160  * Print resource record fields in human readable form.
161  */
162 char *
163 p_rr(cp, msg)
164 	char *cp, *msg;
165 {
166 	int type, class, dlen, n, c;
167 	struct in_addr inaddr;
168 	char *cp1;
169 
170 	if ((cp = p_cdname(cp, msg)) == NULL)
171 		return (NULL);			/* compression error */
172 	printf("\n\ttype = %s", p_type(type = getshort(cp)));
173 	cp += sizeof(u_short);
174 	printf(", class = %s", p_class(class = getshort(cp)));
175 	cp += sizeof(u_short);
176 	printf(", ttl = %ld", getlong(cp));
177 	cp += sizeof(u_long);
178 	printf(", dlen = %d\n", dlen = getshort(cp));
179 	cp += sizeof(u_short);
180 	cp1 = cp;
181 	/*
182 	 * Print type specific data, if appropriate
183 	 */
184 	switch (type) {
185 	case T_A:
186 		switch (class) {
187 		case C_IN:
188 			bcopy(cp, (char *)&inaddr, sizeof(inaddr));
189 			if (dlen == 4) {
190 				printf("\tinternet address = %s\n",
191 					inet_ntoa(inaddr));
192 				cp += dlen;
193 			} else if (dlen == 7) {
194 				printf("\tinternet address = %s",
195 					inet_ntoa(inaddr));
196 				printf(", protocol = %d", cp[4]);
197 				printf(", port = %d\n",
198 					(cp[5] << 8) + cp[6]);
199 				cp += dlen;
200 			}
201 			break;
202 		}
203 		break;
204 	case T_CNAME:
205 	case T_MB:
206 	case T_MD:
207 	case T_MF:
208 	case T_MG:
209 	case T_MR:
210 	case T_NS:
211 	case T_PTR:
212 		printf("\tdomain name = ");
213 		cp = p_cdname(cp, msg);
214 		printf("\n");
215 		break;
216 
217 	case T_HINFO:
218 		if (n = *cp++) {
219 			printf("\tCPU=%.*s\n", n, cp);
220 			cp += n;
221 		}
222 		if (n = *cp++) {
223 			printf("\tOS=%.*s\n", n, cp);
224 			cp += n;
225 		}
226 		break;
227 
228 	case T_SOA:
229 		printf("\torigin = ");
230 		cp = p_cdname(cp, msg);
231 		printf("\n\tmail addr = ");
232 		cp = p_cdname(cp, msg);
233 		printf("\n\tserial=%ld", getlong(cp));
234 		cp += sizeof(u_long);
235 		printf(", refresh=%ld", getlong(cp));
236 		cp += sizeof(u_long);
237 		printf(", retry=%ld", getlong(cp));
238 		cp += sizeof(u_long);
239 		printf(", expire=%ld", getlong(cp));
240 		cp += sizeof(u_long);
241 		printf(", min=%ld\n", getlong(cp));
242 		cp += sizeof(u_long);
243 		break;
244 
245 	case T_MINFO:
246 		printf("\trequests = ");
247 		cp = p_cdname(cp, msg);
248 		printf("\n\terrors = ");
249 		cp = p_cdname(cp, msg);
250 		break;
251 
252 	case T_UINFO:
253 		printf("\t%s\n", cp);
254 		cp += dlen;
255 		break;
256 
257 	case T_UID:
258 	case T_GID:
259 		if (dlen == 4) {
260 			printf("\t%ld\n", getlong(cp));
261 			cp += sizeof(int);
262 		}
263 		break;
264 
265 	case T_WKS:
266 		if (dlen < sizeof(u_long) + 1)
267 			break;
268 		bcopy(cp, (char *)&inaddr, sizeof(inaddr));
269 		cp += sizeof(u_long);
270 		printf("\tinternet address = %s, protocol = %d\n\t",
271 			inet_ntoa(inaddr), *cp++);
272 		n = 0;
273 		while (cp < cp1 + dlen) {
274 			c = *cp++;
275 			do {
276 				if (c & 1)
277 					printf(" %d", n);
278 				c >>= 1;
279 			} while (++n & 07);
280 		}
281 		putchar('\n');
282 		break;
283 
284 	default:
285 		printf("\t???\n");
286 		cp += dlen;
287 	}
288 	if (cp != cp1 + dlen)
289 		printf("packet size error (%#x != %#x)\n", cp, cp1+dlen);
290 	printf("\n");
291 	return (cp);
292 }
293 
294 static	char nbuf[20];
295 extern	char *sprintf();
296 
297 /*
298  * Return a string for the type
299  */
300 char *
301 p_type(type)
302 	int type;
303 {
304 
305 	switch (type) {
306 	case T_A:
307 		return("A");
308 	case T_NS:		/* authoritative server */
309 		return("NS");
310 	case T_MD:		/* mail destination */
311 		return("MD");
312 	case T_MF:		/* mail forwarder */
313 		return("MF");
314 	case T_CNAME:		/* connonical name */
315 		return("CNAME");
316 	case T_SOA:		/* start of authority zone */
317 		return("SOA");
318 	case T_MB:		/* mailbox domain name */
319 		return("MB");
320 	case T_MG:		/* mail group member */
321 		return("MG");
322 	case T_MR:		/* mail rename name */
323 		return("MR");
324 	case T_NULL:		/* null resource record */
325 		return("NULL");
326 	case T_WKS:		/* well known service */
327 		return("WKS");
328 	case T_PTR:		/* domain name pointer */
329 		return("PTR");
330 	case T_HINFO:		/* host information */
331 		return("HINFO");
332 	case T_MINFO:		/* mailbox information */
333 		return("MINFO");
334 	case T_AXFR:		/* zone transfer */
335 		return("AXFR");
336 	case T_MAILB:		/* mail box */
337 		return("MAILB");
338 	case T_MAILA:		/* mail address */
339 		return("MAILA");
340 	case T_ANY:		/* matches any type */
341 		return("ANY");
342 	case T_UINFO:
343 		return("UINFO");
344 	case T_UID:
345 		return("UID");
346 	case T_GID:
347 		return("GID");
348 	default:
349 		return (sprintf(nbuf, "%d", type));
350 	}
351 }
352 
353 /*
354  * Return a mnemonic for class
355  */
356 char *
357 p_class(class)
358 	int class;
359 {
360 
361 	switch (class) {
362 	case C_IN:		/* internet class */
363 		return("IN");
364 	case C_CS:		/* csnet class */
365 		return("CS");
366 	case C_ANY:		/* matches any class */
367 		return("ANY");
368 	default:
369 		return (sprintf(nbuf, "%d", class));
370 	}
371 }
372