home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / RES / NAMED / gethostnamadr.c next >
Text File  |  1994-09-23  |  9KB  |  428 lines

  1. /*
  2.  * Copyright (c) 1985, 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #if defined(LIBC_SCCS) && !defined(lint)
  19. static char sccsid[] = "@(#)gethostnamadr.c    6.39 (Berkeley) 1/4/90";
  20. #endif /* LIBC_SCCS and not lint */
  21.  
  22. #include <sys/param.h>
  23. #ifdef OSK
  24. #include <types.h>
  25. #include <socket.h>
  26. #include <in.h>
  27. #else
  28. #include <sys/socket.h>
  29. #include <netinet/in.h>
  30. #endif
  31. #include <ctype.h>
  32. #include <netdb.h>
  33. #include <stdio.h>
  34. #include <errno.h>
  35. #ifdef OSK
  36. #include <inet.h>
  37. #include <nameser.h>
  38. #else
  39. #include <arpa/inet.h>
  40. #include <arpa/nameser.h>
  41. #endif
  42. #include <resolv.h>
  43.  
  44. #define    MAXALIASES    35
  45. #define    MAXADDRS    35
  46.  
  47. static char *h_addr_ptrs[MAXADDRS + 1];
  48.  
  49. static struct hostent host;
  50. static char *host_aliases[MAXALIASES];
  51. static char hostbuf[BUFSIZ+1];
  52. static struct in_addr host_addr;
  53. static char HOSTDB[] = "/etc/hosts";
  54. static FILE *hostf = NULL;
  55. static char hostaddr[MAXADDRS];
  56. static char *host_addrs[2];
  57. static int stayopen = 0;
  58. char *strpbrk();
  59.  
  60. #if PACKETSZ > 1024
  61. #define    MAXPACKET    PACKETSZ
  62. #else
  63. #define    MAXPACKET    1024
  64. #endif
  65.  
  66. typedef union {
  67.     HEADER hdr;
  68.     u_char buf[MAXPACKET];
  69. } querybuf;
  70.  
  71. typedef union {
  72.     long al;
  73.     char ac;
  74. } align;
  75.  
  76.  
  77. int h_errno;
  78. extern errno;
  79.  
  80. static struct hostent *
  81. getanswer(answer, anslen, iquery)
  82.     querybuf *answer;
  83.     int anslen;
  84.     int iquery;
  85. {
  86.     register HEADER *hp;
  87.     register u_char *cp;
  88.     register int n;
  89.     u_char *eom;
  90.     char *bp, **ap;
  91.     int type, class, buflen, ancount, qdcount;
  92.     int haveanswer, getclass = C_ANY;
  93.     char **hap;
  94.  
  95.     eom = answer->buf + anslen;
  96.     /*
  97.      * find first satisfactory answer
  98.      */
  99.     hp = &answer->hdr;
  100.     ancount = ntohs(hp->ancount);
  101.     qdcount = ntohs(hp->qdcount);
  102.     bp = hostbuf;
  103.     buflen = sizeof(hostbuf);
  104.     cp = answer->buf + sizeof(HEADER);
  105.     if (qdcount) {
  106.         if (iquery) {
  107.             if ((n = dn_expand((char *)answer->buf, eom,
  108.                  cp, bp, buflen)) < 0) {
  109.                 h_errno = NO_RECOVERY;
  110.                 return ((struct hostent *) NULL);
  111.             }
  112.             cp += n + QFIXEDSZ;
  113.             host.h_name = bp;
  114.             n = strlen(bp) + 1;
  115.             bp += n;
  116.             buflen -= n;
  117.         } else
  118.             cp += dn_skipname(cp, eom) + QFIXEDSZ;
  119.         while (--qdcount > 0)
  120.             cp += dn_skipname(cp, eom) + QFIXEDSZ;
  121.     } else if (iquery) {
  122.         if (hp->aa)
  123.             h_errno = HOST_NOT_FOUND;
  124.         else
  125.             h_errno = TRY_AGAIN;
  126.         return ((struct hostent *) NULL);
  127.     }
  128.     ap = host_aliases;
  129.     *ap = NULL;
  130.     host.h_aliases = host_aliases;
  131.     hap = h_addr_ptrs;
  132.     *hap = NULL;
  133. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  134.     host.h_addr_list = h_addr_ptrs;
  135. #endif
  136.     haveanswer = 0;
  137.     while (--ancount >= 0 && cp < eom) {
  138.         if ((n = dn_expand((char *)answer->buf, eom, cp, bp, buflen)) < 0)
  139.             break;
  140.         cp += n;
  141.         type = _getshort(cp);
  142.          cp += sizeof(u_short);
  143.         class = _getshort(cp);
  144.          cp += sizeof(u_short) + sizeof(u_long);
  145.         n = _getshort(cp);
  146.         cp += sizeof(u_short);
  147.         if (type == T_CNAME) {
  148.             cp += n;
  149.             if (ap >= &host_aliases[MAXALIASES-1])
  150.                 continue;
  151.             *ap++ = bp;
  152.             n = strlen(bp) + 1;
  153.             bp += n;
  154.             buflen -= n;
  155.             continue;
  156.         }
  157.         if (iquery && type == T_PTR) {
  158.             if ((n = dn_expand((char *)answer->buf, eom,
  159.                 cp, bp, buflen)) < 0) {
  160.                 cp += n;
  161.                 continue;
  162.             }
  163.             cp += n;
  164.             host.h_name = bp;
  165.             return(&host);
  166.         }
  167.         if (iquery || type != T_A)  {
  168. #ifdef DEBUG
  169.             if (_res.options & RES_DEBUG)
  170.                 printf("unexpected answer type %d, size %d\n",
  171.                     type, n);
  172. #endif
  173.             cp += n;
  174.             continue;
  175.         }
  176.         if (haveanswer) {
  177.             if (n != host.h_length) {
  178.                 cp += n;
  179.                 continue;
  180.             }
  181.             if (class != getclass) {
  182.                 cp += n;
  183.                 continue;
  184.             }
  185.         } else {
  186.             host.h_length = n;
  187.             getclass = class;
  188.             host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
  189.             if (!iquery) {
  190.                 host.h_name = bp;
  191.                 bp += strlen(bp) + 1;
  192.             }
  193.         }
  194.  
  195.         bp += sizeof(align) - ((u_long)bp % sizeof(align));
  196.  
  197.         if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
  198. #ifdef DEBUG
  199.             if (_res.options & RES_DEBUG)
  200.                 printf("size (%d) too big\n", n);
  201. #endif
  202.             break;
  203.         }
  204.         bcopy(cp, *hap++ = bp, n);
  205.         bp +=n;
  206.         cp += n;
  207.         haveanswer++;
  208.     }
  209.     if (haveanswer) {
  210.         *ap = NULL;
  211. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  212.         *hap = NULL;
  213. #else
  214.         host.h_addr = h_addr_ptrs[0];
  215. #endif
  216.         return (&host);
  217.     } else {
  218.         h_errno = TRY_AGAIN;
  219.         return ((struct hostent *) NULL);
  220.     }
  221. }
  222.  
  223. struct hostent *
  224. gethostbyname(name)
  225.     char *name;
  226. {
  227.     querybuf buf;
  228.     register char *cp;
  229.     int n;
  230.     extern struct hostent *_gethtbyname();
  231.  
  232.     /*
  233.      * disallow names consisting only of digits/dots, unless
  234.      * they end in a dot.
  235.      */
  236.     if (isdigit(name[0]))
  237.         for (cp = name;; ++cp) {
  238.             if (!*cp) {
  239.                 if (*--cp == '.')
  240.                     break;
  241.                 /*
  242.                  * All-numeric, no dot at the end.
  243.                  * Fake up a hostent as if we'd actually
  244.                  * done a lookup.  What if someone types
  245.                  * 255.255.255.255?  The test below will
  246.                  * succeed spuriously... ???
  247.                  */
  248.                 if ((host_addr.s_addr = inet_addr(name)) == -1) {
  249.                     h_errno = HOST_NOT_FOUND;
  250.                     return((struct hostent *) NULL);
  251.                 }
  252.                 host.h_name = name;
  253.                 host.h_aliases = host_aliases;
  254.                 host_aliases[0] = NULL;
  255.                 host.h_addrtype = AF_INET;
  256.                 host.h_length = sizeof(u_long);
  257.                 h_addr_ptrs[0] = (char *)&host_addr;
  258.                 h_addr_ptrs[1] = (char *)0;
  259. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  260.                 host.h_addr_list = h_addr_ptrs;
  261. #else
  262.                 host.h_addr = h_addr_ptrs[0];
  263. #endif
  264.                 return (&host);
  265.             }
  266.             if (!isdigit(*cp) && *cp != '.') 
  267.                 break;
  268.         }
  269.  
  270.     if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
  271. #ifdef DEBUG
  272.         if (_res.options & RES_DEBUG)
  273.             printf("res_search failed\n");
  274. #endif
  275.         if (errno == ECONNREFUSED)
  276.             return (_gethtbyname(name));
  277.         else
  278.             return ((struct hostent *) NULL);
  279.     }
  280.     return (getanswer(&buf, n, 0));
  281. }
  282.  
  283. struct hostent *
  284. gethostbyaddr(addr, len, type)
  285.     char *addr;
  286.     int len, type;
  287. {
  288.     int n;
  289.     querybuf buf;
  290.     register struct hostent *hp;
  291.     char qbuf[MAXDNAME];
  292.     extern struct hostent *_gethtbyaddr();
  293.     
  294.     if (type != AF_INET)
  295.         return ((struct hostent *) NULL);
  296.     (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
  297.         ((unsigned)addr[3] & 0xff),
  298.         ((unsigned)addr[2] & 0xff),
  299.         ((unsigned)addr[1] & 0xff),
  300.         ((unsigned)addr[0] & 0xff));
  301.     n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf));
  302.     if (n < 0) {
  303. #ifdef DEBUG
  304.         if (_res.options & RES_DEBUG)
  305.             printf("res_query failed\n");
  306. #endif
  307.         if (errno == ECONNREFUSED)
  308.             return (_gethtbyaddr(addr, len, type));
  309.         return ((struct hostent *) NULL);
  310.     }
  311.     hp = getanswer(&buf, n, 1);
  312.     if (hp == NULL)
  313.         return ((struct hostent *) NULL);
  314.     hp->h_addrtype = type;
  315.     hp->h_length = len;
  316.     h_addr_ptrs[0] = (char *)&host_addr;
  317.     h_addr_ptrs[1] = (char *)0;
  318.     host_addr = *(struct in_addr *)addr;
  319. #if BSD < 43 && !defined(h_addr)    /* new-style hostent structure */
  320.     hp->h_addr = h_addr_ptrs[0];
  321. #endif
  322.     return(hp);
  323. }
  324.  
  325. _sethtent(f)
  326.     int f;
  327. {
  328.     if (hostf == NULL)
  329.         hostf = fopen(HOSTDB, "r" );
  330.     else
  331.         rewind(hostf);
  332.     stayopen |= f;
  333. }
  334.  
  335. _endhtent()
  336. {
  337.     if (hostf && !stayopen) {
  338.         (void) fclose(hostf);
  339.         hostf = NULL;
  340.     }
  341. }
  342.  
  343. struct hostent *
  344. _gethtent()
  345. {
  346.     char *p;
  347.     register char *cp, **q;
  348.  
  349.     if (hostf == NULL && (hostf = fopen(HOSTDB, "r" )) == NULL)
  350.         return (NULL);
  351. again:
  352.     if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
  353.         return (NULL);
  354.     if (*p == '#')
  355.         goto again;
  356.     cp = strpbrk(p, "#\n");
  357.     if (cp == NULL)
  358.         goto again;
  359.     *cp = '\0';
  360.     cp = strpbrk(p, " \t");
  361.     if (cp == NULL)
  362.         goto again;
  363.     *cp++ = '\0';
  364.     /* THIS STUFF IS INTERNET SPECIFIC */
  365. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  366.     host.h_addr_list = host_addrs;
  367. #endif
  368.     host.h_addr = hostaddr;
  369.     *((u_long *)host.h_addr) = inet_addr(p);
  370.     host.h_length = sizeof (u_long);
  371.     host.h_addrtype = AF_INET;
  372.     while (*cp == ' ' || *cp == '\t')
  373.         cp++;
  374.     host.h_name = cp;
  375.     q = host.h_aliases = host_aliases;
  376.     cp = strpbrk(cp, " \t");
  377.     if (cp != NULL) 
  378.         *cp++ = '\0';
  379.     while (cp && *cp) {
  380.         if (*cp == ' ' || *cp == '\t') {
  381.             cp++;
  382.             continue;
  383.         }
  384.         if (q < &host_aliases[MAXALIASES - 1])
  385.             *q++ = cp;
  386.         cp = strpbrk(cp, " \t");
  387.         if (cp != NULL)
  388.             *cp++ = '\0';
  389.     }
  390.     *q = NULL;
  391.     return (&host);
  392. }
  393.  
  394. struct hostent *
  395. _gethtbyname(name)
  396.     char *name;
  397. {
  398.     register struct hostent *p;
  399.     register char **cp;
  400.     
  401.     _sethtent(0);
  402.     while (p = _gethtent()) {
  403.         if (strcasecmp(p->h_name, name) == 0)
  404.             break;
  405.         for (cp = p->h_aliases; *cp != 0; cp++)
  406.             if (strcasecmp(*cp, name) == 0)
  407.                 goto found;
  408.     }
  409. found:
  410.     _endhtent();
  411.     return (p);
  412. }
  413.  
  414. struct hostent *
  415. _gethtbyaddr(addr, len, type)
  416.     char *addr;
  417.     int len, type;
  418. {
  419.     register struct hostent *p;
  420.  
  421.     _sethtent(0);
  422.     while (p = _gethtent())
  423.         if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
  424.             break;
  425.     _endhtent();
  426.     return (p);
  427. }
  428.