Пример #1
0
int 
query_info_parse(struct query_info* m, ldns_buffer* query)
{
	uint8_t* q = ldns_buffer_begin(query);
	/* minimum size: header + \0 + qtype + qclass */
	if(ldns_buffer_limit(query) < LDNS_HEADER_SIZE + 5)
		return 0;
	if(LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY || 
		LDNS_QDCOUNT(q) != 1 || ldns_buffer_position(query) != 0)
		return 0;
	ldns_buffer_skip(query, LDNS_HEADER_SIZE);
	m->qname = ldns_buffer_current(query);
	if((m->qname_len = query_dname_len(query)) == 0)
		return 0; /* parse error */
	if(ldns_buffer_remaining(query) < 4)
		return 0; /* need qtype, qclass */
	m->qtype = ldns_buffer_read_u16(query);
	m->qclass = ldns_buffer_read_u16(query);
	return 1;
}
/** analyse pkt */
static void analyze(ldns_buffer* pkt)
{
	uint16_t i, f, qd, an, ns, ar;
	int rrnum = 0;
	printf("packet length %d\n", (int)ldns_buffer_limit(pkt));
	if(ldns_buffer_limit(pkt) < 12) return;

	i = ldns_buffer_read_u16(pkt);
	printf("id (hostorder): %d (0x%x)\n", (int)i, (unsigned)i);
	f = ldns_buffer_read_u16(pkt);
	printf("flags: 0x%x\n", (unsigned)f);
	qd = ldns_buffer_read_u16(pkt);
	printf("qdcount: %d\n", (int)qd);
	an = ldns_buffer_read_u16(pkt);
	printf("ancount: %d\n", (int)an);
	ns = ldns_buffer_read_u16(pkt);
	printf("nscount: %d\n", (int)ns);
	ar = ldns_buffer_read_u16(pkt);
	printf("arcount: %d\n", (int)ar);
	
	printf(";-- query section\n");
	while(ldns_buffer_remaining(pkt) > 0) {
		if(rrnum == (int)qd) 
			printf(";-- answer section\n");
		if(rrnum == (int)qd+(int)an) 
			printf(";-- authority section\n");
		if(rrnum == (int)qd+(int)an+(int)ns) 
			printf(";-- additional section\n");
		printf("rr %d ", rrnum);
		analyze_rr(pkt, rrnum < (int)qd);
		rrnum++;
	}
}
/** analyze rr in packet */
static void analyze_rr(ldns_buffer* pkt, int q)
{
	uint16_t type, dclass, len;
	uint32_t ttl;
	analyze_dname(pkt);
	type = ldns_buffer_read_u16(pkt);
	dclass = ldns_buffer_read_u16(pkt);
	printf("type %s(%d)", ldns_rr_descript(type)?  
		ldns_rr_descript(type)->_name: "??" , (int)type);
	printf(" class %s(%d) ", ldns_lookup_by_id(ldns_rr_classes, 
		(int)dclass)?ldns_lookup_by_id( ldns_rr_classes, 
		(int)dclass)->name:"??", (int)dclass);
	if(q) {
		printf("\n");
	} else {
		ttl = ldns_buffer_read_u32(pkt);
		printf(" ttl %d (0x%x)", (int)ttl, (unsigned)ttl);
		len = ldns_buffer_read_u16(pkt);
		printf(" rdata len %d:\n", (int)len);
		if(ldns_rr_descript(type))
			analyze_rdata(pkt, ldns_rr_descript(type), len);
		else ldns_buffer_skip(pkt, (ssize_t)len);
	}
}
Пример #4
0
/** do the rdata copy */
static int
rdata_copy(ldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, 
	struct rr_parse* rr, uint32_t* rr_ttl, uint16_t type)
{
	uint16_t pkt_len;
	const ldns_rr_descriptor* desc;

	*rr_ttl = ldns_read_uint32(rr->ttl_data);
	/* RFC 2181 Section 8. if msb of ttl is set treat as if zero. */
	if(*rr_ttl & 0x80000000U)
		*rr_ttl = 0;
	if(*rr_ttl < MIN_TTL)
		*rr_ttl = MIN_TTL;
	if(*rr_ttl < data->ttl)
		data->ttl = *rr_ttl;

	if(rr->outside_packet) {
		/* uncompressed already, only needs copy */
		memmove(to, rr->ttl_data+sizeof(uint32_t), rr->size);
		return 1;
	}

	ldns_buffer_set_position(pkt, (size_t)
		(rr->ttl_data - ldns_buffer_begin(pkt) + sizeof(uint32_t)));
	/* insert decompressed size into rdata len stored in memory */
	/* -2 because rdatalen bytes are not included. */
	pkt_len = htons(rr->size - 2);
	memmove(to, &pkt_len, sizeof(uint16_t));
	to += 2;
	/* read packet rdata len */
	pkt_len = ldns_buffer_read_u16(pkt);
	if(ldns_buffer_remaining(pkt) < pkt_len)
		return 0;
	desc = ldns_rr_descript(type);
	if(pkt_len > 0 && desc && desc->_dname_count > 0) {
		int count = (int)desc->_dname_count;
		int rdf = 0;
		size_t len;
		size_t oldpos;
		/* decompress dnames. */
		while(pkt_len > 0 && count) {
			switch(desc->_wireformat[rdf]) {
			case LDNS_RDF_TYPE_DNAME:
				oldpos = ldns_buffer_position(pkt);
				dname_pkt_copy(pkt, to, 
					ldns_buffer_current(pkt));
				to += pkt_dname_len(pkt);
				pkt_len -= ldns_buffer_position(pkt)-oldpos;
				count--;
				len = 0;
				break;
			case LDNS_RDF_TYPE_STR:
				len = ldns_buffer_current(pkt)[0] + 1;
				break;
			default:
				len = get_rdf_size(desc->_wireformat[rdf]);
				break;
			}
			if(len) {
				memmove(to, ldns_buffer_current(pkt), len);
				to += len;
				ldns_buffer_skip(pkt, (ssize_t)len);
				log_assert(len <= pkt_len);
				pkt_len -= len;
			}
			rdf++;
		}
	}
	/* copy remaining rdata */
	if(pkt_len >  0)
		memmove(to, ldns_buffer_current(pkt), pkt_len);
	
	return 1;
}