home *** CD-ROM | disk | FTP | other *** search
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "global.h"
- #include "mbuf.h"
- #include "domain.h"
- #include "timer.h"
- #include "internet.h"
- #include "icmp.h"
- #include "netuser.h"
- #include "tcp.h"
- #include "dns.h"
- #include "session.h"
- #include "misc.h"
- #include "Terminal.h"
- #include "flex.h"
- #include "vterm.h"
-
- extern char badhost[], hostname[];
-
- extern char *dns_encode_query(vterm vt, char *host, char *type);
- extern int dns_decode_answer(vterm vt, char *answer, int lentgh);
- extern void dns_test(void);
-
- /* Open up a socket to a remote (or the local) host on its dns port. */
-
- int dodns(int argc, char **argv)
- {
- struct session *s;
- struct tcb *tcb;
- struct socket lsocket, fsocket;
- struct dns *dns;
-
- if (argc < 3)
- {
- cwprintf(NULL, "usage: %s <nameserver> <name> [<type>]\r\n", argv[0]);
- return(1);
- }
-
- if (*argv[1]=='.')
- {
- dns_test();
- return 0;
- }
-
- lsocket.address = ip_addr;
- lsocket.port = lport++;
-
- if ((dns = alloc_dns()) == NULLDNS)
- return(1);
-
- if (argc<4)
- dns->user = dns_encode_query(dns->window->vt, argv[2], "");
- else
- dns->user = dns_encode_query(dns->window->vt, argv[2], argv[3]);
-
- if (dns->user==NULL)
- {
- cwprintf(NULL, "Bad query\r\n");
- free_dns(dns);
- return 1;
- }
-
- if ((fsocket.address = resolve(argv[1])) == 0)
- {
- cwprintf(NULL, "%s: ", argv[0]);
- cwprintf(NULL, badhost, argv[1]);
- free_dns(dns);
- return(1);
- }
-
- fsocket.port = dns_PORT; /* use dns wnp */
-
- /* Allocate a session descriptor */
- if ((s = newsession()) == NULLSESSION)
- {
- cwprintf(NULL, "Too many sessions\r\n");
- free_dns(dns);
- return 1;
- }
- dns->window = Window_Open(s, "DNS Query", term_NO_INPUT);
- vterm_resize(dns->window->vt, 80, 200);
- vterm_visible(dns->window->vt, 80, 24);
-
- current = s;
- s->cb.dns = dns;
- dns->session = s;
- s->window = dns->window;
-
- s->type = DNSQUERY;
- s->parse = NULLVFP;
-
- if ((s->name = malloc(strlen(argv[1])+1)) != NULLCHAR)
- strcpy(s->name, argv[1]);
-
- tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
- (void(*)())dnscli_rcv, NULLVFP, (void(*)())d_state, 0, (char *)dns);
-
- dns->tcb = tcb;
- tcb->user = (char *) dns;
- go(s);
-
- return 0;
- }
-
- /* Allocate a dns structure for the new session */
- struct dns *alloc_dns(void)
- {
- struct dns *tmp;
-
- if ((tmp = (struct dns *) malloc(sizeof(struct dns))) == NULLDNS)
- return(NULLDNS);
-
- tmp->session = NULLSESSION;
- tmp->window = NULL;
- tmp->user = (char *) NULL;
- tmp->rxdata = (char *) NULL;
- tmp->rxcount = 0;
- return(tmp);
- }
-
- /*
- * Free a dns structure
- */
- int free_dns(struct dns *dns)
- {
- if (dns != NULLDNS)
- {
- if (dns->session != NULLSESSION)
- freesession(dns->session);
- if (dns->user != (char *) NULL)
- free(dns->user);
- if (dns->rxdata != (char *) NULL)
- flex_free((flex_ptr)&dns->rxdata);
- free(dns);
- }
- return 0;
- }
-
- /* dns receiver upcall routine */
- void dnscli_rcv(register struct tcb *tcb, int16 cnt)
- {
- struct dns *dns = (struct dns *)tcb->user;
- struct mbuf *bp;
- int ok;
-
- /* Make sure it's a valid dns session */
- if (dns == NULLDNS)
- {
- return;
- }
-
- if (recv_tcp(tcb, &bp, cnt) > 0)
- {
- if (dns->rxdata==NULL)
- {
- ok = flex_alloc((flex_ptr)&dns->rxdata, len_mbuf(bp));
- dns->rxcount = 0;
- }
- else
- ok = flex_extend((flex_ptr)&dns->rxdata, dns->rxcount + len_mbuf(bp));
-
- if (!ok)
- {
- cwprintf(dns->window, "Out of memory in DNS CLI\r\n");
- free_p(bp);
- return;
- }
-
- while (bp != NULLBUF)
- {
- memcpy(dns->rxdata+dns->rxcount, bp->data, bp->cnt);
- dns->rxcount += bp->cnt;
- bp = free_mbuf(bp);
- }
- if ( (dns->rxcount-2) == ((dns->rxdata[0]<<8) | dns->rxdata[1]) )
- {
- dns_decode_answer(dns->window->vt, dns->rxdata+2, dns->rxcount-2);
- close_tcp(tcb);
- }
- }
- }
-
- /* State change upcall routine */
- void d_state(register struct tcb *tcb, char old, char new)
- {
- struct dns *dns;
- char notify = 0;
- extern char *tcpstates[];
- extern char *reasons[];
- extern char *unreach[];
- extern char *exceed[];
- struct mbuf *bp;
-
- old = old;
-
- dns = (struct dns *)tcb->user;
-
- if (dns->window || (current != NULLSESSION && current->type == DNSQUERY))
- notify = 1;
-
- switch(new)
- {
- case CLOSE_WAIT:
- if (notify)
- cwprintf(dns->window, "%s\r\n", tcpstates[new]);
- close_tcp(tcb);
- break;
-
- case CLOSED: /* finish up */
- if(notify)
- {
- cwprintf(dns->window, "%s (%s", tcpstates[new], reasons[tcb->reason]);
- if (tcb->reason == NETWORK)
- {
- switch(tcb->type)
- {
- case DEST_UNREACH:
- cwprintf(dns->window, ": %s unreachable", unreach[tcb->code]);
- break;
- case TIME_EXCEED:
- cwprintf(dns->window, ": %s time exceeded", exceed[tcb->code]);
- break;
- }
- }
- cwprintf(dns->window, ")\r\n");
- cmdmode();
- }
- if (dns != NULLDNS)
- {
- if (dns->window)
- {
- dns->window->Attr = ATTR_REVERSE;
- dns->window->Flags.flags.dont_destroy = FALSE;
- dns->window->Session = NULL;
- Window_CloseDown(dns->window);
- }
- free_dns(dns);
- }
- del_tcp(tcb);
- break;
- case ESTABLISHED:
- if (notify)
- {
- cwprintf(dns->window, "%s\r\n", tcpstates[new]);
- }
- cwprintf(dns->window, "[%s]\r\n", dns->session->name);
- bp = qdata(dns->user, ((dns->user[0]<<8)|dns->user[1])+2);
- send_tcp(tcb, bp);
- break;
-
- default:
- if (notify)
- cwprintf(dns->window, "%s\r\n",tcpstates[new]);
- break;
- }
- }
-