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

📄 domain.c

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

	qrrp = make_rr(RR_QUERY,sname,CLASS_IN,dtype,0,0,NULL);

	SysLfree(sname);



	while(looping > 0){

		if((result_rrlp=resolver(qrrp)) == NULL

		|| result_rrlp->type == dtype)

			break;



		/* Should be CNAME or PTR record */

		/* Replace name and try again */

		SysLfree(qrrp->name);

		qrrp->name = strdup(result_rrlp->rdata.name);

		free_rr(result_rrlp);

		result_rrlp = NULL;

		looping--;

	}

	free_rr(qrrp);

	return result_rrlp;

}



/* main entry point for address -> domain name resolution.

 * Returns string, or NULL if no name found.

 */

char *resolve_a(int32 ip_address, int shorten)

//int32 ip_address;		/* search address */

//int shorten;			/* return only first part of name (flag)*/

{

	struct rr *save_rrlp, *rrlp;

	char *result = NULL;



	for( rrlp = save_rrlp = inverse_a(ip_address);

	     rrlp != NULL && result == NULL;

	     rrlp = rrlp->next ){

		if(rrlp->rdlength > 0){

			switch(rrlp->type){

			case TYPE_PTR:

				result = strdup(rrlp->rdata.name);

				break;

			case TYPE_A:

				result = strdup(rrlp->name);

				break;

			}

		}

	}

	free_rr(save_rrlp);



	if(result != NULL && shorten){

		int dot;

		char *shortened;



		if((dot = strcspn(result, ".")) == 0){

			shortened = (char *)SysLcalloc(dot+1);

			strncpy(shortened, result, dot);

			shortened[dot] = '\0';

			SysLfree(result);

			result = shortened;

		}

	}

	return result;

}



/* Main entry point for domain name -> address resolution.

 * Returns 0 if name is currently unresolvable.

 */

int32 resolve(char *name)

{

	register struct rr *rrlp;

	int32 ip_address = 0;



	if(name == NULL)

		return 0;



	if(isaddr(name))

//		return atol(name);

		return inet_addr(name);



	if((rrlp = resolve_rr(name,TYPE_A)) != NULL

	 && rrlp->rdlength > 0)

		ip_address = rrlp->rdata.addr;



	/* multi-homed hosts are handled here */

//	if(rrlp != NULL && rrlp->next != NULL) {

//		register struct rr *rrp;

//		register struct route *rp;

//		u_int16 cost = MAXINT16;

//		rrp = rrlp;

		/* choose the best of a set of routes */

//		while(rrp != NULL) {

//			if(rrp->rdlength > 0

//			 && (rp = rt_lookup(rrp->rdata.addr)) != NULL

//			 && rp->metric <= cost) {

//				ip_address = rrp->rdata.addr;

//				cost = rp->metric;

//			}

//			rrp = rrp->next;

//		}

//	}



	free_rr(rrlp);

	return ip_address;

}





/* Main entry point for MX record lookup.

 * Returns 0 if name is currently unresolvable.

 */

int32 resolve_mx(char *name)

{

	register struct rr *rrp, *arrp;

	char *sname, *tmp, *cp;

	int32 addr, ip_address = 0;

	u_int16 pref = MAXINT16;



	if(name == NULL)

		return 0;



	if(isaddr(name)){

		if((sname = resolve_a(atol(name),FALSE)) == NULL)

			return 0;

	}

	else

		sname = strdup(name);



	cp = sname;

	while(1){

		rrp = arrp = resolve_rr(sname,TYPE_MX);

		/* Search this list of rr's for an MX record */

		while(rrp != NULL){

			if(rrp->rdlength > 0 && rrp->rdata.mx.pref <= pref &&

			   (addr = resolve(rrp->rdata.mx.exch)) != 0L){

				pref = rrp->rdata.mx.pref;

				ip_address = addr;

			}

			rrp = rrp->next;

		}

		free_rr(arrp);

		if(ip_address != 0)

			break;

		/* Compose wild card one level up */

		if((cp = (char *)strchr(cp,(int)'.')) == NULL)

			break;

		tmp = (char *)SysLcalloc(strlen(cp)+2);

		sprintf(tmp,"*%s",cp);		/* wildcard expansion */

		SysLfree(sname);

		sname = tmp;

		cp = sname + 2;

	}

	SysLfree(sname);

	return ip_address;

}



