From: TCY16 Date: Tue, 5 Apr 2022 08:58:46 +0000 (+0200) Subject: add individual functions for EDNS optionss printing X-Git-Tag: 1.8.2-rc.1~3^2~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9139bfa9a420d50b9a412b18f1dbd3e9ce8a324b;p=thirdparty%2Fldns.git add individual functions for EDNS optionss printing --- diff --git a/host2str.c b/host2str.c index 31bc8b33..e0b9cfa3 100644 --- a/host2str.c +++ b/host2str.c @@ -81,6 +81,15 @@ ldns_lookup_table ldns_algorithms[] = { { 0, NULL } }; +/* Hashing algorithms used in the DS record */ +ldns_lookup_table ldns_hashes[] = { + {LDNS_SHA1 , "SHA1" }, /* RFC 4034 */ + {LDNS_SHA256 , "SHA256" }, /* RFC 4509 */ + {LDNS_HASH_GOST, "HASH-GOST" }, /* RFC 5933 */ + {LDNS_SHA384 , "SHA384" }, /* RFC 6605 */ + { 0, NULL } +}; + /* Taken from RFC 4398 */ ldns_lookup_table ldns_cert_algorithms[] = { { LDNS_CERT_PKIX, "PKIX" }, @@ -2108,171 +2117,450 @@ ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt) } +/* print EDNS option data in the Dig format: 76 61 6c 69 ... */ +static void +ldns_edns_hex_data2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + size_t j; + for (j = 0; j < len; j++) { + ldns_buffer_printf(output, " %02x", data[j]); + } +} + +static ldns_status +ldns_edns_llq2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + /* LLQ constants */ + const char* llq_errors[] = {"NO-ERROR", "SERV-FULL", "STATIC", + "FORMAT-ERR", "NO-SUCH-LLQ", "BAD-VERS", "UNKNOWN_ERR"}; + const unsigned int llq_errors_num = 7; + const char* llq_opcodes[] = {"LLQ-SETUP", "LLQ-REFRESH", "LLQ-EVENT"}; + const unsigned int llq_opcodes_num = 3; + + uint16_t version, llq_opcode, error_code; + uint64_t llq_id; + uint32_t lease_life; /* Requested or granted life of LLQ, in seconds */ + ldns_buffer_printf(output, "; Long-Lived Query:"); + /* read the record */ + if(len != 18) { + ldns_buffer_printf(output, " malformed LLQ "); + ldns_edns_hex_data2buffer_str(output, data, len); + + return ldns_buffer_status(output); + } + version = ldns_read_uint16(data); + llq_opcode = ldns_read_uint16(data+2); + error_code = ldns_read_uint16(data+4); + memmove(&llq_id, data+6, sizeof(uint64_t)); + lease_life = ldns_read_uint32(data+14); -static void // @TODO change this <- -ldns_edns_option_list2buffer_str(ldns_buffer *output, ldns_edns_option_list* edns_list) + /* print option field entires */ + ldns_buffer_printf(output, "v%d ", (int)version); + + if(llq_opcode < llq_opcodes_num) { + ldns_buffer_printf(output, "%s", llq_opcodes[llq_opcode]); + } else { + ldns_buffer_printf(output, "opcode %d", (int)llq_opcode); + } + + if(error_code < llq_errors_num) + ldns_buffer_printf(output, " %s", llq_errors[error_code]); + else { + ldns_buffer_printf(output, " error %d", (int)error_code); + } + +#ifndef USE_WINSOCK + ldns_buffer_printf(output, " id %llx lease-life %lu", + (unsigned long long)llq_id, (unsigned long)lease_life); +#else + ldns_buffer_printf(output, " id %I64x lease-life %lu", + (unsigned long long)llq_id, (unsigned long)lease_life); +#endif + return ldns_buffer_status(output); +} + + +static ldns_status +ldns_edns_ul2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) { - size_t count = ldns_edns_option_list_get_count(edns_list); - size_t i, j; - size_t size; - uint8_t* data; + uint32_t lease; - for (i = 0; i < count; i++) { - ldns_edns_option_code code; - ldns_edns_option* edns = ldns_edns_option_list_get_option(edns_list, i); + ldns_buffer_printf(output, "; Update Lease:"); - // @TODO write parser for OPT records "; NSID: " "; EDE: 9 (DNSKEY Missing):" - code = ldns_edns_get_code(edns); + if(len != 4) { + ldns_buffer_printf(output, " malformed UL "); + ldns_edns_hex_data2buffer_str(output, data, len); + return ldns_buffer_status(output); + } + lease = ldns_read_uint32(data); + ldns_buffer_printf(output, "lease %lu", (unsigned long)lease); - // @TODO make function - switch(code) { - case LDNS_EDNS_LLQ: - ldns_buffer_printf(output, ";; Long-Lived Query:"); - break; - case LDNS_EDNS_UL: - ldns_buffer_printf(output, ";; Update Lease:"); - break; - case LDNS_EDNS_NSID: - ldns_buffer_printf(output, ";; NSID:"); - break; - case LDNS_EDNS_DAU: - ldns_buffer_printf(output, ";; :"); - break; - case LDNS_EDNS_DHU: - ldns_buffer_printf(output, ";; :"); - break; - case LDNS_EDNS_N3U: - ldns_buffer_printf(output, ";; :"); - break; - case LDNS_EDNS_CLIENT_SUBNET: - ldns_buffer_printf(output, ";; CLIENT-SUBNET:"); - break; - case LDNS_EDNS_KEEPALIVE: - ldns_buffer_printf(output, ";; KEEPALIVE:"); - break; - case LDNS_EDNS_PADDING: - ldns_buffer_printf(output, ";; PADDING:"); - break; - case LDNS_EDNS_EDE: - ldns_buffer_printf(output, ";; EDE:"); - break; - case LDNS_EDNS_CLIENT_TAG: - ldns_buffer_printf(output, ";; CLIENT-TAG:"); - break; + return ldns_buffer_status(output); +} - default: - ldns_buffer_printf(output, ";; OPT=%d:", code); - break; +static ldns_status +ldns_edns_nsid2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + size_t i, printed=0; + + ldns_buffer_printf(output, "; NSID:"); + ldns_edns_hex_data2buffer_str(output, data, len); + + /* print the human-readable text string */ + for(i = 0; i < len; i++) { + if(isprint((unsigned char)data[i]) || data[i] == '\t') { + if(!printed) { + ldns_buffer_printf(output, " ("); + printed = 1; + } + ldns_buffer_printf(output, "%c", (char)data[i]); } + } + if(printed) + ldns_buffer_printf(output, ")"); + return ldns_buffer_status(output); +} - size = ldns_edns_get_size(edns); - data = ldns_edns_get_data(edns); - if (code == LDNS_EDNS_EDE && size >= 2) { - uint16_t ede = data[1]; +static ldns_status +ldns_edns_dau2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + size_t i; + ldns_lookup_table *lt; - // @TODO make function - switch (ede) { - case LDNS_EDE_OTHER: - ldns_buffer_printf(output, " 0 (Other): "); - break; - case LDNS_EDE_UNSUPPORTED_DNSKEY_ALG: - ldns_buffer_printf(output, "1 (Unsupported DNSKEY Algorithm)"); - break; - case LDNS_EDE_UNSUPPORTED_DS_DIGEST: - ldns_buffer_printf(output, " 2 (Unsupported DS Digest type)"); - break; - case LDNS_EDE_STALE_ANSWER: - ldns_buffer_printf(output, " 3 (Stale Answer)"); - break; - case LDNS_EDE_FORGED_ANSWER: - ldns_buffer_printf(output, " 4 (Forged Answer)"); - break; - case LDNS_EDE_DNSSEC_INDETERMINATE: - ldns_buffer_printf(output, " 5 (DNSSEC Indeterminate)"); - break; - case LDNS_EDE_DNSSEC_BOGUS: - ldns_buffer_printf(output, " 6 (DNSSEC Bogus)"); - break; - case LDNS_EDE_SIGNATURE_EXPIRED: - ldns_buffer_printf(output, " 7 (Signature Expired)"); - break; - case LDNS_EDE_SIGNATURE_NOT_YET_VALID: - ldns_buffer_printf(output, " 8 (Signature Not Yet Valid)"); - break; - case LDNS_EDE_DNSKEY_MISSING: - ldns_buffer_printf(output, " 9 (DNSKEY Missing)"); - break; - case LDNS_EDE_RRSIGS_MISSING: - ldns_buffer_printf(output, " 10 (RRSIGs Missing)"); - break; - case LDNS_EDE_NO_ZONE_KEY_BIT_SET: - ldns_buffer_printf(output, " 11 (No Zone Key Bit Set)"); - break; - case LDNS_EDE_NSEC_MISSING: - ldns_buffer_printf(output, " 12 (NSEC Missing)"); - break; - case LDNS_EDE_CACHED_ERROR: - ldns_buffer_printf(output, " 13 (Cached Error)"); - break; - case LDNS_EDE_NOT_READY: - ldns_buffer_printf(output, " 14 (Not Ready)"); - break; - case LDNS_EDE_BLOCKED: - ldns_buffer_printf(output, " 15 (Blocked)"); - break; - case LDNS_EDE_CENSORED: - ldns_buffer_printf(output, " 16 (Censored)"); - break; - case LDNS_EDE_FILTERED: - ldns_buffer_printf(output, " 17 (Filtered)"); - break; - case LDNS_EDE_PROHIBITED: - ldns_buffer_printf(output, " 18 (Prohibited)"); - break; - case LDNS_EDE_STALE_NXDOMAIN_ANSWER: - ldns_buffer_printf(output, " 19 (NXDOMAIN Answer)"); - break; - case LDNS_EDE_NOT_AUTHORITATIVE: - ldns_buffer_printf(output, " 20 (Not Authoritative)"); - break; - case LDNS_EDE_NOT_SUPPORTED: - ldns_buffer_printf(output, " 21 (Not Supported)"); - break; - case LDNS_EDE_NO_REACHABLE_AUTHORITY: - ldns_buffer_printf(output, " 22 (No Reachable Authority)"); - break; - case LDNS_EDE_NETWORK_ERROR: - ldns_buffer_printf(output, " 23 (Network Error)"); - break; - case LDNS_EDE_INVALID_DATA: - ldns_buffer_printf(output, " 24 (Invalid Data)"); - break; - default: - ldns_buffer_printf(output, " %02x", data[0]); - ldns_buffer_printf(output, " %02x:", data[1]); - break; - } + ldns_buffer_printf(output, "; DAU:"); - data += 2; - size -= 2; + for(i = 0; i name) { + ldns_buffer_printf(output, " %s", lt->name); + } else { + ldns_buffer_printf(output, " ALG%u", data[i]); } + } + return ldns_buffer_status(output); +} - if (size > 2) { - /* format the hex bytes */ - ldns_buffer_printf(output, ":"); - for (j = 0; j < size; j++) { - ldns_buffer_printf(output, " %02x", data[j]); - } +static ldns_status +ldns_edns_dhu2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + size_t i; + ldns_lookup_table *lt; - /* format the human-readable string */ - ldns_buffer_printf(output, " ("); - ldns_characters2buffer_str(output, size, data); - ldns_buffer_printf(output, ")\n"); + ldns_buffer_printf(output, "; DHU:"); + + for(i = 0; i < len; i++) { + lt = ldns_lookup_by_id(ldns_hashes, data[i]); + if (lt && lt->name) { + ldns_buffer_printf(output, " %s", lt->name); + } else { + ldns_buffer_printf(output, " ALG%u", data[i]); } } + return ldns_buffer_status(output); +} + +static ldns_status +ldns_edns_d3u2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + size_t i; + + ldns_buffer_printf(output, "; D3U:"); + + for(i=0; i 4) { + ldns_buffer_printf(output, "trailingdata:"); + ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4); + ldns_buffer_printf(output, " "); + len = 4+4; + } + memmove(ip4, data+4, len-4); + if(!inet_ntop(AF_INET, ip4, buf, (socklen_t) sizeof(buf))) { + ldns_buffer_printf(output, "ip4ntoperror "); + ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4); + } else { + ldns_buffer_printf(output, "%s", buf); + } + } else if(family == 2) { + /* IPv6 */ + char buf[64]; + uint8_t ip6[16]; + memset(ip6, 0, sizeof(ip6)); + if(len-4 > 16) { + ldns_buffer_printf(output, "trailingdata:"); + ldns_edns_hex_data2buffer_str(output, data+4+16, len-4-16); + ldns_buffer_printf(output, " "); + len = 4+16; + } + memmove(ip6, data+4, len-4); +#ifdef AF_INET6 + if(!inet_ntop(AF_INET6, ip6, buf, (socklen_t) sizeof(buf))) { + ldns_buffer_printf(output, "ip6ntoperror "); + ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4); + } else { + ldns_buffer_printf(output, "%s", buf); + } +#else + ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4); +#endif + } else { + /* unknown */ + ldns_buffer_printf(output, "family %d ", (int)family); + ldns_edns_hex_data2buffer_str(output, data, len); + } + ldns_buffer_printf(output, "/%d scope /%d", (int)source, (int)scope); + + return ldns_buffer_status(output); +} + +static ldns_status +ldns_edns_keepalive2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + uint16_t timeout; + + ldns_buffer_printf(output, "; KEEPALIVE:"); + + if(!(len == 0 || len == 2)) { + ldns_buffer_printf(output, "malformed keepalive "); + ldns_edns_hex_data2buffer_str(output, data, len); + + return ldns_buffer_status(output); + } + + if(len == 0) { + ldns_buffer_printf(output, "no timeout value (only valid for client option)"); + } else { + timeout = ldns_read_uint16(data); + ldns_buffer_printf(output, "timeout value in units of 100ms %u", (int)timeout); + } + return ldns_buffer_status(output); +} + +static ldns_status +ldns_edns_padding2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + ldns_buffer_printf(output, "; PADDING: "); + ldns_edns_hex_data2buffer_str(output, data, len); + + return ldns_buffer_status(output); +} + +static ldns_status +ldns_edns_ede2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + size_t i; + uint16_t ede; + ldns_buffer_printf(output, "; EDE:"); + + if(len < 2) { + ldns_buffer_printf(output, "malformed ede "); + ldns_edns_hex_data2buffer_str(output, data, len); + + return ldns_buffer_status(output); + } + + /* currently all EDE options fit into one byte, so skip the first */ + ede = data[1]; + + switch (ede) { + case LDNS_EDE_OTHER: + ldns_buffer_printf(output, " 0 (Other): "); + break; + case LDNS_EDE_UNSUPPORTED_DNSKEY_ALG: + ldns_buffer_printf(output, "1 (Unsupported DNSKEY Algorithm)"); + break; + case LDNS_EDE_UNSUPPORTED_DS_DIGEST: + ldns_buffer_printf(output, " 2 (Unsupported DS Digest type)"); + break; + case LDNS_EDE_STALE_ANSWER: + ldns_buffer_printf(output, " 3 (Stale Answer)"); + break; + case LDNS_EDE_FORGED_ANSWER: + ldns_buffer_printf(output, " 4 (Forged Answer)"); + break; + case LDNS_EDE_DNSSEC_INDETERMINATE: + ldns_buffer_printf(output, " 5 (DNSSEC Indeterminate)"); + break; + case LDNS_EDE_DNSSEC_BOGUS: + ldns_buffer_printf(output, " 6 (DNSSEC Bogus)"); + break; + case LDNS_EDE_SIGNATURE_EXPIRED: + ldns_buffer_printf(output, " 7 (Signature Expired)"); + break; + case LDNS_EDE_SIGNATURE_NOT_YET_VALID: + ldns_buffer_printf(output, " 8 (Signature Not Yet Valid)"); + break; + case LDNS_EDE_DNSKEY_MISSING: + ldns_buffer_printf(output, " 9 (DNSKEY Missing)"); + break; + case LDNS_EDE_RRSIGS_MISSING: + ldns_buffer_printf(output, " 10 (RRSIGs Missing)"); + break; + case LDNS_EDE_NO_ZONE_KEY_BIT_SET: + ldns_buffer_printf(output, " 11 (No Zone Key Bit Set)"); + break; + case LDNS_EDE_NSEC_MISSING: + ldns_buffer_printf(output, " 12 (NSEC Missing)"); + break; + case LDNS_EDE_CACHED_ERROR: + ldns_buffer_printf(output, " 13 (Cached Error)"); + break; + case LDNS_EDE_NOT_READY: + ldns_buffer_printf(output, " 14 (Not Ready)"); + break; + case LDNS_EDE_BLOCKED: + ldns_buffer_printf(output, " 15 (Blocked)"); + break; + case LDNS_EDE_CENSORED: + ldns_buffer_printf(output, " 16 (Censored)"); + break; + case LDNS_EDE_FILTERED: + ldns_buffer_printf(output, " 17 (Filtered)"); + break; + case LDNS_EDE_PROHIBITED: + ldns_buffer_printf(output, " 18 (Prohibited)"); + break; + case LDNS_EDE_STALE_NXDOMAIN_ANSWER: + ldns_buffer_printf(output, " 19 (NXDOMAIN Answer)"); + break; + case LDNS_EDE_NOT_AUTHORITATIVE: + ldns_buffer_printf(output, " 20 (Not Authoritative)"); + break; + case LDNS_EDE_NOT_SUPPORTED: + ldns_buffer_printf(output, " 21 (Not Supported)"); + break; + case LDNS_EDE_NO_REACHABLE_AUTHORITY: + ldns_buffer_printf(output, " 22 (No Reachable Authority)"); + break; + case LDNS_EDE_NETWORK_ERROR: + ldns_buffer_printf(output, " 23 (Network Error)"); + break; + case LDNS_EDE_INVALID_DATA: + ldns_buffer_printf(output, " 24 (Invalid Data)"); + break; + default: + ldns_buffer_printf(output, " %02x", data[0]); + ldns_buffer_printf(output, " %02x:", data[1]); + break; + } + + /* skip the EDE code in the output */ + data += 2; + len -= 2; + + if (len > 2) { + /* format the hex bytes */ + ldns_buffer_printf(output, ":"); + for (i = 0; i < len; i++) { + ldns_buffer_printf(output, " %02x", data[i]); + } + + /* format the human-readable string */ + ldns_buffer_printf(output, " ("); + ldns_characters2buffer_str(output, len, data); + ldns_buffer_printf(output, ")\n"); + } + + return ldns_buffer_status(output); +} + +static ldns_status +ldns_edns_client_tag2buffer_str(ldns_buffer* output, uint8_t* data, size_t len) +{ + ldns_buffer_printf(output, "; CLIENT-TAG:"); + ldns_edns_hex_data2buffer_str(output, data, len); + + return ldns_buffer_status(output); +} + +static ldns_status //@TODO change static? +ldns_edns_list2buffer_str(ldns_buffer *output, ldns_edns_option_list* edns_list) +{ + size_t count = ldns_edns_option_list_get_count(edns_list); + size_t i, size; + uint8_t* data; + + // @TODO parse malformed? of in packet.c:ldns_pkt_edns_option_list() ? + + for (i = 0; i < count; i++) { + ldns_edns_option_code code; + ldns_edns_option* edns = ldns_edns_option_list_get_option(edns_list, i); + + code = ldns_edns_get_code(edns); + size = ldns_edns_get_size(edns); + data = ldns_edns_get_data(edns); + + switch(code) { + case LDNS_EDNS_LLQ: + ldns_edns_llq2buffer_str(output, data, size); + break; + case LDNS_EDNS_UL: + ldns_edns_ul2buffer_str(output, data, size); + break; + case LDNS_EDNS_NSID: + ldns_edns_nsid2buffer_str(output, data, size); + break; + case LDNS_EDNS_DAU: + ldns_edns_dau2buffer_str(output, data, size); + break; + case LDNS_EDNS_DHU: + ldns_edns_dhu2buffer_str(output, data, size); + break; + case LDNS_EDNS_N3U: + ldns_edns_d3u2buffer_str(output, data, size); + break; + case LDNS_EDNS_CLIENT_SUBNET: + ldns_edns_subnet2buffer_str(output, data, size); + break; + case LDNS_EDNS_KEEPALIVE: + ldns_edns_keepalive2buffer_str(output, data, size); + break; + case LDNS_EDNS_PADDING: + ldns_edns_padding2buffer_str(output, data, size); + break; + case LDNS_EDNS_EDE: + ldns_edns_ede2buffer_str(output, data, size); + break; + case LDNS_EDNS_CLIENT_TAG: + ldns_edns_client_tag2buffer_str(output, data, size); + break; + default: + ldns_buffer_printf(output, "; OPT=%d:", code); + ldns_edns_hex_data2buffer_str(output, data, size); + break; + } + } + + return ldns_buffer_status(output); } @@ -2383,7 +2671,7 @@ ldns_pkt2buffer_str_fmt(ldns_buffer *output, * and add them to the list */ edns_list = ldns_pkt_edns_option_list(pkt); - ldns_edns_option_list2buffer_str(output, edns_list); + ldns_edns_list2buffer_str(output, edns_list); // (void)ldns_rdf2buffer_str(output,