|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.