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