From 92e3654a088c6c75b8e8e8caf7b823cc388b1e2a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Sat, 23 Sep 2023 00:30:34 +0200 Subject: [PATCH] sdig: add rudimentary EDE output --- pdns/Makefile.am | 1 + pdns/ednsextendederror.cc | 65 +++++++++++++++++++++++++ pdns/ednsextendederror.hh | 66 +++++++++++++++++++++++++ pdns/recursordist/ednsextendederror.cc | 66 +------------------------ pdns/recursordist/ednsextendederror.hh | 67 +------------------------- pdns/sdig.cc | 6 +++ 6 files changed, 140 insertions(+), 131 deletions(-) create mode 100644 pdns/ednsextendederror.cc create mode 100644 pdns/ednsextendederror.hh mode change 100644 => 120000 pdns/recursordist/ednsextendederror.cc mode change 100644 => 120000 pdns/recursordist/ednsextendederror.hh diff --git a/pdns/Makefile.am b/pdns/Makefile.am index b5eef7a5444a..b22bcfdc3cc8 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -554,6 +554,7 @@ sdig_SOURCES = \ dnsrecords.cc \ dnswriter.cc dnswriter.hh \ dolog.hh \ + ednsextendederror.cc ednsextendederror.hh \ ednssubnet.cc iputils.cc \ libssl.cc libssl.hh \ logger.cc \ diff --git a/pdns/ednsextendederror.cc b/pdns/ednsextendederror.cc new file mode 100644 index 000000000000..5010e3dba52d --- /dev/null +++ b/pdns/ednsextendederror.cc @@ -0,0 +1,65 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include + +#include "ednsextendederror.hh" + +static bool getEDNSExtendedErrorOptFromStringView(const std::string_view& option, EDNSExtendedError& eee) +{ + if (option.size() < sizeof(uint16_t)) { + return false; + } + eee.infoCode = static_cast(option.at(0)) * 256 + static_cast(option.at(1)); + + if (option.size() > sizeof(uint16_t)) { + eee.extraText = std::string(&option.at(sizeof(uint16_t)), option.size() - sizeof(uint16_t)); + } + + return true; +} + +bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee) +{ + return getEDNSExtendedErrorOptFromStringView(std::string_view(option), eee); +} + +bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee) +{ + return getEDNSExtendedErrorOptFromStringView(std::string_view(option, len), eee); +} + +string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee) +{ + if (eee.extraText.size() > static_cast(std::numeric_limits::max() - 2)) { + throw std::runtime_error("Trying to create an EDNS Extended Error option with an extra text of size " + std::to_string(eee.extraText.size())); + } + + string ret; + ret.reserve(sizeof(uint16_t) + eee.extraText.size()); + ret.resize(sizeof(uint16_t)); + + ret[0] = static_cast(static_cast(eee.infoCode) / 256); + ret[1] = static_cast(static_cast(eee.infoCode) % 256); + ret.append(eee.extraText); + + return ret; +} diff --git a/pdns/ednsextendederror.hh b/pdns/ednsextendederror.hh new file mode 100644 index 000000000000..5b264fcf69b6 --- /dev/null +++ b/pdns/ednsextendederror.hh @@ -0,0 +1,66 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once +#include "namespaces.hh" + +struct EDNSExtendedError +{ + enum class code : uint16_t + { + Other = 0, + UnsupportedDNSKEYAlgorithm = 1, + UnsupportedDSDigestType = 2, + StaleAnswer = 3, + ForgedAnswer = 4, + DNSSECIndeterminate = 5, + DNSSECBogus = 6, + SignatureExpired = 7, + SignatureNotYetValid = 8, + DNSKEYMissing = 9, + RRSIGsMissing = 10, + NoZoneKeyBitSet = 11, + NSECMissing = 12, + CachedError = 13, + NotReady = 14, + Blocked = 15, + Censored = 16, + Filtered = 17, + Prohibited = 18, + StaleNXDOMAINAnswer = 19, + NotAuthoritative = 20, + NotSupported = 21, + NoReachableAuthority = 22, + NetworkError = 23, + InvalidData = 24, + SignatureExpiredBeforeValid = 25, + TooEarly = 26, + UnsupportedNSEC3IterationsValue = 27, + UnableToConformToPolicy = 28, + Synthesized = 29, + }; + uint16_t infoCode; + std::string extraText; +}; + +bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee); +bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee); +string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee); diff --git a/pdns/recursordist/ednsextendederror.cc b/pdns/recursordist/ednsextendederror.cc deleted file mode 100644 index 5010e3dba52d..000000000000 --- a/pdns/recursordist/ednsextendederror.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include - -#include "ednsextendederror.hh" - -static bool getEDNSExtendedErrorOptFromStringView(const std::string_view& option, EDNSExtendedError& eee) -{ - if (option.size() < sizeof(uint16_t)) { - return false; - } - eee.infoCode = static_cast(option.at(0)) * 256 + static_cast(option.at(1)); - - if (option.size() > sizeof(uint16_t)) { - eee.extraText = std::string(&option.at(sizeof(uint16_t)), option.size() - sizeof(uint16_t)); - } - - return true; -} - -bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee) -{ - return getEDNSExtendedErrorOptFromStringView(std::string_view(option), eee); -} - -bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee) -{ - return getEDNSExtendedErrorOptFromStringView(std::string_view(option, len), eee); -} - -string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee) -{ - if (eee.extraText.size() > static_cast(std::numeric_limits::max() - 2)) { - throw std::runtime_error("Trying to create an EDNS Extended Error option with an extra text of size " + std::to_string(eee.extraText.size())); - } - - string ret; - ret.reserve(sizeof(uint16_t) + eee.extraText.size()); - ret.resize(sizeof(uint16_t)); - - ret[0] = static_cast(static_cast(eee.infoCode) / 256); - ret[1] = static_cast(static_cast(eee.infoCode) % 256); - ret.append(eee.extraText); - - return ret; -} diff --git a/pdns/recursordist/ednsextendederror.cc b/pdns/recursordist/ednsextendederror.cc new file mode 120000 index 000000000000..4f6ced0eb166 --- /dev/null +++ b/pdns/recursordist/ednsextendederror.cc @@ -0,0 +1 @@ +../ednsextendederror.cc \ No newline at end of file diff --git a/pdns/recursordist/ednsextendederror.hh b/pdns/recursordist/ednsextendederror.hh deleted file mode 100644 index 5b264fcf69b6..000000000000 --- a/pdns/recursordist/ednsextendederror.hh +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#pragma once -#include "namespaces.hh" - -struct EDNSExtendedError -{ - enum class code : uint16_t - { - Other = 0, - UnsupportedDNSKEYAlgorithm = 1, - UnsupportedDSDigestType = 2, - StaleAnswer = 3, - ForgedAnswer = 4, - DNSSECIndeterminate = 5, - DNSSECBogus = 6, - SignatureExpired = 7, - SignatureNotYetValid = 8, - DNSKEYMissing = 9, - RRSIGsMissing = 10, - NoZoneKeyBitSet = 11, - NSECMissing = 12, - CachedError = 13, - NotReady = 14, - Blocked = 15, - Censored = 16, - Filtered = 17, - Prohibited = 18, - StaleNXDOMAINAnswer = 19, - NotAuthoritative = 20, - NotSupported = 21, - NoReachableAuthority = 22, - NetworkError = 23, - InvalidData = 24, - SignatureExpiredBeforeValid = 25, - TooEarly = 26, - UnsupportedNSEC3IterationsValue = 27, - UnableToConformToPolicy = 28, - Synthesized = 29, - }; - uint16_t infoCode; - std::string extraText; -}; - -bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee); -bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee); -string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee); diff --git a/pdns/recursordist/ednsextendederror.hh b/pdns/recursordist/ednsextendederror.hh new file mode 120000 index 000000000000..2e5eee192724 --- /dev/null +++ b/pdns/recursordist/ednsextendederror.hh @@ -0,0 +1 @@ +../ednsextendederror.hh \ No newline at end of file diff --git a/pdns/sdig.cc b/pdns/sdig.cc index 87b4f558e471..05bfc7d6e8e3 100644 --- a/pdns/sdig.cc +++ b/pdns/sdig.cc @@ -6,6 +6,7 @@ #include "dnswriter.hh" #include "ednsoptions.hh" #include "ednssubnet.hh" +#include "ednsextendederror.hh" #include "misc.hh" #include "proxy-protocol.hh" #include "sstuff.hh" @@ -185,6 +186,11 @@ static void printReply(const string& reply, bool showflags, bool hidesoadetails, } } else if (iter->first == EDNSOptionCode::PADDING) { cerr << "EDNS Padding size: " << (iter->second.size()) << endl; + } else if (iter->first == EDNSOptionCode::EXTENDEDERROR) { + EDNSExtendedError eee; + if (getEDNSExtendedErrorOptFromString(iter->second, eee)) { + cerr << "EDNS Extended Error response: " << eee.infoCode << "/" << eee.extraText << endl; + } } else { cerr << "Have unknown option " << (int)iter->first << endl; }