home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC20A01.ZIP / NSLOOKUP.CPP < prev    next >
C/C++ Source or Header  |  1999-06-20  |  8KB  |  447 lines

  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <process.h>
  6. #include <mem.h>
  7. #include <alloc.h>
  8. extern "C" {
  9. #include "tcp.h"
  10. }
  11.  
  12. extern char *def_domain;
  13. extern char *loc_domain;
  14. extern longword def_nameservers[MAX_NAMESERVERS];
  15. extern int _last_nameserver;
  16. extern word _domaintimeout = 0;
  17.  
  18. static longword timeoutwhen;
  19.  
  20. static udp_Socket *dom_sock;
  21.  
  22. #define DOMSIZE 512
  23.  
  24. struct dhead {
  25.   word ident,
  26.    flags, qdcount,
  27.    ancount,
  28.    nscount,
  29.    arcount;
  30. };
  31.  
  32. #define DQR       0x8000
  33. #define DOPCODE   0x7100
  34. #define DAA       0x0400
  35. #define DTC       0x0200
  36. #define DRD       0x0100
  37. #define DRA       0x0080
  38. #define DRCODE    0x000F
  39.  
  40. #define DOPQUERY  0
  41. #define DOPIQ     1
  42. #define DOPCQM    2
  43. #define DOPCQU    3
  44.  
  45. #define DROK    0
  46. #define DRFORM  1
  47. #define DRFAIL  2
  48. #define DRNAME  3
  49. #define DRNOPE  4
  50. #define DRNOWAY 5
  51.  
  52. #define DTYPEA    1
  53.  
  54. #define DTYPEPTR  12
  55.  
  56. #define DIN     1
  57. #define DWILD   255
  58.  
  59. struct rrpart {
  60.   word rtype,
  61.    rclass;
  62.   longword ttl;
  63.   word rdlength;
  64.   byte rdata[DOMSIZE];
  65. };
  66.  
  67. static struct useek {
  68.   struct dhead h;
  69.   byte x[DOMSIZE];
  70. } *question;
  71.  
  72. static packdom(char *dst, char *src)
  73. {
  74.   char *p, *q, *savedst;
  75.   int i, dotflag, defflag;
  76.  
  77.   p = src;
  78.   dotflag = defflag = 0;
  79.   savedst = dst;
  80.  
  81.   do {
  82.     *dst = 0;
  83.     q = dst + 1;
  84.     while (*p && (*p != '.'))
  85.       *q++ = *p++;
  86.  
  87.     i = p - src;
  88.     if (i > 0x3f)
  89.       return (-1);
  90.     *dst = i;
  91.     *q = 0;
  92.  
  93.     if (*p) {
  94.       dotflag = 1;
  95.       src = ++p;
  96.       dst = q;
  97.     } else if (!dotflag && !defflag && loc_domain) {
  98.       p = loc_domain;
  99.       defflag = 1;
  100.       src = p;
  101.       dst = q;
  102.     }
  103.   } while (*p);
  104.   q++;
  105.   return (q - savedst);
  106. }
  107.  
  108. static unpackdom(char *dst, char *src, char *buf)
  109. {
  110.   int i, j, retval;
  111.   char *savesrc;
  112.  
  113.   savesrc = src;
  114.   retval = 0;
  115.  
  116.   while (*src) {
  117.     j = *src;
  118.  
  119.     while ((j & 0xC0) == 0xC0) {
  120.       if (!retval)
  121.         retval = src - savesrc + 2;
  122.       src++;
  123.       src = &buf[(j & 0x3f) * 256 + *src];
  124.       j = *src;
  125.     }
  126.  
  127.     src++;
  128.     for (i = 0; i < (j & 0x3f); i++)
  129.       *dst++ = *src++;
  130.  
  131.     *dst++ = '.';
  132.   }
  133.  
  134.   *(--dst) = 0;
  135.   src++;
  136.  
  137.   if (!retval)
  138.     retval = src - savesrc;
  139.  
  140.   return (retval);
  141. }
  142.  
  143. static sendom(char *s, longword towho, word num)
  144. {
  145.   word i, ulen;
  146.   byte *psave, *p;
  147.  
  148.   psave = (byte *) & (question->x);
  149.   i = packdom((unsigned char *)&(question->x), s);
  150.  
  151.   p = &(question->x[i]);
  152.   *p++ = 0;
  153.   *p++ = DTYPEA;
  154.   *p++ = 0;
  155.   *p++ = DIN;
  156.  
  157.   question->h.ident = intel16(num);
  158.   ulen = sizeof(struct dhead) + (p - psave);
  159.  
  160.   udp_open(dom_sock, 997, towho, 53, NULL);
  161.  
  162.   sock_write(dom_sock, (unsigned char *)question, ulen);
  163.   return (ulen);
  164. }
  165.  
  166.  
  167. static sendrdom(char *s, longword towho, word num)
  168. {
  169.   word i, ulen;
  170.   byte *psave, *p;
  171.  
  172.   psave = (byte *) & (question->x);
  173.   i = packdom((char *)&(question->x), s);
  174.  
  175.   p = &(question->x[i]);
  176.   *p++ = 0;
  177.   *p++ = DTYPEA;
  178.   *p++ = 0;
  179.   *p++ = DIN;
  180.  
  181.   question->h.ident = intel16(num);
  182.   ulen = sizeof(struct dhead) + (p - psave);
  183.  
  184.   udp_open(dom_sock, 997, towho, 53, NULL);
  185.  
  186.   sock_write(dom_sock, (unsigned char *)question, ulen);
  187.   return (ulen);
  188. }
  189.  
  190. static int countpaths(char *pathstring)
  191. {
  192.   int count = 0;
  193.   char *p;
  194.  
  195.   for (p = pathstring; (*p != 0) || (*(p + 1) != 0); p++) {
  196.     if (*p == 0)
  197.       count++;
  198.   }
  199.   return (++count);
  200. }
  201.  
  202. static char *getpath(char *pathstring, int whichone)
  203. {
  204.   char *retval;
  205.  
  206.   if (whichone > countpaths(pathstring))
  207.     return (NULL);
  208.   whichone--;
  209.   for (retval = pathstring; whichone; retval++) {
  210.     if (*retval == 0)
  211.       whichone--;
  212.   }
  213.   return (retval);
  214. }
  215.  
  216. static longword ddextract(struct useek *qp, unsigned char *mip)
  217. {
  218.   word i, j, nans, rcode;
  219.   struct rrpart *rrp;
  220.   byte *p, space[260];
  221.  
  222.   nans = intel16(qp->h.ancount);
  223.   rcode = DRCODE & intel16(qp->h.flags);
  224.   if (rcode > 0)
  225.     return (rcode);
  226.  
  227.   if (nans > 0 &&
  228.       (intel16(qp->h.flags) & DQR)) {
  229.     p = (byte *) & qp->x;
  230.     i = unpackdom(space, p, (unsigned char *)qp);
  231.     p += i + 4;
  232.     printf(" NAME : ? %s\n", space);
  233.  
  234.     while (nans-- > 0) {
  235.       i = unpackdom(space, p, (unsigned char *)qp);
  236.       p += i;
  237.       rrp = (struct rrpart *) p;
  238.       if (!*p && *(p + 1) == DTYPEA &&  !*(p + 2) && *(p + 3) == DIN) {
  239.         movmem(rrp->rdata, mip, 4);
  240.         return (0);
  241.       }
  242.       movmem(&rrp->rdlength, &j, 2);
  243.       p += 10 + intel16(j);
  244.     }
  245.   }
  246.   return -1;
  247. }
  248.  
  249. static longword udpdom(void)
  250. {
  251.   int i, uret;
  252.   longword desired;
  253.  
  254.   uret = sock_fastread(dom_sock, (unsigned char *)question, sizeof(struct useek));
  255.   if (uret < 0)
  256.     return -1;
  257.  
  258.   i = ddextract((useek *)question, (unsigned char *)&desired);
  259.   switch (i) {
  260.     case 3:
  261.       return 0;
  262.     case 0:
  263.       return (intel(desired));
  264.     case -1:
  265.       return 0;
  266.     default:
  267.       return 0;
  268.   }
  269. }
  270.  
  271. static longword Sdomain(char *mname, int adddom, longword nameserver, int *timedout)
  272. {
  273.   char namebuff[512];
  274.   int isaname;
  275.   int status, i;
  276.   longword response;
  277.  
  278.   isaname = !isaddr(mname);
  279.   response = 0;
  280.   *timedout = 1;
  281.  
  282.   if (!nameserver) {
  283.     printf("No nameserver defined!\n\r");
  284.     return (0);
  285.   }
  286.   while (*mname && *mname < 33)
  287.     mname++;
  288.  
  289.   if (!(*mname))
  290.     return (0L);
  291.  
  292.   question->h.flags = intel16(DRD);
  293.   question->h.qdcount = 0;
  294.   question->h.ancount = 0;
  295.   question->h.nscount = 0;
  296.   question->h.arcount = 0;
  297.  
  298. //  qinit();
  299.  
  300.   strcpy(namebuff, mname);
  301.  
  302.   if (isaname) {
  303.     question->h.qdcount = intel16(1);
  304.     if (adddom) {
  305.       if (namebuff[strlen(namebuff) - 1] != '.') {
  306.         if (loc_domain) {
  307.           countpaths(loc_domain);
  308.           strcat(namebuff, ".");
  309.           strcat(namebuff, getpath(loc_domain, 1));
  310.         }
  311.       } else
  312.         namebuff[strlen(namebuff) - 1] = 0;
  313.     }
  314.   } else
  315.     question->h.ancount = intel16(1);
  316.  
  317.   for (i = 2; i < 17; i *= 2) {
  318.     if (isaname)
  319.       sendom(namebuff, nameserver, 0xf001);
  320.     else
  321.       sendrdom(namebuff, nameserver, 0xf001);
  322.  
  323.     ip_timer_init(dom_sock, i);
  324.     do {
  325.       kbhit();
  326.       tcp_tick(dom_sock);
  327.       if (ip_timer_expired(dom_sock))
  328.         break;
  329.       if (watcbroke) {
  330.         break;
  331.       }
  332.       if (chk_timeout(timeoutwhen))
  333.         break;
  334.       if (sock_dataready(dom_sock))
  335.         *timedout = 0;
  336.     } while (*timedout);
  337.  
  338.     if (!*timedout)
  339.       break;
  340.   }
  341.  
  342.   if (!*timedout)
  343.     response = udpdom();
  344.  
  345.   sock_close(dom_sock);
  346.   return (response);
  347. }
  348.  
  349. static char *nextdomain(char *domain, int count)
  350. {
  351.   char *p;
  352.   int i;
  353.  
  354.   p = domain;
  355.  
  356.   for (i = 0; i < count; ++i) {
  357.     p = strchr(p, '.');
  358.     if (!p)
  359.       return (NULL);
  360.     ++p;
  361.   }
  362.   return (p);
  363. }
  364.  
  365.  
  366. longword newresolve(char *name)
  367. {
  368.   longword ip_address, temp;
  369.   int count, i;
  370.   byte timeout[MAX_NAMESERVERS];
  371.   struct useek qp;
  372.   udp_Socket ds;
  373.   word oldhndlcbrk;
  374.  
  375.  
  376.   question = &qp;
  377.   dom_sock = &ds;
  378.   if (!name)
  379.     return (0);
  380.   rip(name);
  381.  
  382.   if (!_domaintimeout)
  383.     _domaintimeout = sock_delay << 2;
  384.   timeoutwhen = set_timeout(_domaintimeout);
  385.  
  386.   count = 0;
  387.   memset(&timeout, 0, sizeof(timeout));
  388.  
  389.   oldhndlcbrk = wathndlcbrk;
  390.   wathndlcbrk = 1;
  391.   watcbroke = 0;
  392.   do {
  393.     if ((loc_domain = nextdomain(def_domain, count)) == NULL)
  394.       count = -1;
  395.  
  396.     for (i = 0; i < _last_nameserver; ++i) {
  397.       if (!timeout[i])
  398.         if ((ip_address = Sdomain(name, count != -1, def_nameservers[i], (int *)&timeout[i])) != 0)
  399.           break;
  400.     }
  401.  
  402.     if (count == -1)
  403.       break;
  404.     count++;
  405.   } while (!ip_address);
  406.   watcbroke = 0;
  407.   wathndlcbrk = oldhndlcbrk;
  408.  
  409.   return (ip_address);
  410. }
  411.  
  412.  
  413.  
  414. main(int argc, char *argv[])
  415. {
  416.   char *name;
  417.   longword host;
  418.   int status, i;
  419.   char buffer[20];
  420.  
  421.   if (argc < 2) {
  422.     puts("NSLOOKUP <hostname>\n\n");
  423.     exit(3);
  424.   }
  425.   sock_init();
  426.  
  427.   for (i = 1; i < argc; ++i) {
  428.     if ((*argv[i] == '/') || (*argv[i] == '-')) {
  429.     } else {
  430.       name = strdup(argv[i]);
  431.  
  432.       printf("resolving \"%s\"...", name);
  433.       host = newresolve(name);
  434.       printf("\r");
  435.       clreol();
  436.     }
  437.   }
  438.   if (host) {
  439.     printf("\r");
  440.     clreol();
  441.     printf("%s : %s\n", name, inet_ntoa(buffer, host));
  442.   }
  443.   exit(host ? 0 : 1);
  444.   return 0;
  445. }
  446.  
  447.