⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp_dom.c

📁 dos下开发TCP网络的库文件部分
💻 C
📖 第 1 页 / 共 2 页
字号:
/* domain name server protocol
 *
 * This portion of the code needs some major work.  I ported it (read STOLE IT)
 * from NCSA and lost about half the code somewhere in the process.
 *
 * Note, this is a user level process.  We include <tcp.h> not <wattcp.h>
 *
 *  0.4 : Aug 28, 1999 - added small dns cache, resolve_fn, only whole domain
 *  0.3 : Jan  8, 1994 - hooks for different RR types; rev lookups. messy!
 *  0.2 : Apr 24, 1991 - use substring portions of domain
 *  0.1 : Mar 18, 1991 - improved the trailing domain list
 *  0.0 : Feb 19, 1991 - pirated by Erick Engelke
 * -1.0 :              - NCSA code
 */

#include <copyright.h>
#include <stdio.h>
#include <string.h>
#include <mem.h>
#include <conio.h>
#include <tcp.h>

/*
 * #include <elib.h>
 */

/* These next 'constants' are loaded from WATTCP.CFG file */

char *def_domain;
char *loc_domain;	/* current subname to be used by the domain system */

longword def_nameservers[ MAX_NAMESERVERS ];
int _last_nameserver;
word _domaintimeout = 0;

static longword timeoutwhen;

/*
longword def_nameserver;
longword def2_nameserver;
*/
static udp_Socket *dom_sock;

#define DOMSIZE 512				/* maximum domain message size to mess with */

/*
 *  Header for the DOMAIN queries
 *  ALL OF THESE ARE BYTE SWAPPED QUANTITIES!
 *  We are the poor slobs who are incompatible with the world's byte order
 */
struct dhead {
    word	ident,		/* unique identifier */
		flags,
		qdcount,	/* question section, # of entries */
		ancount,	/* answers, how many */
		nscount,	/* count of name server RRs */
		arcount;	/* number of "additional" records */
};

/*
 *  flag masks for the flags field of the DOMAIN header
 */
#define DQR		0x8000	/* query = 0, response = 1 */
#define DOPCODE		0x7100	/* opcode, see below */
#define DAA		0x0400	/* Authoritative answer */
#define DTC		0x0200	/* Truncation, response was cut off at 512 */
#define DRD		0x0100	/* Recursion desired */
#define DRA		0x0080	/* Recursion available */
#define DRCODE		0x000F	/* response code, see below */

/* opcode possible values: */
#define DOPQUERY	0	/* a standard query */
#define DOPIQ		1	/* an inverse query */
#define DOPCQM		2	/* a completion query, multiple reply */
#define DOPCQU		3     	/* a completion query, single reply */
/* the rest reserved for future */

/* legal response codes: */
#define DROK	0		/* okay response */
#define DRFORM	1		/* format error */
#define DRFAIL	2		/* their problem, server failed */
#define DRNAME	3		/* name error, we know name doesn't exist */
#define DRNOPE	4		/* no can do request */
#define DRNOWAY	5		/* name server refusing to do request */

#define DTYPEA		1	/* host address resource record (RR) */
#define DTYPEPTR	12	/* a domain name ptr */

#define DIN		1	/* ARPA internet class */
#define DWILD		255	/* wildcard for several of the classifications */

/*
 *  a resource record is made up of a compressed domain name followed by
 *  this structure.  All of these ints need to be byteswapped before use.
 */
struct rrpart {
    word   	rtype,		/* resource record type = DTYPEA */
		rclass;		/* RR class = DIN */
    longword	ttl;		/* time-to-live, changed to 32 bits */
    word	rdlength;	/* length of next field */
    byte 	rdata[DOMSIZE];	/* data field */
};

/*
 *  data for domain name lookup
 */
static struct useek {
    struct dhead h;
    byte         x[DOMSIZE];
} *question;

typedef void (*unpacker_funct)(void *data,struct rrpart *rrp,struct useek *qp);

/*
 * prototypes
 */
static int packdom(char *dst, char *src);
static int countpaths(char *pathstring);
static int unpackdom(char *dst, char *src, char *buf);
static longword ddextract( struct useek *qp, byte type,
      unpacker_funct unpacker, void *data );
static char *getpath(char *pathstring, int whichone);
static int sendom(char *s, longword towho, word num, byte dtype);
static int udpdom(byte dtype, unpacker_funct unpacker, void *data );
static int Sdomain(char *mname, byte dtype, unpacker_funct unpacker,
      void *data, int adddom, longword nameserver, byte *timedout, sockfunct_t fn);  // S. Lawson
static int do_ns_lookup(char *name, byte dtype, unpacker_funct unpacker,
      void *data, sockfunct_t fn );		// S. Lawson

