Пример #1
0
static int append_qsection(const jdns_list_t *src, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
{
	unsigned char *buf, *start, *last;
	int n;

	buf = *bufp;
	start = buf - at;
	last = buf + left;
	for(n = 0; n < src->count; ++n)
	{
		jdns_packet_question_t *q = (jdns_packet_question_t *)src->item[n];

		if(!writelabel(q->qname, buf - start, last - buf, &buf, lookup))
			goto error;

		if(buf + 4 > last)
			goto error;

		short2net(q->qtype, &buf);
		short2net(q->qclass, &buf);
	}

	*bufp = buf;
	return 1;

error:
	return 0;
}
Пример #2
0
static int append_rrsection(const jdns_list_t *src, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
{
	unsigned char *buf, *start, *last, *rdlengthp;
	int n, i, rdlength;

	buf = *bufp;
	start = buf - at;
	last = buf + left;
	for(n = 0; n < src->count; ++n)
	{
		jdns_packet_resource_t *r = (jdns_packet_resource_t *)src->item[n];

		if(!writelabel(r->qname, buf - start, last - buf, &buf, lookup))
			goto error;

		if(buf + 10 > last)
			goto error;

		short2net(r->qtype, &buf);
		short2net(r->qclass, &buf);
		long2net(r->ttl, &buf);

		// skip over rdlength
		rdlengthp = buf;
		buf += 2;

		// play write log
		rdlength = 0;
		for(i = 0; i < r->writelog->count; ++i)
		{
			jdns_packet_write_t *write = (jdns_packet_write_t *)r->writelog->item[i];
			if(write->type == JDNS_PACKET_WRITE_RAW)
			{
				if(buf + write->value->size > last)
					goto error;

				memcpy(buf, write->value->data, write->value->size);
				buf += write->value->size;
			}
			else // JDNS_PACKET_WRITE_NAME
			{
				if(!writelabel(write->value, buf - start, last - buf, &buf, lookup))
					goto error;
			}
		}

		i = buf - rdlengthp; // should be rdata size + 2
		short2net((unsigned short int)(i - 2), &rdlengthp);
	}

	*bufp = buf;
	return 1;

error:
	return 0;
}
Пример #3
0
// nasty, convert host into label using compression
int _host(struct message *m, unsigned char **bufp, unsigned char *name)
{
    unsigned char label[256], *l;
    int len = 0, x = 1, y = 0, last = 0;

    if(name == 0) return 0;

    // make our label
    while(name[y])
    {
        if(name[y] == '.')
        {
            if(!name[y+1]) break;
            label[last] = x - (last + 1);
            last = x;
        }else{
            label[x] = name[y];
        }
        if(x++ == 255) return 0;
        y++;
    }
    label[last] = x - (last + 1);
    if(x == 1) x--; // special case, bad names, but handle correctly
    len = x + 1;
    label[x] = 0; // always terminate w/ a 0

    // double-loop checking each label against all m->_labels for match
    for(x = 0; label[x]; x += label[x] + 1)
    {
        for(y = 0; m->_labels[y]; y++)
            if(_lmatch(m,label+x,m->_labels[y]))
            {
                // matching label, set up pointer
                l = label + x;
                short2net(m->_labels[y] - m->_packet, &l);
                label[x] |= 0xc0;
                len = x + 2;
                break;
            }
        if(label[x] & 0xc0) break;
    }

    // copy into buffer, point there now
    memcpy(*bufp,label,len);
    l = *bufp;
    *bufp += len;

    // for each new label, store it's location for future compression
    for(x = 0; l[x]; x += l[x] + 1)
    {
        if(l[x] & 0xc0) break;
        if(m->_label + 1 >= 19) break;
        m->_labels[m->_label++] = l + x;
    }

    return len;
}
Пример #4
0
int jdns_packet_export(jdns_packet_t *a, int maxsize)
{
	unsigned char *block = 0;
	unsigned char *buf, *last;
	unsigned char c;
	int size;
	jdns_list_t *lookup = 0; // to hold jdns_packet_label_t

	// clear out any existing raw data before we begin
	if(a->raw_data)
	{
		jdns_free(a->raw_data);
		a->raw_data = 0;
		a->raw_size = 0;
	}

	// preallocate
	size = maxsize;
	block = (unsigned char *)jdns_alloc(size);
	memset(block, 0, size);

	buf = block;
	last = block + size;

	if(size < 12)
		goto error;

	short2net(a->id, &buf);
	if(a->opts.qr)
		buf[0] |= 0x80;
	c = (unsigned char)a->opts.opcode;
	buf[0] |= c << 3;
	if(a->opts.aa)
		buf[0] |= 0x04;
	if(a->opts.tc)
		buf[0] |= 0x02;
	if(a->opts.rd)
		buf[0] |= 0x01;
	if(a->opts.ra)
		buf[1] |= 0x80;
	c = (unsigned char)a->opts.z;
	buf[1] |= c << 4;
	c = (unsigned char)a->opts.rcode;
	buf[1] |= c;
	buf += 2;
	short2net((unsigned short int)a->questions->count, &buf);
	short2net((unsigned short int)a->answerRecords->count, &buf);
	short2net((unsigned short int)a->authorityRecords->count, &buf);
	short2net((unsigned short int)a->additionalRecords->count, &buf);

	// append sections
	lookup = jdns_list_new();
	lookup->autoDelete = 1;

	if(!append_qsection(a->questions, buf - block, last - buf, &buf, lookup))
		goto error;
	if(!append_rrsection(a->answerRecords, buf - block, last - buf, &buf, lookup))
		goto error;
	if(!append_rrsection(a->authorityRecords, buf - block, last - buf, &buf, lookup))
		goto error;
	if(!append_rrsection(a->additionalRecords, buf - block, last - buf, &buf, lookup))
		goto error;

	// done with all sections
	jdns_list_delete(lookup);

	// condense
	size = buf - block;
	block = (unsigned char *)jdns_realloc(block, size);

	// finalize
	a->qdcount = a->questions->count;
	a->ancount = a->answerRecords->count;
	a->nscount = a->authorityRecords->count;
	a->arcount = a->additionalRecords->count;
	a->raw_data = block;
	a->raw_size = size;

	return 1;

error:
	jdns_list_delete(lookup);
	if(block)
		jdns_free(block);
	return 0;
}
Пример #5
0
// lookup list is made of jdns_packet_labels
static int writelabel(const jdns_string_t *name, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
{
	unsigned char label[MAX_LABEL_LENGTH];
	int n, i, len;
	unsigned char *l;
	unsigned char *ref;
	int refsize;

	len = name_to_label(name, label);
	if(len == -1)
		return 0;

	ref = *bufp - at;
	refsize = at + left;
	for(n = 0; label[n]; n += label[n] + 1)
	{
		for(i = 0; i < lookup->count; ++i)
		{
			jdns_packet_label_t *pl = (jdns_packet_label_t *)lookup->item[i];

			if(matchlabel(label + n, len - n, pl->value->data, pl->value->size, ref, refsize, 8, 8))
			{
				// set up a pointer right here, overwriting
				//   the length byte and the first content
				//   byte of this section within 'label'.
				//   this is safe, because the length value
				//   will always be greater than zero,
				//   ensuring we have two bytes available to
				//   use.
				l = label + n;
				short2net((unsigned short int)pl->offset, &l);
				label[n] |= 0xc0;
				len = n + 2; // cut things short
				break;
			}
		}
		if(label[n] & 0xc0) // double loop, so break again
			break;
	}

	if(left < len)
		return 0;

	// copy into buffer, point there now
	memcpy(*bufp, label, len);
	l = *bufp;
	*bufp += len;

	// for each new label, store its location for future compression
	for(n = 0; l[n]; n += l[n] + 1)
	{
		jdns_string_t *str;
		jdns_packet_label_t *pl;
		if(l[n] & 0xc0)
			break;

		pl = jdns_packet_label_new();
		str = jdns_string_new();
		jdns_string_set(str, l + n, len - n);
		pl->offset = l + n - ref;
		pl->value = str;
		jdns_list_insert(lookup, pl, -1);
	}

	return 1;
}