Remove old RRs, add C_HS & T_TXT, p_time was called incorrectly
[unix-history] / usr / src / lib / libc / net / res_debug.c
CommitLineData
b423e985 1/*
8ea4199d 2 * Copyright (c) 1985 Regents of the University of California.
6b2f9dd0
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
f4f66d2c
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
b423e985
RC
16 */
17
2ce81398 18#if defined(LIBC_SCCS) && !defined(lint)
606dc84e 19static char sccsid[] = "@(#)res_debug.c 5.25 (Berkeley) %G%";
6b2f9dd0 20#endif /* LIBC_SCCS and not lint */
8ea4199d 21
0d22afd1
RC
22#include <sys/types.h>
23#include <netinet/in.h>
24#include <stdio.h>
02a51825 25#include <arpa/nameser.h>
0d22afd1 26
7134abf2 27extern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time();
0d22afd1
RC
28extern char *inet_ntoa();
29
cd43bd6a 30char *_res_opcodes[] = {
0d22afd1
RC
31 "QUERY",
32 "IQUERY",
33 "CQUERYM",
34 "CQUERYU",
35 "4",
36 "5",
37 "6",
38 "7",
39 "8",
0d22afd1
RC
40 "UPDATEA",
41 "UPDATED",
3e8361d9 42 "UPDATEDA",
0d22afd1 43 "UPDATEM",
3e8361d9 44 "UPDATEMA",
0d22afd1
RC
45 "ZONEINIT",
46 "ZONEREF",
47};
48
cd43bd6a 49char *_res_resultcodes[] = {
0d22afd1
RC
50 "NOERROR",
51 "FORMERR",
52 "SERVFAIL",
53 "NXDOMAIN",
54 "NOTIMP",
55 "REFUSED",
56 "6",
57 "7",
58 "8",
59 "9",
60 "10",
61 "11",
62 "12",
63 "13",
64 "14",
65 "NOCHANGE",
66};
67
a73d974c
KD
68p_query(msg)
69 char *msg;
70{
71 fp_query(msg,stdout);
72}
73
0d22afd1
RC
74/*
75 * Print the contents of a query.
76 * This is intended to be primarily a debugging routine.
77 */
a73d974c 78fp_query(msg,file)
e515a559 79 char *msg;
a73d974c 80 FILE *file;
0d22afd1
RC
81{
82 register char *cp;
83 register HEADER *hp;
84 register int n;
85
86 /*
87 * Print header fields.
88 */
e515a559
RC
89 hp = (HEADER *)msg;
90 cp = msg + sizeof(HEADER);
a73d974c 91 fprintf(file,"HEADER:\n");
d7070d01 92 fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
a73d974c 93 fprintf(file,", id = %d", ntohs(hp->id));
d7070d01 94 fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
a73d974c 95 fprintf(file,"\theader flags: ");
0d22afd1 96 if (hp->qr)
a73d974c 97 fprintf(file," qr");
0d22afd1 98 if (hp->aa)
a73d974c 99 fprintf(file," aa");
0d22afd1 100 if (hp->tc)
a73d974c 101 fprintf(file," tc");
0d22afd1 102 if (hp->rd)
a73d974c 103 fprintf(file," rd");
0d22afd1 104 if (hp->ra)
a73d974c 105 fprintf(file," ra");
0d22afd1 106 if (hp->pr)
a73d974c
KD
107 fprintf(file," pr");
108 fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount));
109 fprintf(file,", ancount = %d", ntohs(hp->ancount));
110 fprintf(file,", nscount = %d", ntohs(hp->nscount));
111 fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount));
0d22afd1
RC
112 /*
113 * Print question records.
114 */
115 if (n = ntohs(hp->qdcount)) {
a73d974c 116 fprintf(file,"QUESTIONS:\n");
0d22afd1 117 while (--n >= 0) {
a73d974c
KD
118 fprintf(file,"\t");
119 cp = p_cdname(cp, msg, file);
0d22afd1
RC
120 if (cp == NULL)
121 return;
20087cad 122 fprintf(file,", type = %s", p_type(_getshort(cp)));
0d22afd1 123 cp += sizeof(u_short);
20087cad 124 fprintf(file,", class = %s\n\n", p_class(_getshort(cp)));
0d22afd1
RC
125 cp += sizeof(u_short);
126 }
127 }
128 /*
129 * Print authoritative answer records
130 */
131 if (n = ntohs(hp->ancount)) {
a73d974c 132 fprintf(file,"ANSWERS:\n");
0d22afd1 133 while (--n >= 0) {
a73d974c
KD
134 fprintf(file,"\t");
135 cp = p_rr(cp, msg, file);
0d22afd1
RC
136 if (cp == NULL)
137 return;
138 }
139 }
140 /*
141 * print name server records
142 */
143 if (n = ntohs(hp->nscount)) {
a73d974c 144 fprintf(file,"NAME SERVERS:\n");
0d22afd1 145 while (--n >= 0) {
a73d974c
KD
146 fprintf(file,"\t");
147 cp = p_rr(cp, msg, file);
0d22afd1
RC
148 if (cp == NULL)
149 return;
150 }
151 }
152 /*
153 * print additional records
154 */
155 if (n = ntohs(hp->arcount)) {
a73d974c 156 fprintf(file,"ADDITIONAL RECORDS:\n");
0d22afd1 157 while (--n >= 0) {
a73d974c
KD
158 fprintf(file,"\t");
159 cp = p_rr(cp, msg, file);
0d22afd1
RC
160 if (cp == NULL)
161 return;
162 }
163 }
164}
165
166char *
a73d974c 167p_cdname(cp, msg, file)
e515a559 168 char *cp, *msg;
a73d974c 169 FILE *file;
0d22afd1
RC
170{
171 char name[MAXDNAME];
172 int n;
173
127b68cb 174 if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0)
0d22afd1
RC
175 return (NULL);
176 if (name[0] == '\0') {
177 name[0] = '.';
178 name[1] = '\0';
179 }
a73d974c 180 fputs(name, file);
0d22afd1
RC
181 return (cp + n);
182}
183
184/*
185 * Print resource record fields in human readable form.
186 */
187char *
a73d974c 188p_rr(cp, msg, file)
e515a559 189 char *cp, *msg;
a73d974c 190 FILE *file;
0d22afd1
RC
191{
192 int type, class, dlen, n, c;
193 struct in_addr inaddr;
194 char *cp1;
195
a73d974c 196 if ((cp = p_cdname(cp, msg, file)) == NULL)
0d22afd1 197 return (NULL); /* compression error */
20087cad 198 fprintf(file,"\n\ttype = %s", p_type(type = _getshort(cp)));
0d22afd1 199 cp += sizeof(u_short);
20087cad 200 fprintf(file,", class = %s", p_class(class = _getshort(cp)));
0d22afd1 201 cp += sizeof(u_short);
606dc84e 202 fprintf(file,", ttl = %s", p_time(_getlong(cp)));
0d22afd1 203 cp += sizeof(u_long);
20087cad 204 fprintf(file,", dlen = %d\n", dlen = _getshort(cp));
0d22afd1
RC
205 cp += sizeof(u_short);
206 cp1 = cp;
207 /*
208 * Print type specific data, if appropriate
209 */
210 switch (type) {
211 case T_A:
212 switch (class) {
213 case C_IN:
11e57e73 214 bcopy(cp, (char *)&inaddr, sizeof(inaddr));
0d22afd1 215 if (dlen == 4) {
a73d974c 216 fprintf(file,"\tinternet address = %s\n",
0d22afd1
RC
217 inet_ntoa(inaddr));
218 cp += dlen;
219 } else if (dlen == 7) {
a73d974c 220 fprintf(file,"\tinternet address = %s",
0d22afd1 221 inet_ntoa(inaddr));
a73d974c
KD
222 fprintf(file,", protocol = %d", cp[4]);
223 fprintf(file,", port = %d\n",
0d22afd1
RC
224 (cp[5] << 8) + cp[6]);
225 cp += dlen;
226 }
227 break;
e0dd8906
KD
228 default:
229 cp += dlen;
0d22afd1
RC
230 }
231 break;
232 case T_CNAME:
233 case T_MB:
0d22afd1
RC
234 case T_MG:
235 case T_MR:
236 case T_NS:
237 case T_PTR:
a73d974c
KD
238 fprintf(file,"\tdomain name = ");
239 cp = p_cdname(cp, msg, file);
240 fprintf(file,"\n");
0d22afd1
RC
241 break;
242
243 case T_HINFO:
244 if (n = *cp++) {
a73d974c 245 fprintf(file,"\tCPU=%.*s\n", n, cp);
0d22afd1
RC
246 cp += n;
247 }
248 if (n = *cp++) {
a73d974c 249 fprintf(file,"\tOS=%.*s\n", n, cp);
0d22afd1
RC
250 cp += n;
251 }
252 break;
253
254 case T_SOA:
a73d974c
KD
255 fprintf(file,"\torigin = ");
256 cp = p_cdname(cp, msg, file);
257 fprintf(file,"\n\tmail addr = ");
258 cp = p_cdname(cp, msg, file);
606dc84e 259 fprintf(file,"\n\tserial = %ld", _getlong(cp));
0d22afd1 260 cp += sizeof(u_long);
606dc84e 261 fprintf(file,"\n\trefresh = %s", p_time(_getlong(cp)));
0d22afd1 262 cp += sizeof(u_long);
606dc84e 263 fprintf(file,"\n\tretry = %s", p_time(_getlong(cp)));
0d22afd1 264 cp += sizeof(u_long);
606dc84e 265 fprintf(file,"\n\texpire = %s", p_time(_getlong(cp)));
0d22afd1 266 cp += sizeof(u_long);
606dc84e 267 fprintf(file,"\n\tmin = %s\n", p_time(_getlong(cp)));
0d22afd1
RC
268 cp += sizeof(u_long);
269 break;
270
73546a32 271 case T_MX:
20087cad 272 fprintf(file,"\tpreference = %ld,",_getshort(cp));
018df4a9
KD
273 cp += sizeof(u_short);
274 fprintf(file," name = ");
73546a32 275 cp = p_cdname(cp, msg, file);
73546a32
KD
276 break;
277
e515a559 278 case T_MINFO:
a73d974c
KD
279 fprintf(file,"\trequests = ");
280 cp = p_cdname(cp, msg, file);
281 fprintf(file,"\n\terrors = ");
282 cp = p_cdname(cp, msg, file);
e515a559
RC
283 break;
284
0d22afd1 285 case T_UINFO:
606dc84e 286 case T_TXT:
a73d974c 287 fprintf(file,"\t%s\n", cp);
0d22afd1
RC
288 cp += dlen;
289 break;
290
291 case T_UID:
292 case T_GID:
293 if (dlen == 4) {
20087cad 294 fprintf(file,"\t%ld\n", _getlong(cp));
0d22afd1
RC
295 cp += sizeof(int);
296 }
297 break;
298
299 case T_WKS:
300 if (dlen < sizeof(u_long) + 1)
301 break;
11e57e73 302 bcopy(cp, (char *)&inaddr, sizeof(inaddr));
0d22afd1 303 cp += sizeof(u_long);
a73d974c 304 fprintf(file,"\tinternet address = %s, protocol = %d\n\t",
0d22afd1
RC
305 inet_ntoa(inaddr), *cp++);
306 n = 0;
307 while (cp < cp1 + dlen) {
308 c = *cp++;
309 do {
a943feed 310 if (c & 0200)
a73d974c 311 fprintf(file," %d", n);
a943feed 312 c <<= 1;
0d22afd1
RC
313 } while (++n & 07);
314 }
a73d974c 315 putc('\n',file);
0d22afd1
RC
316 break;
317
3bf25746 318#ifdef ALLOW_T_UNSPEC
1e12917d
KB
319 case T_UNSPEC:
320 {
321 int NumBytes = 8;
322 char *DataPtr;
323 int i;
3bf25746 324
1e12917d
KB
325 if (dlen < NumBytes) NumBytes = dlen;
326 fprintf(file, "\tFirst %d bytes of hex data:",
327 NumBytes);
328 for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
329 fprintf(file, " %x", *DataPtr);
330 fputs("\n", file);
331 cp += dlen;
332 }
333 break;
334#endif /* ALLOW_T_UNSPEC */
3bf25746 335
0d22afd1 336 default:
a73d974c 337 fprintf(file,"\t???\n");
0d22afd1
RC
338 cp += dlen;
339 }
340 if (cp != cp1 + dlen)
a73d974c
KD
341 fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
342 fprintf(file,"\n");
0d22afd1
RC
343 return (cp);
344}
345
7134abf2 346static char nbuf[40];
0d22afd1
RC
347
348/*
349 * Return a string for the type
350 */
351char *
352p_type(type)
353 int type;
354{
0d22afd1
RC
355 switch (type) {
356 case T_A:
357 return("A");
358 case T_NS: /* authoritative server */
359 return("NS");
0d22afd1
RC
360 case T_CNAME: /* connonical name */
361 return("CNAME");
362 case T_SOA: /* start of authority zone */
363 return("SOA");
364 case T_MB: /* mailbox domain name */
365 return("MB");
366 case T_MG: /* mail group member */
367 return("MG");
368 case T_MR: /* mail rename name */
369 return("MR");
370 case T_NULL: /* null resource record */
371 return("NULL");
372 case T_WKS: /* well known service */
373 return("WKS");
374 case T_PTR: /* domain name pointer */
375 return("PTR");
376 case T_HINFO: /* host information */
377 return("HINFO");
378 case T_MINFO: /* mailbox information */
379 return("MINFO");
606dc84e
JB
380 case T_MX: /* mail routing info */
381 return("MX");
382 case T_TXT: /* text */
383 return("TXT");
0d22afd1
RC
384 case T_AXFR: /* zone transfer */
385 return("AXFR");
386 case T_MAILB: /* mail box */
387 return("MAILB");
388 case T_MAILA: /* mail address */
389 return("MAILA");
390 case T_ANY: /* matches any type */
391 return("ANY");
392 case T_UINFO:
393 return("UINFO");
394 case T_UID:
395 return("UID");
396 case T_GID:
397 return("GID");
3bf25746 398#ifdef ALLOW_T_UNSPEC
1e12917d
KB
399 case T_UNSPEC:
400 return("UNSPEC");
401#endif /* ALLOW_T_UNSPEC */
0d22afd1 402 default:
06eef7c4
KB
403 (void)sprintf(nbuf, "%d", type);
404 return(nbuf);
0d22afd1
RC
405 }
406}
407
408/*
409 * Return a mnemonic for class
410 */
411char *
412p_class(class)
413 int class;
414{
415
416 switch (class) {
417 case C_IN: /* internet class */
418 return("IN");
606dc84e
JB
419 case C_HS: /* internet class */
420 return("HESIOD");
0d22afd1
RC
421 case C_ANY: /* matches any class */
422 return("ANY");
423 default:
06eef7c4
KB
424 (void)sprintf(nbuf, "%d", class);
425 return(nbuf);
0d22afd1
RC
426 }
427}
7134abf2
MK
428
429/*
430 * Return a mnemonic for a time to live
431 */
432char
433*p_time(value)
434 u_long value;
435{
436 int secs, mins, hours;
437 register char *p;
438
439 secs = value % 60;
440 value /= 60;
441 mins = value % 60;
442 value /= 60;
443 hours = value % 24;
444 value /= 24;
445
446#define PLURALIZE(x) x, (x == 1) ? "" : "s"
447 p = nbuf;
448 if (value) {
449 (void)sprintf(p, "%d day%s", PLURALIZE(value));
450 while (*++p);
451 }
452 if (hours) {
453 if (p != nbuf)
454 *p++ = ' ';
455 (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
456 while (*++p);
457 }
458 if (mins) {
459 if (p != nbuf)
460 *p++ = ' ';
461 (void)sprintf(p, "%d min%s", PLURALIZE(mins));
462 while (*++p);
463 }
464 if (secs) {
465 if (p != nbuf)
466 *p++ = ' ';
467 (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
468 while (*++p);
469 }
470 return(nbuf);
471}