# 2.11BSD#431 - /usr/src/usr.sbin/named/tools/nslookup/getinfo.c

##### Functions

    FreeHostInfoPtr   X
    GetHostDomain     X
    GetHostInfoByAddr X
    GetHostInfoByName X

##### Macros

    GetShort          X
    MAXADDRS          X
    MAXALIASES        X
    MAXDOMAINS        X
    MAXSERVERS        X

       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

FreeHostInfoPtr defined in line 716; used 3 times

- in line 136
- in /usr/src/usr.sbin/named/tools/nslookup/main.c line 516
- in /usr/src/usr.sbin/named/tools/nslookup/res.h line 137

GetAnswer defined in line 102; used 2 times

- in line 639, 694

GetHostDomain defined in line 601; used 3 times

- in line 548, 560, 589

GetHostInfoByAddr defined in line 670; used 3 times

- in /usr/src/usr.sbin/named/tools/nslookup/main.c line 245, 502, 580

GetHostInfoByName defined in line 511; used 5 times

- in /usr/src/usr.sbin/named/tools/nslookup/main.c line 334, 344, 506, 585, 738

#### Defined variables

addr_list defined in line 55; used 2 times

- in line 178, 302

host_aliases defined in line 57; used 3 times

- in line 177, 213, 294

host_aliases_len defined in line 58; used 3 times

- in line 218, 293-294(2)

hostbuf defined in line 59; used 4 times

- in line 168-169(2), 268(2)

sccsid defined in line 21; never used

#### Defined macros

GetShort defined in line 81; used 9 times

- in line 204-207(3), 357-360(3), 425-428(3)

MAXADDRS defined in line 51; used 3 times

- in line 55, 65, 437

MAXALIASES defined in line 50; used 3 times

- in line 57-58(2), 213

MAXDOMAINS defined in line 52; used 2 times

- in line 63, 388

MAXSERVERS defined in line 53; used 2 times

- in line 69, 392

Last modified: 1993-04-26 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2387 |