home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / internet / tcpip / src205 / TCPIP_Src / DNS / c / dnscli < prev    next >
Encoding:
Text File  |  1995-03-27  |  7.9 KB  |  352 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 if (argc<5)
  56.     dns->user = dns_encode_query(dns->window->vt, argv[2], argv[3]);
  57.   else if (!strcmp(argv[3], "axfr"))
  58.   {
  59.     dns->user = dns_encode_query(dns->window->vt, argv[2], argv[3]);
  60.     dns->file = fopen(argv[4], "wb");
  61.   }
  62.  
  63.   if (dns->user==NULL)
  64.   {
  65.     cwprintf(NULL, "Bad query\r\n");
  66.     free_dns(dns);
  67.     return 1;
  68.   }
  69.  
  70.   if ((fsocket.address = resolve(argv[1])) == 0)
  71.   {
  72.     cwprintf(NULL, "%s: ", argv[0]);
  73.     cwprintf(NULL, badhost, argv[1]);
  74.     free_dns(dns);
  75.     return(1);
  76.   }
  77.  
  78.   fsocket.port = dns_PORT;             /* use dns wnp */
  79.  
  80.   /* Allocate a session descriptor */
  81.   if ((s = newsession()) == NULLSESSION)
  82.   {
  83.     cwprintf(NULL, "Too many sessions\r\n");
  84.     free_dns(dns);
  85.     return 1;
  86.   }
  87.   dns->window = Window_Open(s, "DNS Query", term_NO_INPUT);
  88.   vterm_resize(dns->window->vt, 80, 200);
  89.   vterm_visible(dns->window->vt, 80, 24);
  90.  
  91.   current = s;
  92.   s->cb.dns = dns;
  93.   dns->session = s;
  94.   s->window = dns->window;
  95.  
  96.   s->type  = DNSQUERY;
  97.   s->parse = NULLVFP;
  98.  
  99.   if ((s->name = malloc(strlen(argv[1])+1)) != NULLCHAR)
  100.     strcpy(s->name, argv[1]);
  101.  
  102.   tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
  103.   (dns->file==NULL) ? (void(*)())dnscli_rcv : (void(*)())dnscli_rcvaxfr,
  104.   NULLVFP, (void(*)())d_state, 0, (char *)dns);
  105.  
  106.   dns->tcb = tcb;
  107.   tcb->user   = (char *) dns;
  108.   go(s);
  109.  
  110.   return 0;
  111. }
  112.  
  113. /* Allocate a dns structure for the new session */
  114. struct dns *alloc_dns(void)
  115. {
  116.   struct dns *tmp;
  117.  
  118.   if ((tmp = (struct dns *) malloc(sizeof(struct dns))) == NULLDNS)
  119.     return(NULLDNS);
  120.  
  121.   tmp->session = NULLSESSION;
  122.   tmp->window  =  NULL;
  123.   tmp->user    = (char *) NULL;
  124.   tmp->rxdata  = (char *) NULL;
  125.   tmp->rxcount = 0;
  126.   tmp->rxexpect = 0;
  127.   tmp->file    = NULL;
  128.   return(tmp);
  129. }
  130.  
  131. /*
  132.  *      Free a dns structure
  133.  */
  134. int free_dns(struct dns *dns)
  135. {
  136.   if (dns != NULLDNS)
  137.   {
  138.     if (dns->session != NULLSESSION)
  139.       freesession(dns->session);
  140.     if (dns->user != (char *) NULL)
  141.       free(dns->user);
  142.     if (dns->rxdata != (char *) NULL)
  143.       flex_free((flex_ptr)&dns->rxdata);
  144.     if (dns->file!=NULL)
  145.       fclose(dns->file);
  146.     free(dns);
  147.   }
  148.   return 0;
  149. }
  150.  
  151. /* dns receiver upcall routine for display */
  152. void dnscli_rcv(register struct tcb *tcb, int16 cnt)
  153. {
  154.   struct dns *dns = (struct dns *)tcb->user;
  155.   struct mbuf   *bp;
  156.   int ok;
  157.  
  158.   /* Make sure it's a valid dns session */
  159.   if (dns == NULLDNS)
  160.   {
  161.     return;
  162.   }
  163.  
  164.   if (recv_tcp(tcb, &bp, cnt) > 0)
  165.   {
  166.     if (dns->rxdata==NULL)
  167.     {
  168.       ok = flex_alloc((flex_ptr)&dns->rxdata, len_mbuf(bp));
  169.       dns->rxcount = 0;
  170.     }
  171.     else
  172.       ok = flex_extend((flex_ptr)&dns->rxdata, dns->rxcount + len_mbuf(bp));
  173.  
  174.     if (!ok)
  175.     {
  176.       cwprintf(dns->window, "Out of memory in DNS CLI\r\n");
  177.       free_p(bp);
  178.       return;
  179.     }
  180.  
  181.     while (bp != NULLBUF)
  182.     {
  183.       memcpy(dns->rxdata+dns->rxcount, bp->data, bp->cnt);
  184.       dns->rxcount += bp->cnt;
  185.       bp = free_mbuf(bp);
  186.     }
  187.     if ( (dns->rxcount-2) == ((dns->rxdata[0]<<8) | dns->rxdata[1]) )
  188.     {
  189.       dns_decode_answer(dns->window->vt, dns->rxdata+2, dns->rxcount-2);
  190.       close_tcp(tcb);
  191.     }
  192.   }
  193. }
  194.  
  195. /* dns receiver upcall routine for output to file */
  196. void dnscli_rcvfile(register struct tcb *tcb, int16 cnt)
  197. {
  198.   struct dns *dns = (struct dns *)tcb->user;
  199.   struct mbuf   *bp;
  200.   int ok;
  201.  
  202.   /* Make sure it's a valid dns session */
  203.   if (dns == NULLDNS)
  204.   {
  205.     return;
  206.   }
  207.  
  208.   if (recv_tcp(tcb, &bp, cnt) > 0)
  209.   {
  210.     while (bp != NULLBUF)
  211.     {
  212.       if (dns->rxexpect==0)
  213.       {
  214.         dns->rxexpect = (bp->data[0]<<8 | bp->data[1])+2;
  215.         cwprintf(dns->window, "Starting transfer to file. Size = %d bytes\r\n", dns->rxexpect); 
  216.       }
  217.       fwrite(bp->data, 1, bp->cnt, dns->file);
  218.       dns->rxcount += bp->cnt;
  219.       bp = free_mbuf(bp);
  220.     }
  221.     if ( dns->rxcount == dns->rxexpect )
  222.     {
  223.       fclose(dns->file);
  224.       dns->file = NULL;
  225.       dns_decode_answer(dns->window->vt, dns->rxdata+2, dns->rxcount-2);
  226.       close_tcp(tcb);
  227.       cwprintf(dns->window, "\r\nRR transfer completed\r\n");
  228.     }
  229.     else
  230.     {
  231.       cwprintf(dns->window, "Received %dbytes (%d%%)\r", dns->rxcount, dns->rxcount*100/dns->rxexpect);
  232.     }
  233.   }
  234. }
  235.  
  236. /* dns receiver upcall routine for output to file */
  237. void dnscli_rcvaxfr(register struct tcb *tcb, int16 cnt)
  238. {
  239.   struct dns *dns = (struct dns *)tcb->user;
  240.   struct mbuf   *bp;
  241.   int ok;
  242.  
  243.   /* Make sure it's a valid dns session */
  244.   if (dns == NULLDNS)
  245.   {
  246.     return;
  247.   }
  248.  
  249.   if (recv_tcp(tcb, &bp, cnt) > 0)
  250.   {
  251.     while (bp != NULLBUF)
  252.     {
  253.       if (dns->rxexpect==0)
  254.       {
  255.         dns->rxexpect = (bp->data[0]<<8 | bp->data[1])+2;
  256.         cwprintf(dns->window, "Starting transfer to file. Size = %d bytes\r\n", dns->rxexpect); 
  257.       }
  258.       fwrite(bp->data, 1, bp->cnt, dns->file);
  259.       dns->rxcount += bp->cnt;
  260.       bp = free_mbuf(bp);
  261.     }
  262.     if ( dns->rxcount == dns->rxexpect )
  263.     {
  264.       fclose(dns->file);
  265.       dns->file = NULL;
  266.       dns_decode_answer(dns->window->vt, dns->rxdata+2, dns->rxcount-2);
  267.       close_tcp(tcb);
  268.       cwprintf(dns->window, "\r\nRR transfer completed\r\n");
  269.     }
  270.     else
  271.     {
  272.       cwprintf(dns->window, "Received %dbytes (%d%%)\r", dns->rxcount, dns->rxcount*100/dns->rxexpect);
  273.     }
  274.   }
  275. }
  276.  
  277. /* State change upcall routine */
  278. void d_state(register struct tcb *tcb, char old, char new)
  279. {
  280.   struct dns   *dns;
  281.   char            notify = 0;
  282.   extern char     *tcpstates[];
  283.   extern char     *reasons[];
  284.   extern char     *unreach[];
  285.   extern char     *exceed[];
  286.   struct mbuf     *bp;
  287.  
  288.   old = old;
  289.  
  290.   dns = (struct dns *)tcb->user;
  291.  
  292.   if (dns->window || (current != NULLSESSION && current->type == DNSQUERY))
  293.     notify = 1;
  294.  
  295.   switch(new)
  296.   {
  297.   case CLOSE_WAIT:
  298.     if (notify)
  299.       cwprintf(dns->window, "%s\r\n", tcpstates[new]);
  300.     close_tcp(tcb);
  301.     break;
  302.  
  303.   case CLOSED:    /* finish up */
  304.     if(notify)
  305.     {
  306.       cwprintf(dns->window, "%s (%s", tcpstates[new], reasons[tcb->reason]);
  307.       if (tcb->reason == NETWORK)
  308.       {
  309.         switch(tcb->type)
  310.         {
  311.         case DEST_UNREACH:
  312.           cwprintf(dns->window, ": %s unreachable", unreach[tcb->code]);
  313.           break;
  314.         case TIME_EXCEED:
  315.           cwprintf(dns->window, ": %s time exceeded", exceed[tcb->code]);
  316.           break;
  317.         }
  318.       }
  319.       cwprintf(dns->window, ")\r\n");
  320.       cmdmode();
  321.     }
  322.     if (dns != NULLDNS)
  323.     {
  324.       if (dns->window)
  325.       {
  326.         dns->window->Attr = ATTR_REVERSE;
  327.         dns->window->Flags.flags.dont_destroy = FALSE;
  328.         dns->window->Session = NULL;
  329.         Window_CloseDown(dns->window);
  330.       }
  331.       free_dns(dns);
  332.     }
  333.     fclose(dns->file);
  334.     del_tcp(tcb);
  335.     break;
  336.   case ESTABLISHED:
  337.     if (notify)
  338.     {
  339.       cwprintf(dns->window, "%s\r\n", tcpstates[new]);
  340.     }
  341.     cwprintf(dns->window, "[%s]\r\n", dns->session->name);
  342.     bp = qdata(dns->user, ((dns->user[0]<<8)|dns->user[1])+2);
  343.     send_tcp(tcb, bp);
  344.     break;
  345.  
  346.   default:
  347.     if (notify)
  348.       cwprintf(dns->window, "%s\r\n",tcpstates[new]);
  349.     break;
  350.   }
  351. }
  352.