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

📄 ns_validate.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		free(nameaddrlist[firstNA].nsname);		nameaddrlist[firstNA].nsname = 0;		lastNA = (lastNA+1) % MAXNAMECACHE;	}	return;}/* * Decode the resource record 'rrp' and validate the RR. * Borrows code almost entirely from doupdate(). is a rather * non-invasive routine since it just goes thru the same motions * as doupdate but just marks the array validatelist entry as  * the return code from validate(). This is later used in doupdate * to cache/not cache the entry. also used in update_msg() to  * delete/keep the record from the outgoing message. */intdovalidate(msg, msglen, rrp, zone, flags, server, VCode)	char *msg;	u_char *rrp;	int  msglen, zone, flags;	struct sockaddr_in *server;	int *VCode;{	register u_char *cp;	register int n;	int class, type, dlen, n1;	u_int32_t ttl;	char dname[MAXDNAME];	u_char *cp1;	u_char data[BUFSIZ];	register HEADER *hp = (HEADER *) msg;	dprintf(2, (ddt, "dovalidate(zone %d, flags %x)\n",		    zone, flags));#ifdef DEBUG	if(debug >= 10)		fp_query((char *)msg,ddt);#endif	cp = rrp;	if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen, cp,			   (u_char *)dname, sizeof(dname))) < 0) {		hp->rcode = FORMERR;		return (-1);	}	cp += n;	GETSHORT(type, cp);	GETSHORT(class, cp);	GETLONG(ttl, cp);	GETSHORT(dlen, cp);	dprintf(2, (ddt, "dovalidate: dname %s type %d class %d ttl %d\n",		    dname, type, class, ttl));	/*	 * Convert the resource record data into the internal	 * database format.	 */	switch (type) {	case T_A:	case T_WKS:	case T_HINFO:	case T_UINFO:	case T_UID:	case T_GID:	case T_TXT:#ifdef ALLOW_T_UNSPEC	case T_UNSPEC:#endif		cp1 = cp;		n = dlen;		cp += n;		break;	case T_CNAME:	case T_MB:	case T_MG:	case T_MR:	case T_NS:	case T_PTR:		if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen,				   cp, data, sizeof(data))) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 = data;		n = strlen((char *)data) + 1;		break;	case T_MINFO:	case T_SOA:	case T_RP:		if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen,				   cp, data, sizeof(data))) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 = data + (n = strlen((char *)data) + 1);		n1 = sizeof(data) - n;		if (type == T_SOA)			n1 -= 5 * sizeof(u_int32_t);		if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen,				   cp, cp1, n1)) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 += strlen((char *)cp1) + 1;		if (type == T_SOA) {			bcopy((char *)cp, (char *)cp1, n = 5 * sizeof(u_int32_t));			cp += n;			cp1 += n;		}		n = cp1 - data;		cp1 = data;		break;	case T_MX:	case T_AFSDB:		/* grab preference */		bcopy((char *)cp, data, sizeof(u_int16_t));		cp1 = data + sizeof(u_int16_t);		cp += sizeof(u_int16_t);		/* get name */		if ((n = dn_expand((u_char *)msg, (u_char *)msg + msglen,				   cp, cp1, sizeof(data) - sizeof(u_int16_t)))		    < 0) {			hp->rcode = FORMERR;			return(-1);		}		cp += n;		/* compute end of data */		cp1 += strlen((char *)cp1) + 1;		/* compute size of data */		n = cp1 - data;		cp1 = data;		break;	default:		dprintf(3, (ddt, "unknown type %d\n", type));		return ((cp - rrp) + dlen);	}	if (n > MAXDATA) {		dprintf(2, (ddt,			    "update type %d: %d bytes is too much data\n",			    type, n));		hp->rcode = NOCHANGE;	/* XXX - FORMERR ??? */		return(-1);	}	*VCode = validate(dname, server, type, class,(char *)cp1, n#ifdef NCACHE			  ,NOERROR#endif			  );	if (*VCode == INVALID) {		dprintf(2, (ddt,			    "validation failed d:%s, t:%d, c:%d\n",			    dname, type, class));	} else {		dprintf(2, (ddt,			    "validation succeeded d:%s, t:%d, c:%d\n",			    dname, type, class));	}	return(cp -rrp);}/******************************************************************  * This manages a data structure that stores all RRs that we were  * unable to validate. Am not sure exactly what purpose this might  * serve but until such time as we are sure it will not help, let  * me do it anyway.  *****************************************************************/static voidstick_in_queue(dname, type, class, data)	char *dname;	int type;	int class;	char *data;{	struct timeval tp;	struct timezone tzp;	TO_Validate *tempVQ;	u_long leasttime;	if (validateQ == NULL) {		validateQ = (TO_Validate *)malloc(sizeof(TO_Validate));		validateQ->type = type;		validateQ->class = class;		validateQ->dname = malloc((unsigned)strlen(dname)+1);		strcpy(validateQ->dname, dname);		validateQ->data = malloc((unsigned)strlen(data)+1);		strcpy(validateQ->data, data);		gettimeofday(&tp, &tzp);		validateQ->time = tp.tv_sec;		VQcount = 1;		validateQ->next = validateQ->prev = NULL;		currentVQ = validateQ;		return;	}	if (VQcount < MAXVQ) {		tempVQ =(TO_Validate *)malloc(sizeof(TO_Validate));		tempVQ->type = type;		tempVQ->class = class;		tempVQ->dname = malloc((unsigned)strlen(dname)+1);		strcpy(tempVQ->dname, dname);		tempVQ->data = malloc((unsigned)strlen(data)+1);		strcpy(tempVQ->data, data);		gettimeofday(&tp,&tzp);		tempVQ->time = tp.tv_sec;		tempVQ->next = currentVQ->next;		tempVQ->prev = currentVQ;		if (currentVQ->next != NULL)			currentVQ->next->prev = tempVQ;		currentVQ->next = tempVQ;		currentVQ = tempVQ;		VQcount++;		return;	}	gettimeofday(&tp, &tzp);	leasttime = validateQ->time;	currentVQ = validateQ;	for (tempVQ = validateQ;  tempVQ != NULL;  tempVQ = tempVQ->next) {		if (tp.tv_sec >= tempVQ->time +VQEXPIRY) {			tempVQ->type = type;			tempVQ->class = class;			strcpy(tempVQ->dname, dname);			strcpy(tempVQ->data, data);			tempVQ->time = tp.tv_sec;			currentVQ = tempVQ;			return;		}		if (tempVQ->time < leasttime) {			leasttime = tempVQ->time;			currentVQ = tempVQ;		}	}	currentVQ->type = type;	currentVQ->class = class;	strcpy(currentVQ->dname, dname);	strcpy(currentVQ->data, data);	currentVQ->time = tp.tv_sec;	return;}/* removes any INVALID RR's from the msg being returned, updates msglen to * reflect the new message length. */intupdate_msg(msg, msglen, Vlist, c)	u_char *msg;	int *msglen;	int Vlist[];	int c;{	register HEADER *hp;	register u_char *cp;	int i;	int n = 0;	u_char *tempcp, *newcp;	int *RRlen;	int qlen; /* the length of the query section*/	u_int16_t rdlength;	u_int16_t ancount, nscount;	u_int16_t new_ancount, new_nscount, new_arcount;	char dname[MAXDNAME], qname[MAXDNAME];	u_char data[MAXDNAME];	u_char **dpp;	u_char *dnptrs[40];	u_char **edp = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);	u_char *eom = msg + *msglen;	int n_new;	int rembuflen, newlen;	u_char *newmsg;	u_int16_t type, class, dlen;	u_int32_t ttl;	int inv = 0;#ifdef DEBUG	if (debug) {		fprintf(ddt, "update_msg: msglen:%d, c:%d\n", *msglen, c);		if (debug >= 10)			fp_query((char *)msg,ddt);	}#endif	/* just making sure we do not do all the work for nothing */	for (i=0;  i<c;  i++) { 		if (Vlist[i] == INVALID) {			inv = 1;			break;		}	}	if (inv != 1) {		/* no invalid records, go about your job */		return (0);	}	dprintf(2, (ddt, "update_msg: NEEDS updating:\n"));	RRlen = (int *)malloc((unsigned)c*sizeof(int));	hp = (HEADER *)msg;	new_ancount = ancount = ntohs(hp->ancount);	new_nscount = nscount = ntohs(hp->nscount);	new_arcount = ntohs(hp->nscount);	cp = msg + sizeof(HEADER);	newlen = sizeof(HEADER);	/* skip the query section */	qlen = dn_expand(msg, eom, cp, (u_char *)qname, sizeof(qname));	if (qlen <= 0) {		dprintf(2, (ddt, "dn_skipname() failed, bad record\n"));		goto badend;	}	cp +=qlen;	GETSHORT(type,cp);	GETSHORT(class,cp);	qlen += 2 * sizeof(u_int16_t);	newlen += qlen;	for (i = 0;  i < c;  i++) {		if (Vlist[i] == INVALID) {			if (i < ancount)				new_ancount--;			else if (i < ancount+nscount)				new_nscount--;			else				new_arcount--;		}		RRlen[i] = dn_skipname(cp, msg + *msglen);		if (RRlen[i] <= 0) {			dprintf(2, (ddt,				    "dn_skipname() failed, bad record\n"));			goto badend;		}		RRlen[i] += 2 * sizeof(u_int16_t) + sizeof(u_int32_t);				/*type+class+TTL*/		cp += RRlen[i];		GETSHORT(rdlength, cp);		RRlen[i] += sizeof(u_int16_t); /*rdlength*/		RRlen[i] += rdlength; /*rdata field*/		dprintf(3, (ddt, "RRlen[%d]=%d\n", i, RRlen[i]));		if (Vlist[i] != INVALID)			newlen += RRlen[i];		cp += rdlength; /*increment pointer to next RR*/	}	hp->ancount = htons(new_ancount);	hp->nscount = htons(new_nscount);	hp->arcount = htons(new_nscount);	/* get new buffer */	dprintf(3, (ddt,		    "newlen:%d, if no RR is INVALID == msglen\n", newlen));	newmsg = (u_char *)calloc(1,newlen + MAXDNAME);	if(newmsg == NULL)		goto badend;	dpp = dnptrs;	*dpp++ = newmsg;	*dpp = NULL;	/* bcopy the header, with all the length fields correctly put in */	bcopy((char *)msg, (char*)newmsg, sizeof(HEADER)); /*header copied */	newcp = newmsg +sizeof(HEADER);  /*need a pointer in the new buffer */	rembuflen = newlen +MAXDNAME - sizeof(HEADER); /*buflen we can workin*/	newlen = sizeof(HEADER); /* this will now contain the length of msg */	n_new = dn_comp((u_char *)qname, (u_char *)newcp, rembuflen,			(u_char **)dnptrs, (u_char **)edp);	if (n_new < 0)		goto badend;	newcp += n_new;	PUTSHORT(type, newcp);	PUTSHORT(class, newcp); /*query section complete*/	newlen += (n_new+2*sizeof(u_int16_t));	rembuflen -= (n_new+2*sizeof(u_int16_t));	/* have to decode and copy every Valid RR from here */  	cp = msg +sizeof(HEADER) +qlen;	/*skip header and query section*/	for (i = 0;  i < c;  i++) {		if (Vlist[i] == INVALID) {			/* go to next RR if this one is not INVALID */			cp += RRlen[i];			continue;		}		/* we have a valid record, must put it in the newmsg */		if ((n = dn_expand((u_char *)msg, eom, cp,				   (u_char *)dname, sizeof(dname))) < 0) {			hp->rcode = FORMERR;			goto badend;		}		n_new = dn_comp((u_char *)dname, (u_char *)newcp, rembuflen,				(u_char **)dnptrs, (u_char **)edp); 		if (n_new < 0)			goto badend;		cp += n;		newcp += n_new;		dprintf(5, (ddt,			    "cp:0x%x newcp:0x%x after getting name\n",			    cp, newcp));		GETSHORT(type, cp);		PUTSHORT(type, newcp);		dprintf(5, (ddt,			    "cp:0x%x newcp:0x%x after getting type\n",			    cp, newcp));		GETSHORT(class, cp);		PUTSHORT(class, newcp);		dprintf(5, (ddt,			    "cp:0x%x newcp:0x%x after getting class\n",			    cp, newcp));		GETLONG(ttl, cp);		PUTLONG(ttl, newcp);		dprintf(5, (ddt,			    "cp:0x%x newcp:0x%x after getting ttl\n",			    cp, newcp));		/* this will probably be modified for newmsg,		 * will put this in later, after compression		 */		GETSHORT(dlen, cp);		newlen += (n_new+3*sizeof(u_int16_t) + sizeof(u_int32_t));		rembuflen -= (n_new+3*sizeof(u_int16_t)+ sizeof(u_int32_t));		tempcp = newcp;		newcp += sizeof(u_int16_t); /*advance to rdata field*/		dprintf(5, (ddt, "tempcp:0x%x newcp:0x%x\n",			    tempcp, newcp));		dprintf(3, (ddt,			    "update_msg: dname %s type %d class %d ttl %d\n",			    dname, type, class, ttl));		/* read off the data section */		switch (type) {		case T_A:		case T_WKS:		case T_HINFO:		case T_UINFO:		case T_UID:		case T_GID:		case T_TXT:#ifdef ALLOW_T_UNSPEC		case T_UNSPEC:#endif			n = dlen;			PUTSHORT(n, tempcp); /*time to put in the dlen*/			bcopy(cp, newcp,n); /*done here*/			cp +=n;			newcp +=n;			newlen += n;			rembuflen -= n;			dprintf(3, (ddt, "\tcp:0x%x newcp:0x%x dlen:%d\n",				    cp, newcp, dlen));			break;		case T_CNAME:		case T_MB:		case T_MG:		case T_MR:		case T_NS:		case T_PTR:			 /*read off name from data section */			if ((n = dn_expand((u_char *)msg, eom,					   cp, data, sizeof(data))) < 0) {				hp->rcode = FORMERR;				goto badend;			}			cp += n; /*advance pointer*/			/* fill in new packet */			n_new = dn_comp((u_char *)data, (u_char *)newcp,					rembuflen,					(u_char **)dnptrs, (u_char **)edp);			if (n_new < 0)				goto badend;			PUTSHORT(n_new,tempcp);	/*put in dlen field*/			newcp += n_new; /*advance new pointer*/			newlen += n_new;			rembuflen -= n_new;			break;		case T_MINFO:		case T_SOA:		case T_RP:			if ((n = dn_expand((u_char *)msg, eom, cp,					   data, sizeof(data))) < 0) {				hp->rcode = FORMERR;				goto badend;			}			cp += n;			n_new = dn_comp((u_char *)data, (u_char *)newcp,					rembuflen,					(u_char **)dnptrs, (u_char **)edp);			if (n_new < 0)				goto badend;			newcp += n_new;			newlen += n_new;			rembuflen -= n_new;			dlen = n_new;			if ((n = dn_expand((u_char *)msg, eom, cp,					   data, sizeof(data))) < 0) {				hp->rcode = FORMERR;				goto badend;			}			cp += n;			n_new = dn_comp((u_char *)data, (u_char *)newcp,					rembuflen,					(u_char **)dnptrs, (u_char **)edp);			if (n_new < 0)				goto badend;			newcp += n_new;			newlen += n_new;			rembuflen -= n_new;			dlen += n_new;			if (type == T_SOA) {				bcopy(cp, newcp, n = 5*sizeof(u_int32_t));				cp += n;				newcp += n;				newlen +=n;				rembuflen -= n;				dlen +=n;			}			PUTSHORT(dlen, tempcp);			break;		case T_MX:		case T_AFSDB:			/* grab preference */			bcopy(cp,newcp,sizeof(u_int16_t));			cp += sizeof(u_int16_t);			newcp += sizeof(u_int16_t);					/* get name */			if ((n = dn_expand((u_char *)msg, eom, cp,					   data, sizeof(data))) < 0) {				hp->rcode = FORMERR;				goto badend;			}			cp += n;			n_new = dn_comp((u_char *)data, (u_char *)newcp,					rembuflen,					(u_char **)dnptrs, (u_char **)edp);			if (n_new < 0)				goto badend;			PUTSHORT(n_new+sizeof(u_int16_t), tempcp);			newcp += n_new;			newlen += n_new+sizeof(u_int16_t);			rembuflen -= n_new+sizeof(u_int16_t);			break;		default:			dprintf(3, (ddt, "unknown type %d\n", type));			goto badend;		}		dprintf(2, (ddt,			    "newlen:%d, i:%d newcp:0x%x cp:0x%x\n\n",			    newlen, i, newcp, cp));	}	bcopy(newmsg, msg, newlen);	n = *msglen - newlen;	if (n < 0) {		dprintf(2, (ddt,			"update_msg():newmsg longer than old: n:%d o:%d ???\n",			    newlen, *msglen));	}	*msglen = newlen;	free((char *)newmsg);  #ifdef DEBUG	if (debug >= 10)		fp_query((char *)msg, ddt);#endif	free((char *)RRlen);	return(n);badend:	dprintf(2, (ddt, "encountered problems: UPDATE_MSG\n"));	free((char *)RRlen);	return(-1);}#endif /*VALIDATE*/

⌨️ 快捷键说明

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