home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / dns.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-12  |  2.6 KB  |  117 lines

  1. #include <alloca.h>
  2. #include <sys/socket.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <resolv.h>
  6. #include <arpa/nameser.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. /* This is dumb, but glibc doesn't like to do hostname lookups w/o libc.so */
  11.  
  12. union dns_response{
  13.     HEADER hdr;
  14.     u_char buf[PACKETSZ];
  15. } ;
  16.  
  17. static int doQuery(char * query, int queryType,
  18.            char ** domainName, struct in_addr * ipNum) {
  19.     int len, ancount, type;
  20.     u_char * data, * end;
  21.     char name[MAXDNAME];
  22.     union dns_response response;
  23.  
  24.     _res.retry = 2;
  25.  
  26.     len = res_search(query, C_IN, queryType, (void *) &response, 
  27.             sizeof(response));
  28.     if (len <= 0) return -1;
  29.  
  30.     if (ntohs(response.hdr.rcode) != NOERROR) return -1;
  31.     ancount = ntohs(response.hdr.ancount);
  32.     if (ancount < 1) return -1;
  33.  
  34.     data = response.buf + sizeof(HEADER);
  35.     end = response.buf + len;
  36.     
  37.     /* skip the question */
  38.     data += dn_skipname(data, end) + QFIXEDSZ;
  39.  
  40.     /* parse the answer(s) */
  41.     while (--ancount >= 0 && data < end) {
  42.  
  43.       /* skip the domain name portion of the RR record */
  44.       data += dn_skipname(data, end);
  45.  
  46.       /* get RR information */
  47.       GETSHORT(type, data);
  48.       data += INT16SZ; /* skipp class */
  49.       data += INT32SZ; /* skipp TTL */
  50.       GETSHORT(len,  data);
  51.  
  52.       if (type == T_PTR) {
  53.     /* we got a pointer */
  54.     len = dn_expand(response.buf, end, data, name, sizeof(name));
  55.     if (len <= 0) return -1;
  56.     if (queryType == T_PTR && domainName) {
  57.       /* we wanted a pointer */
  58.       *domainName = malloc(strlen(name) + 1);
  59.       strcpy(*domainName, name);
  60.       return 0;
  61.     }
  62.       } else if (type == T_A) {
  63.     /* we got an address */
  64.     if (queryType == T_A && ipNum) {
  65.       /* we wanted an address */
  66.       memcpy(ipNum, data, sizeof(*ipNum));
  67.       return 0;
  68.     }
  69.       }
  70.  
  71.       /* move ahead to next RR */
  72.       data += len;
  73.     } 
  74.  
  75.     return -1;
  76. }
  77.  
  78. char * mygethostbyaddr(char * ipnum) {
  79.     int rc;
  80.     char * result;
  81.     char * strbuf;
  82.     char * chptr;
  83.     char * splits[4];
  84.     int i;
  85.  
  86.     _res.retry = 1;
  87.  
  88.     strbuf = alloca(strlen(ipnum) + 1);
  89.     strcpy(strbuf, ipnum);
  90.  
  91.     ipnum = alloca(strlen(strbuf) + 20);
  92.  
  93.     for (i = 0; i < 4; i++) {
  94.     chptr = strbuf;
  95.     while (*chptr && *chptr != '.') chptr++;
  96.     *chptr = '\0';
  97.  
  98.     if (chptr - strbuf > 3) return NULL;
  99.     splits[i] = strbuf;
  100.     strbuf = chptr + 1;
  101.     }
  102.  
  103.     sprintf(ipnum, "%s.%s.%s.%s.in-addr.arpa", splits[3], splits[2],
  104.         splits[1], splits[0]);
  105.  
  106.     rc = doQuery(ipnum, T_PTR, &result, NULL);
  107.  
  108.     if (rc) 
  109.     return NULL;
  110.     else
  111.     return result;
  112. }
  113.  
  114. int mygethostbyname(char * name, struct in_addr * addr) {
  115.     return doQuery(name, T_A, NULL, addr);
  116. }
  117.