Annotation of 43BSDReno/usr.sbin/named/tools/nslookup/getinfo.c, revision 1.1.1.1

1.1       root        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: #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:     unsigned 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, (char *)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:            NULL,  0, 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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.