f3c2b7869f
MFC after: 3 weeks
2640 lines
70 KiB
C
2640 lines
70 KiB
C
/*
|
|
* 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;
|
|
|
|
static bool
|
|
ldns_output_format_covers_type(const ldns_output_format* fmt, ldns_rr_type t)
|
|
{
|
|
return fmt && (fmt->flags & LDNS_FMT_RFC3597) &&
|
|
((ldns_output_format_storage*)fmt)->bitmap &&
|
|
ldns_nsec_bitmap_covers_type(
|
|
((ldns_output_format_storage*)fmt)->bitmap, t);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type t)
|
|
{
|
|
ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
|
|
ldns_status s;
|
|
|
|
assert(fmt != NULL);
|
|
|
|
if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
|
|
ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
|
|
}
|
|
if (! fmt_st->bitmap) {
|
|
s = ldns_rdf_bitmap_known_rr_types_space(&fmt_st->bitmap);
|
|
if (s != LDNS_STATUS_OK) {
|
|
return s;
|
|
}
|
|
}
|
|
return ldns_nsec_bitmap_set_type(fmt_st->bitmap, t);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type t)
|
|
{
|
|
ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
|
|
ldns_status s;
|
|
|
|
assert(fmt != NULL);
|
|
|
|
if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
|
|
ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
|
|
}
|
|
if (! fmt_st->bitmap) {
|
|
s = ldns_rdf_bitmap_known_rr_types(&fmt_st->bitmap);
|
|
if (s != LDNS_STATUS_OK) {
|
|
return s;
|
|
}
|
|
}
|
|
return ldns_nsec_bitmap_clear_type(fmt_st->bitmap, t);
|
|
}
|
|
|
|
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_buffer_export2str(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_buffer_export2str(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_buffer_export2str(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_buffer_export2str(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);
|
|
}
|
|
|
|
static void
|
|
ldns_characters2buffer_str(ldns_buffer* output,
|
|
size_t amount, const uint8_t* characters)
|
|
{
|
|
uint8_t ch;
|
|
while (amount > 0) {
|
|
ch = *characters++;
|
|
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);
|
|
}
|
|
amount--;
|
|
}
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
if(ldns_rdf_size(rdf) < 1) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
ldns_buffer_printf(output, "\"");
|
|
ldns_characters2buffer_str(output,
|
|
ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf) + 1);
|
|
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);
|
|
}
|
|
|
|
static ldns_status
|
|
ldns_rdf2buffer_str_type_fmt(ldns_buffer *output,
|
|
const ldns_output_format* fmt, const ldns_rdf *rdf)
|
|
{
|
|
uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
|
|
|
|
if (! ldns_output_format_covers_type(fmt, data) &&
|
|
ldns_rr_descript(data) &&
|
|
ldns_rr_descript(data)->_name) {
|
|
|
|
ldns_buffer_printf(output, "%s",ldns_rr_descript(data)->_name);
|
|
} else {
|
|
ldns_buffer_printf(output, "TYPE%u", data);
|
|
}
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
return ldns_rdf2buffer_str_type_fmt(output,
|
|
ldns_output_format_default, rdf);
|
|
}
|
|
|
|
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_buffer_export2str(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_buffer_export2str(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;
|
|
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(ldns_rdf_size(rdf) < 1) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
version = ldns_rdf_data(rdf)[0];
|
|
if (version == 0) {
|
|
if(ldns_rdf_size(rdf) < 16) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
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;
|
|
|
|
if(ldns_rdf_size(rdf) < 1) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
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);
|
|
}
|
|
|
|
static ldns_status
|
|
ldns_rdf2buffer_str_nsec_fmt(ldns_buffer *output,
|
|
const ldns_output_format* fmt, 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);
|
|
|
|
while((size_t)(pos + 2) < ldns_rdf_size(rdf)) {
|
|
window_block_nr = data[pos];
|
|
bitmap_length = data[pos + 1];
|
|
pos += 2;
|
|
if (ldns_rdf_size(rdf) < pos + bitmap_length) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
|
|
if (! ldns_get_bit(&data[pos], bit_pos)) {
|
|
continue;
|
|
}
|
|
type = 256 * (uint16_t) window_block_nr + bit_pos;
|
|
|
|
if (! ldns_output_format_covers_type(fmt, type) &&
|
|
ldns_rr_descript(type) &&
|
|
ldns_rr_descript(type)->_name){
|
|
|
|
ldns_buffer_printf(output, "%s ",
|
|
ldns_rr_descript(type)->_name);
|
|
} else {
|
|
ldns_buffer_printf(output, "TYPE%u ", type);
|
|
}
|
|
}
|
|
pos += (uint16_t) bitmap_length;
|
|
}
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
return ldns_rdf2buffer_str_nsec_fmt(output,
|
|
ldns_output_format_default, rdf);
|
|
}
|
|
|
|
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) < 1) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
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 */
|
|
if (ldns_rdf_size(rdf) != 4) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
ldns_buffer_printf(output, "%u", ldns_read_uint32(ldns_rdf_data(rdf)));
|
|
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);
|
|
uint64_t d0, d1, d2, d3, d4, d5;
|
|
|
|
if (ldns_rdf_size(rdf) < 6) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
d0 = data[0]; /* cast to uint64 for shift operations */
|
|
d1 = data[1];
|
|
d2 = data[2];
|
|
d3 = data[3];
|
|
d4 = data[4];
|
|
d5 = data[5];
|
|
tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
|
|
|
|
ldns_buffer_printf(output, "%llu ", (long long)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_WIRE_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_WIRE_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_WIRE_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_WIRE_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)
|
|
{
|
|
size_t size;
|
|
char *b64;
|
|
if (ldns_rdf_size(rdf) < 2) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
/* Subtract the size (2) of the number that specifies the length */
|
|
size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
|
|
ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
|
|
if (ldns_rdf_size(rdf) > 2) {
|
|
b64 = LDNS_XMALLOC(char, size);
|
|
if(!b64)
|
|
return LDNS_STATUS_MEM_ERR;
|
|
|
|
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;
|
|
|
|
if (ldns_rdf_size(rdf) < 3) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
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;
|
|
if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
|
|
return LDNS_STATUS_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;
|
|
if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
|
|
return LDNS_STATUS_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;
|
|
}
|
|
|
|
if (ldns_rdf_size(rdf) <= offset) {
|
|
return LDNS_STATUS_ERR;
|
|
}
|
|
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_ilnp64(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
if (ldns_rdf_size(rdf) != 8) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
ldns_buffer_printf(output,"%.4x:%.4x:%.4x:%.4x",
|
|
ldns_read_uint16(ldns_rdf_data(rdf)),
|
|
ldns_read_uint16(ldns_rdf_data(rdf)+2),
|
|
ldns_read_uint16(ldns_rdf_data(rdf)+4),
|
|
ldns_read_uint16(ldns_rdf_data(rdf)+6));
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str_eui48(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
if (ldns_rdf_size(rdf) != 6) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
|
|
ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
|
|
ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
|
|
ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5]);
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
if (ldns_rdf_size(rdf) != 8) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
|
|
ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
|
|
ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
|
|
ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5],
|
|
ldns_rdf_data(rdf)[6], ldns_rdf_data(rdf)[7]);
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str_tag(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
size_t nchars;
|
|
const uint8_t* chars;
|
|
char ch;
|
|
if (ldns_rdf_size(rdf) < 2) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
nchars = ldns_rdf_data(rdf)[0];
|
|
if (nchars >= ldns_rdf_size(rdf) || /* should be rdf_size - 1 */
|
|
nchars < 1) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
chars = ldns_rdf_data(rdf) + 1;
|
|
while (nchars > 0) {
|
|
ch = (char)*chars++;
|
|
if (! isalnum(ch)) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
ldns_buffer_printf(output, "%c", ch);
|
|
nchars--;
|
|
}
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
|
|
ldns_buffer_printf(output, "\"");
|
|
ldns_characters2buffer_str(output,
|
|
ldns_rdf_size(rdf), ldns_rdf_data(rdf));
|
|
ldns_buffer_printf(output, "\"");
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
|
|
{
|
|
uint8_t *data = ldns_rdf_data(rdf);
|
|
size_t rdf_size = ldns_rdf_size(rdf);
|
|
uint8_t hit_size;
|
|
uint16_t pk_size;
|
|
int written;
|
|
|
|
if (rdf_size < 6) {
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
if ((hit_size = data[0]) == 0 ||
|
|
(pk_size = ldns_read_uint16(data + 2)) == 0 ||
|
|
rdf_size < (size_t) hit_size + pk_size + 4) {
|
|
|
|
return LDNS_STATUS_WIRE_RDATA_ERR;
|
|
}
|
|
|
|
ldns_buffer_printf(output, "%d ", (int) data[1]);
|
|
|
|
for (data += 4; hit_size > 0; hit_size--, data++) {
|
|
|
|
ldns_buffer_printf(output, "%02x", (int) *data);
|
|
}
|
|
ldns_buffer_write_u8(output, (uint8_t) ' ');
|
|
|
|
if (ldns_buffer_reserve(output,
|
|
ldns_b64_ntop_calculate_size(pk_size))) {
|
|
|
|
written = ldns_b64_ntop(data, pk_size,
|
|
(char *) ldns_buffer_current(output),
|
|
ldns_buffer_remaining(output));
|
|
|
|
if (written > 0 &&
|
|
written < (int) ldns_buffer_remaining(output)) {
|
|
|
|
output->_position += written;
|
|
}
|
|
}
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
static ldns_status
|
|
ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
|
|
const ldns_output_format* fmt, 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_fmt(buffer, fmt, 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_fmt(buffer, fmt, 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_HIP:
|
|
res = ldns_rdf2buffer_str_hip(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_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;
|
|
case LDNS_RDF_TYPE_ILNP64:
|
|
res = ldns_rdf2buffer_str_ilnp64(buffer, rdf);
|
|
break;
|
|
case LDNS_RDF_TYPE_EUI48:
|
|
res = ldns_rdf2buffer_str_eui48(buffer, rdf);
|
|
break;
|
|
case LDNS_RDF_TYPE_EUI64:
|
|
res = ldns_rdf2buffer_str_eui64(buffer, rdf);
|
|
break;
|
|
case LDNS_RDF_TYPE_TAG:
|
|
res = ldns_rdf2buffer_str_tag(buffer, rdf);
|
|
break;
|
|
case LDNS_RDF_TYPE_LONG_STR:
|
|
res = ldns_rdf2buffer_str_long_str(buffer, rdf);
|
|
break;
|
|
}
|
|
} else {
|
|
/** This will write mangled RRs */
|
|
ldns_buffer_printf(buffer, "(null) ");
|
|
res = LDNS_STATUS_ERR;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
ldns_status
|
|
ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
|
|
{
|
|
return ldns_rdf2buffer_str_fmt(buffer,ldns_output_format_default,rdf);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static ldns_status
|
|
ldns_rr2buffer_str_rfc3597(ldns_buffer *output, const ldns_rr *rr)
|
|
{
|
|
size_t total_rdfsize = 0;
|
|
size_t i, j;
|
|
|
|
ldns_buffer_printf(output, "TYPE%u\t", ldns_rr_get_type(rr));
|
|
for (i = 0; i < ldns_rr_rd_count(rr); i++) {
|
|
total_rdfsize += ldns_rdf_size(ldns_rr_rdf(rr, i));
|
|
}
|
|
if (total_rdfsize == 0) {
|
|
ldns_buffer_printf(output, "\\# 0\n");
|
|
return ldns_buffer_status(output);
|
|
}
|
|
ldns_buffer_printf(output, "\\# %d ", total_rdfsize);
|
|
for (i = 0; i < ldns_rr_rd_count(rr); i++) {
|
|
for (j = 0; j < ldns_rdf_size(ldns_rr_rdf(rr, i)); j++) {
|
|
ldns_buffer_printf(output, "%.2x",
|
|
ldns_rdf_data(ldns_rr_rdf(rr, i))[j]);
|
|
}
|
|
}
|
|
ldns_buffer_printf(output, "\n");
|
|
return ldns_buffer_status(output);
|
|
}
|
|
|
|
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;
|
|
ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
|
|
|
|
if (fmt_st == NULL) {
|
|
fmt_st = (ldns_output_format_storage*)
|
|
ldns_output_format_default;
|
|
}
|
|
if (!rr) {
|
|
if (LDNS_COMMENT_NULLS & fmt_st->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");
|
|
|
|
if (ldns_output_format_covers_type(fmt, ldns_rr_get_type(rr))) {
|
|
return ldns_rr2buffer_str_rfc3597(output, rr);
|
|
}
|
|
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! */
|
|
if ((fmt_st->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
|
|
(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
|
|
((/* inception */ i == 4 &&
|
|
ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) ==
|
|
LDNS_RDF_TYPE_TIME) ||
|
|
(/* expiration */ i == 5 &&
|
|
ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
|
|
LDNS_RDF_TYPE_TIME) ||
|
|
(/* signature */ i == 8 &&
|
|
ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
|
|
LDNS_RDF_TYPE_B64))) {
|
|
|
|
ldns_buffer_printf(output, "(null)");
|
|
status = ldns_buffer_status(output);
|
|
} else if ((fmt_st->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
|
|
(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
|
|
/* serial */ i == 2 &&
|
|
ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
|
|
LDNS_RDF_TYPE_INT32) {
|
|
ldns_buffer_printf(output, "%10lu",
|
|
(unsigned long) ldns_read_uint32(
|
|
ldns_rdf_data(ldns_rr_rdf(rr, 2))));
|
|
status = ldns_buffer_status(output);
|
|
} else {
|
|
status = ldns_rdf2buffer_str_fmt(output,
|
|
fmt, 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_st->flags & LDNS_COMMENT_KEY)) {
|
|
break;
|
|
}
|
|
flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
|
|
ldns_buffer_printf(output, " ;{");
|
|
if (fmt_st->flags & LDNS_COMMENT_KEY_ID) {
|
|
ldns_buffer_printf(output, "id = %u",
|
|
(unsigned int) ldns_calc_keytag(rr));
|
|
}
|
|
if ((fmt_st->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_st->flags & LDNS_COMMENT_KEY_SIZE){
|
|
ldns_buffer_printf(output, ", ");
|
|
}
|
|
} else if (fmt_st->flags
|
|
& (LDNS_COMMENT_KEY_ID
|
|
|LDNS_COMMENT_KEY_SIZE)) {
|
|
ldns_buffer_printf( output, ", ");
|
|
}
|
|
if (fmt_st->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_st->flags & LDNS_COMMENT_KEY)
|
|
&& (fmt_st->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_st->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_st->flags & LDNS_COMMENT_FLAGS) &&
|
|
! (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
|
|
break;
|
|
}
|
|
ldns_buffer_printf(output, " ;{");
|
|
if ((fmt_st->flags & LDNS_COMMENT_FLAGS)) {
|
|
if (ldns_nsec3_optout(rr)) {
|
|
ldns_buffer_printf(output,
|
|
" flags: optout");
|
|
} else {
|
|
ldns_buffer_printf(output," flags: -");
|
|
}
|
|
if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
|
|
fmt_st->hashmap != NULL) {
|
|
ldns_buffer_printf(output, ", ");
|
|
}
|
|
}
|
|
if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
|
|
fmt_st->hashmap != NULL) {
|
|
ldns_rbnode_t *node;
|
|
ldns_rdf *key = ldns_dname_label(
|
|
ldns_rr_owner(rr), 0);
|
|
if (key) {
|
|
node = ldns_rbtree_search(
|
|
fmt_st->hashmap,
|
|
(void *) key);
|
|
if (node->data) {
|
|
ldns_buffer_printf(output,
|
|
"from: ");
|
|
(void) ldns_rdf2buffer_str(
|
|
output,
|
|
ldns_dnssec_name_name(
|
|
(ldns_dnssec_name*)
|
|
node->data
|
|
));
|
|
}
|
|
ldns_rdf_free(key);
|
|
}
|
|
key = ldns_b32_ext2dname(
|
|
ldns_nsec3_next_owner(rr));
|
|
if (key) {
|
|
node = ldns_rbtree_search(
|
|
fmt_st->hashmap,
|
|
(void *) key);
|
|
if (node->data) {
|
|
ldns_buffer_printf(output,
|
|
" to: ");
|
|
(void) ldns_rdf2buffer_str(
|
|
output,
|
|
ldns_dnssec_name_name(
|
|
(ldns_dnssec_name*)
|
|
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;
|
|
#ifdef HAVE_SSL
|
|
# ifndef S_SPLINT_S
|
|
uint16_t i;
|
|
# endif
|
|
/* not used when ssl is not defined */
|
|
/*@unused@*/
|
|
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:
|
|
#ifdef STDERR_MSGS
|
|
fprintf(stderr, "Warning: unknown signature ");
|
|
fprintf(stderr,
|
|
"algorithm type %u\n",
|
|
ldns_key_algorithm(k));
|
|
#endif
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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) {
|
|
ldns_rdf_deep_free(b64_bignum);
|
|
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 {
|
|
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 copy data.
|
|
*/
|
|
char *
|
|
ldns_buffer2str(ldns_buffer *buffer)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
str = strdup((const char *)ldns_buffer_begin(buffer));
|
|
if(!str) {
|
|
return NULL;
|
|
}
|
|
return str;
|
|
}
|
|
|
|
/*
|
|
* Zero terminate the buffer and export data.
|
|
*/
|
|
char *
|
|
ldns_buffer_export2str(ldns_buffer *buffer)
|
|
{
|
|
/* Append '\0' as string terminator */
|
|
if (! ldns_buffer_reserve(buffer, 1)) {
|
|
return NULL;
|
|
}
|
|
ldns_buffer_write_u8(buffer, 0);
|
|
|
|
/* reallocate memory to the size of the string and export */
|
|
ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
|
|
return ldns_buffer_export(buffer);
|
|
}
|
|
|
|
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_buffer_export2str(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_buffer_export2str(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_buffer_export2str(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_buffer_export2str(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_buffer_export2str(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);
|
|
}
|