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

📄 domain.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/*

 *	DOMAIN.C -- domain name system stub resolver

 *	Original code by zhengkaidong&lingming

 */

 

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>


#include <sys\lmalloc.h>



#include "net.h"
#include "netudp.h"
#include "netconf.h"

#include "domain.h"
#include "InetAddr.h"






//#undef	DEBUG				/* for certain trace messages */

//#undef	DEBUG_PAIN			/* for painful debugging */



struct rr *Dcache = NULL;		/* Cache of resource records */

int Dcache_size = 20;			/* size limit */



int Dfile_clean = FALSE; 		/* discard expired records (flag) */

int Dfile_reading = 0;			/* read interlock (count) */

int Dfile_writing = 0;			/* write interlock (count) */



struct proc *Dfile_updater = NULL;

int32 Dfile_wait_absolute = 0L;		/* timeout Clock time */

int Dfile_wait_relative = 300;		/* timeout file activity (seconds) */



struct dserver *Dservers = NULL; 	/* List of potential servers */

int Dserver_retries = 2;		/* Attempts to reach servers */



char *Dsuffix = NULL;			/* Default suffix for names without periods */

int Dtrace = FALSE;



static char *Dtypes[] = {

	"",

	"A",

	"NS",

	"MD",

	"MF",

	"CNAME",

	"SOA",

	"MB",

	"MG",

	"MR",

	"NULL",

	"WKS",

	"PTR",

	"HINFO",

	"MINFO",

	"MX",

	"TXT"

};

static int Ndtypes = 17;

// static char delim[] = " \t\r\n";                           已经修改



/*static int docache(int argc,char *argv[],void *p);

static int dosuffix(int argc,char *argv[],void *p);



static int docacheclean(int argc,char *argv[],void *p);

static int docachelist(int argc,char *argv[],void *p);

static int docachesize(int argc,char *argv[],void *p);

static int docachewait(int argc,char *argv[],void *p);

*/

static void dlist_add(struct dserver *dp);

static void dlist_drop(struct dserver *dp);

/*

static int dodnsadd(int argc,char *argv[],void *p);

static int dodnsdrop(int argc,char *argv[],void *p);

static int dodnslist(int argc,char *argv[],void *p);

static int dodnsquery(int argc,char *argv[],void *p);

static int dodnsretry(int argc,char *argv[],void *p);

static int dodnstrace(int argc,char *argv[],void *p);*/



static char * dtype(int value);

static int check_ttl(struct rr *rrlp);

static int compare_rr(struct rr *search_rrp,struct rr *target_rrp);

static int compare_rr_list(struct rr *rrlp,struct rr *target_rrp);

static struct rr *copy_rr(struct rr *rrp);

static struct rr *copy_rr_list(struct rr *rrlp);

static struct rr *make_rr(int source,

	char *dname,u_int16 class,u_int16 type,int32 ttl,u_int16 rdl,void *data);



static void dcache_add(struct rr *rrlp);

static void dcache_drop(struct rr *rrp);

static struct rr *dcache_search(struct rr *rrlp);

static void dcache_update(struct rr *rrlp);



static struct rr *get_rr(KFILE *fp, struct rr *lastrrp);

static void put_rr(KFILE *fp,struct rr *rrp);

static struct rr *dfile_search(struct rr *rrlp);

static void dfile_update(int s,void *unused,void *p);



static void dumpdomain(struct dhdr *dhp,int32 rtt);

static int dns_makequery(u_int16 op,struct rr *rrp,

								u_int8 *buffer,u_int16 buflen);

static int dns_query(struct rr *rrlp);



static int isaddr(char *s);/* we may use it in other program*/

static char *checksuffix(char *dname);

static struct rr *resolver(struct rr *rrlp);



char *strdup(const char *s);

static u_int8 *put16(u_int8 *cp, u_int16 x);

static u_int8 *put32(u_int8 *cp, int32 x);

static u_int16 get16(u_int8 *cp);

static int32 get32(u_int8 *cp);

static int dn_expand(u_int8 *msg,u_int8 *eom,

					u_int8 *compressed,char *full,int fullen);

static u_int8 *getq(struct rr **rrpp,u_int8 *msg,u_int8 *cp);

static u_int8 *ntohrr(struct rr **rrpp,u_int8 *msg,u_int8 *cp);

int setint(int *var, char *label, int argc, char *argv[]);



void free_rr(struct rr *rrlp);

struct rr *inverse_a(int32 ip_address);

struct rr *resolve_rr(char *dname,u_int16 dtype);

char *resolve_a(int32 ip_address, int shorten);

struct rr *resolve_mailb(char *name);





/**

 **	Domain Resolver Commands

 **/



