home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / DNS / c / dnscli < prev    next >
Text File  |  1994-09-28  |  6KB  |  259 lines

  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "domain.h"
  8. #include "timer.h"
  9. #include "internet.h"
  10. #include "icmp.h"
  11. #include "netuser.h"
  12. #include "tcp.h"
  13. #include "dns.h"
  14. #include "session.h"
  15. #include "misc.h"
  16. #include "Terminal.h"
  17. #include "flex.h"
  18. #include "vterm.h"
  19.  
  20. extern char badhost[], hostname[];
  21.  
  22. extern char *dns_encode_query(vterm vt, char *host, char *type);
  23. extern int dns_decode_answer(vterm vt, char *answer, int lentgh);
  24. extern void dns_test(void);
  25.  
  26. /* Open up a socket to a remote (or the local) host on its dns port. */
  27.  
  28. int dodns(int argc, char **argv)
  29. {
  30.   struct session  *s;
  31.   struct tcb      *tcb;
  32.   struct socket   lsocket, fsocket;
  33.   struct dns      *dns;
  34.  
  35.   if (argc < 3)
  36.   {
  37.     cwprintf(NULL, "usage: %s <nameserver> <name> [<type>]\r\n", argv[0]);
  38.     return(1);
  39.   }
  40.  
  41.   if (*argv[1]=='.')
  42.   {
  43.     dns_test();
  44.     return 0;
  45.   }
  46.  
  47.   lsocket.address = ip_addr;
  48.   lsocket.port = lport++;
  49.  
  50.   if ((dns = alloc_dns()) == NULLDNS)
  51.     return(1);
  52.  
  53.   if (argc<4)
  54.     dns->user = dns_encode_query(dns->window->vt, argv[2], "");
  55.   else
  56.     dns->user = dns_encode_query(dns->window->vt, argv[2], argv[3]);
  57.  
  58.   if (dns->user==NULL)
  59.   {
  60.     cwprintf(NULL, "Bad query\r\n");
  61.     free_dns(dns);
  62.     return 1;
  63.   }
  64.  
  65.   if ((fsocket.address = resolve(argv[1])) == 0)
  66.   {
  67.     cwprintf(NULL, "%s: ", argv[0]);
  68.     cwprintf(NULL, badhost, argv[1]);
  69.     free_dns(dns);
  70.     return(1);
  71.   }
  72.  
  73.   fsocket.port = dns_PORT;             /* use dns wnp */
  74.  
  75.   /* Allocate a session descriptor */
  76.   if ((s = newsession()) == NULLSESSION)
  77.   {
  78.     cwprintf(NULL, "Too many sessions\r\n");
  79.     free_dns(dns);
  80.     return 1;
  81.   }
  82.   dns->window = Window_Open(s, "DNS Query", term_NO_INPUT);
  83.   vterm_resize(dns->window->vt, 80, 200);
  84.   vterm_visible(dns->window->vt, 80, 24);
  85.  
  86.   current = s;
  87.   s->cb.dns = dns;
  88.   dns->session = s;
  89.   s->window = dns->window;
  90.  
  91.   s->type  = DNSQUERY;
  92.   s->parse = NULLVFP;
  93.  
  94.   if ((s->name = malloc(strlen(argv[1])+1)) != NULLCHAR)
  95.     strcpy(s->name, argv[1]);
  96.  
  97.   tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
  98.   (void(*)())dnscli_rcv, NULLVFP, (void(*)())d_state, 0, (char *)dns);
  99.  
  100.   dns->tcb = tcb;
  101.   tcb->user   = (char *) dns;
  102.   go(s);
  103.  
  104.   return 0;
  105. }
  106.  
  107. /* Allocate a dns structure for the new session */
  108. struct dns *alloc_dns(void)
  109. {
  110.   struct dns *tmp;
  111.  
  112.   if ((tmp = (struct dns *) malloc(sizeof(struct dns))) == NULLDNS)
  113.     return(NULLDNS);
  114.  
  115.   tmp->session = NULLSESSION;
  116.   tmp->window  =  NULL;
  117.   tmp->user    = (char *) NULL;
  118.   tmp->rxdata  = (char *) NULL;
  119.   tmp->rxcount = 0;
  120.   return(tmp);
  121. }
  122.  
  123. /*
  124.  *      Free a dns structure
  125.  */
  126. int free_dns(struct dns *dns)
  127. {
  128.   if (dns != NULLDNS)
  129.   {
  130.     if (dns->session != NULLSESSION)
  131.       freesession(dns->session);
  132.     if (dns->user != (char *) NULL)
  133.       free(dns->user);
  134.     if (dns->rxdata != (char *) NULL)
  135.       flex_free((flex_ptr)&dns->rxdata);
  136.     free(dns);
  137.   }
  138.   return 0;
  139. }
  140.  
  141. /* dns receiver upcall routine */
  142. void dnscli_rcv(register struct tcb *tcb, int16 cnt)
  143. {
  144.   struct dns *dns = (struct dns *)tcb->user;
  145.   struct mbuf   *bp;
  146.   int ok;
  147.  
  148.   /* Make sure it's a valid dns session */
  149.   if (dns == NULLDNS)
  150.   {
  151.     return;
  152.   }
  153.  
  154.   if (recv_tcp(tcb, &bp, cnt) > 0)
  155.   {
  156.     if (dns->rxdata==NULL)
  157.     {
  158.       ok = flex_alloc((flex_ptr)&dns->rxdata, len_mbuf(bp));
  159.       dns->rxcount = 0;
  160.     }
  161.     else
  162.       ok = flex_extend((flex_ptr)&dns->rxdata, dns->rxcount + len_mbuf(bp));
  163.  
  164.     if (!ok)
  165.     {
  166.       cwprintf(dns->window, "Out of memory in DNS CLI\r\n");
  167.       free_p(bp);
  168.       return;
  169.     }
  170.  
  171.     while (bp != NULLBUF)
  172.     {
  173.       memcpy(dns->rxdata+dns->rxcount, bp->data, bp->cnt);
  174.       dns->rxcount += bp->cnt;
  175.       bp = free_mbuf(bp);
  176.     }
  177.     if ( (dns->rxcount-2) == ((dns->rxdata[0]<<8) | dns->rxdata[1]) )
  178.     {
  179.       dns_decode_answer(dns->window->vt, dns->rxdata+2, dns->rxcount-2);
  180.       close_tcp(tcb);
  181.     }
  182.   }
  183. }
  184.  
  185. /* State change upcall routine */
  186. void d_state(register struct tcb *tcb, char old, char new)
  187. {
  188.   struct dns   *dns;
  189.   char            notify = 0;
  190.   extern char     *tcpstates[];
  191.   extern char     *reasons[];
  192.   extern char     *unreach[];
  193.   extern char     *exceed[];
  194.   struct mbuf     *bp;
  195.  
  196.   old = old;
  197.  
  198.   dns = (struct dns *)tcb->user;
  199.  
  200.   if (dns->window || (current != NULLSESSION && current->type == DNSQUERY))
  201.     notify = 1;
  202.  
  203.   switch(new)
  204.   {
  205.   case CLOSE_WAIT:
  206.     if (notify)
  207.       cwprintf(dns->window, "%s\r\n", tcpstates[new]);
  208.     close_tcp(tcb);
  209.     break;
  210.  
  211.   case CLOSED:    /* finish up */
  212.     if(notify)
  213.     {
  214.       cwprintf(dns->window, "%s (%s", tcpstates[new], reasons[tcb->reason]);
  215.       if (tcb->reason == NETWORK)
  216.       {
  217.         switch(tcb->type)
  218.         {
  219.         case DEST_UNREACH:
  220.           cwprintf(dns->window, ": %s unreachable", unreach[tcb->code]);
  221.           break;
  222.         case TIME_EXCEED:
  223.           cwprintf(dns->window, ": %s time exceeded", exceed[tcb->code]);
  224.           break;
  225.         }
  226.       }
  227.       cwprintf(dns->window, ")\r\n");
  228.       cmdmode();
  229.     }
  230.     if (dns != NULLDNS)
  231.     {
  232.       if (dns->window)
  233.       {
  234.         dns->window->Attr = ATTR_REVERSE;
  235.         dns->window->Flags.flags.dont_destroy = FALSE;
  236.         dns->window->Session = NULL;
  237.         Window_CloseDown(dns->window);
  238.       }
  239.       free_dns(dns);
  240.     }
  241.     del_tcp(tcb);
  242.     break;
  243.   case ESTABLISHED:
  244.     if (notify)
  245.     {
  246.       cwprintf(dns->window, "%s\r\n", tcpstates[new]);
  247.     }
  248.     cwprintf(dns->window, "[%s]\r\n", dns->session->name);
  249.     bp = qdata(dns->user, ((dns->user[0]<<8)|dns->user[1])+2);
  250.     send_tcp(tcb, bp);
  251.     break;
  252.  
  253.   default:
  254.     if (notify)
  255.       cwprintf(dns->window, "%s\r\n",tcpstates[new]);
  256.     break;
  257.   }
  258. }
  259.