1
0
Fork 0
dnscap/src/dump_cbor.c

681 lines
27 KiB
C
Raw Normal View History

/*
* Copyright (c) 2016-2022, OARC, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
DNS-in-JSON
- generally naming convention
- compressedNAME.length is there a point here? isn't the length in the
compressed data itself? Maybe have compressedNAME as just the data
of the compressed name
- 2.5 Additional Message Object Members
- IP stuff:
- ipProtocol: num
- sourceIpAddress: string
- sourcePort: num
- destinationIpAddress: string
- destinationPort: num
or
- ip: [ ipProtocol, sourceIpAddress, sourcePort, destinationIpAddress, destinationPort ]
- dateNanoFractions as addition to dateSeconds, specify the fraction of
nano seconds separatly to have better precision.
*/
#include "config.h"
#include "dump_cbor.h"
#include "dnscap.h"
#include "iaddr.h"
#if HAVE_LIBTINYCBOR
#include <ldns/ldns.h>
#if HAVE_CBOR_CBOR_H
#include <cbor/cbor.h>
#endif
#if HAVE_CBOR_H
#include <cbor.h>
#endif
static uint8_t* cbor_buf = 0;
static size_t cbor_size = 128 * 1024;
/*static size_t cbor_size = 1024;*/
static size_t cbor_reserve = 64 * 1024;
static CborEncoder cbor_root, cbor_pkts;
/*static cbor_stringref_t *cbor_stringrefs = 0;*/
/*static size_t cbor_stringref_size = 8192;*/
static int cbor_flushed = 1;
int cbor_set_size(size_t size)
{
if (!size) {
return DUMP_CBOR_EINVAL;
}
cbor_size = size;
return DUMP_CBOR_OK;
}
int cbor_set_reserve(size_t reserve)
{
if (!reserve) {
return DUMP_CBOR_EINVAL;
}
cbor_reserve = reserve;
return DUMP_CBOR_OK;
}
#define append_cbor(func, name, type) \
CborError func(CborEncoder* encoder, type value, int* should_flush) \
{ \
CborError err; \
uint8_t* ptr = encoder->data.ptr; \
err = name(encoder, value); \
if (err == CborErrorOutOfMemory && !*should_flush) { \
*should_flush = 1; \
encoder->data.ptr = ptr; \
encoder->end = cbor_buf + cbor_size + cbor_reserve; \
err = name(encoder, value); \
} \
return err; \
}
static append_cbor(append_cbor_text_stringz, cbor_encode_text_stringz, const char*);
static append_cbor(append_cbor_boolean, cbor_encode_boolean, bool);
static append_cbor(append_cbor_int, cbor_encode_int, int64_t);
static append_cbor(append_cbor_uint, cbor_encode_uint, uint64_t);
static append_cbor(append_cbor_double, cbor_encode_double, double);
static CborError append_cbor_bytes(CborEncoder* encoder, uint8_t* bytes, size_t length, int* should_flush)
{
CborError err;
uint8_t* ptr = encoder->data.ptr;
err = cbor_encode_byte_string(encoder, bytes, length);
if (err == CborErrorOutOfMemory && !*should_flush) {
*should_flush = 1;
encoder->data.ptr = ptr;
encoder->end = cbor_buf + cbor_size + cbor_reserve;
err = cbor_encode_byte_string(encoder, bytes, length);
}
return err;
}
/*CborError append_cbor_text_stringz2(CborEncoder *encoder, const char *value, int *should_flush) {*/
/* CborError err;*/
/* uint8_t *ptr = encoder->data.ptr;*/
/* err = cbor_encode_byte_string(encoder, bytes, length);*/
/* if (err == CborErrorOutOfMemory && !*should_flush) {*/
/* *should_flush = 1;*/
/* encoder->data.ptr = ptr;*/
/* encoder->end = cbor_buf + cbor_size + cbor_reserve;*/
/* err = cbor_encode_byte_string(encoder, bytes, length);*/
/* }*/
/* return err;*/
/*}*/
#define append_cbor_container(func, name) \
CborError func(CborEncoder* encoder, CborEncoder* container, size_t length, int* should_flush) \
{ \
CborError err; \
uint8_t* ptr = encoder->data.ptr; \
err = name(encoder, container, length); \
if (err == CborErrorOutOfMemory && !*should_flush) { \
*should_flush = 1; \
encoder->data.ptr = ptr; \
encoder->end = cbor_buf + cbor_size + cbor_reserve; \
err = name(encoder, container, length); \
} \
return err; \
}
static append_cbor_container(append_cbor_array, cbor_encoder_create_array);
static append_cbor_container(append_cbor_map, cbor_encoder_create_map);
static CborError close_cbor_container(CborEncoder* encoder, CborEncoder* container, int* should_flush)
{
CborError err;
uint8_t* ptr = encoder->data.ptr;
err = cbor_encoder_close_container_checked(encoder, container);
if (err == CborErrorOutOfMemory && !*should_flush) {
*should_flush = 1;
encoder->data.ptr = ptr;
encoder->end = cbor_buf + cbor_size + cbor_reserve;
err = cbor_encoder_close_container_checked(encoder, container);
}
return err;
}
static CborError cbor_ldns_rr_list(CborEncoder* encoder, ldns_rr_list* list, size_t count, int* should_flush)
{
CborError cbor_err = CborNoError;
size_t n;
ldns_buffer* dname;
char* dname_str;
if (!encoder) {
return CborErrorInternalError;
}
if (!list) {
return CborErrorInternalError;
}
if (!count) {
return CborErrorInternalError;
}
if (!should_flush) {
return CborErrorInternalError;
}
for (n = 0; cbor_err == CborNoError && n < count; n++) {
CborEncoder cbor_rr;
uint8_t* rdata_bytes;
ldns_buffer* rdata;
ldns_rr* rr = ldns_rr_list_rr(list, n);
size_t rd_count;
if (!rr) {
return CborErrorInternalError;
}
rd_count = ldns_rr_rd_count(rr);
if (!(dname = ldns_buffer_new(512))) {
return CborErrorOutOfMemory;
}
if (ldns_rdf2buffer_str_dname(dname, ldns_rr_owner(rr)) != LDNS_STATUS_OK) {
ldns_buffer_free(dname);
return CborErrorInternalError;
}
ldns_buffer_write_u8(dname, 0);
if (!(dname_str = ldns_buffer_export(dname))) {
ldns_buffer_free(dname);
return CborErrorOutOfMemory;
}
if (cbor_err == CborNoError)
cbor_err = append_cbor_map(encoder, &cbor_rr, CborIndefiniteLength, should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor_rr, "NAME", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor_rr, dname_str, should_flush);
free(dname_str);
ldns_buffer_free(dname);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor_rr, "CLASS", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor_rr, ldns_rr_get_class(rr), should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor_rr, "TYPE", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor_rr, ldns_rr_get_type(rr), should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor_rr, "TTL", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor_rr, ldns_rr_ttl(rr), should_flush);
if (rd_count == 1) {
if (!(rdata = ldns_buffer_new(64 * 1024))) {
return CborErrorOutOfMemory;
}
if (ldns_rdf2buffer_wire(rdata, ldns_rr_rdf(rr, 0)) != LDNS_STATUS_OK) {
ldns_buffer_free(rdata);
return CborErrorInternalError;
}
if (!(rdata_bytes = ldns_buffer_export(rdata))) {
ldns_buffer_free(rdata);
return CborErrorOutOfMemory;
}
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor_rr, "RDLENGTH", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor_rr, ldns_buffer_position(rdata), should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor_rr, "RDATA", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_bytes(&cbor_rr, rdata_bytes, ldns_buffer_position(rdata), should_flush);
free(rdata_bytes);
ldns_buffer_free(rdata);
} else if (rd_count > 1) {
size_t n2;
CborEncoder rr_set;
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor_rr, "rrSet", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_array(&cbor_rr, &rr_set, CborIndefiniteLength, should_flush);
for (n2 = 0; n2 < rd_count; n2++) {
if (!(rdata = ldns_buffer_new(64 * 1024))) {
return CborErrorOutOfMemory;
}
if (ldns_rdf2buffer_wire(rdata, ldns_rr_rdf(rr, n2)) != LDNS_STATUS_OK) {
ldns_buffer_free(rdata);
return CborErrorInternalError;
}
if (!(rdata_bytes = ldns_buffer_export(rdata))) {
ldns_buffer_free(rdata);
return CborErrorOutOfMemory;
}
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&rr_set, "RDLENGTH", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&rr_set, ldns_buffer_position(rdata), should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&rr_set, "RDATA", should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_bytes(&rr_set, rdata_bytes, ldns_buffer_position(rdata), should_flush);
free(rdata_bytes);
ldns_buffer_free(rdata);
}
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(&cbor_rr, &rr_set, should_flush);
}
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(encoder, &cbor_rr, should_flush);
}
return cbor_err;
}
int output_cbor(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* payload, size_t payloadlen)
{
ldns_pkt* pkt = 0;
ldns_status ldns_rc;
if (!payload) {
return DUMP_CBOR_EINVAL;
}
if (!payloadlen) {
return DUMP_CBOR_EINVAL;
}
/* if (!cbor_stringrefs) {*/
/* cbor_stringrefs = calloc(1, cbor_stringref_size);*/
/* }*/
if (!cbor_buf) {
if (!(cbor_buf = calloc(1, cbor_size + cbor_reserve))) {
return DUMP_CBOR_ENOMEM;
}
}
if (cbor_flushed) {
CborError cbor_err;
cbor_encoder_init(&cbor_root, cbor_buf, cbor_size, 0);
/* cbor_err = cbor_encode_tag(&cbor_root, 256);*/
/* if (cbor_err == CborNoError)*/
cbor_err = cbor_encoder_create_array(&cbor_root, &cbor_pkts, CborIndefiniteLength);
if (cbor_err != CborNoError) {
fprintf(stderr, "cbor init error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err));
return DUMP_CBOR_ECBOR;
}
cbor_flushed = 0;
}
ldns_rc = ldns_wire2pkt(&pkt, payload, payloadlen);
if (ldns_rc != LDNS_STATUS_OK) {
fprintf(stderr, "ldns error [%d]: %s\n", ldns_rc, ldns_get_errorstr_by_id(ldns_rc));
return DUMP_CBOR_ELDNS;
}
if (!pkt) {
return DUMP_CBOR_ELDNS;
}
CborEncoder cbor, ip;
CborError cbor_err = CborNoError;
int should_flush = 0;
cbor_err = append_cbor_map(&cbor_pkts, &cbor, CborIndefiniteLength, &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "dateSeconds", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_double(&cbor, (double)ts.tv_sec + ((double)ts.tv_usec / 1000000), &should_flush);
/* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "dateNanoFractions", &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, ts.tv_usec * 1000, &should_flush);*/
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "ip", &should_flush);
/* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, proto, &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "sourceIpAddress", &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, ia_str(from), &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "sourcePort", &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, sport, &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "destinationIpAddress", &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, ia_str(to), &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_text_stringz(&cbor, "destinationPort", &should_flush);*/
/* if (cbor_err == CborNoError) cbor_err = append_cbor_uint(&cbor, dport, &should_flush);*/
if (cbor_err == CborNoError)
cbor_err = append_cbor_array(&cbor, &ip, CborIndefiniteLength, &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&ip, proto, &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&ip, ia_str(from), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&ip, sport, &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&ip, ia_str(to), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&ip, dport, &should_flush);
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(&cbor, &ip, &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "ID", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_pkt_id(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "QR", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_boolean(&cbor, ldns_pkt_qr(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "Opcode", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_pkt_get_opcode(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "AA", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_boolean(&cbor, ldns_pkt_aa(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "TC", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_boolean(&cbor, ldns_pkt_tc(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "RD", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_boolean(&cbor, ldns_pkt_rd(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "RA", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_boolean(&cbor, ldns_pkt_ra(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "AD", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_boolean(&cbor, ldns_pkt_ad(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "CD", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_boolean(&cbor, ldns_pkt_cd(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "RCODE", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_pkt_get_rcode(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "QDCOUNT", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_pkt_qdcount(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "ANCOUNT", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_pkt_ancount(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "NSCOUNT", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_pkt_nscount(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "ARCOUNT", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_pkt_arcount(pkt), &should_flush);
/* questionRRs */
if (ldns_pkt_qdcount(pkt) > 0) {
ldns_rr_list* list = ldns_pkt_question(pkt);
ldns_rr* rr;
size_t n, qdcount = ldns_pkt_qdcount(pkt);
ldns_buffer* dname;
char* dname_str;
if (!list) {
ldns_pkt_free(pkt);
return DUMP_CBOR_ELDNS;
}
rr = ldns_rr_list_rr(list, 0);
if (!rr) {
ldns_pkt_free(pkt);
return DUMP_CBOR_ELDNS;
}
if (!(dname = ldns_buffer_new(512))) {
ldns_pkt_free(pkt);
return DUMP_CBOR_ENOMEM;
}
if (ldns_rdf2buffer_str_dname(dname, ldns_rr_owner(rr)) != LDNS_STATUS_OK) {
ldns_buffer_free(dname);
ldns_pkt_free(pkt);
return DUMP_CBOR_ELDNS;
}
ldns_buffer_write_u8(dname, 0);
if (!(dname_str = ldns_buffer_export(dname))) {
ldns_buffer_free(dname);
ldns_pkt_free(pkt);
return DUMP_CBOR_ENOMEM;
}
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "QNAME", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, dname_str, &should_flush);
free(dname_str);
ldns_buffer_free(dname);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "QCLASS", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_rr_get_class(rr), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "QTYPE", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&cbor, ldns_rr_get_type(rr), &should_flush);
if (qdcount > 1) {
CborEncoder queries;
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "questionRRs", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_array(&cbor, &queries, CborIndefiniteLength, &should_flush);
for (n = 1; cbor_err == CborNoError && n < qdcount; n++) {
CborEncoder query;
rr = ldns_rr_list_rr(list, n);
if (!rr) {
ldns_pkt_free(pkt);
return DUMP_CBOR_ELDNS;
}
if (!(dname = ldns_buffer_new(512))) {
ldns_pkt_free(pkt);
return DUMP_CBOR_ENOMEM;
}
if (ldns_rdf2buffer_str_dname(dname, ldns_rr_owner(rr)) != LDNS_STATUS_OK) {
ldns_buffer_free(dname);
ldns_pkt_free(pkt);
return DUMP_CBOR_ELDNS;
}
ldns_buffer_write_u8(dname, 0);
if (!(dname_str = ldns_buffer_export(dname))) {
ldns_buffer_free(dname);
ldns_pkt_free(pkt);
return DUMP_CBOR_ENOMEM;
}
if (cbor_err == CborNoError)
cbor_err = append_cbor_map(&queries, &query, CborIndefiniteLength, &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&query, "NAME", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&query, dname_str, &should_flush);
free(dname_str);
ldns_buffer_free(dname);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&query, "CLASS", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&query, ldns_rr_get_class(rr), &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&query, "TYPE", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_uint(&query, ldns_rr_get_type(rr), &should_flush);
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(&queries, &query, &should_flush);
}
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(&cbor, &queries, &should_flush);
}
}
/* answerRRs */
if (ldns_pkt_ancount(pkt) > 0) {
CborEncoder cbor_rrs;
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "answerRRs", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush);
cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_answer(pkt), ldns_pkt_ancount(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush);
}
/* authorityRRs */
if (ldns_pkt_nscount(pkt) > 0) {
CborEncoder cbor_rrs;
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "authorityRRs", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush);
cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_authority(pkt), ldns_pkt_nscount(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush);
}
/* additionalRRs */
if (ldns_pkt_arcount(pkt) > 0) {
CborEncoder cbor_rrs;
if (cbor_err == CborNoError)
cbor_err = append_cbor_text_stringz(&cbor, "additionalRRs", &should_flush);
if (cbor_err == CborNoError)
cbor_err = append_cbor_array(&cbor, &cbor_rrs, CborIndefiniteLength, &should_flush);
cbor_ldns_rr_list(&cbor_rrs, ldns_pkt_additional(pkt), ldns_pkt_arcount(pkt), &should_flush);
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(&cbor, &cbor_rrs, &should_flush);
}
ldns_pkt_free(pkt);
if (cbor_err == CborNoError)
cbor_err = close_cbor_container(&cbor_pkts, &cbor, &should_flush);
if (cbor_err != CborNoError) {
fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err));
return DUMP_CBOR_ECBOR;
}
if (should_flush) {
if ((cbor_err = cbor_encoder_close_container_checked(&cbor_root, &cbor_pkts)) != CborNoError) {
fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err));
return DUMP_CBOR_ECBOR;
}
fprintf(stderr, "cbor output: %lu bytes\n", cbor_encoder_get_buffer_size(&cbor_root, cbor_buf));
cbor_flushed = 1;
return DUMP_CBOR_FLUSH;
}
return DUMP_CBOR_OK;
}
int dump_cbor(FILE* fp)
{
CborError cbor_err;
if (!fp) {
return DUMP_CBOR_EINVAL;
}
if ((cbor_err = cbor_encoder_close_container_checked(&cbor_root, &cbor_pkts)) != CborNoError) {
fprintf(stderr, "cbor error[%d]: %s\n", cbor_err, cbor_error_string(cbor_err));
return DUMP_CBOR_ECBOR;
}
fprintf(stderr, "cbor output: %lu bytes\n", cbor_encoder_get_buffer_size(&cbor_root, cbor_buf));
if (fwrite(cbor_buf, cbor_encoder_get_buffer_size(&cbor_root, cbor_buf), 1, fp) != 1) {
return DUMP_CBOR_EWRITE;
}
return DUMP_CBOR_OK;
}
int have_cbor_support()
{
return 1;
}
#else /* HAVE_LIBTINYCBOR */
int cbor_set_size(size_t size)
{
return DUMP_CBOR_ENOSUP;
}
int cbor_set_reserve(size_t reserve)
{
return DUMP_CBOR_ENOSUP;
}
int output_cbor(iaddr from, iaddr to, uint8_t proto, unsigned flags, unsigned sport, unsigned dport, my_bpftimeval ts, const u_char* payload, size_t payloadlen)
{
return DUMP_CBOR_ENOSUP;
}
int dump_cbor(FILE* fp)
{
return DUMP_CBOR_ENOSUP;
}
int have_cbor_support()
{
return 0;
}
#endif