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

📄 convdns2m.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <ip.h>#include "dns.h"/* *  a dictionary of domain names for packing messages */enum{	Ndict=	64,};typedef struct Dict	Dict;struct Dict{	struct {		ushort	offset;		/* pointer to packed name in message */		char	*name;		/* pointer to unpacked name in buf */	} x[Ndict];	int n;			/* size of dictionary */	uchar *start;		/* start of packed message */	char buf[4*1024];	/* buffer for unpacked names */	char *ep;		/* first free char in buf */};#define NAME(x)		p = pname(p, ep, x, dp)#define SYMBOL(x)	p = psym(p, ep, x)#define STRING(x)	p = pstr(p, ep, x)#define BYTES(x, n)	p = pbytes(p, ep, x, n)#define USHORT(x)	p = pushort(p, ep, x)#define UCHAR(x)	p = puchar(p, ep, x)#define ULONG(x)	p = pulong(p, ep, x)#define V4ADDR(x)	p = pv4addr(p, ep, x)#define V6ADDR(x)	p = pv6addr(p, ep, x)static uchar*psym(uchar *p, uchar *ep, char *np){	int n;	n = strlen(np);	if(n >= Strlen)			/* DNS maximum length string */		n = Strlen - 1;	if(ep - p < n+1)		/* see if it fits in the buffer */		return ep+1;	*p++ = n;	memmove(p, np, n);	return p + n;}static uchar*pstr(uchar *p, uchar *ep, char *np){	int n;	n = strlen(np);	if(n >= Strlen)			/* DNS maximum length string */		n = Strlen - 1;	if(ep - p < n+1)		/* see if it fits in the buffer */		return ep+1;	*p++ = n;	memmove(p, np, n);	return p + n;}static uchar*pbytes(uchar *p, uchar *ep, uchar *np, int n){	if(ep - p < n)		return ep+1;	memmove(p, np, n);	return p + n;}static uchar*puchar(uchar *p, uchar *ep, int val){	if(ep - p < 1)		return ep+1;	*p++ = val;	return p;}static uchar*pushort(uchar *p, uchar *ep, int val){	if(ep - p < 2)		return ep+1;	*p++ = val>>8;	*p++ = val;	return p;}static uchar*pulong(uchar *p, uchar *ep, int val){	if(ep - p < 4)		return ep+1;	*p++ = val>>24;	*p++ = val>>16;	*p++ = val>>8;	*p++ = val;	return p;}static uchar*pv4addr(uchar *p, uchar *ep, char *name){	uchar ip[IPaddrlen];	if(ep - p < 4)		return ep+1;	parseip(ip, name);	v6tov4(p, ip);	return p + 4;}static uchar*pv6addr(uchar *p, uchar *ep, char *name){	if(ep - p < IPaddrlen)		return ep+1;	parseip(p, name);	return p + IPaddrlen;}static uchar*pname(uchar *p, uchar *ep, char *np, Dict *dp){	char *cp;	int i;	char *last;		/* last component packed */	if(strlen(np) >= Domlen)	/* make sure we don't exceed DNS limits */		return ep+1;	last = 0;	while(*np){		/* look through every component in the dictionary for a match */		for(i = 0; i < dp->n; i++){			if(strcmp(np, dp->x[i].name) == 0){				if(ep - p < 2)					return ep+1;				*p++ = (dp->x[i].offset>>8) | 0xc0;				*p++ = dp->x[i].offset;				return p;			}		}		/* if there's room, enter this name in dictionary */		if(dp->n < Ndict){			if(last){				/* the whole name is already in dp->buf */				last = strchr(last, '.') + 1;				dp->x[dp->n].name = last;				dp->x[dp->n].offset = p - dp->start;				dp->n++;			} else {				/* add to dp->buf */				i = strlen(np);				if(dp->ep + i + 1 < &dp->buf[sizeof(dp->buf)]){					strcpy(dp->ep, np);					dp->x[dp->n].name = dp->ep;					last = dp->ep;					dp->x[dp->n].offset = p - dp->start;					dp->ep += i + 1;					dp->n++;				}			}		}		/* put next component into message */		cp = strchr(np, '.');		if(cp == 0){			i = strlen(np);			cp = np + i;	/* point to null terminator */		} else {			i = cp - np;			cp++;		/* point past '.' */		}		if(ep-p < i+1)			return ep+1;		*p++ = i;		/* count of chars in label */		memmove(p, np, i);		np = cp;		p += i;	}	if(p >= ep)		return ep+1;	*p++ = 0;	/* add top level domain */	return p;}static uchar*convRR2M(RR *rp, uchar *p, uchar *ep, Dict *dp){	uchar *lp, *data;	int len, ttl;	Txt *t;	NAME(rp->owner->name);	USHORT(rp->type);	USHORT(rp->owner->class);	/* egregious overuse of ttl (it's absolute time in the cache) */	if(rp->db)		ttl = rp->ttl;	else		ttl = rp->ttl - now;	if(ttl < 0)		ttl = 0;	ULONG(ttl);	lp = p;			/* leave room for the rdata length */	p += 2;	data = p;	if(data >= ep)		return p+1;	switch(rp->type){	case Thinfo:		SYMBOL(rp->cpu->name);		SYMBOL(rp->os->name);		break;	case Tcname:	case Tmb:	case Tmd:	case Tmf:	case Tns:		NAME(rp->host->name);		break;	case Tmg:	case Tmr:		NAME(rp->mb->name);		break;	case Tminfo:		NAME(rp->rmb->name);		NAME(rp->mb->name);		break;	case Tmx:		USHORT(rp->pref);		NAME(rp->host->name);		break;	case Ta:		V4ADDR(rp->ip->name);		break;	case Taaaa:		V6ADDR(rp->ip->name);		break;	case Tptr:		NAME(rp->ptr->name);		break;	case Tsoa:		NAME(rp->host->name);		NAME(rp->rmb->name);		ULONG(rp->soa->serial);		ULONG(rp->soa->refresh);		ULONG(rp->soa->retry);		ULONG(rp->soa->expire);		ULONG(rp->soa->minttl);		break;	case Ttxt:		for(t = rp->txt; t != nil; t = t->next)			STRING(t->p);		break;	case Tnull:		BYTES(rp->null->data, rp->null->dlen);		break;	case Trp:		NAME(rp->rmb->name);		NAME(rp->rp->name);		break;	case Tkey:		USHORT(rp->key->flags);		UCHAR(rp->key->proto);		UCHAR(rp->key->alg);		BYTES(rp->key->data, rp->key->dlen);		break;	case Tsig:		USHORT(rp->sig->type);		UCHAR(rp->sig->alg);		UCHAR(rp->sig->labels);		ULONG(rp->sig->ttl);		ULONG(rp->sig->exp);		ULONG(rp->sig->incep);		USHORT(rp->sig->tag);		NAME(rp->sig->signer->name);		BYTES(rp->sig->data, rp->sig->dlen);		break;	case Tcert:		USHORT(rp->cert->type);		USHORT(rp->cert->tag);		UCHAR(rp->cert->alg);		BYTES(rp->cert->data, rp->cert->dlen);		break;	}	/* stuff in the rdata section length */	len = p - data;	*lp++ = len >> 8;	*lp = len;	return p;}static uchar*convQ2M(RR *rp, uchar *p, uchar *ep, Dict *dp){	NAME(rp->owner->name);	USHORT(rp->type);	USHORT(rp->owner->class);	return p;}static uchar*rrloop(RR *rp, int *countp, uchar *p, uchar *ep, Dict *dp, int quest){	uchar *np;	*countp = 0;	for(; rp && p < ep; rp = rp->next){		if(quest)			np = convQ2M(rp, p, ep, dp);		else			np = convRR2M(rp, p, ep, dp);		if(np > ep)			break;		p = np;		(*countp)++;	}	return p;}/* *  convert into a message */intconvDNS2M(DNSmsg *m, uchar *buf, int len){	uchar *p, *ep, *np;	Dict d;	d.n = 0;	d.start = buf;	d.ep = d.buf;	memset(buf, 0, len);	m->qdcount = m->ancount = m->nscount = m->arcount = 0;	/* first pack in the RR's so we can get real counts */	p = buf + 12;	ep = buf + len;	p = rrloop(m->qd, &m->qdcount, p, ep, &d, 1);	p = rrloop(m->an, &m->ancount, p, ep, &d, 0);	p = rrloop(m->ns, &m->nscount, p, ep, &d, 0);	p = rrloop(m->ar, &m->arcount, p, ep, &d, 0);	if(p > ep)		return -1;	/* now pack the rest */	np = p;	p = buf;	ep = buf + len;	USHORT(m->id);	USHORT(m->flags);	USHORT(m->qdcount);	USHORT(m->ancount);	USHORT(m->nscount);	USHORT(m->arcount);	if(p > ep)		return -1;	return np - buf;}

⌨️ 快捷键说明

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