Annotation of 43BSDReno/usr.sbin/named/tools/nslookup/getinfo.c, revision 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.