static void qinit( void )
{
    question->h.flags = intel16(DRD);
    question->h.qdcount = intel16(1);
    question->h.ancount = 0;
    question->h.nscount = 0;
    question->h.arcount = 0;
}

/*********************************************************************/
/*  packdom
*   pack a regular text string into a packed domain name, suitable
*   for the name server.
*
*   returns length
*/
static packdom( char *dst,char *src )
{
    char *p,*q,*savedst;
    int i,dotflag,defflag;

    p = src;
    dotflag = defflag = 0;
    savedst = dst;

    do {			/* copy whole string */
	*dst = 0;
	q = dst + 1;
	while (*p && (*p != '.'))
	    *q++ = *p++;

	i = (int) (p - src);
	if (i > 0x3f)
	    return(-1);
	*dst = i;
	*q = 0;

	if (*p) {					/* update pointers */
	    dotflag = 1;
	    src = ++p;
	    dst = q;
	}
	else if (!dotflag && !defflag && loc_domain) {
	    p = loc_domain;		/* continue packing with default */
	    defflag = 1;
	    src = p;
	    dst = q;
	}
    }
    while (*p);
    q++;
    return((int) (q-savedst));			/* length of packed string */
}

/*********************************************************************/
/*  unpackdom
*  Unpack a compressed domain name that we have received from another
*  host.  Handles pointers to continuation domain names -- buf is used
*  as the base for the offset of any pointer which is present.
*  returns the number of bytes at src which should be skipped over.
*  Includes the NULL terminator in its length count.
*/
static int unpackdom( char *dst, char *src, char *buf )
{
    int i,j,retval;
    char *savesrc;

    savesrc = src;
    retval = 0;

    while (*src) {
	j = *src;

	while ((j & 0xC0) == 0xC0) {
	    if (!retval)
		retval = (int) (src-savesrc+2);
	    src++;
	    src = &buf[(j & 0x3f)*256+*src];		/* pointer dereference */
	    j = *src;
	}

	src++;
	for (i=0; i < (j & 0x3f) ; i++)
	    *dst++ = *src++;

	*dst++ = '.';
    }

    *(--dst) = 0;			/* add terminator */
    src++;					/* account for terminator on src */

    if (!retval)
	retval = (int) (src-savesrc);

    return(retval);
}

/*********************************************************************/
/*  sendom
*   put together a domain lookup packet and send it
*   uses port 53
*	num is used as identifier
*/
static int sendom( char *s, longword towho, word num, byte dtype )
{
    word i,ulen;
    byte *psave,*p;

    psave = (byte*)&(question->x);
    i = packdom((char *)&(question->x),s);

    p = &(question->x[i]);
    *p++ = 0;				/* high byte of qtype */
    *p++ = dtype;			/* number is < 256, so we know high byte=0 */
    *p++ = 0;				/* high byte of qclass */
    *p++ = DIN;				/* qtype is < 256 */

    question->h.ident = intel16(num);
    ulen = sizeof(struct dhead)+(p-psave);

    udp_open( dom_sock, 997, towho, 53, NULL );    /* divide err */

    sock_write( (sock_type*)dom_sock, (byte*)question, ulen );
    return( ulen);
}

static int countpaths( char *pathstring )
{
    int     count = 0;
    char    *p;

    for(p=pathstring; (*p != 0) || (*(p+1) != 0); p++) {
	if(*p == 0)
	    count++;
    }
    return(++count);
}

static char *getpath( char *pathstring, int whichone )
            /* the path list to search      */
            /* which path to get, starts at 1 */
{
    char    *retval;

    if(whichone > countpaths(pathstring))
	return(NULL);
    whichone--;
    for(retval = pathstring;whichone ; retval++ ) {
	if(*retval == 0)
	    whichone--;
    }
    return(retval);
}

/*
 * Unpack a DTYPA RR (address record)
 */
static void typea_unpacker( void *data,   /* where to put IP */
                    struct rrpart *rrp, struct useek *qp )
{
   qp = qp;
   movmem(rrp->rdata,data,4);	/* save IP # 		*/
}

/*
 * Unpack a DTYPEPTR RR
 *
 * assumes: data buffer long enough for the name.
 *          256 chars should be enough(?)
 */
static void typeptr_unpacker( void *data,
                     struct rrpart *rrp, struct useek *qp )
{
   unpackdom((char*)data,(char*)rrp->rdata,(char*)qp);
}

/*********************************************************************/
/*  ddextract
*   extract the data from a response message.
*   returns the appropriate status code and if the data is available,
*   copies it into data
*   dtype is the RR type;  unpacker is the function to get the data
*         from the RR.
*/
static longword ddextract( struct useek *qp, byte dtype,
                        unpacker_funct unpacker, void *data )
{
    word i,j,nans,rcode;
    struct rrpart *rrp;
    byte *p,space[260];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -