示例#1
0
void
log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, 
	uint16_t type, uint16_t dclass)
{
	char buf[LDNS_MAX_DOMAINLEN+1];
	char t[12], c[12];
	const char *ts, *cs; 
	if(verbosity < v)
		return;
	dname_str(name, buf);
	if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG";
	else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR";
	else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR";
	else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB";
	else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA";
	else if(type == LDNS_RR_TYPE_ANY) ts = "ANY";
	else if(ldns_rr_descript(type) && ldns_rr_descript(type)->_name)
		ts = ldns_rr_descript(type)->_name;
	else {
		snprintf(t, sizeof(t), "TYPE%d", (int)type);
		ts = t;
	}
	if(ldns_lookup_by_id(ldns_rr_classes, (int)dclass) &&
		ldns_lookup_by_id(ldns_rr_classes, (int)dclass)->name)
		cs = ldns_lookup_by_id(ldns_rr_classes, (int)dclass)->name;
	else {
		snprintf(c, sizeof(c), "CLASS%d", (int)dclass);
		cs = c;
	}
	log_info("%s %s %s %s", str, buf, ts, cs);
}
/** perf test a packet */
static void
perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_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, ldns_buffer_begin(pkt), sizeof(id));
	if(ldns_buffer_limit(pkt) < 2)
		flags = 0;
	else	memmove(&flags, ldns_buffer_at(pkt, 2), sizeof(flags));
	flags = ntohs(flags);
	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
	if(ret != 0) {
		if(vbmp) printf("parse code %d: %s\n", ret, 
			ldns_lookup_by_id(ldns_rcodes, ret)->name);
		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);
}
示例#3
0
ldns_rr *
ldns_axfr_next(ldns_resolver *resolver)
{
	ldns_rr *cur_rr;
	uint8_t *packet_wire;
	size_t packet_wire_size;
	ldns_lookup_table *rcode;
	ldns_status status;
	
	/* check if start() has been called */
	if (!resolver || resolver->_socket == 0) {
		return NULL;
	}
	
	if (resolver->_cur_axfr_pkt) {
		if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
			ldns_pkt_free(resolver->_cur_axfr_pkt);
			resolver->_cur_axfr_pkt = NULL;
			return ldns_axfr_next(resolver);
		}
		cur_rr = ldns_rr_clone(ldns_rr_list_rr(
					ldns_pkt_answer(resolver->_cur_axfr_pkt), 
					resolver->_axfr_i));
		resolver->_axfr_i++;
		if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
			resolver->_axfr_soa_count++;
			if (resolver->_axfr_soa_count >= 2) {
				close(resolver->_socket);
				resolver->_socket = 0;
				ldns_pkt_free(resolver->_cur_axfr_pkt);
				resolver->_cur_axfr_pkt = NULL;
			}
		}
		return cur_rr;
	} else {
		packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size);
		if(!packet_wire) 
			return NULL;
		
		status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire, 
				     packet_wire_size);
		free(packet_wire);

		resolver->_axfr_i = 0;
		if (status != LDNS_STATUS_OK) {
			/* TODO: make status return type of this function (...api change) */
			fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
			return NULL;
		} else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
			rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt));
			fprintf(stderr, "Error in AXFR: %s\n", rcode->name);
			return NULL;
		} else {
			return ldns_axfr_next(resolver);
		}
		
	}
	
}
示例#4
0
/** nice string for rcode */
static void
pretty_rcode(char* s, size_t len, int r)
{
	ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes, r);
	if(rcode) {
		snprintf(s, len, "%s", rcode->name);
	} else {
		snprintf(s, len, "RCODE%d", r);
	}
}
示例#5
0
文件: error.c 项目: jelu/ldns-mm
const char *
ldns_get_errorstr_by_id(ldns_status err)
{
        ldns_lookup_table *lt;

        lt = ldns_lookup_by_id(ldns_error_str, err);

        if (lt) {
                return lt->name;
        }
        return NULL;
}
示例#6
0
void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s)
{
	char buf[256];
	ldns_lookup_table *t = ldns_lookup_by_id(ldns_algorithms, alg);
	if(t&&t->name)
		snprintf(buf, sizeof(buf), "%s with algorithm %s", s, t->name);
	else	snprintf(buf, sizeof(buf), "%s with algorithm ALG%u", s,
			(unsigned)alg);
	*reason = regional_strdup(env->scratch, buf);
	if(!*reason)
		*reason = s;
}
/** 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);
	}
}
/** entry to reply info conversion */
static void
entry_to_repinfo(struct entry* e, struct alloc_cache* alloc, 
	struct regional* region, ldns_buffer* pkt, struct query_info* qi, 
	struct reply_info** rep)
{
	int ret;
	struct edns_data edns;
	entry_to_buf(e, pkt);
	/* lock alloc lock to please lock checking software. 
	 * alloc_special_obtain assumes it is talking to a ub-alloc,
	 * and does not need to perform locking. Here the alloc is
	 * the only one, so we lock it here */
	lock_quick_lock(&alloc->lock);
	ret = reply_info_parse(pkt, alloc, qi, rep, region, &edns);
	lock_quick_unlock(&alloc->lock);
	if(ret != 0) {
		printf("parse code %d: %s\n", ret,
			ldns_lookup_by_id(ldns_rcodes, ret)->name);
		unit_assert(ret != 0);
	}
}
示例#9
0
文件: remote.c 项目: RS-liuyang/rsdns
/** print extended stats */
static int
print_ext(SSL* ssl, struct stats_info* s)
{
	int i;
	char nm[16];
	const ldns_rr_descriptor* desc;
	const ldns_lookup_table* lt;
	/* TYPE */
	for(i=0; i<STATS_QTYPE_NUM; i++) {
		if(inhibit_zero && s->svr.qtype[i] == 0)
			continue;
		desc = ldns_rr_descript((uint16_t)i);
		if(desc && desc->_name) {
			snprintf(nm, sizeof(nm), "%s", desc->_name);
		} else if (i == LDNS_RR_TYPE_IXFR) {
			snprintf(nm, sizeof(nm), "IXFR");
		} else if (i == LDNS_RR_TYPE_AXFR) {
			snprintf(nm, sizeof(nm), "AXFR");
		} else if (i == LDNS_RR_TYPE_MAILA) {
			snprintf(nm, sizeof(nm), "MAILA");
		} else if (i == LDNS_RR_TYPE_MAILB) {
			snprintf(nm, sizeof(nm), "MAILB");
		} else if (i == LDNS_RR_TYPE_ANY) {
			snprintf(nm, sizeof(nm), "ANY");
		} else {
			snprintf(nm, sizeof(nm), "TYPE%d", i);
		}
		if(!ssl_printf(ssl, "num.query.type.%s"SQ"%u\n", 
			nm, (unsigned)s->svr.qtype[i])) return 0;
	}
	if(!inhibit_zero || s->svr.qtype_big) {
		if(!ssl_printf(ssl, "num.query.type.other"SQ"%u\n", 
			(unsigned)s->svr.qtype_big)) return 0;
	}
	/* CLASS */
	for(i=0; i<STATS_QCLASS_NUM; i++) {
		if(inhibit_zero && s->svr.qclass[i] == 0)
			continue;
		lt = ldns_lookup_by_id(ldns_rr_classes, i);
		if(lt && lt->name) {
			snprintf(nm, sizeof(nm), "%s", lt->name);
		} else {
			snprintf(nm, sizeof(nm), "CLASS%d", i);
		}
		if(!ssl_printf(ssl, "num.query.class.%s"SQ"%u\n", 
			nm, (unsigned)s->svr.qclass[i])) return 0;
	}
	if(!inhibit_zero || s->svr.qclass_big) {
		if(!ssl_printf(ssl, "num.query.class.other"SQ"%u\n", 
			(unsigned)s->svr.qclass_big)) return 0;
	}
	/* OPCODE */
	for(i=0; i<STATS_OPCODE_NUM; i++) {
		if(inhibit_zero && s->svr.qopcode[i] == 0)
			continue;
		lt = ldns_lookup_by_id(ldns_opcodes, i);
		if(lt && lt->name) {
			snprintf(nm, sizeof(nm), "%s", lt->name);
		} else {
			snprintf(nm, sizeof(nm), "OPCODE%d", i);
		}
		if(!ssl_printf(ssl, "num.query.opcode.%s"SQ"%u\n", 
			nm, (unsigned)s->svr.qopcode[i])) return 0;
	}
	/* transport */
	if(!ssl_printf(ssl, "num.query.tcp"SQ"%u\n", 
		(unsigned)s->svr.qtcp)) return 0;
	if(!ssl_printf(ssl, "num.query.ipv6"SQ"%u\n", 
		(unsigned)s->svr.qipv6)) return 0;
	/* flags */
	if(!ssl_printf(ssl, "num.query.flags.QR"SQ"%u\n", 
		(unsigned)s->svr.qbit_QR)) return 0;
	if(!ssl_printf(ssl, "num.query.flags.AA"SQ"%u\n", 
		(unsigned)s->svr.qbit_AA)) return 0;
	if(!ssl_printf(ssl, "num.query.flags.TC"SQ"%u\n", 
		(unsigned)s->svr.qbit_TC)) return 0;
	if(!ssl_printf(ssl, "num.query.flags.RD"SQ"%u\n", 
		(unsigned)s->svr.qbit_RD)) return 0;
	if(!ssl_printf(ssl, "num.query.flags.RA"SQ"%u\n", 
		(unsigned)s->svr.qbit_RA)) return 0;
	if(!ssl_printf(ssl, "num.query.flags.Z"SQ"%u\n", 
		(unsigned)s->svr.qbit_Z)) return 0;
	if(!ssl_printf(ssl, "num.query.flags.AD"SQ"%u\n", 
		(unsigned)s->svr.qbit_AD)) return 0;
	if(!ssl_printf(ssl, "num.query.flags.CD"SQ"%u\n", 
		(unsigned)s->svr.qbit_CD)) return 0;
	if(!ssl_printf(ssl, "num.query.edns.present"SQ"%u\n", 
		(unsigned)s->svr.qEDNS)) return 0;
	if(!ssl_printf(ssl, "num.query.edns.DO"SQ"%u\n", 
		(unsigned)s->svr.qEDNS_DO)) return 0;

	/* RCODE */
	for(i=0; i<STATS_RCODE_NUM; i++) {
		if(inhibit_zero && s->svr.ans_rcode[i] == 0)
			continue;
		lt = ldns_lookup_by_id(ldns_rcodes, i);
		if(lt && lt->name) {
			snprintf(nm, sizeof(nm), "%s", lt->name);
		} else {
			snprintf(nm, sizeof(nm), "RCODE%d", i);
		}
		if(!ssl_printf(ssl, "num.answer.rcode.%s"SQ"%u\n", 
			nm, (unsigned)s->svr.ans_rcode[i])) return 0;
	}
	if(!inhibit_zero || s->svr.ans_rcode_nodata) {
		if(!ssl_printf(ssl, "num.answer.rcode.nodata"SQ"%u\n", 
			(unsigned)s->svr.ans_rcode_nodata)) return 0;
	}
	/* validation */
	if(!ssl_printf(ssl, "num.answer.secure"SQ"%u\n", 
		(unsigned)s->svr.ans_secure)) return 0;
	if(!ssl_printf(ssl, "num.answer.bogus"SQ"%u\n", 
		(unsigned)s->svr.ans_bogus)) return 0;
	if(!ssl_printf(ssl, "num.rrset.bogus"SQ"%u\n", 
		(unsigned)s->svr.rrset_bogus)) return 0;
	/* threat detection */
	if(!ssl_printf(ssl, "unwanted.queries"SQ"%u\n", 
		(unsigned)s->svr.unwanted_queries)) return 0;
	if(!ssl_printf(ssl, "unwanted.replies"SQ"%u\n", 
		(unsigned)s->svr.unwanted_replies)) return 0;
	return 1;
}
/** test a packet */
static void
testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_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, ldns_buffer_begin(pkt), sizeof(id));
	if(ldns_buffer_limit(pkt) < 2)
		flags = 0;
	else	memmove(&flags, ldns_buffer_at(pkt, 2), sizeof(flags));
	flags = ntohs(flags);
	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
	if(ret != 0) {
		if(vbmp) printf("parse code %d: %s\n", ret, 
			ldns_lookup_by_id(ldns_rcodes, ret)->name);
		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)ldns_buffer_limit(pkt),
			(unsigned)ldns_buffer_limit(out));
		test_buffers(pkt, out);
		if(check_rrsigs)
			check_the_rrsigs(&qi, rep);

		if(ldns_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(ldns_buffer_begin(out)) !=
				LDNS_QDCOUNT(ldns_buffer_begin(pkt)) ||
				LDNS_ANCOUNT(ldns_buffer_begin(out)) !=
				LDNS_ANCOUNT(ldns_buffer_begin(pkt)) ||
				LDNS_NSCOUNT(ldns_buffer_begin(out)) !=
				LDNS_NSCOUNT(ldns_buffer_begin(pkt)))
				unit_assert(
				LDNS_TC_WIRE(ldns_buffer_begin(out)));
				/* must set TC bit if shortened */
			unit_assert(ldns_buffer_limit(out) <= lim);
		}
	} 

	query_info_clear(&qi);
	reply_info_parsedelete(rep, alloc);
	regional_destroy(region);
}
示例#11
0
ldns_rr *
ldns_axfr_next(ldns_resolver *resolver)
{
    ldns_rr *cur_rr;
    uint8_t *packet_wire;
    size_t packet_wire_size;
    ldns_lookup_table *rcode;
    ldns_status status;

    /* check if start() has been called */
    if (!resolver || resolver->_socket == 0) {
        return NULL;
    }

    if (resolver->_cur_axfr_pkt) {
        if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
            ldns_pkt_free(resolver->_cur_axfr_pkt);
            resolver->_cur_axfr_pkt = NULL;
            return ldns_axfr_next(resolver);
        }
        cur_rr = ldns_rr_clone(ldns_rr_list_rr(
                                   ldns_pkt_answer(resolver->_cur_axfr_pkt),
                                   resolver->_axfr_i));
        resolver->_axfr_i++;
        if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
            resolver->_axfr_soa_count++;
            if (resolver->_axfr_soa_count >= 2) {
#ifndef USE_WINSOCK
                close(resolver->_socket);
#else
                closesocket(resolver->_socket);
#endif
                resolver->_socket = 0;
                ldns_pkt_free(resolver->_cur_axfr_pkt);
                resolver->_cur_axfr_pkt = NULL;
            }
        }
        return cur_rr;
    } else {
        packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size);
        if(!packet_wire)
            return NULL;

        status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
                               packet_wire_size);
        free(packet_wire);

        resolver->_axfr_i = 0;
        if (status != LDNS_STATUS_OK) {
            /* TODO: make status return type of this function (...api change) */
            fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));

            /* RoRi: we must now also close the socket, otherwise subsequent uses of the
               same resolver structure will fail because the link is still open or
               in an undefined state */
#ifndef USE_WINSOCK
            close(resolver->_socket);
#else
            closesocket(resolver->_socket);
#endif
            resolver->_socket = 0;

            return NULL;
        } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
            rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt));
            fprintf(stderr, "Error in AXFR: %s\n", rcode->name);

            /* RoRi: we must now also close the socket, otherwise subsequent uses of the
               same resolver structure will fail because the link is still open or
               in an undefined state */
#ifndef USE_WINSOCK
            close(resolver->_socket);
#else
            closesocket(resolver->_socket);
#endif
            resolver->_socket = 0;

            return NULL;
        } else {
            return ldns_axfr_next(resolver);
        }

    }

}