Exemple #1
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;
}
Exemple #2
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++;
    }
}
Exemple #3
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;
}
Exemple #4
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++;
    }
}
Exemple #5
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);
}
Exemple #6
0
int
dname_is_root(uint8_t* dname)
{
    uint8_t len;
    log_assert(dname);
    len = dname[0];
    log_assert(!LABEL_IS_PTR(len));
    return (len == 0);
}
Exemple #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;
}
Exemple #8
0
void
dname_remove_label(uint8_t** dname, size_t* len)
{
    size_t lablen;
    log_assert(dname && *dname && len);
    lablen = (*dname)[0];
    log_assert(!LABEL_IS_PTR(lablen));
    log_assert(*len > lablen);
    if(lablen == 0)
        return; /* do not modify root label */
    *len -= lablen+1;
    *dname += lablen+1;
}
Exemple #9
0
size_t
pkt_dname_len(sldns_buffer* pkt)
{
    size_t len = 0;
    int ptrcount = 0;
    uint8_t labellen;
    size_t endpos = 0;

    /* read dname and determine length */
    /* check compression pointers, loops, out of bounds */
    while(1) {
        /* read next label */
        if(sldns_buffer_remaining(pkt) < 1)
            return 0;
        labellen = sldns_buffer_read_u8(pkt);
        if(LABEL_IS_PTR(labellen)) {
            /* compression ptr */
            uint16_t ptr;
            if(sldns_buffer_remaining(pkt) < 1)
                return 0;
            ptr = PTR_OFFSET(labellen, sldns_buffer_read_u8(pkt));
            if(ptrcount++ > MAX_COMPRESS_PTRS)
                return 0; /* loop! */
            if(sldns_buffer_limit(pkt) <= ptr)
                return 0; /* out of bounds! */
            if(!endpos)
                endpos = sldns_buffer_position(pkt);
            sldns_buffer_set_position(pkt, ptr);
        } else {
            /* label contents */
            if(labellen > 0x3f)
                return 0; /* label too long */
            len += 1 + labellen;
            if(len > LDNS_MAX_DOMAINLEN)
                return 0;
            if(labellen == 0) {
                /* end of dname */
                break;
            }
            if(sldns_buffer_remaining(pkt) < labellen)
                return 0;
            sldns_buffer_skip(pkt, (ssize_t)labellen);
        }
    }
    if(endpos)
        sldns_buffer_set_position(pkt, endpos);

    return len;
}