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[] = "@(#)getinfo.c	5.22 (Berkeley) 6/1/90";
  22: #endif
  23: 
  24: /*
  25:  *******************************************************************************
  26:  *
  27:  *  getinfo.c --
  28:  *
  29:  *	Routines to create requests to name servers
  30:  *	and interpret the answers.
  31:  *
  32:  *	Adapted from 4.3BSD BIND gethostnamadr.c
  33:  *
  34:  *******************************************************************************
  35:  */
  36: 
  37: #include <sys/types.h>
  38: #include <sys/socket.h>
  39: #include <netinet/in.h>
  40: #include <stdio.h>
  41: #include <ctype.h>
  42: #include <arpa/nameser.h>
  43: #include <arpa/inet.h>
  44: #include <resolv.h>
  45: #include "res.h"
  46: 
  47: extern char *_res_resultcodes[];
  48: extern char *res_skip();
  49: 
  50: #define MAXALIASES  35
  51: #define MAXADDRS    35
  52: #define MAXDOMAINS  35
  53: #define MAXSERVERS  10
  54: 
  55: static char *addr_list[MAXADDRS + 1];
  56: 
  57: static char *host_aliases[MAXALIASES];
  58: static int   host_aliases_len[MAXALIASES];
  59: static char  hostbuf[BUFSIZ+1];
  60: 
  61: typedef struct {
  62:     char *name;
  63:     char *domain[MAXDOMAINS];
  64:     int   numDomains;
  65:     char *address[MAXADDRS];
  66:     int   numAddresses;
  67: } ServerTable;
  68: 
  69: ServerTable server[MAXSERVERS];
  70: 
  71: typedef union {
  72:     HEADER qb1;
  73:     char qb2[PACKETSZ];
  74: } querybuf;
  75: 
  76: typedef union {
  77:     long al;
  78:     char ac;
  79: } align;
  80: 
  81: #define GetShort(cp)    _getshort(cp); cp += sizeof(unsigned short);
  82: 
  83: 
  84: /*
  85:  *******************************************************************************
  86:  *
  87:  *  GetAnswer --
  88:  *
  89:  *	Interprets an answer packet and retrieves the following
  90:  *	information:
  91:  *
  92:  *  Results:
  93:  *      SUCCESS         the info was retrieved.
  94:  *      NO_INFO         the packet did not contain an answer.
  95:  *	NONAUTH		non-authoritative information was found.
  96:  *      ERROR           the answer was malformed.
  97:  *      Other errors    returned in the packet header.
  98:  *
  99:  *******************************************************************************
 100:  */
 101: 
 102: static int
 103: GetAnswer(nsAddrPtr, queryType, msg, msglen, iquery, hostPtr, isServer)
 104:     struct in_addr  *nsAddrPtr;
 105:     char        *msg;
 106:     int         queryType;
 107:     int         msglen;
 108:     Boolean     iquery;
 109:     register HostInfo   *hostPtr;
 110:     Boolean     isServer;
 111: {
 112:     register HEADER *headerPtr;
 113:     register char   *cp;
 114:     querybuf        answer;
 115:     char        *eom, *bp, **aliasPtr;
 116:     char        **addrPtr;
 117:     char        *namePtr;
 118:     char        *dnamePtr;
 119:     int         type, class;
 120:     int         qdcount, ancount, arcount, nscount, buflen;
 121:     int         origClass;
 122:     int         numAliases = 0;
 123:     int         numAddresses = 0;
 124:     int         n, i, j;
 125:     int         len;
 126:     int         dlen;
 127:     int         status;
 128:     int         numServers;
 129:     Boolean     haveAnswer;
 130:     Boolean     printedAnswers = FALSE;
 131: 
 132: 
 133:     /*
 134:      *  If the hostPtr was used before, free up the calloc'd areas.
 135:      */
 136:     FreeHostInfoPtr(hostPtr);
 137: 
 138:     status = SendRequest(nsAddrPtr, msg, msglen, (char *) &answer,
 139:                 sizeof(answer), &n);
 140: 
 141:     if (status != SUCCESS) {
 142:         if (_res.options & RES_DEBUG2)
 143:             printf("SendRequest failed\n");
 144:         return (status);
 145:     }
 146:     eom = (char *) &answer + n;
 147: 
 148:     headerPtr = (HEADER *) &answer;
 149: 
 150:     if (headerPtr->rcode != NOERROR) {
 151:     return (headerPtr->rcode);
 152:     }
 153: 
 154:     qdcount = ntohs(headerPtr->qdcount);
 155:     ancount = ntohs(headerPtr->ancount);
 156:     arcount = ntohs(headerPtr->arcount);
 157:     nscount = ntohs(headerPtr->nscount);
 158: 
 159:     /*
 160:      * If there are no answer, n.s. or additional records
 161:      * then return with an error.
 162:      */
 163:     if (ancount == 0 && nscount == 0 && arcount == 0) {
 164:     return (NO_INFO);
 165:     }
 166: 
 167: 
 168:     bp     = hostbuf;
 169:     buflen = sizeof(hostbuf);
 170:     cp     = (char *) &answer + sizeof(HEADER);
 171: 
 172:     /* Skip over question section. */
 173:     while (qdcount-- > 0) {
 174:     cp += dn_skipname(cp, eom) + QFIXEDSZ;
 175:     }
 176: 
 177:     aliasPtr    = host_aliases;
 178:     addrPtr = addr_list;
 179:     haveAnswer  = FALSE;
 180: 
 181:     /*
 182:      * Scan through the answer resource records.
 183:      * Answers for address query types are saved.
 184:      * Other query type answers are just printed.
 185:      */
 186:     if (ancount != 0) {
 187:     if (!isServer && !headerPtr->aa) {
 188:         printf("Non-authoritative answer:\n");
 189:     }
 190: 
 191:     if (queryType != T_A && !(iquery && queryType == T_PTR)) {
 192:         while (--ancount >= 0 && cp < eom) {
 193:         if ((cp = Print_rr(cp, (char *)&answer, eom, stdout)) == NULL) {
 194:             return(ERROR);
 195:         }
 196:         }
 197:         printedAnswers = TRUE;
 198:     } else {
 199:         while (--ancount >= 0 && cp < eom) {
 200:         if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0) {
 201:             return(ERROR);
 202:         }
 203:         cp   += n;
 204:         type  = GetShort(cp);
 205:         class = GetShort(cp);
 206:         cp   += sizeof(u_long); /* skip TTL */
 207:         dlen  = GetShort(cp);
 208:         if (type == T_CNAME) {
 209:             /*
 210: 		     * Found an alias.
 211: 		     */
 212:             cp += dlen;
 213:             if (aliasPtr >= &host_aliases[MAXALIASES-1]) {
 214:             continue;
 215:             }
 216:             *aliasPtr++ = bp;
 217:             n = strlen(bp) + 1;
 218:             host_aliases_len[numAliases] = n;
 219:             numAliases++;
 220:             bp += n;
 221:             buflen -= n;
 222:             continue;
 223:         } else if (type == T_PTR) {
 224:             /*
 225: 		     *  Found a "pointer" to the real name.
 226: 		     */
 227:             if((n=dn_expand((char *)&answer, eom, cp, bp,buflen)) < 0) {
 228:             cp += n;
 229:             continue;
 230:             }
 231:             cp += n;
 232:             len = strlen(bp) + 1;
 233:             hostPtr->name = Calloc(1, len);
 234:             bcopy(bp, hostPtr->name, len);
 235:             haveAnswer = TRUE;
 236:             break;
 237:         } else if (type != T_A) {
 238:             cp += dlen;
 239:             continue;
 240:         }
 241:         if (haveAnswer) {
 242:             /*
 243: 		     * If we've already got 1 address, we aren't interested
 244: 		     * in addresses with a different length or class.
 245: 		     */
 246:             if (dlen != hostPtr->addrLen) {
 247:             cp += dlen;
 248:             continue;
 249:             }
 250:             if (class != origClass) {
 251:             cp += dlen;
 252:             continue;
 253:             }
 254:         } else {
 255:             /*
 256: 		     * First address: record its length and class so we
 257: 		     * only save additonal ones with the same attributes.
 258: 		     */
 259:             hostPtr->addrLen = dlen;
 260:             origClass = class;
 261:             hostPtr->addrType = (class == C_IN) ? AF_INET : AF_UNSPEC;
 262:             len = strlen(bp) + 1;
 263:             hostPtr->name = Calloc(1, len);
 264:             bcopy(bp, hostPtr->name, len);
 265:         }
 266:         bp += (((u_long)bp) % sizeof(align));
 267: 
 268:         if (bp + dlen >= &hostbuf[sizeof(hostbuf)]) {
 269:             if (_res.options & RES_DEBUG) {
 270:             printf("Size (%d) too big\n", dlen);
 271:             }
 272:             break;
 273:         }
 274:         bcopy(cp, *addrPtr++ = bp, dlen);
 275:         bp +=dlen;
 276:         cp += dlen;
 277:         numAddresses++;
 278:         haveAnswer = TRUE;
 279:         }
 280:     }
 281:     }
 282: 
 283:     if ((queryType == T_A || queryType == T_PTR) && haveAnswer) {
 284: 
 285:     /*
 286: 	 *  Go through the alias and address lists and return them
 287: 	 *  in the hostPtr variable.
 288: 	 */
 289: 
 290:     if (numAliases > 0) {
 291:         hostPtr->aliases = (char **) Calloc(1 + numAliases, sizeof(char *));
 292:         for (i = 0; i < numAliases; i++) {
 293:         hostPtr->aliases[i] = Calloc(1, host_aliases_len[i]);
 294:         bcopy(host_aliases[i], hostPtr->aliases[i],host_aliases_len[i]);
 295:         }
 296:         hostPtr->aliases[i] = NULL;
 297:     }
 298:     if (numAddresses > 0) {
 299:         hostPtr->addrList = (char **)Calloc(1+numAddresses, sizeof(char *));
 300:         for (i = 0; i < numAddresses; i++) {
 301:         hostPtr->addrList[i] = Calloc(1, hostPtr->addrLen);
 302:         bcopy(addr_list[i], hostPtr->addrList[i], hostPtr->addrLen);
 303:         }
 304:         hostPtr->addrList[i] = NULL;
 305:     }
 306: #ifdef verbose
 307:     if (headerPtr->aa || nscount == 0) {
 308:         hostPtr->servers = NULL;
 309:         return (SUCCESS);
 310:     }
 311: #else
 312:     hostPtr->servers = NULL;
 313:     return (SUCCESS);
 314: #endif
 315:     }
 316: 
 317:     /*
 318:      * At this point, for the T_A query type, only empty answers remain.
 319:      * For other query types, additional information might be found
 320:      * in the additional resource records part.
 321:      */
 322: 
 323:     if (!headerPtr->aa && (queryType != T_A) && (nscount > 0 || arcount > 0)) {
 324:     if (printedAnswers) {
 325:         putchar('\n');
 326:     }
 327:     printf("Authoritative answers can be found from:\n");
 328:     }
 329: 
 330:     cp = res_skip((char *) &answer, 2, eom);
 331: 
 332:     numServers = 0;
 333:     if (queryType != T_A) {
 334:     /*
 335: 	 * If we don't need to save the record, just print it.
 336: 	 */
 337:     while (--nscount >= 0 && cp < eom) {
 338:         if ((cp = Print_rr(cp, (char *) &answer, eom, stdout)) == NULL) {
 339:         return(ERROR);
 340:         }
 341:     }
 342:     } else {
 343:     while (--nscount >= 0 && cp < eom) {
 344:         /*
 345: 	     *  Go through the NS records and retrieve the names of hosts
 346: 	     *  that serve the requested domain.
 347: 	     */
 348: 
 349:         if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
 350:         return(ERROR);
 351:         }
 352:         cp += n;
 353:         len = strlen(bp) + 1;
 354:         dnamePtr = Calloc(1, len);   /* domain name */
 355:         bcopy(bp, dnamePtr, len);
 356: 
 357:         type  = GetShort(cp);
 358:         class = GetShort(cp);
 359:         cp   += sizeof(u_long); /* skip TTL */
 360:         dlen  = GetShort(cp);
 361: 
 362:         if (type != T_NS) {
 363:         cp += dlen;
 364:         } else {
 365:         Boolean found;
 366: 
 367:         if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0){
 368:             return(ERROR);
 369:         }
 370:         cp += n;
 371:         len = strlen(bp) + 1;
 372:         namePtr = Calloc(1, len); /* server host name */
 373:         bcopy(bp, namePtr, len);
 374: 
 375:         /*
 376: 		 * Store the information keyed by the server host name.
 377: 		 */
 378:         found = FALSE;
 379:         for (j = 0; j < numServers; j++) {
 380:             if (strcmp(namePtr, server[j].name) == 0) {
 381:             found = TRUE;
 382:             free(namePtr);
 383:             break;
 384:             }
 385:         }
 386:         if (found) {
 387:             server[j].numDomains++;
 388:             if (server[j].numDomains <= MAXDOMAINS) {
 389:             server[j].domain[server[j].numDomains-1] = dnamePtr;
 390:             }
 391:         } else {
 392:             if (numServers >= MAXSERVERS) {
 393:             break;
 394:             }
 395:             server[numServers].name = namePtr;
 396:             server[numServers].domain[0] = dnamePtr;
 397:             server[numServers].numDomains = 1;
 398:             server[numServers].numAddresses = 0;
 399:             numServers++;
 400:         }
 401:         }
 402:     }
 403:     }
 404: 
 405:     /*
 406:      * Additional resource records contain addresses of servers.
 407:      */
 408:     cp = res_skip((char *) &answer, 3, eom);
 409: 
 410:     if (queryType != T_A) {
 411:     /*
 412: 	 * If we don't need to save the record, just print it.
 413: 	 */
 414:     while (--arcount >= 0 && cp < eom) {
 415:         if ((cp = Print_rr(cp, (char *) &answer, eom, stdout)) == NULL) {
 416:         return(ERROR);
 417:         }
 418:     }
 419:     } else {
 420:     while (--arcount >= 0 && cp < eom) {
 421:         if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
 422:         break;
 423:         }
 424:         cp   += n;
 425:         type  = GetShort(cp);
 426:         class = GetShort(cp);
 427:         cp   += sizeof(u_long); /* skip TTL */
 428:         dlen  = GetShort(cp);
 429: 
 430:         if (type != T_A)  {
 431:         cp += dlen;
 432:         continue;
 433:         } else {
 434:         for (j = 0; j < numServers; j++) {
 435:             if (strcmp(bp, server[j].name) == 0) {
 436:             server[j].numAddresses++;
 437:             if (server[j].numAddresses <= MAXADDRS) {
 438:                 server[j].address[server[j].numAddresses-1] =
 439:                                     Calloc(1,dlen);
 440:                 bcopy(cp,
 441:                   server[j].address[server[j].numAddresses-1],dlen);
 442:                 break;
 443:             }
 444:             }
 445:         }
 446:         cp += dlen;
 447:         }
 448:     }
 449:     }
 450: 
 451:     /*
 452:      * If we are returning name server info, transfer it to the hostPtr.
 453:      */
 454:     if (numServers > 0) {
 455:     hostPtr->servers = (ServerInfo **)
 456:                 Calloc(numServers+1, sizeof(ServerInfo *));
 457: 
 458:     for (i = 0; i < numServers; i++) {
 459:         hostPtr->servers[i] = (ServerInfo *) Calloc(1, sizeof(ServerInfo));
 460:         hostPtr->servers[i]->name = server[i].name;
 461: 
 462: 
 463:         hostPtr->servers[i]->domains = (char **)
 464:                 Calloc(server[i].numDomains+1,sizeof(char *));
 465:         for (j = 0; j < server[i].numDomains; j++) {
 466:         hostPtr->servers[i]->domains[j] = server[i].domain[j];
 467:         }
 468:         hostPtr->servers[i]->domains[j] = NULL;
 469: 
 470: 
 471:         hostPtr->servers[i]->addrList = (char **)
 472:                 Calloc(server[i].numAddresses+1,sizeof(char *));
 473:         for (j = 0; j < server[i].numAddresses; j++) {
 474:         hostPtr->servers[i]->addrList[j] = server[i].address[j];
 475:         }
 476:         hostPtr->servers[i]->addrList[j] = NULL;
 477: 
 478:     }
 479:     hostPtr->servers[i] = NULL;
 480:     }
 481: 
 482:     switch (queryType) {
 483:     case T_A:
 484:         return NONAUTH;
 485:     case T_PTR:
 486:         if (iquery)
 487:             return NO_INFO;
 488:         /* fall through */
 489:     default:
 490:         return SUCCESS;
 491:     }
 492: }
 493: 
 494: /*
 495: *******************************************************************************
 496: *
 497: *  GetHostInfo --
 498: *
 499: *	Retrieves host name, address and alias information
 500: *	for a domain.
 501: *
 502: *	Algorithm from res_search().
 503: *
 504: *  Results:
 505: *	ERROR		- res_mkquery failed.
 506: *	+ return values from GetAnswer()
 507: *
 508: *******************************************************************************
 509: */
 510: 
 511: int
 512: GetHostInfoByName(nsAddrPtr, queryClass, queryType, name, hostPtr, isServer)
 513:     struct in_addr  *nsAddrPtr;
 514:     int         queryClass;
 515:     int         queryType;
 516:     char        *name;
 517:     HostInfo        *hostPtr;
 518:     Boolean     isServer;
 519: {
 520:     int         n;
 521:     register int    result;
 522:     register char   *cp, **domain;
 523:     extern char     *hostalias();
 524:     Boolean     got_nodata = FALSE;
 525:     u_long  ina;
 526: 
 527:     /* Catch explicit addresses */
 528:     if ((queryType == T_A) && IsAddr(name, &ina)) {
 529:     hostPtr->name = Calloc(strlen(name)+3, 1);
 530:     (void)sprintf(hostPtr->name,"[%s]",name);
 531:     hostPtr->aliases = NULL;
 532:     hostPtr->servers = NULL;
 533:     hostPtr->addrType = AF_INET;
 534:     hostPtr->addrLen = sizeof(struct in_addr);
 535:     hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
 536:     hostPtr->addrList[0] = Calloc(sizeof(long), sizeof(char));
 537:     bcopy((char *)&ina, hostPtr->addrList[0], sizeof(ina));
 538:     hostPtr->addrList[1] = NULL;
 539:     return(SUCCESS);
 540:     }
 541: 
 542:     result = NXDOMAIN;
 543:     for (cp = name, n = 0; *cp; cp++)
 544:         if (*cp == '.')
 545:             n++;
 546:     if (n == 0 && (cp = hostalias(name))) {
 547:         printf("Aliased to \"%s\"\n\n", cp);
 548:         return (GetHostDomain(nsAddrPtr, queryClass, queryType,
 549:             cp, (char *)NULL, hostPtr, isServer));
 550:     }
 551:     /*
 552:      * We do at least one level of search if
 553:      *	- there is no dot and RES_DEFNAME is set, or
 554:      *	- there is at least one dot, there is no trailing dot,
 555:      *	  and RES_DNSRCH is set.
 556:      */
 557:     if ((n == 0 && _res.options & RES_DEFNAMES) ||
 558:        (n != 0 && *--cp != '.' && _res.options & RES_DNSRCH))
 559:      for (domain = _res.dnsrch; *domain; domain++) {
 560:         result = GetHostDomain(nsAddrPtr, queryClass, queryType,
 561:             name, *domain, hostPtr, isServer);
 562:         /*
 563: 	     * If no server present, give up.
 564: 	     * If name isn't found in this domain,
 565: 	     * keep trying higher domains in the search list
 566: 	     * (if that's enabled).
 567: 	     * On a NO_INFO error, keep trying, otherwise
 568: 	     * a wildcard entry of another type could keep us
 569: 	     * from finding this entry higher in the domain.
 570: 	     * If we get some other error (negative answer or
 571: 	     * server failure), then stop searching up,
 572: 	     * but try the input name below in case it's fully-qualified.
 573: 	     */
 574:         if (result == SUCCESS || result == NO_RESPONSE)
 575:             return result;
 576:         if (result == NO_INFO)
 577:             got_nodata++;
 578:         if ((result != NXDOMAIN && result != NO_INFO) ||
 579:         (_res.options & RES_DNSRCH) == 0)
 580:             break;
 581:     }
 582:     /*
 583:      * If the search/default failed, try the name as fully-qualified,
 584:      * but only if it contained at least one dot (even trailing).
 585:      * This is purely a heuristic; we assume that any reasonable query
 586:      * about a top-level domain (for servers, SOA, etc) will not use
 587:      * res_search.
 588:      */
 589:     if (n && (result = GetHostDomain(nsAddrPtr, queryClass, queryType,
 590:             name, (char *)NULL, hostPtr, isServer)) == SUCCESS)
 591:         return result;
 592:     if (got_nodata)
 593:     result = NO_INFO;
 594:     return (result);
 595: }
 596: 
 597: /*
 598:  * Perform a query on the concatenation of name and domain,
 599:  * removing a trailing dot from name if domain is NULL.
 600:  */
 601: GetHostDomain(nsAddrPtr, queryClass, queryType, name, domain, hostPtr, isServer)
 602:     struct in_addr  *nsAddrPtr;
 603:     int         queryClass;
 604:     int         queryType;
 605:     char        *name, *domain;
 606:     HostInfo        *hostPtr;
 607:     Boolean     isServer;
 608: {
 609:     querybuf buf;
 610:     char nbuf[2*MAXDNAME+2];
 611:     char *longname = nbuf;
 612:     int n;
 613: 
 614:     if (domain == NULL) {
 615:         /*
 616: 	     * Check for trailing '.';
 617: 	     * copy without '.' if present.
 618: 	     */
 619:         n = strlen(name) - 1;
 620:         if (name[n] == '.' && n < sizeof(nbuf) - 1) {
 621:             bcopy(name, nbuf, n);
 622:             nbuf[n] = '\0';
 623:         } else
 624:             longname = name;
 625:     } else {
 626:         (void)sprintf(nbuf, "%.*s.%.*s",
 627:             MAXDNAME, name, MAXDNAME, domain);
 628:         longname = nbuf;
 629:     }
 630:     n = res_mkquery(QUERY, longname, queryClass, queryType,
 631:             (char *)0, 0, (struct rrec *)0, (char *) &buf, sizeof(buf));
 632:     if (n < 0) {
 633:     if (_res.options & RES_DEBUG) {
 634:         printf("Res_mkquery failed\n");
 635:     }
 636:     return (ERROR);
 637:     }
 638: 
 639:     n = GetAnswer(nsAddrPtr, queryType, (char *)&buf, n, 0, hostPtr, isServer);
 640: 
 641:     /*
 642:      * GetAnswer didn't find a name, so set it to the specified one.
 643:      */
 644:     if (n == NONAUTH) {
 645:     if (hostPtr->name == NULL) {
 646:         int len = strlen(longname) + 1;
 647:         hostPtr->name = Calloc(len, sizeof(char));
 648:         bcopy(longname, hostPtr->name, len);
 649:     }
 650:     }
 651:     return(n);
 652: }
 653: 
 654: 
 655: /*
 656: *******************************************************************************
 657: *
 658: *  GetHostInfoByAddr --
 659: *
 660: *	Performs an inverse query to find the host name
 661: *	that corresponds to the given address.
 662: *
 663: *  Results:
 664: *	ERROR		- res_mkquery failed.
 665: *	+ return values from GetAnswer()
 666: *
 667: *******************************************************************************
 668: */
 669: 
 670: int
 671: GetHostInfoByAddr(nsAddrPtr, address, hostPtr)
 672:     struct in_addr  *nsAddrPtr;
 673:     struct in_addr  *address;
 674:     HostInfo        *hostPtr;
 675: {
 676:     int     n;
 677:     querybuf    buf;
 678:     char    qbuf[MAXDNAME];
 679:     char    *p = (char *) &address->s_addr;
 680: 
 681:     (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
 682:         ((unsigned)p[3] & 0xff),
 683:         ((unsigned)p[2] & 0xff),
 684:         ((unsigned)p[1] & 0xff),
 685:         ((unsigned)p[0] & 0xff));
 686:     n = res_mkquery(QUERY, qbuf, C_IN, T_PTR,
 687:         (char *)NULL,  0, (struct rrec *)NULL, (char *) &buf, sizeof(buf));
 688:     if (n < 0) {
 689:     if (_res.options & RES_DEBUG) {
 690:         printf("res_mkquery() failed\n");
 691:     }
 692:     return (ERROR);
 693:     }
 694:     n = GetAnswer(nsAddrPtr, T_PTR, (char *) &buf, n, 1, hostPtr, 1);
 695:     if (n == SUCCESS) {
 696:     hostPtr->addrType = AF_INET;
 697:     hostPtr->addrLen = 4;
 698:     hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
 699:     hostPtr->addrList[0] = Calloc(sizeof(long), sizeof(char));
 700:     bcopy((char *)p, hostPtr->addrList[0], sizeof(struct in_addr));
 701:     hostPtr->addrList[1] = NULL;
 702:     }
 703:     return n;
 704: }
 705: 
 706: /*
 707: *******************************************************************************
 708: *
 709: *  FreeHostInfoPtr --
 710: *
 711: *	Deallocates all the calloc'd areas for a HostInfo variable.
 712: *
 713: *******************************************************************************
 714: */
 715: 
 716: void
 717: FreeHostInfoPtr(hostPtr)
 718:     register HostInfo *hostPtr;
 719: {
 720:     int i, j;
 721: 
 722:     if (hostPtr->name != NULL) {
 723:     free(hostPtr->name);
 724:     hostPtr->name = NULL;
 725:     }
 726: 
 727:     if (hostPtr->aliases != NULL) {
 728:     i = 0;
 729:     while (hostPtr->aliases[i] != NULL) {
 730:         free(hostPtr->aliases[i]);
 731:         i++;
 732:     }
 733:     free((char *)hostPtr->aliases);
 734:     hostPtr->aliases = NULL;
 735:     }
 736: 
 737:     if (hostPtr->addrList != NULL) {
 738:     i = 0;
 739:     while (hostPtr->addrList[i] != NULL) {
 740:         free(hostPtr->addrList[i]);
 741:         i++;
 742:     }
 743:     free((char *)hostPtr->addrList);
 744:     hostPtr->addrList = NULL;
 745:     }
 746: 
 747:     if (hostPtr->servers != NULL) {
 748:     i = 0;
 749:     while (hostPtr->servers[i] != NULL) {
 750: 
 751:         if (hostPtr->servers[i]->name != NULL) {
 752:         free(hostPtr->servers[i]->name);
 753:         }
 754: 
 755:         if (hostPtr->servers[i]->domains != NULL) {
 756:         j = 0;
 757:         while (hostPtr->servers[i]->domains[j] != NULL) {
 758:             free(hostPtr->servers[i]->domains[j]);
 759:             j++;
 760:         }
 761:         free((char *)hostPtr->servers[i]->domains);
 762:         }
 763: 
 764:         if (hostPtr->servers[i]->addrList != NULL) {
 765:         j = 0;
 766:         while (hostPtr->servers[i]->addrList[j] != NULL) {
 767:             free(hostPtr->servers[i]->addrList[j]);
 768:             j++;
 769:         }
 770:         free((char *)hostPtr->servers[i]->addrList);
 771:         }
 772:         free((char *)hostPtr->servers[i]);
 773:         i++;
 774:     }
 775:     free((char *)hostPtr->servers);
 776:     hostPtr->servers = NULL;
 777:     }
 778: }

Defined functions

GetAnswer defined in line 102; used 2 times
GetHostDomain defined in line 601; used 3 times

Defined variables

addr_list defined in line 55; used 2 times
host_aliases defined in line 57; used 3 times
host_aliases_len defined in line 58; used 3 times
hostbuf defined in line 59; used 4 times
sccsid defined in line 21; never used

Defined macros

GetShort defined in line 81; used 9 times
MAXADDRS defined in line 51; used 3 times
MAXALIASES defined in line 50; used 3 times
MAXDOMAINS defined in line 52; used 2 times
MAXSERVERS defined in line 53; used 2 times
Last modified: 1993-04-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4669
Valid CSS Valid XHTML 1.0 Strict