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

Defined functions

fp_query defined in line 83; used 1 times
  • in line 76
p_cdname defined in line 171; used 9 times
p_query defined in line 73; used 3 times
p_rr defined in line 192; used 4 times
p_time defined in line 455; used 12 times

Defined variables

_res_opcodes defined in line 35; used 2 times
nbuf defined in line 369; used 8 times
sccsid defined in line 23; never used

Defined macros

PLURALIZE defined in line 474; used 4 times
Last modified: 1993-04-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3725
Valid CSS Valid XHTML 1.0 Strict