xref: /csrg-svn/lib/libc/net/res_debug.c (revision 18141)
1 #ifndef lint
2 static char sccsid[] = "@(#)res_debug.c	4.1 (Berkeley) 03/01/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(buf)
56 	char *buf;
57 {
58 	register char *cp;
59 	register HEADER *hp;
60 	register int n;
61 
62 	/*
63 	 * Print header fields.
64 	 */
65 	hp = (HEADER *)buf;
66 	cp = buf + 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, buf);
96 			if (cp == NULL)
97 				return;
98 			printf(", type = %s", p_type(ntohs(*(u_short *)cp)));
99 			cp += sizeof(u_short);
100 			printf(", class = %s\n\n", p_class(ntohs(*(u_short *)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, buf);
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, buf);
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, buf);
136 			if (cp == NULL)
137 				return;
138 		}
139 	}
140 }
141 
142 char *
143 p_cdname(cp, buf)
144 	char *cp, *buf;
145 {
146 	char name[MAXDNAME];
147 	int n;
148 
149 	if ((n = dn_expand(buf, 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, buf)
164 	char *cp, *buf;
165 {
166 	int type, class, dlen, n, c;
167 	struct in_addr inaddr;
168 	char *cp1;
169 
170 	if ((cp = p_cdname(cp, buf)) == NULL)
171 		return (NULL);			/* compression error */
172 	printf("\n\ttype = %s", p_type(type = ntohs(*(u_short *)cp)));
173 	cp += sizeof(u_short);
174 	printf(", class = %s", p_class(class = ntohs(*(u_short *)cp)));
175 	cp += sizeof(u_short);
176 	printf(", ttl = %d", ntohl(*(u_int *)cp));
177 	cp += sizeof(u_long);
178 	printf(", dlen = %d\n", dlen = ntohs(*(u_short *)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 			inaddr.s_addr = *(u_long *)cp;
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, buf);
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, buf);
231 		printf("\n\tmail addr = ");
232 		cp = p_cdname(cp, buf);
233 		printf("\n\tserial=%d", ntohl(*(u_long *)cp));
234 		cp += sizeof(u_long);
235 		printf(", refresh=%d", ntohl(*(u_long *)cp));
236 		cp += sizeof(u_long);
237 		printf(", retry=%d", ntohl(*(u_long *)cp));
238 		cp += sizeof(u_long);
239 		printf(", expire=%d", ntohl(*(u_long *)cp));
240 		cp += sizeof(u_long);
241 		printf(", min=%d\n", ntohl(*(u_long *)cp));
242 		cp += sizeof(u_long);
243 		break;
244 
245 	case T_UINFO:
246 		printf("\t%s\n", cp);
247 		cp += dlen;
248 		break;
249 
250 	case T_UID:
251 	case T_GID:
252 		if (dlen == 4) {
253 			printf("\t%d\n", ntohl(*(int *)cp));
254 			cp += sizeof(int);
255 		}
256 		break;
257 
258 	case T_WKS:
259 		if (dlen < sizeof(u_long) + 1)
260 			break;
261 		inaddr.s_addr = *(u_long *)cp;
262 		cp += sizeof(u_long);
263 		printf("\tinternet address = %s, protocol = %d\n\t",
264 			inet_ntoa(inaddr), *cp++);
265 		n = 0;
266 		while (cp < cp1 + dlen) {
267 			c = *cp++;
268 			do {
269 				if (c & 1)
270 					printf(" %d", n);
271 				c >>= 1;
272 			} while (++n & 07);
273 		}
274 		putchar('\n');
275 		break;
276 
277 	default:
278 		printf("\t???\n");
279 		cp += dlen;
280 	}
281 	if (cp != cp1 + dlen)
282 		printf("packet size error (%#x != %#x)\n", cp, cp1+dlen);
283 	printf("\n");
284 	return (cp);
285 }
286 
287 static	char nbuf[20];
288 extern	char *sprintf();
289 
290 /*
291  * Return a string for the type
292  */
293 char *
294 p_type(type)
295 	int type;
296 {
297 
298 	switch (type) {
299 	case T_A:
300 		return("A");
301 	case T_NS:		/* authoritative server */
302 		return("NS");
303 	case T_MD:		/* mail destination */
304 		return("MD");
305 	case T_MF:		/* mail forwarder */
306 		return("MF");
307 	case T_CNAME:		/* connonical name */
308 		return("CNAME");
309 	case T_SOA:		/* start of authority zone */
310 		return("SOA");
311 	case T_MB:		/* mailbox domain name */
312 		return("MB");
313 	case T_MG:		/* mail group member */
314 		return("MG");
315 	case T_MR:		/* mail rename name */
316 		return("MR");
317 	case T_NULL:		/* null resource record */
318 		return("NULL");
319 	case T_WKS:		/* well known service */
320 		return("WKS");
321 	case T_PTR:		/* domain name pointer */
322 		return("PTR");
323 	case T_HINFO:		/* host information */
324 		return("HINFO");
325 	case T_MINFO:		/* mailbox information */
326 		return("MINFO");
327 	case T_AXFR:		/* zone transfer */
328 		return("AXFR");
329 	case T_MAILB:		/* mail box */
330 		return("MAILB");
331 	case T_MAILA:		/* mail address */
332 		return("MAILA");
333 	case T_ANY:		/* matches any type */
334 		return("ANY");
335 	case T_UINFO:
336 		return("UINFO");
337 	case T_UID:
338 		return("UID");
339 	case T_GID:
340 		return("GID");
341 	default:
342 		return (sprintf(nbuf, "%d", type));
343 	}
344 }
345 
346 /*
347  * Return a mnemonic for class
348  */
349 char *
350 p_class(class)
351 	int class;
352 {
353 
354 	switch (class) {
355 	case C_IN:		/* internet class */
356 		return("IN");
357 	case C_CS:		/* csnet class */
358 		return("CS");
359 	case C_ANY:		/* matches any class */
360 		return("ANY");
361 	default:
362 		return (sprintf(nbuf, "%d", class));
363 	}
364 }
365