]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Print DNS decode failure reason as a string
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 18 Feb 2024 20:13:44 +0000 (14:13 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 18 Feb 2024 20:13:44 +0000 (14:13 -0600)
src/listen/dns/proto_dns_udp.c
src/protocols/dns/base.c
src/protocols/dns/decode.c
src/protocols/dns/dns.h

index 5e9241ac2c9e9fc075527eb58c8416d27e46acd8..000ce7252f6aa5acd1089eb83a54fe7578bfbf6f 100644 (file)
@@ -26,6 +26,7 @@
 #include <freeradius-devel/server/protocol.h>
 #include <freeradius-devel/server/cf_util.h>
 #include <freeradius-devel/util/udp.h>
+#include <freeradius-devel/util/table.h>
 #include <freeradius-devel/util/trie.h>
 #include <freeradius-devel/io/application.h>
 #include <freeradius-devel/io/listen.h>
@@ -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;
        }
 
index 7f361a87bffa92d7a3dd0c8f8da9c3a226af5da1..2ca99035fce31040b1868b418261ddfd6ca4686e 100644 (file)
@@ -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)
 {
index 0a0635c80841af57d5aadbe29f319fba630e75a1..218693a62d08117aaddcd56c87bfdaa4cef4860f 100644 (file)
@@ -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, "<INVALID>"));
+                                          fr_table_str_by_value(fr_dns_reason_fail_table, reason, "<INVALID>"));
                        return -1;
                }
        }
index 2e4b952ae3a18c05745dde5954297cfd32f3a22c..be44b42ef7a635f960ae6d653dca50ddc52d309f 100644 (file)
@@ -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);