/build/ldns-00A0O8/ldns-1.8.4/higher.c
Go to the documentation of this file.
/*
* higher.c
*
* Specify some higher level functions that would
* be useful to would be developers
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2004-2006
*
* See the file LICENSE for the license
*/
#include <ldns/config.h>
#include <ldns/ldns.h>
#ifdef HAVE_SSL
#include <openssl/ssl.h>
#include <openssl/sha.h>
#endif /* HAVE_SSL */
ldns_rr_list *
ldns_get_rr_list_addr_by_name(ldns_resolver *res, const ldns_rdf *name,
ldns_rr_class c, uint16_t flags)
{
ldns_pkt *pkt;
ldns_rr_list *aaaa;
ldns_rr_list *a;
ldns_rr_list *result = NULL;
ldns_rr_list *hostsfilenames;
size_t i;
uint8_t ip6;
a = NULL;
aaaa = NULL;
result = NULL;
if (!res) {
return NULL;
}
if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
return NULL;
}
ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
what was there */
ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
if (ldns_rdf_compare(name,
ldns_rr_owner(ldns_rr_list_rr(hostsfilenames,
i))) == 0) {
if (!result) {
result = ldns_rr_list_new();
}
ldns_rr_list_push_rr(result,
ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
}
}
ldns_rr_list_deep_free(hostsfilenames);
if (result) {
return result;
}
/* add the RD flags, because we want an answer */
pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
if (pkt) {
/* extract the data we need */
aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA,
LDNS_SECTION_ANSWER);
ldns_pkt_free(pkt);
}
pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
if (pkt) {
/* extract the data we need */
a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
ldns_pkt_free(pkt);
}
ldns_resolver_set_ip6(res, ip6);
if (aaaa && a) {
result = ldns_rr_list_cat_clone(aaaa, a);
ldns_rr_list_deep_free(aaaa);
ldns_rr_list_deep_free(a);
return result;
}
if (aaaa) {
result = ldns_rr_list_clone(aaaa);
}
if (a) {
result = ldns_rr_list_clone(a);
}
ldns_rr_list_deep_free(aaaa);
ldns_rr_list_deep_free(a);
return result;
}
ldns_rr_list *
ldns_get_rr_list_name_by_addr(ldns_resolver *res, const ldns_rdf *addr,
ldns_rr_class c, uint16_t flags)
{
ldns_pkt *pkt;
ldns_rr_list *names;
ldns_rdf *name;
names = NULL;
if (!res || !addr) {
return NULL;
}
if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
return NULL;
}
name = ldns_rdf_address_reverse(addr);
/* add the RD flags, because we want an answer */
pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
ldns_rdf_deep_free(name);
if (pkt) {
/* extract the data we need */
names = ldns_pkt_rr_list_by_type(pkt,
LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
ldns_pkt_free(pkt);
}
return names;
}
/* read a line, put it in a buffer, parse the buffer */
ldns_rr_list *
ldns_get_rr_list_hosts_frm_fp(FILE *fp)
{
return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
}
ldns_rr_list *
ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
{
ssize_t i, j;
size_t cnt;
char *line;
char *word;
char *addr;
char *rr_str;
ldns_buffer *linebuf;
ldns_rr *rr;
ldns_rr_list *list;
ldns_rdf *tmp;
bool ip6;
ldns_status parse_result;
line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
ip6 = false;
list = ldns_rr_list_new();
rr = NULL;
if(!line || !word || !addr || !rr_str || !list) {
LDNS_FREE(line);
LDNS_FREE(word);
LDNS_FREE(addr);
LDNS_FREE(rr_str);
ldns_rr_list_free(list);
return NULL;
}
for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
/* # is comment */
if (line[0] == '#') {
continue;
}
/* put it in a buffer for further processing */
linebuf = LDNS_MALLOC(ldns_buffer);
if(!linebuf) {
LDNS_FREE(line);
LDNS_FREE(word);
LDNS_FREE(addr);
LDNS_FREE(rr_str);
ldns_rr_list_deep_free(list);
return NULL;
}
ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
j > 0;
j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
if (cnt == 0) {
/* the address */
if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
word))) {
/* ip6 */
ldns_rdf_deep_free(tmp);
ip6 = true;
} else {
if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
word))) {
/* ip4 */
ldns_rdf_deep_free(tmp);
ip6 = false;
} else {
/* kaput */
break;
}
}
(void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
} else {
/* Stop parsing line when a comment begins. */
if (word[0] == '#')
break;
/* la al la la */
if (ip6) {
snprintf(rr_str, LDNS_MAX_LINELEN,
"%s IN AAAA %s", word, addr);
} else {
snprintf(rr_str, LDNS_MAX_LINELEN,
"%s IN A %s", word, addr);
}
parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
ldns_rr_free(rr);
}
}
}
ldns_buffer_free(linebuf);
}
LDNS_FREE(line);
LDNS_FREE(word);
LDNS_FREE(addr);
LDNS_FREE(rr_str);
return list;
}
ldns_rr_list *
ldns_get_rr_list_hosts_frm_file(char *filename)
{
ldns_rr_list *names;
FILE *fp;
if (!filename) {
fp = fopen(LDNS_RESOLV_HOSTS, "r");
} else {
fp = fopen(filename, "r");
}
if (!fp) {
return NULL;
}
names = ldns_get_rr_list_hosts_frm_fp(fp);
fclose(fp);
return names;
}
uint16_t
ldns_getaddrinfo(ldns_resolver *res, const ldns_rdf *node,
ldns_rr_class c, ldns_rr_list **ret)
{
ldns_rdf_type t;
uint16_t names_found;
ldns_resolver *r;
ldns_status s;
t = ldns_rdf_get_type(node);
names_found = 0;
r = res;
if (res == NULL) {
/* prepare a new resolver, using /etc/resolv.conf as a guide */
s = ldns_resolver_new_frm_file(&r, NULL);
if (s != LDNS_STATUS_OK) {
return 0;
}
}
if (t == LDNS_RDF_TYPE_DNAME) {
/* we're asked to query for a name */
*ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
names_found = ldns_rr_list_rr_count(*ret);
}
if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
/* an address */
*ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
names_found = ldns_rr_list_rr_count(*ret);
}
if (res == NULL) {
ldns_resolver_deep_free(r);
}
return names_found;
}
bool
ldns_nsec_type_check(const ldns_rr *nsec, ldns_rr_type t)
{
switch (ldns_rr_get_type(nsec)) {
case LDNS_RR_TYPE_NSEC : if (ldns_rr_rd_count(nsec) < 2) {
return false;
}
return ldns_nsec_bitmap_covers_type(
ldns_rr_rdf(nsec, 1), t);
case LDNS_RR_TYPE_NSEC3 : if (ldns_rr_rd_count(nsec) < 6) {
return false;
}
return ldns_nsec_bitmap_covers_type(
ldns_rr_rdf(nsec, 5), t);
default : return false;
}
}
void
ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
{
int16_t rdf;
ldns_rdf *rd;
va_list va_rdf;
va_start(va_rdf, rdfnum);
for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
{
rd = ldns_rr_rdf(r, rdf);
if (!rd) {
continue;
} else {
ldns_rdf_print(fp, rd);
fprintf(fp, " "); /* not sure if we want to do this */
}
}
va_end(va_rdf);
}
ldns_buffer_free
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition buffer.c:137
ldns_buffer
struct ldns_struct_buffer ldns_buffer
Definition buffer.h:72
ldns_buffer_new_frm_data
void ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
creates a buffer with the specified data.
Definition buffer.c:41
config.h
ldns_nsec_bitmap_covers_type
signed char ldns_nsec_bitmap_covers_type(const ldns_rdf *bitmap, ldns_rr_type type)
Check if RR type t is enumerated and set in the RR type bitmap rdf.
Definition dnssec.c:1393
LDNS_STATUS_OK
@ LDNS_STATUS_OK
Definition error.h:26
ldns_status
enum ldns_enum_status ldns_status
Definition error.h:148
ldns_get_rr_list_addr_by_name
ldns_rr_list * ldns_get_rr_list_addr_by_name(ldns_resolver *res, const ldns_rdf *name, ldns_rr_class c, uint16_t flags)
Ask the resolver about name and return all address records.
Definition higher.c:24
ldns_get_rr_list_hosts_frm_fp
ldns_rr_list * ldns_get_rr_list_hosts_frm_fp(FILE *fp)
wade through fp (a /etc/hosts like file) and return a rr_list containing all the defined hosts in the...
Definition higher.c:141
ldns_print_rr_rdf
void ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum,...)
Print a number of rdf's of the RR.
Definition higher.c:328
ldns_getaddrinfo
uint16_t ldns_getaddrinfo(ldns_resolver *res, const ldns_rdf *node, ldns_rr_class c, ldns_rr_list **ret)
This function is a wrapper function for ldns_get_rr_list_name_by_addr and ldns_get_rr_list_addr_by_na...
Definition higher.c:268
ldns_get_rr_list_name_by_addr
ldns_rr_list * ldns_get_rr_list_name_by_addr(ldns_resolver *res, const ldns_rdf *addr, ldns_rr_class c, uint16_t flags)
ask the resolver about the address and return the name
Definition higher.c:107
ldns_nsec_type_check
signed char ldns_nsec_type_check(const ldns_rr *nsec, ldns_rr_type t)
Check if t is enumerated in the nsec type rdata.
Definition higher.c:308
ldns_get_rr_list_hosts_frm_fp_l
ldns_rr_list * ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
wade through fp (a /etc/hosts like file) and return a rr_list containing all the defined hosts in the...
Definition higher.c:147
ldns_get_rr_list_hosts_frm_file
ldns_rr_list * ldns_get_rr_list_hosts_frm_file(char *filename)
wade through fp (a /etc/hosts like file) and return a rr_list containing all the defined hosts in the...
Definition higher.c:247
ldns_rdf_print
void ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
Prints the data in the rdata field to the given file stream (in presentation format).
Definition host2str.c:3394
ldns_pkt_free
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
Definition packet.c:897
ldns_pkt_rr_list_by_type
ldns_rr_list * ldns_pkt_rr_list_by_type(const ldns_pkt *p, ldns_rr_type t, ldns_pkt_section s)
return all the rr with a specific type from a packet.
Definition packet.c:304
ldns_pkt
struct ldns_struct_pkt ldns_pkt
Definition packet.h:272
LDNS_SECTION_ANSWER
@ LDNS_SECTION_ANSWER
Definition packet.h:279
LDNS_RD
#define LDNS_RD
Definition packet.h:30
ldns_fget_token_l
ssize_t ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
returns a token/char from the stream F.
Definition parse.c:247
LDNS_MAX_LINELEN
#define LDNS_MAX_LINELEN
Definition parse.h:23
ldns_bget_token
ssize_t ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
returns a token/char from the buffer b.
Definition parse.c:301
LDNS_PARSE_NO_NL
#define LDNS_PARSE_NO_NL
Definition parse.h:22
ldns_rdf_new_frm_str
ldns_rdf * ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
creates a new rdf from a string.
Definition rdata.c:249
ldns_rdf_get_type
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
Definition rdata.c:31
ldns_rdf_deep_free
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition rdata.c:230
LDNS_RDF_TYPE_AAAA
@ LDNS_RDF_TYPE_AAAA
AAAA record.
Definition rdata.h:60
LDNS_RDF_TYPE_DNAME
@ LDNS_RDF_TYPE_DNAME
domain name
Definition rdata.h:50
LDNS_RDF_TYPE_A
@ LDNS_RDF_TYPE_A
A record.
Definition rdata.h:58
ldns_rdf
struct ldns_struct_rdf ldns_rdf
Definition rdata.h:205
ldns_rdf_compare
int ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
compares two rdf's on their wire formats.
Definition rdata.c:657
ldns_rdf_address_reverse
ldns_rdf * ldns_rdf_address_reverse(const ldns_rdf *rd)
reverses an rdf, only actually useful for AAAA and A records.
Definition rdata.c:419
ldns_rdf_type
enum ldns_enum_rdf_type ldns_rdf_type
Definition rdata.h:151
LDNS_RESOLV_INETANY
#define LDNS_RESOLV_INETANY
Definition resolver.h:49
ldns_resolver_set_ip6
void ldns_resolver_set_ip6(ldns_resolver *r, uint8_t i)
Whether the resolver uses ip6.
Definition resolver.c:440
ldns_resolver
struct ldns_struct_resolver ldns_resolver
Definition resolver.h:147
ldns_resolver_ip6
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
Definition resolver.c:60
LDNS_RESOLV_HOSTS
#define LDNS_RESOLV_HOSTS
Default location of the hosts file.
Definition resolver.h:38
ldns_resolver_query
ldns_pkt * ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Send a query to a nameserver.
Definition resolver.c:1129
ldns_resolver_deep_free
void ldns_resolver_deep_free(ldns_resolver *res)
Frees the allocated space for this resolver and all it's data.
Definition resolver.c:1004
ldns_resolver_new_frm_file
ldns_status ldns_resolver_new_frm_file(ldns_resolver **r, const char *filename)
Configure a resolver by means of a resolv.conf file The file may be NULL in which case there will be ...
Definition resolver.c:967
ldns_rr_list_free
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition rr.c:1015
ldns_rr_list_deep_free
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition rr.c:1024
ldns_rr_free
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition rr.c:81
ldns_rr
struct ldns_struct_rr ldns_rr
Definition rr.h:337
ldns_rr_list_new
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition rr.c:1004
ldns_rr_new_frm_str
ldns_status ldns_rr_new_frm_str(ldns_rr **n, const char *str, uint32_t default_ttl, const ldns_rdf *origin, ldns_rdf **prev)
creates an rr from a string.
Definition rr.c:676
ldns_rr_type
enum ldns_enum_rr_type ldns_rr_type
Definition rr.h:251
LDNS_RR_TYPE_A
@ LDNS_RR_TYPE_A
a host address
Definition rr.h:80
LDNS_RR_TYPE_NSEC
@ LDNS_RR_TYPE_NSEC
Definition rr.h:171
LDNS_RR_TYPE_NSEC3
@ LDNS_RR_TYPE_NSEC3
Definition rr.h:176
LDNS_RR_TYPE_PTR
@ LDNS_RR_TYPE_PTR
a domain name pointer
Definition rr.h:102
LDNS_RR_TYPE_AAAA
@ LDNS_RR_TYPE_AAAA
ipv6 address
Definition rr.h:134
ldns_rr_list_cat_clone
ldns_rr_list * ldns_rr_list_cat_clone(const ldns_rr_list *left, const ldns_rr_list *right)
concatenates two ldns_rr_lists together, but makes clones of the rr's (instead of pointer copying).
Definition rr.c:1063
ldns_rr_list_push_rr
signed char ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition rr.c:1136
ldns_rr_rd_count
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
Definition rr.c:941
ldns_rr_rdf
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition rr.c:913
ldns_rr_list_rr_count
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition rr.c:961
ldns_rr_get_type
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition rr.c:947
ldns_rr_clone
ldns_rr * ldns_rr_clone(const ldns_rr *rr)
clones a rr and all its data
Definition rr.c:1404
ldns_rr_list
struct ldns_struct_rr_list ldns_rr_list
Definition rr.h:351
ldns_rr_class
enum ldns_enum_rr_class ldns_rr_class
Definition rr.h:61
ldns_rr_list_rr
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition rr.c:994
ldns_rr_list_clone
ldns_rr_list * ldns_rr_list_clone(const ldns_rr_list *rrlist)
clones an rrlist.
Definition rr.c:1435
ldns_rr_owner
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition rr.c:923
LDNS_FREE
#define LDNS_FREE(ptr)
Definition util.h:60
LDNS_MALLOC
#define LDNS_MALLOC(type)
Memory management macros.
Definition util.h:49
LDNS_XMALLOC
#define LDNS_XMALLOC(type, count)
Definition util.h:51