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