/* Search for local records of the MB, MG and MR type. Returns list of

 * matching records.

 */

struct rr *resolve_mailb(char *name)		/* local username, without trailing dot */

{

	register struct rr *result_rrlp;

	struct rr *rrlp;

	char *sname;



	/* Append trailing dot */

	sname = (char *)SysLcalloc(strlen(name)+2);

	sprintf(sname,"%s.",name);

	rrlp = make_rr(RR_QUERY,sname,CLASS_IN,TYPE_MB,0,0,NULL);

	rrlp->next = make_rr(RR_QUERY,sname,CLASS_IN,TYPE_MG,0,0,NULL);

	rrlp->next->next = make_rr(RR_QUERY,sname,CLASS_IN,TYPE_MR,0,0,NULL);

	SysLfree(sname);

	if((result_rrlp = dcache_search(rrlp)) == NULL){

		result_rrlp = dfile_search(rrlp);

	}

	free_rr(rrlp);

	if(Dsuffix != NULL){

		rrlp = result_rrlp;

		while(rrlp != NULL){	/* add domain suffix to data */

			if(rrlp->rdlength > 0 &&

			   rrlp->rdata.name[rrlp->rdlength-1] != '.'){

				sname = (char *)SysLcalloc(rrlp->rdlength +

					strlen(Dsuffix)+2);

				sprintf(sname,"%s.%s",rrlp->rdata.name,Dsuffix);

				SysLfree(rrlp->rdata.name);

				rrlp->rdata.name = sname;

				rrlp->rdlength = (unsigned short)(strlen(sname));

			}

			rrlp = rrlp->next;

		}

	}

	dcache_add(copy_rr_list(result_rrlp));

	return result_rrlp;

}

















/*>>>>>>>>>>>>>>>>>>>>APPEND FUNCTIONS<<<<<<<<<<<<<<<<<<<*/



/* Copy a string to a SysLmalloc'ed buffer. Turbo C has this one in its

 * library, but it doesn't call SysLmalloc() and can therefore return NULL.

 * NOS uses of strdup() generally don't check for NULL, so they need this one.

 */

char *strdup(const char *s)

{

	register char *out;

	register int len;



	if(s == NULL)

		return NULL;

	len = strlen(s);

	out = (char *)SysLcalloc(len+1);

	/* This is probably a tad faster than strcpy, since we know the len */

	memcpy(out,s,len);

	out[len] = '\0';

	return out;

}



/* Get the dns packet header from the data buf, return -1 if failed,

 * return 0 if successful.

 */

int getdnshdr(struct dhdr *dhdr, u_char *buf)

{

	u_int16 tmp;

	register u_int16 i;

	u_int8 *cp;

	struct rr **rrpp;

	

	dhdr->id = get16(&buf[0]);

	tmp = get16(&buf[2]);

	if(tmp & 0x8000)

		dhdr->qr = 1;

	dhdr->opcode = (tmp >> 11) & 0xf;

	if(tmp & 0x0400)

		dhdr->aa = 1;

	if(tmp & 0x0200)

		dhdr->tc = 1;

	if(tmp & 0x0100)

		dhdr->rd = 1;

	if(tmp & 0x0080)

		dhdr->ra = 1;

	dhdr->rcode = tmp & 0xf;

	dhdr->qdcount = get16(&buf[4]);

	dhdr->ancount = get16(&buf[6]);

	dhdr->nscount = get16(&buf[8]);

	dhdr->arcount = get16(&buf[10]);

	

	/* Now parse the variable length sections */

	cp = &buf[12];



	/* Question section */

	rrpp = &dhdr->questions;

	for(i=0;i<dhdr->qdcount;i++){

		if((cp = (u_int8 *)getq(rrpp,buf,cp)) == NULL){

			SysLfree(buf);

			return -1;

		}

		(*rrpp)->source = RR_QUESTION;

		rrpp = &(*rrpp)->next;

	}

	*rrpp = NULL;



	/* Answer section */

	rrpp = &dhdr->answers;

	for(i=0;i<dhdr->ancount;i++){

		if((cp = (u_int8 *)ntohrr(rrpp,buf,cp)) == NULL){

			SysLfree(buf);

			return -1;

		}

		(*rrpp)->source = RR_ANSWER;

		rrpp = &(*rrpp)->next;

	}

	*rrpp = NULL;



	/* Name server (authority) section */

	rrpp = &dhdr->authority;

	for(i=0;i<dhdr->nscount;i++){

		if((cp = (u_int8 *)ntohrr(rrpp,buf,cp)) == NULL){

			SysLfree(buf);

			return -1;

		}

		(*rrpp)->source = RR_AUTHORITY;

		rrpp = &(*rrpp)->next;

	}

	*rrpp = NULL;



	/* Additional section */

	rrpp = &dhdr->additional;

	for(i=0;i<dhdr->arcount;i++){

		if((cp = (u_int8 *)ntohrr(rrpp,buf,cp)) == NULL){

			SysLfree(buf);

			return -1;

		}

		(*rrpp)->source = RR_ADDITIONAL;

		rrpp = &(*rrpp)->next;

	}

	*rrpp = NULL;

	SysLfree(buf);

	return 0;

}







