home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / TOOLS / NSLOOKUP / getinfo.c < prev    next >
Text File  |  1994-09-23  |  20KB  |  785 lines

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