Example #1
0
/** test pkt_dname_tolower */
static void
dname_test_pdtl(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
{
	unit_show_func("util/data/dname.c", "pkt_dname_tolower");
	pkt_dname_tolower(loopbuf, sldns_buffer_at(loopbuf, 12));
	pkt_dname_tolower(boundbuf, sldns_buffer_at(boundbuf, 12));
}
Example #2
0
/** perf test a packet */
static void
perftestpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out, 
	const char* hex)
{
	struct query_info qi;
	struct reply_info* rep = 0;
	int ret;
	uint16_t id;
	uint16_t flags;
	time_t timenow = 0;
	struct regional* region = regional_create();
	struct edns_data edns;

	hex_to_buf(pkt, hex);
	memmove(&id, sldns_buffer_begin(pkt), sizeof(id));
	if(sldns_buffer_limit(pkt) < 2)
		flags = 0;
	else	memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags));
	flags = ntohs(flags);
	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
	if(ret != 0) {
		char rbuf[16];
		sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
		if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
		if(ret == LDNS_RCODE_FORMERR)
			checkformerr(pkt);
		unit_assert(ret != LDNS_RCODE_SERVFAIL);
	} else {
		perf_encode(&qi, rep, id, flags, out, timenow, &edns);
	} 

	query_info_clear(&qi);
	reply_info_parsedelete(rep, alloc);
	regional_destroy(region);
}
Example #3
0
void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname)
{
    uint8_t lablen;
    if(!out) out = stdout;
    if(!dname) return;

    lablen = *dname++;
    if(!lablen)
        fputc('.', out);
    while(lablen) {
        if(LABEL_IS_PTR(lablen)) {
            /* follow pointer */
            if(!pkt) {
                fputs("??compressionptr??", out);
                return;
            }
            dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
            lablen = *dname++;
            continue;
        }
        if(lablen > LDNS_MAX_LABELLEN) {
            fputs("??extendedlabel??", out);
            return;
        }
        while(lablen--)
            fputc((int)*dname++, out);
        fputc('.', out);
        lablen = *dname++;
    }
}
Example #4
0
void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname)
{
    /* copy over the dname and decompress it at the same time */
    size_t len = 0;
    uint8_t lablen;
    lablen = *dname++;
    while(lablen) {
        if(LABEL_IS_PTR(lablen)) {
            /* follow pointer */
            dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
            lablen = *dname++;
            continue;
        }
        log_assert(lablen <= LDNS_MAX_LABELLEN);
        len += (size_t)lablen+1;
        if(len >= LDNS_MAX_DOMAINLEN) {
            *to = 0; /* end the result prematurely */
            log_err("bad dname in dname_pkt_copy");
            return;
        }
        *to++ = lablen;
        memmove(to, dname, lablen);
        dname += lablen;
        to += lablen;
        lablen = *dname++;
    }
    /* copy last \0 */
    *to = 0;
}
Example #5
0
hashvalue_t
dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_t h)
{
    uint8_t labuf[LDNS_MAX_LABELLEN+1];
    uint8_t lablen;
    int i;

    /* preserve case of query, make hash label by label */
    lablen = *dname++;
    while(lablen) {
        if(LABEL_IS_PTR(lablen)) {
            /* follow pointer */
            dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
            lablen = *dname++;
            continue;
        }
        log_assert(lablen <= LDNS_MAX_LABELLEN);
        labuf[0] = lablen;
        i=0;
        while(lablen--)
            labuf[++i] = (uint8_t)tolower((int)*dname++);
        h = hashlittle(labuf, labuf[0] + 1, h);
        lablen = *dname++;
    }

    return h;
}
Example #6
0
void
pkt_dname_tolower(sldns_buffer* pkt, uint8_t* dname)
{
    uint8_t lablen;
    int count = 0;
    if(dname >= sldns_buffer_end(pkt))
        return;
    lablen = *dname++;
    while(lablen) {
        if(LABEL_IS_PTR(lablen)) {
            if((size_t)PTR_OFFSET(lablen, *dname)
                    >= sldns_buffer_limit(pkt))
                return;
            dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
            lablen = *dname++;
            if(count++ > MAX_COMPRESS_PTRS)
                return;
            continue;
        }
        if(dname+lablen >= sldns_buffer_end(pkt))
            return;
        while(lablen--) {
            *dname = (uint8_t)tolower((int)*dname);
            dname++;
        }
        if(dname >= sldns_buffer_end(pkt))
            return;
        lablen = *dname++;
    }
}
Example #7
0
int
dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2)
{
    uint8_t len1, len2;
    log_assert(pkt && d1 && d2);
    len1 = *d1++;
    len2 = *d2++;
    while( len1 != 0 || len2 != 0 ) {
        /* resolve ptrs */
        if(LABEL_IS_PTR(len1)) {
            d1 = sldns_buffer_at(pkt, PTR_OFFSET(len1, *d1));
            len1 = *d1++;
            continue;
        }
        if(LABEL_IS_PTR(len2)) {
            d2 = sldns_buffer_at(pkt, PTR_OFFSET(len2, *d2));
            len2 = *d2++;
            continue;
        }
        /* check label length */
        log_assert(len1 <= LDNS_MAX_LABELLEN);
        log_assert(len2 <= LDNS_MAX_LABELLEN);
        if(len1 != len2) {
            if(len1 < len2) return -1;
            return 1;
        }
        log_assert(len1 == len2 && len1 != 0);
        /* compare labels */
        while(len1--) {
            if(tolower((int)*d1++) != tolower((int)*d2++)) {
                if(tolower((int)d1[-1]) < tolower((int)d2[-1]))
                    return -1;
                return 1;
            }
        }
        len1 = *d1++;
        len2 = *d2++;
    }
    return 0;
}
Example #8
0
/** smart comparison of (compressed, valid) dnames from packet */
static int
smart_compare(sldns_buffer* pkt, uint8_t* dnow, 
	uint8_t* dprfirst, uint8_t* dprlast)
{
	if(LABEL_IS_PTR(*dnow)) {
		/* ptr points to a previous dname */
		uint8_t* p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1]));
		if( p == dprfirst || p == dprlast )
			return 0;
		/* prev dname is also a ptr, both ptrs are the same. */
		if(LABEL_IS_PTR(*dprlast) &&
			dprlast[0] == dnow[0] && dprlast[1] == dnow[1])
			return 0;
	}
	return dname_pkt_compare(pkt, dnow, dprlast);
}
Example #9
0
/** see if buffers contain the same packet */
static int
test_buffers(sldns_buffer* pkt, sldns_buffer* out)
{
	/* check binary same */
	if(sldns_buffer_limit(pkt) == sldns_buffer_limit(out) &&
		memcmp(sldns_buffer_begin(pkt), sldns_buffer_begin(out),
			sldns_buffer_limit(pkt)) == 0) {
		if(vbmp) printf("binary the same (length=%u)\n",
				(unsigned)sldns_buffer_limit(pkt));
		return 1;
	}

	if(vbmp) {
		size_t sz = 16;
		size_t count;
		size_t lim = sldns_buffer_limit(out);
		if(sldns_buffer_limit(pkt) < lim)
			lim = sldns_buffer_limit(pkt);
		for(count=0; count<lim; count+=sz) {
			size_t rem = sz;
			if(lim-count < sz) rem = lim-count;
			if(memcmp(sldns_buffer_at(pkt, count), 
				sldns_buffer_at(out, count), rem) == 0) {
				log_info("same %d %d", (int)count, (int)rem);
				log_hex("same: ", sldns_buffer_at(pkt, count),
					rem);
			} else {
				log_info("diff %d %d", (int)count, (int)rem);
				log_hex("difp: ", sldns_buffer_at(pkt, count),
					rem);
				log_hex("difo: ", sldns_buffer_at(out, count),
					rem);
			}
		}
	}

	/* check if it 'means the same' */
	if(vbmp) {
		char* s1, *s2;
		log_buf(0, "orig in hex", pkt);
		log_buf(0, "unbound out in hex", out);
		printf("\npacket from unbound (%d):\n", 
			(int)sldns_buffer_limit(out));
		s1 = sldns_wire2str_pkt(sldns_buffer_begin(out),
			sldns_buffer_limit(out));
		printf("%s\n", s1?s1:"null");
		free(s1);

		printf("\npacket original (%d):\n", 
			(int)sldns_buffer_limit(pkt));
		s2 = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
			sldns_buffer_limit(pkt));
		printf("%s\n", s2?s2:"null");
		free(s2);
		printf("\n");
	}
	/* if it had two EDNS sections, skip comparison */
	if(1) {
		char* s = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
			sldns_buffer_limit(pkt));
		char* e1 = strstr(s, "; EDNS:");
		if(e1 && strstr(e1+4, "; EDNS:")) {
			free(s);
			return 0;
		}
		free(s);
	}
	/* compare packets */
	unit_assert(match_all(sldns_buffer_begin(pkt), sldns_buffer_limit(pkt),
		sldns_buffer_begin(out), sldns_buffer_limit(out), 1,
		matches_nolocation));
	return 0;
}
Example #10
0
/** test a packet */
static void
testpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out, 
	const char* hex)
{
	struct query_info qi;
	struct reply_info* rep = 0;
	int ret;
	uint16_t id;
	uint16_t flags;
	uint32_t timenow = 0;
	struct regional* region = regional_create();
	struct edns_data edns;

	hex_to_buf(pkt, hex);
	memmove(&id, sldns_buffer_begin(pkt), sizeof(id));
	if(sldns_buffer_limit(pkt) < 2)
		flags = 0;
	else	memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags));
	flags = ntohs(flags);
	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
	if(ret != 0) {
		char rbuf[16];
		sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
		if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
		if(ret == LDNS_RCODE_FORMERR) {
			unit_assert(!check_formerr_gone);
			checkformerr(pkt);
		}
		unit_assert(ret != LDNS_RCODE_SERVFAIL);
	} else if(!check_formerr_gone) {
		const size_t lim = 512;
		ret = reply_info_encode(&qi, rep, id, flags, out, timenow,
			region, 65535, (int)(edns.bits & EDNS_DO) );
		unit_assert(ret != 0); /* udp packets should fit */
		attach_edns_record(out, &edns);
		if(vbmp) printf("inlen %u outlen %u\n", 
			(unsigned)sldns_buffer_limit(pkt),
			(unsigned)sldns_buffer_limit(out));
		if(!check_nosameness)
			test_buffers(pkt, out);
		if(check_rrsigs)
			check_the_rrsigs(&qi, rep);

		if(sldns_buffer_limit(out) > lim) {
			ret = reply_info_encode(&qi, rep, id, flags, out, 
				timenow, region, 
				lim - calc_edns_field_size(&edns),
				(int)(edns.bits & EDNS_DO));
			unit_assert(ret != 0); /* should fit, but with TC */
			attach_edns_record(out, &edns);
			if( LDNS_QDCOUNT(sldns_buffer_begin(out)) !=
				LDNS_QDCOUNT(sldns_buffer_begin(pkt)) ||
				LDNS_ANCOUNT(sldns_buffer_begin(out)) !=
				LDNS_ANCOUNT(sldns_buffer_begin(pkt)) ||
				LDNS_NSCOUNT(sldns_buffer_begin(out)) !=
				LDNS_NSCOUNT(sldns_buffer_begin(pkt)))
				unit_assert(
				LDNS_TC_WIRE(sldns_buffer_begin(out)));
				/* must set TC bit if shortened */
			unit_assert(sldns_buffer_limit(out) <= lim);
		}
	} 

	query_info_clear(&qi);
	reply_info_parsedelete(rep, alloc);
	regional_destroy(region);
}