From: Arran Cudbard-Bell Date: Sun, 18 Feb 2024 20:13:44 +0000 (-0600) Subject: Print DNS decode failure reason as a string X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=10aeae039521562eafe3293bcf904f2890171aa5;p=thirdparty%2Ffreeradius-server.git Print DNS decode failure reason as a string --- diff --git a/src/listen/dns/proto_dns_udp.c b/src/listen/dns/proto_dns_udp.c index 5e9241ac2c9..000ce7252f6 100644 --- a/src/listen/dns/proto_dns_udp.c +++ b/src/listen/dns/proto_dns_udp.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -161,7 +162,8 @@ static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time packet = (fr_dns_packet_t *) buffer; if (!fr_dns_packet_ok(buffer, packet_len, true, &reason)) { - RATE_LIMIT_GLOBAL(WARN, "Invalid DNS packet failed with reason %d - ignoring", reason); + RATE_LIMIT_GLOBAL(WARN, "Ignoring invalid DNS packet - %s", + fr_table_str_by_value(fr_dns_reason_fail_table, reason, "unknown")); return 0; } diff --git a/src/protocols/dns/base.c b/src/protocols/dns/base.c index 7f361a87bff..2ca99035fce 100644 --- a/src/protocols/dns/base.c +++ b/src/protocols/dns/base.c @@ -73,7 +73,7 @@ fr_dict_attr_autoload_t dns_dict_attr[] = { [FR_DNS_STATEFUL_OP] = "stateful-operations", }; -#define DECODE_FAIL(_reason) if (reason) *reason = DECODE_FAIL_ ## _reason +#define DECODE_FAIL(_reason) if (reason) *reason = FR_DNS_DECODE_FAIL_ ## _reason static bool fr_dns_tlv_ok(uint8_t const *p, uint8_t const *end, fr_dns_decode_fail_t *reason) { diff --git a/src/protocols/dns/decode.c b/src/protocols/dns/decode.c index 0a0635c8084..218693a62d0 100644 --- a/src/protocols/dns/decode.c +++ b/src/protocols/dns/decode.c @@ -384,33 +384,33 @@ static int decode_test_ctx(void **out, TALLOC_CTX *ctx) return 0; } -static fr_table_num_ordered_t reason_fail_table[] = { - { L("none"), DECODE_FAIL_NONE }, - { L("packet is smaller than DNS header"), DECODE_FAIL_MIN_LENGTH_PACKET }, - { L("packet is larger than 65535"), DECODE_FAIL_MAX_LENGTH_PACKET }, - { L("expected query / answer, got answer / query"), DECODE_FAIL_UNEXPECTED }, - { L("no 'questions' in query packet"), DECODE_FAIL_NO_QUESTIONS }, - { L("unexprected answers in query packet"), DECODE_FAIL_ANSWERS_IN_QUESTION }, - { L("unexpected NS records in query packet"), DECODE_FAIL_NS_IN_QUESTION }, - { L("invalid label for resource record"), DECODE_FAIL_INVALID_RR_LABEL }, - { L("missing resource record header"), DECODE_FAIL_MISSING_RR_HEADER }, - { L("missing resource record length field"), DECODE_FAIL_MISSING_RR_LEN }, - { L("resource record length field is zero"), DECODE_FAIL_ZERO_RR_LEN }, - { L("resource record length overflows the packet"), DECODE_FAIL_RR_OVERFLOWS_PACKET }, - { L("more resource records than indicated in header"), DECODE_FAIL_TOO_MANY_RRS }, - { L("fewer resource records than indicated in header"), DECODE_FAIL_TOO_FEW_RRS }, - { L("pointer overflows packet"), DECODE_FAIL_POINTER_OVERFLOWS_PACKET }, - { L("pointer points to packet header"), DECODE_FAIL_POINTER_TO_HEADER }, - { L("pointer does not point to a label"), DECODE_FAIL_POINTER_TO_NON_LABEL }, - { L("pointer creates a loop"), DECODE_FAIL_POINTER_LOOPS }, - { L("invalid pointer"), DECODE_FAIL_INVALID_POINTER }, - { L("label overflows the packet"), DECODE_FAIL_LABEL_OVERFLOWS_PACKET }, - { L("too many characters in label"), DECODE_FAIL_LABEL_TOO_LONG }, - { L("query record header is missing"), DECODE_FAIL_MISSING_QD_HEADER }, - { L("missing TLV header in OPT RR"), DECODE_FAIL_MISSING_TLV_HEADER }, - { L("TLV overflows enclosing RR"), DECODE_FAIL_TLV_OVERFLOWS_RR }, +fr_table_num_ordered_t fr_dns_reason_fail_table[] = { + { L("none"), FR_DNS_DECODE_FAIL_NONE }, + { L("packet is smaller than DNS header"), FR_DNS_DECODE_FAIL_MIN_LENGTH_PACKET }, + { L("packet is larger than 65535"), FR_DNS_DECODE_FAIL_MAX_LENGTH_PACKET }, + { L("expected query / answer, got answer / query"), FR_DNS_DECODE_FAIL_UNEXPECTED }, + { L("no 'questions' in query packet"), FR_DNS_DECODE_FAIL_NO_QUESTIONS }, + { L("unexprected answers in query packet"), FR_DNS_DECODE_FAIL_ANSWERS_IN_QUESTION }, + { L("unexpected NS records in query packet"), FR_DNS_DECODE_FAIL_NS_IN_QUESTION }, + { L("invalid label for resource record"), FR_DNS_DECODE_FAIL_INVALID_RR_LABEL }, + { L("missing resource record header"), FR_DNS_DECODE_FAIL_MISSING_RR_HEADER }, + { L("missing resource record length field"), FR_DNS_DECODE_FAIL_MISSING_RR_LEN }, + { L("resource record length field is zero"), FR_DNS_DECODE_FAIL_ZERO_RR_LEN }, + { L("resource record length overflows the packet"), FR_DNS_DECODE_FAIL_RR_OVERFLOWS_PACKET }, + { L("more resource records than indicated in header"), FR_DNS_DECODE_FAIL_TOO_MANY_RRS }, + { L("fewer resource records than indicated in header"), FR_DNS_DECODE_FAIL_TOO_FEW_RRS }, + { L("pointer overflows packet"), FR_DNS_DECODE_FAIL_POINTER_OVERFLOWS_PACKET }, + { L("pointer points to packet header"), FR_DNS_DECODE_FAIL_POINTER_TO_HEADER }, + { L("pointer does not point to a label"), FR_DNS_DECODE_FAIL_POINTER_TO_NON_LABEL }, + { L("pointer creates a loop"), FR_DNS_DECODE_FAIL_POINTER_LOOPS }, + { L("invalid pointer"), FR_DNS_DECODE_FAIL_INVALID_POINTER }, + { L("label overflows the packet"), FR_DNS_DECODE_FAIL_LABEL_OVERFLOWS_PACKET }, + { L("too many characters in label"), FR_DNS_DECODE_FAIL_LABEL_TOO_LONG }, + { L("query record header is missing"), FR_DNS_DECODE_FAIL_MISSING_QD_HEADER }, + { L("missing TLV header in OPT RR"), FR_DNS_DECODE_FAIL_MISSING_TLV_HEADER }, + { L("TLV overflows enclosing RR"), FR_DNS_DECODE_FAIL_TLV_OVERFLOWS_RR }, }; -static size_t reason_fail_table_len = NUM_ELEMENTS(reason_fail_table); +size_t fr_dns_reason_fail_table_len = NUM_ELEMENTS(fr_dns_reason_fail_table); static ssize_t decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx) { @@ -423,12 +423,12 @@ static ssize_t decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const * Allow queries or answers */ if (!fr_dns_packet_ok(data, data_len, true, &reason)) { - if (reason != DECODE_FAIL_UNEXPECTED) goto fail; + if (reason != FR_DNS_DECODE_FAIL_UNEXPECTED) goto fail; if (!fr_dns_packet_ok(data, data_len, false, &reason)) { fail: fr_strerror_printf("DNS packet malformed - %s", - fr_table_str_by_value(reason_fail_table, reason, "")); + fr_table_str_by_value(fr_dns_reason_fail_table, reason, "")); return -1; } } diff --git a/src/protocols/dns/dns.h b/src/protocols/dns/dns.h index 2e4b952ae3a..be44b42ef7a 100644 --- a/src/protocols/dns/dns.h +++ b/src/protocols/dns/dns.h @@ -109,38 +109,40 @@ typedef enum { } fr_dns_packet_code_t; typedef enum { - DECODE_FAIL_NONE = 0, - DECODE_FAIL_MIN_LENGTH_PACKET, - DECODE_FAIL_MAX_LENGTH_PACKET, - DECODE_FAIL_UNEXPECTED, - DECODE_FAIL_NO_QUESTIONS, - DECODE_FAIL_ANSWERS_IN_QUESTION, - DECODE_FAIL_NS_IN_QUESTION, - DECODE_FAIL_INVALID_RR_LABEL, - DECODE_FAIL_MISSING_RR_HEADER, - DECODE_FAIL_MISSING_RR_LEN, - DECODE_FAIL_ZERO_RR_LEN, - DECODE_FAIL_RR_OVERFLOWS_PACKET, - DECODE_FAIL_TOO_MANY_RRS, - DECODE_FAIL_TOO_FEW_RRS, - DECODE_FAIL_POINTER_TO_NON_LABEL, - DECODE_FAIL_POINTER_OVERFLOWS_PACKET, - DECODE_FAIL_POINTER_TO_HEADER, - DECODE_FAIL_POINTER_LOOPS, - DECODE_FAIL_INVALID_POINTER, - DECODE_FAIL_LABEL_OVERFLOWS_PACKET, - DECODE_FAIL_LABEL_TOO_LONG, - DECODE_FAIL_MISSING_QD_HEADER, - DECODE_FAIL_MISSING_TLV_HEADER, - DECODE_FAIL_TLV_OVERFLOWS_RR, - DECODE_FAIL_MAX + FR_DNS_DECODE_FAIL_NONE = 0, + FR_DNS_DECODE_FAIL_MIN_LENGTH_PACKET, + FR_DNS_DECODE_FAIL_MAX_LENGTH_PACKET, + FR_DNS_DECODE_FAIL_UNEXPECTED, + FR_DNS_DECODE_FAIL_NO_QUESTIONS, + FR_DNS_DECODE_FAIL_ANSWERS_IN_QUESTION, + FR_DNS_DECODE_FAIL_NS_IN_QUESTION, + FR_DNS_DECODE_FAIL_INVALID_RR_LABEL, + FR_DNS_DECODE_FAIL_MISSING_RR_HEADER, + FR_DNS_DECODE_FAIL_MISSING_RR_LEN, + FR_DNS_DECODE_FAIL_ZERO_RR_LEN, + FR_DNS_DECODE_FAIL_RR_OVERFLOWS_PACKET, + FR_DNS_DECODE_FAIL_TOO_MANY_RRS, + FR_DNS_DECODE_FAIL_TOO_FEW_RRS, + FR_DNS_DECODE_FAIL_POINTER_TO_NON_LABEL, + FR_DNS_DECODE_FAIL_POINTER_OVERFLOWS_PACKET, + FR_DNS_DECODE_FAIL_POINTER_TO_HEADER, + FR_DNS_DECODE_FAIL_POINTER_LOOPS, + FR_DNS_DECODE_FAIL_INVALID_POINTER, + FR_DNS_DECODE_FAIL_LABEL_OVERFLOWS_PACKET, + FR_DNS_DECODE_FAIL_LABEL_TOO_LONG, + FR_DNS_DECODE_FAIL_MISSING_QD_HEADER, + FR_DNS_DECODE_FAIL_MISSING_TLV_HEADER, + FR_DNS_DECODE_FAIL_TLV_OVERFLOWS_RR, + FR_DNS_DECODE_FAIL_MAX } fr_dns_decode_fail_t; #define FR_DNS_PACKET_CODE_VALID(_code) (((_code) < FR_DNS_CODE_MAX) || (((_code & 0x10) != 0) && ((_code & ~0x10) < FR_DNS_CODE_MAX))) #define DNS_HDR_LEN (12) +extern fr_table_num_ordered_t fr_dns_reason_fail_table[]; extern char const *fr_dns_packet_names[FR_DNS_CODE_MAX]; +extern size_t fr_dns_reason_fail_table_len; bool fr_dns_packet_ok(uint8_t const *packet, size_t packet_len, bool query, fr_dns_decode_fail_t *reason);