static u_int8 *getq(rrpp,msg,cp)

struct rr **rrpp;

u_int8 *msg;

u_int8 *cp;

{

	register struct rr *rrp;

	int len;

	char *name;



	*rrpp = rrp = (struct rr *)SysLcalloc(sizeof(struct rr));

	name = (char *)SysLcalloc(512);

	len = dn_expand(msg,NULL,cp,name,512);

	if(len == -1){

		SysLfree(name);

		return NULL;

	}

	cp += len;

	rrp->name = strdup(name);

	rrp->type = get16(cp);

	cp += 2;

	rrp->class = get16(cp);

	cp += 2;

	rrp->ttl = 0;

	rrp->rdlength = 0;

	SysLfree(name);

	return cp;

}

/* Read a resource record from a domain message into a host structure */

static u_int8 *

ntohrr(rrpp,msg,cp)

struct rr **rrpp; /* Where to allocate resource record structure */

u_int8 *msg;	/* Pointer to beginning of domain message */

u_int8 *cp;	/* Pointer to start of encoded RR record */

{

	register struct rr *rrp;

	int len;

	char *name;



	*rrpp = rrp = (struct rr *)SysLcalloc(sizeof(struct rr));

	name = (char *)SysLcalloc(512);

	if((len = dn_expand(msg,NULL,cp,name,512)) == -1){

		SysLfree(name);

		return NULL;

	}

	cp += len;

	rrp->name = strdup(name);

	rrp->type = get16(cp);

	cp += 2;

	rrp->class = get16(cp);

	cp+= 2;

	rrp->ttl = get32(cp);

	cp += 4;

	rrp->rdlength = get16(cp);

	cp += 2;

	switch(rrp->type){

	case TYPE_A:

		/* Just read the address directly into the structure */

		rrp->rdata.addr = get32(cp);

		cp += 4;

		break;

	case TYPE_CNAME:

	case TYPE_MB:

	case TYPE_MG:

	case TYPE_MR:

	case TYPE_NS:

	case TYPE_PTR:

		/* These types all consist of a single domain name;

		 * convert it to ascii format

		 */

		len = dn_expand(msg,NULL,cp,name,512);

		if(len == -1){

			SysLfree(name);

			return NULL;

		}

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

		rrp->rdlength = (unsigned short)(strlen(name));

		cp += len;

		break;

	case TYPE_HINFO:

		len = *cp++;

		rrp->rdata.hinfo.cpu = (char *)SysLcalloc(len+1);

		strncpy(rrp->rdata.hinfo.cpu,(char *)cp,len);

		cp += len;



		len = *cp++;

		rrp->rdata.hinfo.os = (char *)SysLcalloc(len+1);

		strncpy(rrp->rdata.hinfo.os,(char *)cp,len);

		cp += len;

		break;

	case TYPE_MX:

		rrp->rdata.mx.pref = get16(cp);

		cp += 2;

		/* Get domain name of exchanger */

		len = dn_expand(msg,NULL,cp,name,512);

		if(len == -1){

			SysLfree(name);

			return NULL;

		}

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

		cp += len;

		break;

	case TYPE_SOA:

		/* Get domain name of name server */

		len = dn_expand(msg,NULL,cp,name,512);

		if(len == -1){

			SysLfree(name);

			return NULL;

		}

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

		cp += len;



		/* Get domain name of responsible person */

		len = dn_expand(msg,NULL,cp,name,512);

		if(len == -1){

			SysLfree(name);

			return NULL;

		}

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

		cp += len;



		rrp->rdata.soa.serial = get32(cp);

		cp += 4;

		rrp->rdata.soa.refresh = get32(cp);

		cp += 4;

		rrp->rdata.soa.retry = get32(cp);

		cp += 4;

		rrp->rdata.soa.expire = get32(cp);

		cp += 4;

		rrp->rdata.soa.minimum = get32(cp);

		cp += 4;

		break;

	case TYPE_TXT:

		/* Just stash */

		rrp->rdata.data = (char *)SysLcalloc(rrp->rdlength);

		memcpy(rrp->rdata.data,cp,rrp->rdlength);

		cp += rrp->rdlength;

		break;

	default:

		/* Ignore */

		cp += rrp->rdlength;

		break;

	}

	SysLfree(name);

	return cp;

}



