home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / osi / isode / vmsisode / vmsisode80_tar.Z / vmsisode80_tar / sockit / source / dns / gethostnamadr.c next >
Encoding:
C/C++ Source or Header  |  1991-03-28  |  9.2 KB  |  422 lines

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