/*static struct cmds Dcmds[] = {

	"addserver",	dodnsadd,	0, 2, "add <hostid>",

	"dropserver",	dodnsdrop,	0, 2, "drop <hostid>",

	"list",		dodnslist,	0, 0, NULL,

	"query",	dodnsquery,   512, 2, "query <hostid>",

	"retry",	dodnsretry,	0, 0, NULL,

	"suffix",	dosuffix,	0, 0, NULL,

	"trace",	dodnstrace,	0, 0, NULL,

	"cache",	docache,	0, 0, NULL,

	NULL,

};



static struct cmds Dcachecmds[] = {

	"clean",	docacheclean,	0, 0, NULL,

	"list",		docachelist,  512, 0, NULL,

	"size",		docachesize,	0, 0, NULL,

	"wait",		docachewait,	0, 0, NULL,

	NULL,

};



int

dodomain(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	return subcmd(Dcmds,argc,argv,p);

}



static int

docache(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	return subcmd(Dcachecmds,argc,argv,p);

}



static int

dosuffix(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	if(argc < 2){

		return 0;

	}

	SysLfree(Dsuffix);

	Dsuffix = strdup(argv[1]);

	return 0;

}



static int

docacheclean(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	return 0;

}



static int

docachelist(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	struct rr *rrp;

	struct session *sp;

	int row = 25;



	(void)dcache_search(NULL); 

	return 0;

}



static int

docachesize(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	int newsize;

	int oldsize;

	int result;



	newsize = oldsize = Dcache_size;

	result = setint( &newsize, "memory cache size", argc,argv );



	if(newsize > 0){

		Dcache_size = newsize;

		if(newsize < oldsize){

			(void)dcache_search(NULL); // update size 

		}

	}

	return result;

}



static int

docachewait(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	return setint( &Dfile_wait_relative, "time before file update (seconds)", argc,argv );

}*/



static void

dlist_add(struct dserver *dp)

{

	struct dserver *server;

	

	server = Dservers;

	while (server != NULL) {

		if (server->address == dp->address) return;

		else server = server->next;

		}

	dp->prev = NULL;

	dp->next = Dservers;

	if(Dservers != NULL)

		Dservers->prev = dp;

	Dservers = dp;

}



static void

dlist_drop(dp)

register struct dserver *dp;

{

	if(dp->prev != NULL)

		dp->prev->next = dp->next;

	else

		Dservers = dp->next;

	if(dp->next != NULL)

		dp->next->prev = dp->prev;

}



/*static int

dodnsadd(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	int32 address;

	char *tempstr;



	if((address = resolve(argv[1])) == 0L){

		sprintf(tempstr,"Resolver %s unknown\n",argv[1]);

		//Disp16String(tempstr,10,10);

		return 1;

	}

	return add_nameserver(address);

}*/



int add_nameserver(address)

int32 address;

{

	struct dserver *dp;



	if ((dp = (struct dserver *)SysLcalloc(sizeof(struct dserver))) == NULL) 

		return -1;

	dp->address = address;

	dp->srtt = INITRTT;

	dp->mdev = 0;

	dp->timeout = 2 * dp->mdev + dp->srtt + 3;

	dlist_add(dp);

	return 0;

}



/*static int

dodnsdrop(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	struct dserver *dp;

	int32 addr;



	addr = resolve(argv[1]);

	for(dp = Dservers;dp != NULL;dp = dp->next)

		if(addr == dp->address)

			break;



	if(dp == NULL){

		//Disp16String("Not found",10,10);

		return 1;

	}



	dlist_drop(dp);

	SysLfree(dp);

	return 0;

}



static int

dodnslist(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	register struct dserver *dp;



	return 0;

}



static int

dodnsquery(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	struct rr *rrp;

	struct rr *result_rrlp;

	char *sname;

	struct session *sp;

	int row = 25;



	if ( isaddr( argv[1] ) ) {

		result_rrlp = inverse_a( atol( argv[1] ) );

	} else {

		sname = checksuffix( argv[1] );

		rrp = make_rr(RR_QUERY,sname,CLASS_IN,TYPE_ANY,0,0,NULL);

		SysLfree(sname);



		dns_query(rrp);

		result_rrlp = dcache_search(rrp);

		free_rr(rrp);

	}

	return 0;

}



static int

dodnsretry(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	return setint( &Dserver_retries, "server retries", argc,argv );

}



static int

dodnstrace(argc,argv,p)

int argc;

char *argv[];

void *p;

{

	return 0;

}*/





/**

 **	Domain Resource Record Utilities

 **/



static char *

dtype(value)

int value;

{

	static char buf[10];



	if (value < Ndtypes)

		return Dtypes[value];



	sprintf( buf, "{%d}", value);

	return buf;

}



/* check list of resource records for any expired ones.

 * returns number of expired records.

 */

static int

check_ttl(rrlp)

register struct rr *rrlp;

{

	int count = 0;



	while(rrlp != NULL){

		if(rrlp->ttl == 0L)

			count++;

		rrlp = rrlp->next;

	}

	return count;

}



/* Compare two resource records.

 * returns 0 if match, nonzero otherwise.

 */

static int

compare_rr(search_rrp,target_rrp)

register struct rr *search_rrp,*target_rrp;

