1: /*
   2:  * Copyright (c) 1985,1989 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: 
  20: #if !defined(lint) && defined(DOSCCS)
  21: static char sccsid[] = "@(#)debug.c	5.22 (Berkeley) 6/29/90";
  22: #endif
  23: 
  24: /*
  25:  *******************************************************************************
  26:  *
  27:  *  debug.c --
  28:  *
  29:  *	Routines to print out packets received from a name server query.
  30:  *
  31:  *      Modified version of 4.3BSD BIND res_debug.c 5.30 6/27/90
  32:  *
  33:  *******************************************************************************
  34:  */
  35: 
  36: #include <sys/types.h>
  37: #include <netinet/in.h>
  38: #include <stdio.h>
  39: #include <arpa/nameser.h>
  40: #include <arpa/inet.h>
  41: #include <resolv.h>
  42: #include <netdb.h>
  43: #include "res.h"
  44: 
  45: extern char ctime();
  46: 
  47: /*
  48:  *  Imported from res_debug.c
  49:  */
  50: extern char *_res_resultcodes[];
  51: extern char *_res_opcodes[];
  52: 
  53: /*
  54:  *  Used to highlight the start of a record when printing it.
  55:  */
  56: #define INDENT "    ->  "
  57: 
  58: 
  59: 
  60: /*
  61:  * Print the contents of a query.
  62:  * This is intended to be primarily a debugging routine.
  63:  */
  64: 
  65: Print_query(msg, eom, printHeader)
  66:     char *msg, *eom;
  67:     int printHeader;
  68: {
  69:     Fprint_query(msg, eom, printHeader,stdout);
  70: }
  71: 
  72: Fprint_query(msg, eom, printHeader,file)
  73:     char *msg, *eom;
  74:     int printHeader;
  75:     FILE *file;
  76: {
  77:     register char *cp;
  78:     register HEADER *hp;
  79:     register int n;
  80:     short class;
  81:     short type;
  82: 
  83:     /*
  84: 	 * Print header fields.
  85: 	 */
  86:     hp = (HEADER *)msg;
  87:     cp = msg + sizeof(HEADER);
  88:     if (printHeader || (_res.options & RES_DEBUG2)) {
  89:         fprintf(file,"    HEADER:\n");
  90:         fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
  91:         fprintf(file,", id = %d", ntohs(hp->id));
  92:         fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
  93:         fprintf(file,"\theader flags: ");
  94:         if (hp->qr) {
  95:             fprintf(file," response");
  96:         } else {
  97:             fprintf(file," query");
  98:         }
  99:         if (hp->aa)
 100:             fprintf(file,", auth. answer");
 101:         if (hp->tc)
 102:             fprintf(file,", truncation");
 103:         if (hp->rd)
 104:             fprintf(file,", want recursion");
 105:         if (hp->ra)
 106:             fprintf(file,", recursion avail.");
 107:         if (hp->pr)
 108:             fprintf(file,", primary");
 109:         fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
 110:         fprintf(file,",  answers = %d", ntohs(hp->ancount));
 111:         fprintf(file,",  authority records = %d", ntohs(hp->nscount));
 112:         fprintf(file,",  additional = %d\n\n", ntohs(hp->arcount));
 113:     }
 114: 
 115:     /*
 116: 	 * Print question records.
 117: 	 */
 118:     if (n = ntohs(hp->qdcount)) {
 119:         fprintf(file,"    QUESTIONS:\n");
 120:         while (--n >= 0) {
 121:             fprintf(file,"\t");
 122:             cp = Print_cdname(cp, msg, eom, file);
 123:             if (cp == NULL)
 124:                 return;
 125:             type = _getshort(cp);
 126:             cp += sizeof(u_short);
 127:             class = _getshort(cp);
 128:             cp += sizeof(u_short);
 129:             fprintf(file,", type = %s", p_type(type));
 130:             fprintf(file,", class = %s\n", p_class(class));
 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, INDENT);
 140:             cp = Print_rr(cp, msg, eom, 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,"    AUTHORITY RECORDS:\n");
 150:         while (--n >= 0) {
 151:             fprintf(file, INDENT);
 152:             cp = Print_rr(cp, msg, eom, 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, INDENT);
 164:             cp = Print_rr(cp, msg, eom, file);
 165:             if (cp == NULL)
 166:                 return;
 167:         }
 168:     }
 169:     fprintf(file,"\n------------\n");
 170: }
 171: 
 172: 
 173: char *
 174: Print_cdname_sub(cp, msg, eom, file, format)
 175:     char *cp, *msg, *eom;
 176:     FILE *file;
 177:     int format;
 178: {
 179:     int n;
 180:     char name[MAXDNAME];
 181:     extern char *strcpy();
 182: 
 183:     if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
 184:         return (NULL);
 185:     if (name[0] == '\0') {
 186:         (void) strcpy(name, "(root)");
 187:     }
 188:     if (format) {
 189:         fprintf(file, "%-30s", name);
 190:     } else {
 191:         fputs(name, file);
 192:     }
 193:     return (cp + n);
 194: }
 195: 
 196: char *
 197: Print_cdname(cp, msg, eom, file)
 198:     char *cp, *msg, *eom;
 199:     FILE *file;
 200: {
 201:     return(Print_cdname_sub(cp, msg, eom, file, 0));
 202: }
 203: 
 204: char *
 205: Print_cdname2(cp, msg, eom, file)
 206:     char *cp, *msg, *eom;
 207:     FILE *file;
 208: {
 209:     return(Print_cdname_sub(cp, msg, eom, file, 1));
 210: }
 211: 
 212: /*
 213:  * Print resource record fields in human readable form.
 214:  */
 215: char *
 216: Print_rr(cp, msg, eom, file)
 217:     char *cp, *msg, *eom;
 218:     FILE *file;
 219: {
 220:     int type, class, dlen, n, c;
 221:     u_long rrttl, ttl;
 222:     struct in_addr inaddr;
 223:     char *cp1, *cp2;
 224:     long debug;
 225: 
 226:     if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) {
 227:         fprintf(file, "(name truncated?)\n");
 228:         return (NULL);          /* compression error */
 229:     }
 230: 
 231:     type = _getshort(cp);
 232:     cp += sizeof(u_short);
 233:     class = _getshort(cp);
 234:     cp += sizeof(u_short);
 235:     rrttl = _getlong(cp);
 236:     cp += sizeof(u_long);
 237:     dlen = _getshort(cp);
 238:     cp += sizeof(u_short);
 239: 
 240:     debug = _res.options & (RES_DEBUG|RES_DEBUG2);
 241:     if (debug) {
 242:         if (_res.options & RES_DEBUG2) {
 243:         fprintf(file,"\n\ttype = %s, class = %s, dlen = %d",
 244:                 p_type(type), p_class(class), dlen);
 245:         }
 246:         if (type == T_SOA) {
 247:         fprintf(file,"\n\tttl = %ld (%s)", rrttl, p_time(rrttl));
 248:         }
 249:         (void) putc('\n', file);
 250:     }
 251: 
 252:     cp1 = cp;
 253: 
 254:     /*
 255: 	 * Print type specific data, if appropriate
 256: 	 */
 257:     switch (type) {
 258:     case T_A:
 259:         switch (class) {
 260:         case C_IN:
 261:         case C_HS:
 262:             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
 263:             if (dlen == 4) {
 264:                 fprintf(file,"\tinternet address = %s\n",
 265:                     inet_ntoa(inaddr));
 266:                 cp += dlen;
 267:             } else if (dlen == 7) {
 268:                 fprintf(file,"\tinternet address = %s",
 269:                     inet_ntoa(inaddr));
 270:                 fprintf(file,", protocol = %d", cp[4]);
 271:                 fprintf(file,", port = %d\n",
 272:                     (cp[5] << 8) + cp[6]);
 273:                 cp += dlen;
 274:             }
 275:             break;
 276:         default:
 277:             fprintf(file,"\taddress, class = %d, len = %d\n",
 278:                 class, dlen);
 279:             cp += dlen;
 280:         }
 281:         break;
 282: 
 283:     case T_CNAME:
 284:         fprintf(file,"\tcanonical name = ");
 285:         goto doname;
 286: 
 287:     case T_MG:
 288:         fprintf(file,"\tmail group member = ");
 289:         goto doname;
 290:     case T_MB:
 291:         fprintf(file,"\tmail box = ");
 292:         goto doname;
 293:     case T_MR:
 294:         fprintf(file,"\tmailbox rename = ");
 295:         goto doname;
 296:     case T_MX:
 297:         fprintf(file,"\tpreference = %u",_getshort(cp));
 298:         cp += sizeof(u_short);
 299:         fprintf(file,", mail exchanger = ");
 300:         goto doname;
 301:     case T_NS:
 302:         fprintf(file,"\tnameserver = ");
 303:         goto doname;
 304:     case T_PTR:
 305:         fprintf(file,"\tname = ");
 306: doname:
 307:         cp = Print_cdname(cp, msg, eom, file);
 308:         (void) putc('\n', file);
 309:         break;
 310: 
 311:     case T_HINFO:
 312:         if (n = *cp++) {
 313:             fprintf(file,"\tCPU = %.*s", n, cp);
 314:             cp += n;
 315:         }
 316:         if (n = *cp++) {
 317:             fprintf(file,"\tOS = %.*s\n", n, cp);
 318:             cp += n;
 319:         }
 320:         break;
 321: 
 322:     case T_SOA:
 323:         if (!debug)
 324:             (void) putc('\n', file);
 325:         fprintf(file,"\torigin = ");
 326:         cp = Print_cdname(cp, msg, eom, file);
 327:         fprintf(file,"\n\tmail addr = ");
 328:         cp = Print_cdname(cp, msg, eom, file);
 329:         fprintf(file,"\n\tserial = %ld", _getlong(cp));
 330:         cp += sizeof(u_long);
 331:         ttl = _getlong(cp);
 332:         fprintf(file,"\n\trefresh = %ld (%s)", ttl, p_time(ttl));
 333:         cp += sizeof(u_long);
 334:         ttl = _getlong(cp);
 335:         fprintf(file,"\n\tretry   = %ld (%s)", ttl, p_time(ttl));
 336:         cp += sizeof(u_long);
 337:         ttl = _getlong(cp);
 338:         fprintf(file,"\n\texpire  = %ld (%s)", ttl, p_time(ttl));
 339:         cp += sizeof(u_long);
 340:         ttl = _getlong(cp);
 341:         fprintf(file,"\n\tminimum ttl = %ld (%s)\n", ttl, p_time(ttl));
 342:         cp += sizeof(u_long);
 343:         break;
 344: 
 345:     case T_MINFO:
 346:         if (!debug)
 347:             (void) putc('\n', file);
 348:         fprintf(file,"\trequests = ");
 349:         cp = Print_cdname(cp, msg, eom, file);
 350:         fprintf(file,"\n\terrors = ");
 351:         cp = Print_cdname(cp, msg, eom, file);
 352:         (void) putc('\n', file);
 353:         break;
 354: 
 355:     case T_TXT:
 356:         (void) fputs("\ttext = \"", file);
 357:         cp2 = cp1 + dlen;
 358:         while (cp < cp2) {
 359:             if (n = (unsigned char) *cp++) {
 360:                 for (c = n; c > 0 && cp < cp2; c--)
 361:                     if (*cp == '\n') {
 362:                         (void) putc('\\', file);
 363:                         (void) putc(*cp++, file);
 364:                     } else
 365:                         (void) putc(*cp++, file);
 366:             }
 367:         }
 368:         (void) fputs("\"\n", file);
 369:         break;
 370: 
 371:     case T_UINFO:
 372:         fprintf(file,"\tuser info = %s\n", cp);
 373:         cp += dlen;
 374:         break;
 375: 
 376:     case T_UID:
 377:     case T_GID:
 378:         if (dlen == 4) {
 379:             fprintf(file,"\t%cid = %ld\n",type == T_UID ? 'u' : 'g',
 380:                 _getlong(cp));
 381:             cp += sizeof(int);
 382:         } else {
 383:             fprintf(file,"\t%cid of length %d?\n",
 384:                 type == T_UID ? 'u' : 'g', dlen);
 385:             cp += dlen;
 386:         }
 387:         break;
 388: 
 389:     case T_WKS: {
 390:         struct protoent *protoPtr;
 391: 
 392:         if (dlen < sizeof(u_long) + 1)
 393:             break;
 394:         if (!debug)
 395:             (void) putc('\n', file);
 396:         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
 397:         cp += sizeof(u_long);
 398:         if ((protoPtr = getprotobynumber(*cp)) != NULL) {
 399:             fprintf(file,"\tinet address = %s, protocol = %s\n\t",
 400:             inet_ntoa(inaddr), protoPtr->p_name);
 401:         } else {
 402:             fprintf(file,"\tinet address = %s, protocol = %d\n\t",
 403:             inet_ntoa(inaddr), *cp);
 404:         }
 405:         cp++;
 406:         n = 0;
 407:         while (cp < cp1 + dlen) {
 408:             c = *cp++;
 409:             do {
 410:                 struct servent *s;
 411: 
 412:                 if (c & 0200) {
 413:                     s = getservbyport(n, (char *)NULL);
 414:                     if (s != NULL) {
 415:                         fprintf(file,"  %s", s->s_name);
 416:                     } else {
 417:                         fprintf(file," #%d", n);
 418:                     }
 419:                 }
 420:                 c <<= 1;
 421:             } while (++n & 07);
 422:         }
 423:         putc('\n',file);
 424:         }
 425:         break;
 426: 
 427:     case T_NULL:
 428:         fprintf(file, "\tNULL (dlen %d)\n", dlen);
 429:         cp += dlen;
 430:         break;
 431: 
 432:     default:
 433:         fprintf(file,"\t??? unknown type %d ???\n", type);
 434:         cp += dlen;
 435:     }
 436:     if (_res.options & RES_DEBUG && type != T_SOA) {
 437:         fprintf(file,"\tttl = %ld (%s)\n", rrttl, p_time(rrttl));
 438:     }
 439:     if (cp != cp1 + dlen) {
 440:         fprintf(file,
 441:             "\n*** Error: record size incorrect (%d != %d)\n\n",
 442:             cp - cp1, dlen);
 443:         cp = NULL;
 444:     }
 445:     return (cp);
 446: }

Defined functions

Fprint_query defined in line 72; used 1 times
  • in line 69
Print_cdname_sub defined in line 173; used 2 times

Defined variables

sccsid defined in line 21; never used

Defined macros

INDENT defined in line 56; used 3 times
Last modified: 1993-04-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4040
Valid CSS Valid XHTML 1.0 Strict