/* Convert a compressed domain name to the human-readable form */

static int

dn_expand(msg,eom,compressed,full,fullen)

u_int8 *msg;		/* Complete domain message */

u_int8 *eom;

u_int8 *compressed;	/* Pointer to compressed name */

char *full;		/* Pointer to result buffer */

int fullen;		/* Length of same */

{

	unsigned int slen;	/* Length of current segment */

	register u_int8 *cp;

	int clen = 0;	/* Total length of compressed name */

	int indirect = 0;	/* Set if indirection encountered */

	int nseg = 0;		/* Total number of segments in name */



	cp = compressed;

	for(;;){

		slen = *cp++;	/* Length of this segment */

		if(!indirect)

			clen++;

		if((slen & 0xc0) == 0xc0){

			if(!indirect)

				clen++;

			indirect = 1;

			/* Follow indirection */

			cp = &msg[((slen & 0x3f)<<8) + *cp];

			slen = *cp++;

		}

		if(slen == 0)	/* zero length == all done */

			break;

		fullen -= slen + 1;

		if(fullen < 0)

			return -1;

		if(!indirect)

			clen += slen;

		while(slen-- != 0)

			*full++ = (char)*cp++;

		*full++ = '.';

		nseg++;

	}

	if(nseg == 0){

		/* Root name; represent as single dot */

		*full++ = '.';

		fullen--;

	}

	*full++ = '\0';

	fullen--;

	return clen;	/* Length of compressed message */

}



/* Put a long in host order into a char array in network order */

static u_int8 *put32(cp,x)

register u_int8 *cp;

int32 x;

{

	*cp++ = (unsigned char)(x >> 24);

	*cp++ = (unsigned char)(x >> 16);

	*cp++ = (unsigned char)(x >> 8);

	*cp++ = (unsigned char)x;

	return cp;

}

/* Put a short in host order into a char array in network order */

static u_int8 *put16(cp,x)

register u_int8 *cp;

u_int16 x;

{

	*cp++ = x >> 8;

	*cp++ = (unsigned char)x;



	return cp;

}



static u_int16 get16(u_int8 *cp)

{

	register u_int16 x;



	x = *cp++;

	x <<= 8;

	x |= *cp;

	return x;

}

/* Machine-independent, alignment insensitive network-to-host long conversion */

static int32 get32(u_int8 *cp)

{

	int32 rval;



	rval = *cp++;

	rval <<= 8;

	rval |= *cp++;

	rval <<= 8;

	rval |= *cp++;

	rval <<= 8;

	rval |= *cp;



	return rval;

}



int setint(var,label,argc,argv)

int *var;

char *label;

int argc;

char *argv[];

{

	*var = atoi(argv[1]);

	return 0;

}


⌨️ 快捷键说明

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