Example #1
0
jdns_packet_t *jdns_packet_copy(const jdns_packet_t *a)
{
	jdns_packet_t *c = jdns_packet_new();
	c->id = a->id;
	c->opts.qr = a->opts.qr;
	c->opts.opcode = a->opts.opcode;
	c->opts.aa = a->opts.aa;
	c->opts.tc = a->opts.tc;
	c->opts.rd = a->opts.rd;
	c->opts.ra = a->opts.ra;
	c->opts.z = a->opts.z;
	c->opts.rcode = a->opts.rcode;

	jdns_list_delete(c->questions);
	jdns_list_delete(c->answerRecords);
	jdns_list_delete(c->authorityRecords);
	jdns_list_delete(c->additionalRecords);
	c->questions = jdns_list_copy(a->questions);
	c->answerRecords = jdns_list_copy(a->answerRecords);
	c->authorityRecords = jdns_list_copy(a->authorityRecords);
	c->additionalRecords = jdns_list_copy(a->additionalRecords);

	c->fully_parsed = a->fully_parsed;

	c->raw_size = a->raw_size;
	c->raw_data = jdns_copy_array(a->raw_data, a->raw_size);

	return c;
}
Example #2
0
static int process_rrsection(jdns_list_t *dest, int count, const unsigned char *data, int size, const unsigned char **bufp)
{
	int n;
	int offset, at;
	jdns_string_t *name = 0;
	const unsigned char *buf;

	buf = *bufp;
	for(n = 0; n < count; ++n)
	{
		jdns_packet_resource_t *r;

		offset = buf - data;
		at = 0;

		if(!readlabel(data + offset, size - offset, data, size, &at, &name))
			goto error;

		offset += at;

		// need 10 more bytes
		if(offset + 10 > size)
			goto error;

		buf = data + offset;

		r = jdns_packet_resource_new();
		r->qname = name;
		name = 0;
		r->qtype = net2short(&buf);
		r->qclass = net2short(&buf);
		r->ttl = net2long(&buf);
		r->rdlength = net2short(&buf);

		offset = buf - data;

		// make sure we have enough for the rdata
		if(size - offset < r->rdlength)
		{
			jdns_packet_resource_delete(r);
			goto error;
		}

		r->rdata = jdns_copy_array(buf, r->rdlength);
		buf += r->rdlength;

		jdns_list_insert_value(dest, r, -1);
		jdns_packet_resource_delete(r);
	}

	*bufp = buf;
	return 1;

error:
	jdns_string_delete(name);
	return 0;
}
Example #3
0
jdns_packet_resource_t *jdns_packet_resource_copy(const jdns_packet_resource_t *a)
{
	jdns_packet_resource_t *c = jdns_packet_resource_new();
	if(a->qname)
		c->qname = jdns_string_copy(a->qname);
	c->qtype = a->qtype;
	c->qclass = a->qclass;
	c->ttl = a->ttl;
	c->rdlength = a->rdlength;
	c->rdata = jdns_copy_array(a->rdata, a->rdlength);

	jdns_list_delete(c->writelog);
	c->writelog = jdns_list_copy(a->writelog);
	return c;
}
Example #4
0
int jdns_packet_import(jdns_packet_t **a, const unsigned char *data, int size)
{
	jdns_packet_t *tmp = 0;
	const unsigned char *buf;

	// need at least some data
	if(!data || size == 0)
		return 0;

	// header (id + options + item counts) is 12 bytes
	if(size < 12)
		goto error;

	tmp = jdns_packet_new();
	buf = data;

	// id
	tmp->id = net2short(&buf);

	// options
	if(buf[0] & 0x80)                        // qr is bit 7
		tmp->opts.qr = 1;
	tmp->opts.opcode = (buf[0] & 0x78) >> 3; // opcode is bits 6,5,4,3
	if(buf[0] & 0x04)                        // aa is bit 2
		tmp->opts.aa = 1;
	if(buf[0] & 0x02)                        // tc is bit 1
		tmp->opts.tc = 1;
	if(buf[0] & 0x01)                        // rd is bit 0
		tmp->opts.rd = 1;
	if(buf[1] & 0x80)                        // ra is bit 7 (second byte)
		tmp->opts.ra = 1;
	tmp->opts.z = (buf[1] & 0x70) >> 4;      // z is bits 6,5,4
	tmp->opts.rcode = buf[1] & 0x0f;         // rcode is bits 3,2,1,0
	buf += 2;

	// item counts
	tmp->qdcount = net2short(&buf);
	tmp->ancount = net2short(&buf);
	tmp->nscount = net2short(&buf);
	tmp->arcount = net2short(&buf);

	// if these fail, we don't count them as errors, since the packet
	//   might have been truncated
	if(!process_qsection(tmp->questions, tmp->qdcount, data, size, &buf))
		goto skip;
	if(!process_rrsection(tmp->answerRecords, tmp->ancount, data, size, &buf))
		goto skip;
	if(!process_rrsection(tmp->authorityRecords, tmp->nscount, data, size, &buf))
		goto skip;
	if(!process_rrsection(tmp->additionalRecords, tmp->arcount, data, size, &buf))
		goto skip;

	tmp->fully_parsed = 1;

skip:
	// keep the raw data for reference during rdata parsing
	tmp->raw_size = size;
	tmp->raw_data = jdns_copy_array(data, size);

	*a = tmp;
	return 1;

error:
	jdns_packet_delete(tmp);
	return 0;
}