diff options
Diffstat (limited to 'contrib/ldns/host2str.c')
-rw-r--r-- | contrib/ldns/host2str.c | 2314 |
1 files changed, 2314 insertions, 0 deletions
diff --git a/contrib/ldns/host2str.c b/contrib/ldns/host2str.c new file mode 100644 index 0000000..e906f83 --- /dev/null +++ b/contrib/ldns/host2str.c @@ -0,0 +1,2314 @@ +/* + * host2str.c + * + * conversion routines from the host format + * to the presentation format (strings) + * + * 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> + +#include <limits.h> + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#include <time.h> +#include <sys/time.h> + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif + +/* lookup tables for standard DNS stuff */ + +/* Taken from RFC 2535, section 7. */ +ldns_lookup_table ldns_algorithms[] = { + { LDNS_RSAMD5, "RSAMD5" }, + { LDNS_DH, "DH" }, + { LDNS_DSA, "DSA" }, + { LDNS_ECC, "ECC" }, + { LDNS_RSASHA1, "RSASHA1" }, + { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" }, + { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" }, +#ifdef USE_SHA2 + { LDNS_RSASHA256, "RSASHA256"}, + { LDNS_RSASHA512, "RSASHA512"}, +#endif +#ifdef USE_GOST + { LDNS_ECC_GOST, "ECC-GOST"}, +#endif +#ifdef USE_ECDSA + { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"}, + { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"}, +#endif + { LDNS_INDIRECT, "INDIRECT" }, + { LDNS_PRIVATEDNS, "PRIVATEDNS" }, + { LDNS_PRIVATEOID, "PRIVATEOID" }, + { 0, NULL } +}; + +/* Taken from RFC 4398 */ +ldns_lookup_table ldns_cert_algorithms[] = { + { LDNS_CERT_PKIX, "PKIX" }, + { LDNS_CERT_SPKI, "SPKI" }, + { LDNS_CERT_PGP, "PGP" }, + { LDNS_CERT_IPKIX, "IPKIX" }, + { LDNS_CERT_ISPKI, "ISPKI" }, + { LDNS_CERT_IPGP, "IPGP" }, + { LDNS_CERT_ACPKIX, "ACPKIX" }, + { LDNS_CERT_IACPKIX, "IACPKIX" }, + { LDNS_CERT_URI, "URI" }, + { LDNS_CERT_OID, "OID" }, + { 0, NULL } +}; + +/* classes */ +ldns_lookup_table ldns_rr_classes[] = { + { LDNS_RR_CLASS_IN, "IN" }, + { LDNS_RR_CLASS_CH, "CH" }, + { LDNS_RR_CLASS_HS, "HS" }, + { LDNS_RR_CLASS_NONE, "NONE" }, + { LDNS_RR_CLASS_ANY, "ANY" }, + { 0, NULL } +}; + +/* if these are used elsewhere */ +ldns_lookup_table ldns_rcodes[] = { + { LDNS_RCODE_NOERROR, "NOERROR" }, + { LDNS_RCODE_FORMERR, "FORMERR" }, + { LDNS_RCODE_SERVFAIL, "SERVFAIL" }, + { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" }, + { LDNS_RCODE_NOTIMPL, "NOTIMPL" }, + { LDNS_RCODE_REFUSED, "REFUSED" }, + { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" }, + { LDNS_RCODE_YXRRSET, "YXRRSET" }, + { LDNS_RCODE_NXRRSET, "NXRRSET" }, + { LDNS_RCODE_NOTAUTH, "NOTAUTH" }, + { LDNS_RCODE_NOTZONE, "NOTZONE" }, + { 0, NULL } +}; + +ldns_lookup_table ldns_opcodes[] = { + { LDNS_PACKET_QUERY, "QUERY" }, + { LDNS_PACKET_IQUERY, "IQUERY" }, + { LDNS_PACKET_STATUS, "STATUS" }, + { LDNS_PACKET_NOTIFY, "NOTIFY" }, + { LDNS_PACKET_UPDATE, "UPDATE" }, + { 0, NULL } +}; + +const ldns_output_format ldns_output_format_nocomments_record = { 0, NULL }; +const ldns_output_format *ldns_output_format_nocomments + = &ldns_output_format_nocomments_record; +const ldns_output_format ldns_output_format_onlykeyids_record = { + LDNS_COMMENT_KEY, NULL +}; +const ldns_output_format *ldns_output_format_onlykeyids + = &ldns_output_format_onlykeyids_record; +const ldns_output_format *ldns_output_format_default + = &ldns_output_format_onlykeyids_record; +const ldns_output_format ldns_output_format_bubblebabble_record = { + LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL +}; +const ldns_output_format *ldns_output_format_bubblebabble + = &ldns_output_format_bubblebabble_record; + +ldns_status +ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode) +{ + ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode); + if (lt && lt->name) { + ldns_buffer_printf(output, "%s", lt->name); + } else { + ldns_buffer_printf(output, "OPCODE%u", opcode); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode) +{ + ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode); + if (lt && lt->name) { + ldns_buffer_printf(output, "%s", lt->name); + } else { + ldns_buffer_printf(output, "RCODE%u", rcode); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_algorithm2buffer_str(ldns_buffer *output, + ldns_algorithm algorithm) +{ + ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms, + algorithm); + if (lt && lt->name) { + ldns_buffer_printf(output, "%s", lt->name); + } else { + ldns_buffer_printf(output, "ALG%u", algorithm); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_cert_algorithm2buffer_str(ldns_buffer *output, + ldns_cert_algorithm cert_algorithm) +{ + ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms, + cert_algorithm); + if (lt && lt->name) { + ldns_buffer_printf(output, "%s", lt->name); + } else { + ldns_buffer_printf(output, "CERT_ALG%u", + cert_algorithm); + } + return ldns_buffer_status(output); +} + +char * +ldns_pkt_opcode2str(ldns_pkt_opcode opcode) +{ + char *str; + ldns_buffer *buf; + + buf = ldns_buffer_new(12); + if (!buf) { + return NULL; + } + + str = NULL; + if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) { + str = ldns_buffer2str(buf); + } + + ldns_buffer_free(buf); + return str; +} + +char * +ldns_pkt_rcode2str(ldns_pkt_rcode rcode) +{ + char *str; + ldns_buffer *buf; + + buf = ldns_buffer_new(10); + if (!buf) { + return NULL; + } + + str = NULL; + if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) { + str = ldns_buffer2str(buf); + } + + ldns_buffer_free(buf); + return str; +} + +char * +ldns_pkt_algorithm2str(ldns_algorithm algorithm) +{ + char *str; + ldns_buffer *buf; + + buf = ldns_buffer_new(10); + if (!buf) { + return NULL; + } + + str = NULL; + if (ldns_algorithm2buffer_str(buf, algorithm) + == LDNS_STATUS_OK) { + str = ldns_buffer2str(buf); + } + + ldns_buffer_free(buf); + return str; +} + +char * +ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm) +{ + char *str; + ldns_buffer *buf; + + buf = ldns_buffer_new(10); + if (!buf) { + return NULL; + } + + str = NULL; + if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm) + == LDNS_STATUS_OK) { + str = ldns_buffer2str(buf); + } + + ldns_buffer_free(buf); + return str; +} + + +/* do NOT pass compressed data here :p */ +ldns_status +ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname) +{ + /* can we do with 1 pos var? or without at all? */ + uint8_t src_pos = 0; + uint8_t len; + uint8_t *data; + uint8_t i; + unsigned char c; + + data = (uint8_t*)ldns_rdf_data(dname); + len = data[src_pos]; + + if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) { + /* too large, return */ + return LDNS_STATUS_DOMAINNAME_OVERFLOW; + } + + /* special case: root label */ + if (1 == ldns_rdf_size(dname)) { + ldns_buffer_printf(output, "."); + } else { + while ((len > 0) && src_pos < ldns_rdf_size(dname)) { + src_pos++; + for(i = 0; i < len; i++) { + /* paranoia check for various 'strange' + characters in dnames + */ + c = (unsigned char) data[src_pos]; + if(c == '.' || c == ';' || + c == '(' || c == ')' || + c == '\\') { + ldns_buffer_printf(output, "\\%c", + data[src_pos]); + } else if (!(isascii(c) && isgraph(c))) { + ldns_buffer_printf(output, "\\%03u", + data[src_pos]); + } else { + ldns_buffer_printf(output, "%c", data[src_pos]); + } + src_pos++; + } + + if (src_pos < ldns_rdf_size(dname)) { + ldns_buffer_printf(output, "."); + } + len = data[src_pos]; + } + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint8_t data = ldns_rdf_data(rdf)[0]; + ldns_buffer_printf(output, "%lu", (unsigned long) data); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf)); + ldns_buffer_printf(output, "%lu", (unsigned long) data); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf)); + ldns_buffer_printf(output, "%lu", (unsigned long) data); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* create a YYYYMMDDHHMMSS string if possible */ + struct tm tm; + char date_buf[16]; + + memset(&tm, 0, sizeof(tm)); + if (ldns_serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm) + && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) { + ldns_buffer_printf(output, "%s", date_buf); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf) +{ + char str[INET_ADDRSTRLEN]; + + if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) { + ldns_buffer_printf(output, "%s", str); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf) +{ + char str[INET6_ADDRSTRLEN]; + + if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) { + ldns_buffer_printf(output, "%s", str); + } + + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf) +{ + const uint8_t *data = ldns_rdf_data(rdf); + uint8_t length = data[0]; + size_t i; + + ldns_buffer_printf(output, "\""); + for (i = 1; i <= length; ++i) { + char ch = (char) data[i]; + if (isprint((int)ch) || ch=='\t') { + if (ch=='\"'||ch=='\\') + ldns_buffer_printf(output, "\\%c", ch); + else + ldns_buffer_printf(output, "%c", ch); + } else { + ldns_buffer_printf(output, "\\%03u", + (unsigned)(uint8_t) ch); + } + } + ldns_buffer_printf(output, "\""); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf) +{ + size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf)); + char *b64 = LDNS_XMALLOC(char, size); + if(!b64) return LDNS_STATUS_MEM_ERR; + if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) { + ldns_buffer_printf(output, "%s", b64); + } + LDNS_FREE(b64); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf) +{ + size_t size; + char *b32; + if(ldns_rdf_size(rdf) == 0) + return LDNS_STATUS_OK; + /* remove -1 for the b32-hash-len octet */ + size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1); + /* add one for the end nul for the string */ + b32 = LDNS_XMALLOC(char, size + 1); + if(!b32) return LDNS_STATUS_MEM_ERR; + size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1, + ldns_rdf_size(rdf) - 1, b32, size+1); + if (size > 0) { + ldns_buffer_printf(output, "%s", b32); + } + LDNS_FREE(b32); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf) +{ + size_t i; + for (i = 0; i < ldns_rdf_size(rdf); i++) { + ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]); + } + + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf)); + const ldns_rr_descriptor *descriptor; + + descriptor = ldns_rr_descript(data); + if (descriptor && descriptor->_name) { + ldns_buffer_printf(output, "%s", descriptor->_name); + } else { + ldns_buffer_printf(output, "TYPE%u", data); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf)); + ldns_lookup_table *lt; + + lt = ldns_lookup_by_id(ldns_rr_classes, (int) data); + if (lt) { + ldns_buffer_printf(output, "\t%s", lt->name); + } else { + ldns_buffer_printf(output, "\tCLASS%d", data); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf)); + ldns_lookup_table *lt; + lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data); + if (lt) { + ldns_buffer_printf(output, "%s", lt->name); + } else { + ldns_buffer_printf(output, "%d", data); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* don't use algorithm mnemonics in the presentation format + this kind of got sneaked into the rfc's */ + uint8_t data = ldns_rdf_data(rdf)[0]; + ldns_buffer_printf(output, "%d", data); + return ldns_buffer_status(output); +} + +static void +loc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent) +{ + uint8_t i; + /* is it 0.<two digits> ? */ + if(exponent < 2) { + if(exponent == 1) + mantissa *= 10; + ldns_buffer_printf(output, "0.%02ld", (long)mantissa); + return; + } + /* always <digit><string of zeros> */ + ldns_buffer_printf(output, "%d", (int)mantissa); + for(i=0; i<exponent-2; i++) + ldns_buffer_printf(output, "0"); +} + +ldns_status +ldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type) +{ + const ldns_rr_descriptor *descriptor; + + descriptor = ldns_rr_descript(type); + + if (descriptor && descriptor->_name) { + ldns_buffer_printf(output, "%s", descriptor->_name); + } else { + /* exceptions for pseudotypes */ + switch (type) { + case LDNS_RR_TYPE_IXFR: + ldns_buffer_printf(output, "IXFR"); + break; + case LDNS_RR_TYPE_AXFR: + ldns_buffer_printf(output, "AXFR"); + break; + case LDNS_RR_TYPE_MAILA: + ldns_buffer_printf(output, "MAILA"); + break; + case LDNS_RR_TYPE_MAILB: + ldns_buffer_printf(output, "MAILB"); + break; + case LDNS_RR_TYPE_ANY: + ldns_buffer_printf(output, "ANY"); + break; + default: + ldns_buffer_printf(output, "TYPE%u", type); + } + } + return ldns_buffer_status(output); +} + +char * +ldns_rr_type2str(const ldns_rr_type type) +{ + char *str; + ldns_buffer *buf; + + buf = ldns_buffer_new(10); + if (!buf) { + return NULL; + } + + str = NULL; + if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) { + str = ldns_buffer2str(buf); + } + + ldns_buffer_free(buf); + return str; +} + + +ldns_status +ldns_rr_class2buffer_str(ldns_buffer *output, + const ldns_rr_class klass) +{ + ldns_lookup_table *lt; + + lt = ldns_lookup_by_id(ldns_rr_classes, klass); + if (lt) { + ldns_buffer_printf(output, "%s", lt->name); + } else { + ldns_buffer_printf(output, "CLASS%d", klass); + } + return ldns_buffer_status(output); +} + +char * +ldns_rr_class2str(const ldns_rr_class klass) +{ + ldns_buffer *buf; + char *str; + + buf = ldns_buffer_new(10); + if (!buf) { + return NULL; + } + + str = NULL; + if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) { + str = ldns_buffer2str(buf); + } + ldns_buffer_free(buf); + return str; +} + +ldns_status +ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* we could do checking (ie degrees < 90 etc)? */ + uint8_t version = ldns_rdf_data(rdf)[0]; + uint8_t size; + uint8_t horizontal_precision; + uint8_t vertical_precision; + uint32_t longitude; + uint32_t latitude; + uint32_t altitude; + char northerness; + char easterness; + uint32_t h; + uint32_t m; + double s; + + uint32_t equator = (uint32_t) ldns_power(2, 31); + + if (version == 0) { + size = ldns_rdf_data(rdf)[1]; + horizontal_precision = ldns_rdf_data(rdf)[2]; + vertical_precision = ldns_rdf_data(rdf)[3]; + + latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]); + longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]); + altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]); + + if (latitude > equator) { + northerness = 'N'; + latitude = latitude - equator; + } else { + northerness = 'S'; + latitude = equator - latitude; + } + h = latitude / (1000 * 60 * 60); + latitude = latitude % (1000 * 60 * 60); + m = latitude / (1000 * 60); + latitude = latitude % (1000 * 60); + s = (double) latitude / 1000.0; + ldns_buffer_printf(output, "%02u %02u %0.3f %c ", + h, m, s, northerness); + + if (longitude > equator) { + easterness = 'E'; + longitude = longitude - equator; + } else { + easterness = 'W'; + longitude = equator - longitude; + } + h = longitude / (1000 * 60 * 60); + longitude = longitude % (1000 * 60 * 60); + m = longitude / (1000 * 60); + longitude = longitude % (1000 * 60); + s = (double) longitude / (1000.0); + ldns_buffer_printf(output, "%02u %02u %0.3f %c ", + h, m, s, easterness); + + + s = ((double) altitude) / 100; + s -= 100000; + + if(altitude%100 != 0) + ldns_buffer_printf(output, "%.2f", s); + else + ldns_buffer_printf(output, "%.0f", s); + + ldns_buffer_printf(output, "m "); + + loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f); + ldns_buffer_printf(output, "m "); + + loc_cm_print(output, (horizontal_precision & 0xf0) >> 4, + horizontal_precision & 0x0f); + ldns_buffer_printf(output, "m "); + + loc_cm_print(output, (vertical_precision & 0xf0) >> 4, + vertical_precision & 0x0f); + ldns_buffer_printf(output, "m"); + + return ldns_buffer_status(output); + } else { + return ldns_rdf2buffer_str_hex(output, rdf); + } +} + +ldns_status +ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf) +{ + ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf)); + return ldns_rdf2buffer_str_hex(output, rdf); +} + +ldns_status +ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf) +{ + ldns_buffer_printf(output, "0x"); + return ldns_rdf2buffer_str_hex(output, rdf); +} + +ldns_status +ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf) +{ + return ldns_rdf2buffer_str_hex(output, rdf); +} + +ldns_status +ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* protocol, followed by bitmap of services */ + struct protoent *protocol; + char *proto_name = NULL; + uint8_t protocol_nr; + struct servent *service; + uint16_t current_service; + + protocol_nr = ldns_rdf_data(rdf)[0]; + protocol = getprotobynumber((int) protocol_nr); + if (protocol && (protocol->p_name != NULL)) { + proto_name = protocol->p_name; + ldns_buffer_printf(output, "%s ", protocol->p_name); + } else { + ldns_buffer_printf(output, "%u ", protocol_nr); + } + +#ifdef HAVE_ENDPROTOENT + endprotoent(); +#endif + + for (current_service = 0; + current_service < ldns_rdf_size(rdf) * 7; current_service++) { + if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) { + service = getservbyport((int) htons(current_service), + proto_name); + if (service && service->s_name) { + ldns_buffer_printf(output, "%s ", service->s_name); + } else { + ldns_buffer_printf(output, "%u ", current_service); + } +#ifdef HAVE_ENDSERVENT + endservent(); +#endif + } + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* Note: this code is duplicated in higher.c in + * ldns_nsec_type_check() function + */ + uint8_t window_block_nr; + uint8_t bitmap_length; + uint16_t type; + uint16_t pos = 0; + uint16_t bit_pos; + uint8_t *data = ldns_rdf_data(rdf); + const ldns_rr_descriptor *descriptor; + + while(pos < ldns_rdf_size(rdf)) { + window_block_nr = data[pos]; + bitmap_length = data[pos + 1]; + pos += 2; + + for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) { + if (ldns_get_bit(&data[pos], bit_pos)) { + type = 256 * (uint16_t) window_block_nr + bit_pos; + descriptor = ldns_rr_descript(type); + + if (descriptor && descriptor->_name) { + ldns_buffer_printf(output, "%s ", + descriptor->_name); + } else { + ldns_buffer_printf(output, "TYPE%u ", type); + } + } + } + + pos += (uint16_t) bitmap_length; + } + + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint8_t salt_length; + uint8_t salt_pos; + + uint8_t *data = ldns_rdf_data(rdf); + + if(ldns_rdf_size(rdf) == 0) { + output->_status = LDNS_STATUS_ERR; + return ldns_buffer_status(output); + } + salt_length = data[0]; + /* from now there are variable length entries so remember pos */ + if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) { + ldns_buffer_printf(output, "- "); + } else { + for (salt_pos = 0; salt_pos < salt_length; salt_pos++) { + ldns_buffer_printf(output, "%02x", data[1 + salt_pos]); + } + ldns_buffer_printf(output, " "); + } + + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* period is the number of seconds */ + uint32_t p = ldns_read_uint32(ldns_rdf_data(rdf)); + ldns_buffer_printf(output, "%u", p); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const ldns_rdf *rdf) +{ + /* tsigtime is 48 bits network order unsigned integer */ + uint64_t tsigtime = 0; + uint8_t *data = ldns_rdf_data(rdf); + + if (ldns_rdf_size(rdf) != 6) { + return LDNS_STATUS_ERR; + } + + tsigtime = ldns_read_uint16(data); + tsigtime *= 65536; + tsigtime += ldns_read_uint16(data+2); + tsigtime *= 65536; + + ldns_buffer_printf(output, "%llu ", tsigtime); + + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint8_t *data = ldns_rdf_data(rdf); + uint16_t address_family; + uint8_t prefix; + bool negation; + uint8_t adf_length; + size_t i; + size_t pos = 0; + + while (pos < (unsigned int) ldns_rdf_size(rdf)) { + if(pos + 3 >= (unsigned)ldns_rdf_size(rdf)) + return LDNS_STATUS_SYNTAX_RDATA_ERR; + address_family = ldns_read_uint16(&data[pos]); + prefix = data[pos + 2]; + negation = data[pos + 3] & LDNS_APL_NEGATION; + adf_length = data[pos + 3] & LDNS_APL_MASK; + if (address_family == LDNS_APL_IP4) { + /* check if prefix < 32? */ + if (negation) { + ldns_buffer_printf(output, "!"); + } + ldns_buffer_printf(output, "%u:", address_family); + /* address is variable length 0 - 4 */ + for (i = 0; i < 4; i++) { + if (i > 0) { + ldns_buffer_printf(output, "."); + } + if (i < (unsigned short) adf_length) { + if(pos+i+4 >= ldns_rdf_size(rdf)) + return LDNS_STATUS_SYNTAX_RDATA_ERR; + ldns_buffer_printf(output, "%d", + data[pos + i + 4]); + } else { + ldns_buffer_printf(output, "0"); + } + } + ldns_buffer_printf(output, "/%u ", prefix); + } else if (address_family == LDNS_APL_IP6) { + /* check if prefix < 128? */ + if (negation) { + ldns_buffer_printf(output, "!"); + } + ldns_buffer_printf(output, "%u:", address_family); + /* address is variable length 0 - 16 */ + for (i = 0; i < 16; i++) { + if (i % 2 == 0 && i > 0) { + ldns_buffer_printf(output, ":"); + } + if (i < (unsigned short) adf_length) { + if(pos+i+4 >= ldns_rdf_size(rdf)) + return LDNS_STATUS_SYNTAX_RDATA_ERR; + ldns_buffer_printf(output, "%02x", + data[pos + i + 4]); + } else { + ldns_buffer_printf(output, "00"); + } + } + ldns_buffer_printf(output, "/%u ", prefix); + + } else { + /* unknown address family */ + ldns_buffer_printf(output, "Unknown address family: %u data: ", + address_family); + for (i = 1; i < (unsigned short) (4 + adf_length); i++) { + if(pos+i >= ldns_rdf_size(rdf)) + return LDNS_STATUS_SYNTAX_RDATA_ERR; + ldns_buffer_printf(output, "%02x", data[i]); + } + } + pos += 4 + adf_length; + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* Subtract the size (2) of the number that specifies the length */ + size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2); + char *b64 = LDNS_XMALLOC(char, size); + if(!b64) + return LDNS_STATUS_MEM_ERR; + + ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2); + + if (ldns_rdf_size(rdf) > 2 && + ldns_b64_ntop(ldns_rdf_data(rdf) + 2, + ldns_rdf_size(rdf) - 2, + b64, size)) { + ldns_buffer_printf(output, "%s", b64); + } + LDNS_FREE(b64); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* wire format from + http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt + */ + uint8_t *data = ldns_rdf_data(rdf); + uint8_t precedence; + uint8_t gateway_type; + uint8_t algorithm; + + ldns_rdf *gateway = NULL; + uint8_t *gateway_data; + + size_t public_key_size; + uint8_t *public_key_data; + ldns_rdf *public_key; + + size_t offset = 0; + ldns_status status; + + precedence = data[0]; + gateway_type = data[1]; + algorithm = data[2]; + offset = 3; + + switch (gateway_type) { + case 0: + /* no gateway */ + break; + case 1: + gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN); + if(!gateway_data) + return LDNS_STATUS_MEM_ERR; + memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN); + gateway = ldns_rdf_new(LDNS_RDF_TYPE_A, LDNS_IP4ADDRLEN , gateway_data); + offset += LDNS_IP4ADDRLEN; + if(!gateway) { + LDNS_FREE(gateway_data); + return LDNS_STATUS_MEM_ERR; + } + break; + case 2: + gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN); + if(!gateway_data) + return LDNS_STATUS_MEM_ERR; + memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN); + offset += LDNS_IP6ADDRLEN; + gateway = + ldns_rdf_new(LDNS_RDF_TYPE_AAAA, LDNS_IP6ADDRLEN, gateway_data); + if(!gateway) { + LDNS_FREE(gateway_data); + return LDNS_STATUS_MEM_ERR; + } + break; + case 3: + status = ldns_wire2dname(&gateway, data, ldns_rdf_size(rdf), &offset); + if(status != LDNS_STATUS_OK) + return status; + break; + default: + /* error? */ + break; + } + + public_key_size = ldns_rdf_size(rdf) - offset; + public_key_data = LDNS_XMALLOC(uint8_t, public_key_size); + if(!public_key_data) { + ldns_rdf_free(gateway); + return LDNS_STATUS_MEM_ERR; + } + memcpy(public_key_data, &data[offset], public_key_size); + public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64, public_key_size, public_key_data); + if(!public_key) { + LDNS_FREE(public_key_data); + ldns_rdf_free(gateway); + return LDNS_STATUS_MEM_ERR; + } + + ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm); + if (gateway) + (void) ldns_rdf2buffer_str(output, gateway); + else + ldns_buffer_printf(output, "."); + ldns_buffer_printf(output, " "); + (void) ldns_rdf2buffer_str(output, public_key); + + ldns_rdf_free(gateway); + ldns_rdf_free(public_key); + + return ldns_buffer_status(output); +} + +ldns_status +ldns_rdf2buffer_str_tsig(ldns_buffer *output, const ldns_rdf *rdf) +{ + /* TSIG RRs have no presentation format, make them #size <data> */ + return ldns_rdf2buffer_str_unknown(output, rdf); +} + + +ldns_status +ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf) +{ + ldns_status res = LDNS_STATUS_OK; + + /*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/ + if (rdf) { + switch(ldns_rdf_get_type(rdf)) { + case LDNS_RDF_TYPE_NONE: + break; + case LDNS_RDF_TYPE_DNAME: + res = ldns_rdf2buffer_str_dname(buffer, rdf); + break; + case LDNS_RDF_TYPE_INT8: + res = ldns_rdf2buffer_str_int8(buffer, rdf); + break; + case LDNS_RDF_TYPE_INT16: + res = ldns_rdf2buffer_str_int16(buffer, rdf); + break; + case LDNS_RDF_TYPE_INT32: + res = ldns_rdf2buffer_str_int32(buffer, rdf); + break; + case LDNS_RDF_TYPE_PERIOD: + res = ldns_rdf2buffer_str_period(buffer, rdf); + break; + case LDNS_RDF_TYPE_TSIGTIME: + res = ldns_rdf2buffer_str_tsigtime(buffer, rdf); + break; + case LDNS_RDF_TYPE_A: + res = ldns_rdf2buffer_str_a(buffer, rdf); + break; + case LDNS_RDF_TYPE_AAAA: + res = ldns_rdf2buffer_str_aaaa(buffer, rdf); + break; + case LDNS_RDF_TYPE_STR: + res = ldns_rdf2buffer_str_str(buffer, rdf); + break; + case LDNS_RDF_TYPE_APL: + res = ldns_rdf2buffer_str_apl(buffer, rdf); + break; + case LDNS_RDF_TYPE_B32_EXT: + res = ldns_rdf2buffer_str_b32_ext(buffer, rdf); + break; + case LDNS_RDF_TYPE_B64: + res = ldns_rdf2buffer_str_b64(buffer, rdf); + break; + case LDNS_RDF_TYPE_HEX: + res = ldns_rdf2buffer_str_hex(buffer, rdf); + break; + case LDNS_RDF_TYPE_NSEC: + res = ldns_rdf2buffer_str_nsec(buffer, rdf); + break; + case LDNS_RDF_TYPE_NSEC3_SALT: + res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf); + break; + case LDNS_RDF_TYPE_TYPE: + res = ldns_rdf2buffer_str_type(buffer, rdf); + break; + case LDNS_RDF_TYPE_CLASS: + res = ldns_rdf2buffer_str_class(buffer, rdf); + break; + case LDNS_RDF_TYPE_CERT_ALG: + res = ldns_rdf2buffer_str_cert_alg(buffer, rdf); + break; + case LDNS_RDF_TYPE_ALG: + res = ldns_rdf2buffer_str_alg(buffer, rdf); + break; + case LDNS_RDF_TYPE_UNKNOWN: + res = ldns_rdf2buffer_str_unknown(buffer, rdf); + break; + case LDNS_RDF_TYPE_TIME: + res = ldns_rdf2buffer_str_time(buffer, rdf); + break; + case LDNS_RDF_TYPE_LOC: + res = ldns_rdf2buffer_str_loc(buffer, rdf); + break; + case LDNS_RDF_TYPE_WKS: + case LDNS_RDF_TYPE_SERVICE: + res = ldns_rdf2buffer_str_wks(buffer, rdf); + break; + case LDNS_RDF_TYPE_NSAP: + res = ldns_rdf2buffer_str_nsap(buffer, rdf); + break; + case LDNS_RDF_TYPE_ATMA: + res = ldns_rdf2buffer_str_atma(buffer, rdf); + break; + case LDNS_RDF_TYPE_IPSECKEY: + res = ldns_rdf2buffer_str_ipseckey(buffer, rdf); + break; + case LDNS_RDF_TYPE_TSIG: + res = ldns_rdf2buffer_str_tsig(buffer, rdf); + break; + case LDNS_RDF_TYPE_INT16_DATA: + res = ldns_rdf2buffer_str_int16_data(buffer, rdf); + break; + case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER: + res = ldns_rdf2buffer_str_b32_ext(buffer, rdf); + break; + } + } else { + ldns_buffer_printf(buffer, "(null) "); + res = ldns_buffer_status(buffer); + } + return res; +} + +static ldns_rdf * +ldns_b32_ext2dname(const ldns_rdf *rdf) +{ + size_t size; + char *b32; + ldns_rdf *out; + if(ldns_rdf_size(rdf) == 0) + return NULL; + /* remove -1 for the b32-hash-len octet */ + size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1); + /* add one for the end nul for the string */ + b32 = LDNS_XMALLOC(char, size + 2); + if (b32) { + if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1, + ldns_rdf_size(rdf) - 1, b32, size+1) > 0) { + b32[size] = '.'; + b32[size+1] = '\0'; + if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) { + LDNS_FREE(b32); + return out; + } + } + LDNS_FREE(b32); + } + return NULL; +} + +ldns_status +ldns_rr2buffer_str_fmt(ldns_buffer *output, + const ldns_output_format *fmt, const ldns_rr *rr) +{ + uint16_t i, flags; + ldns_status status = LDNS_STATUS_OK; + + if (fmt == NULL) { + fmt = ldns_output_format_default; + } + if (!rr) { + if (LDNS_COMMENT_NULLS & fmt->flags) { + ldns_buffer_printf(output, "; (null)\n"); + } + return ldns_buffer_status(output); + } + if (ldns_rr_owner(rr)) { + status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr)); + } + if (status != LDNS_STATUS_OK) { + return status; + } + + /* TTL should NOT be printed if it is a question */ + if (!ldns_rr_is_question(rr)) { + ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr)); + } + + ldns_buffer_printf(output, "\t"); + status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr)); + if (status != LDNS_STATUS_OK) { + return status; + } + ldns_buffer_printf(output, "\t"); + + status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr)); + if (status != LDNS_STATUS_OK) { + return status; + } + + if (ldns_rr_rd_count(rr) > 0) { + ldns_buffer_printf(output, "\t"); + } else if (!ldns_rr_is_question(rr)) { + ldns_buffer_printf(output, "\t\\# 0"); + } + + for (i = 0; i < ldns_rr_rd_count(rr); i++) { + /* ldns_rdf2buffer_str handles NULL input fine! */ + status = ldns_rdf2buffer_str(output, ldns_rr_rdf(rr, i)); + if(status != LDNS_STATUS_OK) + return status; + if (i < ldns_rr_rd_count(rr) - 1) { + ldns_buffer_printf(output, " "); + } + } + /* per RR special comments - handy for DNSSEC types */ + /* check to prevent question sec. rr from + * getting here */ + if (ldns_rr_rd_count(rr) > 0) { + switch (ldns_rr_get_type(rr)) { + case LDNS_RR_TYPE_DNSKEY: + /* if ldns_rr_rd_count(rr) > 0 + then ldns_rr_rdf(rr, 0) exists! */ + if (! (fmt->flags & LDNS_COMMENT_KEY)) { + break; + } + flags = ldns_rdf2native_int16( + ldns_rr_rdf(rr, 0)); + ldns_buffer_printf(output, " ;{"); + if (fmt->flags & LDNS_COMMENT_KEY_ID) { + ldns_buffer_printf(output, "id = %u", + (unsigned int) + ldns_calc_keytag(rr)); + } + if ((fmt->flags & LDNS_COMMENT_KEY_TYPE) + && (flags & LDNS_KEY_ZONE_KEY)){ + if (flags & LDNS_KEY_SEP_KEY) { + ldns_buffer_printf( + output, " (ksk)"); + } + else { + ldns_buffer_printf( + output, " (zsk)"); + } + if (fmt->flags & LDNS_COMMENT_KEY_SIZE){ + ldns_buffer_printf( + output, ", "); + } + } else if (fmt->flags + & (LDNS_COMMENT_KEY_ID + |LDNS_COMMENT_KEY_SIZE)) { + ldns_buffer_printf( output, ", "); + } + if (fmt->flags & LDNS_COMMENT_KEY_SIZE) { + ldns_buffer_printf(output, "size = %db", + ldns_rr_dnskey_key_size(rr)); + } + ldns_buffer_printf(output, "}"); + break; + case LDNS_RR_TYPE_RRSIG: + if ((fmt->flags & LDNS_COMMENT_KEY) + && (fmt->flags + & LDNS_COMMENT_RRSIGS) + && ldns_rr_rdf(rr, 6) != NULL) { + ldns_buffer_printf(output + , " ;{id = %d}" + , ldns_rdf2native_int16( + ldns_rr_rdf(rr, 6))); + } + break; + case LDNS_RR_TYPE_DS: + if ((fmt->flags & LDNS_COMMENT_BUBBLEBABBLE) + && ldns_rr_rdf(rr, 3) != NULL) { + uint8_t *data = ldns_rdf_data( + ldns_rr_rdf(rr, 3)); + size_t len = ldns_rdf_size( + ldns_rr_rdf(rr, 3)); + char *babble = ldns_bubblebabble( + data, len); + if(babble) { + ldns_buffer_printf(output + , " ;{%s}", babble); + } + LDNS_FREE(babble); + } + break; + case LDNS_RR_TYPE_NSEC3: + if (! (fmt->flags & LDNS_COMMENT_FLAGS) && + ! (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN)) { + break; + } + ldns_buffer_printf(output, " ;{"); + if ((fmt->flags & LDNS_COMMENT_FLAGS)) { + if (ldns_nsec3_optout(rr)) { + ldns_buffer_printf(output, + " flags: optout"); + } else { + ldns_buffer_printf(output, + " flags: -"); + } + if (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN + && fmt->data != NULL) { + ldns_buffer_printf(output, ", "); + } + } + if (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN + && fmt->data != NULL) { + ldns_rbnode_t *node; + ldns_rdf *key = ldns_dname_label( + ldns_rr_owner(rr), 0); + if (key) { + node = ldns_rbtree_search( + (ldns_rbtree_t *) + fmt->data, + (void *) key); + if (node->data) { + ldns_buffer_printf( + output, + "from: "); + (void) + ldns_rdf2buffer_str( + output, + (ldns_rdf *) + node->data); + } + ldns_rdf_free(key); + } + key = ldns_b32_ext2dname( + ldns_nsec3_next_owner(rr)); + if (key) { + node = ldns_rbtree_search( + (ldns_rbtree_t *) + fmt->data, + (void *) key); + if (node->data) { + ldns_buffer_printf( + output, + " to: "); + (void) + ldns_rdf2buffer_str( + output, + (ldns_rdf *) + node->data); + } + ldns_rdf_free(key); + } + } + ldns_buffer_printf(output, "}"); + break; + default: + break; + + } + } + /* last */ + ldns_buffer_printf(output, "\n"); + return ldns_buffer_status(output); +} + +ldns_status +ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr) +{ + return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr); +} + +ldns_status +ldns_rr_list2buffer_str_fmt(ldns_buffer *output, + const ldns_output_format *fmt, const ldns_rr_list *list) +{ + uint16_t i; + + for(i = 0; i < ldns_rr_list_rr_count(list); i++) { + (void) ldns_rr2buffer_str_fmt(output, fmt, + ldns_rr_list_rr(list, i)); + } + return ldns_buffer_status(output); +} + +ldns_status +ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list) +{ + return ldns_rr_list2buffer_str_fmt( + output, ldns_output_format_default, list); +} + +ldns_status +ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt) +{ + ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes, + (int) ldns_pkt_get_opcode(pkt)); + ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes, + (int) ldns_pkt_get_rcode(pkt)); + + ldns_buffer_printf(output, ";; ->>HEADER<<- "); + if (opcode) { + ldns_buffer_printf(output, "opcode: %s, ", opcode->name); + } else { + ldns_buffer_printf(output, "opcode: ?? (%u), ", + ldns_pkt_get_opcode(pkt)); + } + if (rcode) { + ldns_buffer_printf(output, "rcode: %s, ", rcode->name); + } else { + ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt)); + } + ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt)); + ldns_buffer_printf(output, ";; flags: "); + + if (ldns_pkt_qr(pkt)) { + ldns_buffer_printf(output, "qr "); + } + if (ldns_pkt_aa(pkt)) { + ldns_buffer_printf(output, "aa "); + } + if (ldns_pkt_tc(pkt)) { + ldns_buffer_printf(output, "tc "); + } + if (ldns_pkt_rd(pkt)) { + ldns_buffer_printf(output, "rd "); + } + if (ldns_pkt_cd(pkt)) { + ldns_buffer_printf(output, "cd "); + } + if (ldns_pkt_ra(pkt)) { + ldns_buffer_printf(output, "ra "); + } + if (ldns_pkt_ad(pkt)) { + ldns_buffer_printf(output, "ad "); + } + ldns_buffer_printf(output, "; "); + ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt)); + ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt)); + ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt)); + ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt)); + return ldns_buffer_status(output); +} + +ldns_status +ldns_pkt2buffer_str_fmt(ldns_buffer *output, + const ldns_output_format *fmt, const ldns_pkt *pkt) +{ + uint16_t i; + ldns_status status = LDNS_STATUS_OK; + char *tmp; + struct timeval time; + time_t time_tt; + + if (!pkt) { + ldns_buffer_printf(output, "null"); + return LDNS_STATUS_OK; + } + + if (ldns_buffer_status_ok(output)) { + status = ldns_pktheader2buffer_str(output, pkt); + if (status != LDNS_STATUS_OK) { + return status; + } + + ldns_buffer_printf(output, "\n"); + + ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; "); + + + for (i = 0; i < ldns_pkt_qdcount(pkt); i++) { + status = ldns_rr2buffer_str_fmt(output, fmt, + ldns_rr_list_rr( + ldns_pkt_question(pkt), i)); + if (status != LDNS_STATUS_OK) { + return status; + } + } + ldns_buffer_printf(output, "\n"); + + ldns_buffer_printf(output, ";; ANSWER SECTION:\n"); + for (i = 0; i < ldns_pkt_ancount(pkt); i++) { + status = ldns_rr2buffer_str_fmt(output, fmt, + ldns_rr_list_rr( + ldns_pkt_answer(pkt), i)); + if (status != LDNS_STATUS_OK) { + return status; + } + + } + ldns_buffer_printf(output, "\n"); + + ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n"); + + for (i = 0; i < ldns_pkt_nscount(pkt); i++) { + status = ldns_rr2buffer_str_fmt(output, fmt, + ldns_rr_list_rr( + ldns_pkt_authority(pkt), i)); + if (status != LDNS_STATUS_OK) { + return status; + } + } + ldns_buffer_printf(output, "\n"); + + ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n"); + for (i = 0; i < ldns_pkt_arcount(pkt); i++) { + status = ldns_rr2buffer_str_fmt(output, fmt, + ldns_rr_list_rr( + ldns_pkt_additional(pkt), i)); + if (status != LDNS_STATUS_OK) { + return status; + } + + } + ldns_buffer_printf(output, "\n"); + /* add some futher fields */ + ldns_buffer_printf(output, ";; Query time: %d msec\n", + ldns_pkt_querytime(pkt)); + if (ldns_pkt_edns(pkt)) { + ldns_buffer_printf(output, + ";; EDNS: version %u; flags:", + ldns_pkt_edns_version(pkt)); + if (ldns_pkt_edns_do(pkt)) { + ldns_buffer_printf(output, " do"); + } + /* the extended rcode is the value set, shifted four bits, + * and or'd with the original rcode */ + if (ldns_pkt_edns_extended_rcode(pkt)) { + ldns_buffer_printf(output, " ; ext-rcode: %d", + (ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt))); + } + ldns_buffer_printf(output, " ; udp: %u\n", + ldns_pkt_edns_udp_size(pkt)); + + if (ldns_pkt_edns_data(pkt)) { + ldns_buffer_printf(output, ";; Data: "); + (void)ldns_rdf2buffer_str(output, + ldns_pkt_edns_data(pkt)); + ldns_buffer_printf(output, "\n"); + } + } + if (ldns_pkt_tsig(pkt)) { + ldns_buffer_printf(output, ";; TSIG:\n;; "); + (void) ldns_rr2buffer_str_fmt( + output, fmt, ldns_pkt_tsig(pkt)); + ldns_buffer_printf(output, "\n"); + } + if (ldns_pkt_answerfrom(pkt)) { + tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt)); + ldns_buffer_printf(output, ";; SERVER: %s\n", tmp); + LDNS_FREE(tmp); + } + time = ldns_pkt_timestamp(pkt); + time_tt = (time_t)time.tv_sec; + ldns_buffer_printf(output, ";; WHEN: %s", + (char*)ctime(&time_tt)); + + ldns_buffer_printf(output, ";; MSG SIZE rcvd: %d\n", + (int)ldns_pkt_size(pkt)); + } else { + return ldns_buffer_status(output); + } + return status; +} + +ldns_status +ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt) +{ + return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt); +} + + +#ifdef HAVE_SSL +static ldns_status +ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k) +{ + ldns_status status; + size_t i; + ldns_rdf *b64_bignum; + + ldns_buffer_printf(output, "Key: "); + + i = ldns_key_hmac_size(k); + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k)); + status = ldns_rdf2buffer_str(output, b64_bignum); + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + return status; +} +#endif + +#if defined(HAVE_SSL) && defined(USE_GOST) +static ldns_status +ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p) +{ + unsigned char* pp = NULL; + int ret; + ldns_rdf *b64_bignum; + ldns_status status; + + ldns_buffer_printf(output, "GostAsn1: "); + + ret = i2d_PrivateKey(p, &pp); + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp); + status = ldns_rdf2buffer_str(output, b64_bignum); + + ldns_rdf_deep_free(b64_bignum); + OPENSSL_free(pp); + ldns_buffer_printf(output, "\n"); + return status; +} +#endif + +ldns_status +ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k) +{ + ldns_status status = LDNS_STATUS_OK; + unsigned char *bignum; +#ifndef S_SPLINT_S + uint16_t i; +#endif + +#ifdef HAVE_SSL + /* not used when ssl is not defined */ + ldns_rdf *b64_bignum = NULL; + + RSA *rsa; + DSA *dsa; +#endif /* HAVE_SSL */ + + if (!k) { + return LDNS_STATUS_ERR; + } + + bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); + if (!bignum) { + return LDNS_STATUS_ERR; + } + + if (ldns_buffer_status_ok(output)) { +#ifdef HAVE_SSL + switch(ldns_key_algorithm(k)) { + case LDNS_SIGN_RSASHA1: + case LDNS_SIGN_RSASHA1_NSEC3: + case LDNS_SIGN_RSASHA256: + case LDNS_SIGN_RSASHA512: + case LDNS_SIGN_RSAMD5: + /* copied by looking at dnssec-keygen output */ + /* header */ + rsa = ldns_key_rsa_key(k); + + ldns_buffer_printf(output,"Private-key-format: v1.2\n"); + switch(ldns_key_algorithm(k)) { + case LDNS_SIGN_RSAMD5: + ldns_buffer_printf(output, + "Algorithm: %u (RSA)\n", + LDNS_RSAMD5); + break; + case LDNS_SIGN_RSASHA1: + ldns_buffer_printf(output, + "Algorithm: %u (RSASHA1)\n", + LDNS_RSASHA1); + break; + case LDNS_SIGN_RSASHA1_NSEC3: + ldns_buffer_printf(output, + "Algorithm: %u (RSASHA1_NSEC3)\n", + LDNS_RSASHA1_NSEC3); + break; +#ifdef USE_SHA2 + case LDNS_SIGN_RSASHA256: + ldns_buffer_printf(output, + "Algorithm: %u (RSASHA256)\n", + LDNS_RSASHA256); + break; + case LDNS_SIGN_RSASHA512: + ldns_buffer_printf(output, + "Algorithm: %u (RSASHA512)\n", + LDNS_RSASHA512); + break; +#endif + default: + fprintf(stderr, "Warning: unknown signature "); + fprintf(stderr, + "algorithm type %u\n", + ldns_key_algorithm(k)); + ldns_buffer_printf(output, + "Algorithm: %u (Unknown)\n", + ldns_key_algorithm(k)); + break; + } + + /* print to buf, convert to bin, convert to b64, + * print to buf */ + ldns_buffer_printf(output, "Modulus: "); +#ifndef S_SPLINT_S + i = (uint16_t)BN_bn2bin(rsa->n, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + ldns_buffer_printf(output, "PublicExponent: "); + i = (uint16_t)BN_bn2bin(rsa->e, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + + ldns_buffer_printf(output, "PrivateExponent: "); + if (rsa->d) { + i = (uint16_t)BN_bn2bin(rsa->d, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + ldns_buffer_printf(output, "(Not available)\n"); + } + + ldns_buffer_printf(output, "Prime1: "); + if (rsa->p) { + i = (uint16_t)BN_bn2bin(rsa->p, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + ldns_buffer_printf(output, "(Not available)\n"); + } + + ldns_buffer_printf(output, "Prime2: "); + if (rsa->q) { + i = (uint16_t)BN_bn2bin(rsa->q, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + ldns_buffer_printf(output, "(Not available)\n"); + } + + ldns_buffer_printf(output, "Exponent1: "); + if (rsa->dmp1) { + i = (uint16_t)BN_bn2bin(rsa->dmp1, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + ldns_buffer_printf(output, "(Not available)\n"); + } + + ldns_buffer_printf(output, "Exponent2: "); + if (rsa->dmq1) { + i = (uint16_t)BN_bn2bin(rsa->dmq1, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + ldns_buffer_printf(output, "(Not available)\n"); + } + + ldns_buffer_printf(output, "Coefficient: "); + if (rsa->iqmp) { + i = (uint16_t)BN_bn2bin(rsa->iqmp, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + ldns_buffer_printf(output, "(Not available)\n"); + } +#endif /* splint */ + + RSA_free(rsa); + break; + case LDNS_SIGN_DSA: + case LDNS_SIGN_DSA_NSEC3: + dsa = ldns_key_dsa_key(k); + + ldns_buffer_printf(output,"Private-key-format: v1.2\n"); + if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) { + ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n"); + } else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) { + ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n"); + } + + /* print to buf, convert to bin, convert to b64, + * print to buf */ + ldns_buffer_printf(output, "Prime(p): "); +#ifndef S_SPLINT_S + if (dsa->p) { + i = (uint16_t)BN_bn2bin(dsa->p, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + printf("(Not available)\n"); + } + + ldns_buffer_printf(output, "Subprime(q): "); + if (dsa->q) { + i = (uint16_t)BN_bn2bin(dsa->q, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + printf("(Not available)\n"); + } + + ldns_buffer_printf(output, "Base(g): "); + if (dsa->g) { + i = (uint16_t)BN_bn2bin(dsa->g, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + printf("(Not available)\n"); + } + + ldns_buffer_printf(output, "Private_value(x): "); + if (dsa->priv_key) { + i = (uint16_t)BN_bn2bin(dsa->priv_key, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + printf("(Not available)\n"); + } + + ldns_buffer_printf(output, "Public_value(y): "); + if (dsa->pub_key) { + i = (uint16_t)BN_bn2bin(dsa->pub_key, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + } else { + printf("(Not available)\n"); + } +#endif /* splint */ + break; + case LDNS_SIGN_ECC_GOST: + /* no format defined, use blob */ +#if defined(HAVE_SSL) && defined(USE_GOST) + ldns_buffer_printf(output, "Private-key-format: v1.2\n"); + ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST); + status = ldns_gost_key2buffer_str(output, +#ifndef S_SPLINT_S + k->_key.key +#else + NULL +#endif + ); +#else + goto error; +#endif /* GOST */ + break; + case LDNS_SIGN_ECDSAP256SHA256: + case LDNS_SIGN_ECDSAP384SHA384: +#ifdef USE_ECDSA + ldns_buffer_printf(output, "Private-key-format: v1.2\n"); + ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k)); + status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k)); +#ifndef S_SPLINT_S + ldns_buffer_printf(output, ")\n"); + if(k->_key.key) { + EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key); + const BIGNUM* b = EC_KEY_get0_private_key(ec); + ldns_buffer_printf(output, "PrivateKey: "); + i = (uint16_t)BN_bn2bin(b, bignum); + if (i > LDNS_MAX_KEYLEN) { + goto error; + } + b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum); + if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) { + goto error; + } + ldns_rdf_deep_free(b64_bignum); + ldns_buffer_printf(output, "\n"); + /* down reference count in EC_KEY + * its still assigned to the PKEY */ + EC_KEY_free(ec); + } +#endif /* splint */ +#else + goto error; +#endif /* ECDSA */ + break; + case LDNS_SIGN_HMACMD5: + /* there's not much of a format defined for TSIG */ + /* It's just a binary blob, Same for all algorithms */ + ldns_buffer_printf(output, "Private-key-format: v1.2\n"); + ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n"); + status = ldns_hmac_key2buffer_str(output, k); + break; + case LDNS_SIGN_HMACSHA1: + ldns_buffer_printf(output, "Private-key-format: v1.2\n"); + ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n"); + status = ldns_hmac_key2buffer_str(output, k); + break; + case LDNS_SIGN_HMACSHA256: + ldns_buffer_printf(output, "Private-key-format: v1.2\n"); + ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n"); + status = ldns_hmac_key2buffer_str(output, k); + break; + } +#endif /* HAVE_SSL */ + } else { +#ifdef HAVE_SSL + LDNS_FREE(b64_bignum); +#endif + LDNS_FREE(bignum); + return ldns_buffer_status(output); + } + LDNS_FREE(bignum); + return status; + +#ifdef HAVE_SSL + /* compiles warn the label isn't used */ +error: + LDNS_FREE(bignum); + return LDNS_STATUS_ERR; +#endif /* HAVE_SSL */ + +} + +/* + * Zero terminate the buffer and fix it to the size of the string. + */ +char * +ldns_buffer2str(ldns_buffer *buffer) +{ + char *tmp_str; + char *str; + + /* check if buffer ends with \0, if not, and + if there is space, add it */ + if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) { + if (!ldns_buffer_reserve(buffer, 1)) { + return NULL; + } + ldns_buffer_write_u8(buffer, (uint8_t) '\0'); + if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) { + return NULL; + } + } + + tmp_str = ldns_buffer_export(buffer); + str = LDNS_XMALLOC(char, strlen(tmp_str) + 1); + if(!str) { + return NULL; + } + memcpy(str, tmp_str, strlen(tmp_str) + 1); + + return str; +} + +char * +ldns_rdf2str(const ldns_rdf *rdf) +{ + char *result = NULL; + ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); + + if (!tmp_buffer) { + return NULL; + } + if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) { + /* export and return string, destroy rest */ + result = ldns_buffer2str(tmp_buffer); + } + ldns_buffer_free(tmp_buffer); + return result; +} + +char * +ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr) +{ + char *result = NULL; + ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); + + if (!tmp_buffer) { + return NULL; + } + if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr) + == LDNS_STATUS_OK) { + /* export and return string, destroy rest */ + result = ldns_buffer2str(tmp_buffer); + } + ldns_buffer_free(tmp_buffer); + return result; +} + +char * +ldns_rr2str(const ldns_rr *rr) +{ + return ldns_rr2str_fmt(ldns_output_format_default, rr); +} + +char * +ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt) +{ + char *result = NULL; + ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); + + if (!tmp_buffer) { + return NULL; + } + if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt) + == LDNS_STATUS_OK) { + /* export and return string, destroy rest */ + result = ldns_buffer2str(tmp_buffer); + } + + ldns_buffer_free(tmp_buffer); + return result; +} + +char * +ldns_pkt2str(const ldns_pkt *pkt) +{ + return ldns_pkt2str_fmt(ldns_output_format_default, pkt); +} + +char * +ldns_key2str(const ldns_key *k) +{ + char *result = NULL; + ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); + + if (!tmp_buffer) { + return NULL; + } + if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) { + /* export and return string, destroy rest */ + result = ldns_buffer2str(tmp_buffer); + } + ldns_buffer_free(tmp_buffer); + return result; +} + +char * +ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list) +{ + char *result = NULL; + ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); + + if (!tmp_buffer) { + return NULL; + } + if (list) { + if (ldns_rr_list2buffer_str_fmt( + tmp_buffer, fmt, list) + == LDNS_STATUS_OK) { + } + } else { + if (fmt == NULL) { + fmt = ldns_output_format_default; + } + if (fmt->flags & LDNS_COMMENT_NULLS) { + ldns_buffer_printf(tmp_buffer, "; (null)\n"); + } + } + + /* export and return string, destroy rest */ + result = ldns_buffer2str(tmp_buffer); + ldns_buffer_free(tmp_buffer); + return result; +} + +char * +ldns_rr_list2str(const ldns_rr_list *list) +{ + return ldns_rr_list2str_fmt(ldns_output_format_default, list); +} + +void +ldns_rdf_print(FILE *output, const ldns_rdf *rdf) +{ + char *str = ldns_rdf2str(rdf); + if (str) { + fprintf(output, "%s", str); + } else { + fprintf(output, "Unable to convert rdf to string\n"); + } + LDNS_FREE(str); +} + +void +ldns_rr_print_fmt(FILE *output, + const ldns_output_format *fmt, const ldns_rr *rr) +{ + char *str = ldns_rr2str_fmt(fmt, rr); + if (str) { + fprintf(output, "%s", str); + } else { + fprintf(output, "Unable to convert rr to string\n"); + } + LDNS_FREE(str); +} + +void +ldns_rr_print(FILE *output, const ldns_rr *rr) +{ + ldns_rr_print_fmt(output, ldns_output_format_default, rr); +} + +void +ldns_pkt_print_fmt(FILE *output, + const ldns_output_format *fmt, const ldns_pkt *pkt) +{ + char *str = ldns_pkt2str_fmt(fmt, pkt); + if (str) { + fprintf(output, "%s", str); + } else { + fprintf(output, "Unable to convert packet to string\n"); + } + LDNS_FREE(str); +} + +void +ldns_pkt_print(FILE *output, const ldns_pkt *pkt) +{ + ldns_pkt_print_fmt(output, ldns_output_format_default, pkt); +} + +void +ldns_rr_list_print_fmt(FILE *output, + const ldns_output_format *fmt, const ldns_rr_list *lst) +{ + size_t i; + for (i = 0; i < ldns_rr_list_rr_count(lst); i++) { + ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i)); + } +} + +void +ldns_rr_list_print(FILE *output, const ldns_rr_list *lst) +{ + ldns_rr_list_print_fmt(output, ldns_output_format_default, lst); +} + +void +ldns_resolver_print_fmt(FILE *output, + const ldns_output_format *fmt, const ldns_resolver *r) +{ + uint16_t i; + ldns_rdf **n; + ldns_rdf **s; + size_t *rtt; + if (!r) { + return; + } + n = ldns_resolver_nameservers(r); + s = ldns_resolver_searchlist(r); + rtt = ldns_resolver_rtt(r); + + fprintf(output, "port: %d\n", (int)ldns_resolver_port(r)); + fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r)); + fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r)); + + fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r)); + fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r)); + fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r)); + fprintf(output, "fail: %d\n", ldns_resolver_fail(r)); + fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r)); + fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r)); + fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r)); + fprintf(output, "random: %d\n", ldns_resolver_random(r)); + fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec); + fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r)); + fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r)); + fprintf(output, "trust anchors (%d listed):\n", + (int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r))); + ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r)); + fprintf(output, "tsig: %s %s\n", + ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-", + ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-"); + fprintf(output, "debug: %d\n", ldns_resolver_debug(r)); + + fprintf(output, "default domain: "); + ldns_rdf_print(output, ldns_resolver_domain(r)); + fprintf(output, "\n"); + fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r)); + + fprintf(output, "searchlist (%d listed):\n", (int)ldns_resolver_searchlist_count(r)); + for (i = 0; i < ldns_resolver_searchlist_count(r); i++) { + fprintf(output, "\t"); + ldns_rdf_print(output, s[i]); + fprintf(output, "\n"); + } + fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r)); + + fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r)); + for (i = 0; i < ldns_resolver_nameserver_count(r); i++) { + fprintf(output, "\t"); + ldns_rdf_print(output, n[i]); + + switch ((int)rtt[i]) { + case LDNS_RESOLV_RTT_MIN: + fprintf(output, " - reachable\n"); + break; + case LDNS_RESOLV_RTT_INF: + fprintf(output, " - unreachable\n"); + break; + } + } +} + +void +ldns_resolver_print(FILE *output, const ldns_resolver *r) +{ + ldns_resolver_print_fmt(output, ldns_output_format_default, r); +} + +void +ldns_zone_print_fmt(FILE *output, + const ldns_output_format *fmt, const ldns_zone *z) +{ + if(ldns_zone_soa(z)) + ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z)); + ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z)); +} +void +ldns_zone_print(FILE *output, const ldns_zone *z) +{ + ldns_zone_print_fmt(output, ldns_output_format_default, z); +} |