{

	int i;



	if(search_rrp == NULL || target_rrp == NULL)

		return -32765;



	if(search_rrp->class != target_rrp->class)

		return -32763;



	if(search_rrp->type != TYPE_ANY

	&& search_rrp->type != target_rrp->type

	&& (search_rrp->source != RR_QUERY

	 || (target_rrp->type != TYPE_CNAME

	  && target_rrp->type != TYPE_PTR)))

		return -32761;



	if(search_rrp->source != RR_INQUERY){

		if((i = strlen(search_rrp->name)) != (signed int)(strlen(target_rrp->name)))

			return -32759;

		if((i = strncmp(search_rrp->name,target_rrp->name,i)) != 0)/*modified by zkd 8.19 1999*/

			return i;



		/* match negative records so that they are replaced */

		if(target_rrp->rdlength == 0)

			return 0;

	}



	/* if a query has gotten this far, match it */

	if(search_rrp->source == RR_QUERY)

		return 0;



	/* ensure negative records don't replace older records */

	if(search_rrp->rdlength == 0)

		return -32757;



	/* match expired records so that they are replaced */

	if(search_rrp->source != RR_INQUERY){

		if(target_rrp->ttl == 0L)

			return 0;

	}



	/* Note: rdlengths are not compared because they vary depending

	 * on the representation (ASCII or encoded) this record was

	 * generated from.

	 */



	switch(search_rrp->type){

	case TYPE_A:

		i = search_rrp->rdata.addr != target_rrp->rdata.addr;

		break;

	case TYPE_CNAME:

	case TYPE_MB:

	case TYPE_MG:

	case TYPE_MR:

	case TYPE_NS:

	case TYPE_PTR:

	case TYPE_TXT:

		i = strcmp(search_rrp->rdata.data,target_rrp->rdata.data);

		break;

	case TYPE_HINFO:

		i = strcmp(search_rrp->rdata.hinfo.cpu,target_rrp->rdata.hinfo.cpu) ||

			strcmp(search_rrp->rdata.hinfo.os,target_rrp->rdata.hinfo.os);

		break;

	case TYPE_MX:

		i = strcmp(search_rrp->rdata.mx.exch,target_rrp->rdata.mx.exch);

		break;

	case TYPE_SOA:

		i = search_rrp->rdata.soa.serial != target_rrp->rdata.soa.serial;

		break;

	default:

		i = -32755;	/* unsupported */

	}

	return i;

}



static int

compare_rr_list(rrlp,target_rrp)

register struct rr *rrlp,*target_rrp;

{

	while(rrlp != NULL){

		if(compare_rr(rrlp,target_rrp) == 0)

			return 0;

		rrlp = rrlp->next;

	}

	return -32767;

}



/* Make a new copy of a resource record */

static struct rr *copy_rr(struct rr *rrp)

{

	register struct rr *newrr;



	if(rrp == NULL)

		return NULL;



	newrr = (struct rr *)SysLcalloc(sizeof(struct rr));

	newrr->source =	rrp->source;

	newrr->name =	strdup(rrp->name);

	newrr->type =	rrp->type;

	newrr->class =	rrp->class;

	newrr->ttl =	rrp->ttl;

	if((newrr->rdlength = rrp->rdlength) == 0)

		return newrr;



	switch(rrp->type){

	case TYPE_A:

		newrr->rdata.addr = rrp->rdata.addr;

		break;

	case TYPE_CNAME:

	case TYPE_MB:

	case TYPE_MG:

	case TYPE_MR:

	case TYPE_NS:

	case TYPE_PTR:

	case TYPE_TXT:

		newrr->rdata.name = strdup(rrp->rdata.name);

		break;

	case TYPE_HINFO:

		newrr->rdata.hinfo.cpu = strdup(rrp->rdata.hinfo.cpu);

		newrr->rdata.hinfo.os = strdup(rrp->rdata.hinfo.os);

		break;

	case TYPE_MX:

		newrr->rdata.mx.pref = rrp->rdata.mx.pref;

		newrr->rdata.mx.exch = strdup(rrp->rdata.mx.exch);

		break;

	case TYPE_SOA:

		newrr->rdata.soa.mname = 	strdup(rrp->rdata.soa.mname);

		newrr->rdata.soa.rname = 	strdup(rrp->rdata.soa.rname);

		newrr->rdata.soa.serial = 	rrp->rdata.soa.serial;

		newrr->rdata.soa.refresh = 	rrp->rdata.soa.refresh;

		newrr->rdata.soa.retry = 	rrp->rdata.soa.retry;

		newrr->rdata.soa.expire = 	rrp->rdata.soa.expire;

		newrr->rdata.soa.minimum = 	rrp->rdata.soa.minimum;

		break;

	}

	return newrr;

}



static struct rr *copy_rr_list(struct rr *rrlp)

{

	register struct rr **rrpp;

	struct rr *result_rrlp;



	rrpp = &result_rrlp;

⌨️ 快捷键说明

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