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