From: Peter van Dijk Date: Tue, 25 Jul 2017 11:38:42 +0000 (+0200) Subject: sdig correctly shows XPF record from bindbackend for v4; v6 is broken X-Git-Tag: dnsdist-1.3.0~126^2~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f435263686bc51ca5624b545b1b5f3b8782b5be8;p=pdns sdig correctly shows XPF record from bindbackend for v4; v6 is broken --- diff --git a/pdns/dnsparser.hh b/pdns/dnsparser.hh index 2df65e2ab..9ddc942ab 100644 --- a/pdns/dnsparser.hh +++ b/pdns/dnsparser.hh @@ -37,6 +37,7 @@ #include "dnswriter.hh" #include "dnsname.hh" #include "pdnsexception.hh" +#include "iputils.hh" /** DNS records have three representations: 1) in the packet @@ -98,6 +99,20 @@ public: xfrBlob(val, 16); } + void xfrCAWithoutPort(uint8_t version, ComboAddress &val) { + string blob; + if (version == 4) xfrBlob(blob, 4); + else if (version == 6) xfrBlob(blob, 16); + else throw runtime_error("invalid IP protocol"); + val = makeComboAddressFromRaw(version, blob); + } + + void xfrCAPort(ComboAddress &val) { + uint16_t port; + xfr16BitInt(port); + val.sin4.sin_port = port; + } + void xfrTime(uint32_t& val) { xfr32BitInt(val); diff --git a/pdns/dnsrecords.cc b/pdns/dnsrecords.cc index 6bce49013..0b7e92d54 100644 --- a/pdns/dnsrecords.cc +++ b/pdns/dnsrecords.cc @@ -104,6 +104,7 @@ AAAARecordContent::AAAARecordContent(const ComboAddress& ca) } + ComboAddress ARecordContent::getCA(int port) const { ComboAddress ret; @@ -133,6 +134,13 @@ void ARecordContent::doRecordCheck(const DNSRecord& dr) boilerplate_conv(AAAA, QType::AAAA, conv.xfrIP6(d_ip6); ); +boilerplate_conv(XPF, QType::XPF, conv.xfr8BitInt(d_version); + conv.xfr8BitInt(d_protocol); + conv.xfrCAWithoutPort(d_version, d_src); + conv.xfrCAWithoutPort(d_version, d_dst); + conv.xfrCAPort(d_src); + conv.xfrCAPort(d_dst)); + boilerplate_conv(NS, QType::NS, conv.xfrName(d_content, true)); boilerplate_conv(PTR, QType::PTR, conv.xfrName(d_content, true)); boilerplate_conv(CNAME, QType::CNAME, conv.xfrName(d_content, true)); @@ -616,6 +624,7 @@ void reportOtherTypes() DLVRecordContent::report(); DNSRecordContent::regist(QClass::ANY, QType::TSIG, &TSIGRecordContent::make, &TSIGRecordContent::make, "TSIG"); DNSRecordContent::regist(QClass::ANY, QType::TKEY, &TKEYRecordContent::make, &TKEYRecordContent::make, "TKEY"); + XPFRecordContent::report(); //TSIGRecordContent::report(); OPTRecordContent::report(); EUI48RecordContent::report(); diff --git a/pdns/dnsrecords.hh b/pdns/dnsrecords.hh index f1154b77d..72afd9a6c 100644 --- a/pdns/dnsrecords.hh +++ b/pdns/dnsrecords.hh @@ -28,6 +28,7 @@ #include #include #include "namespaces.hh" +#include "iputils.hh" #define includeboilerplate(RNAME) RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \ RNAME##RecordContent(const string& zoneData); \ @@ -89,6 +90,18 @@ private: string d_ip6; // why?? }; +class XPFRecordContent : public DNSRecordContent +{ +public: + XPFRecordContent(uint8_t protocol, const ComboAddress& src, const ComboAddress& dst); + includeboilerplate(XPF); + + uint8_t d_version; + uint8_t d_protocol; + ComboAddress d_src; + ComboAddress d_dst; +}; + class MXRecordContent : public DNSRecordContent { public: diff --git a/pdns/dnswriter.hh b/pdns/dnswriter.hh index 0227b920f..64b1e35ea 100644 --- a/pdns/dnswriter.hh +++ b/pdns/dnswriter.hh @@ -28,6 +28,7 @@ #include "dns.hh" #include "dnsname.hh" #include "namespaces.hh" +#include "iputils.hh" #include @@ -100,6 +101,25 @@ public: { xfrBlob(val,16); } + + void xfrCAWithoutPort(uint8_t version, ComboAddress &val) + { + if (version == 4) xfrIP(val.sin4.sin_addr.s_addr); + else if (version == 6) { + string blob; + blob.assign((const char*)val.sin6.sin6_addr.s6_addr, 16); + xfrBlob(blob, 16); + } + else throw runtime_error("invalid IP protocol"); + } + + void xfrCAPort(ComboAddress &val) + { + uint16_t port; + port = val.sin4.sin_port; + xfr16BitInt(port); + } + void xfrTime(const uint32_t& val) { xfr32BitInt(val); diff --git a/pdns/iputils.hh b/pdns/iputils.hh index b6cf7b4bd..9fb7fa346 100644 --- a/pdns/iputils.hh +++ b/pdns/iputils.hh @@ -267,10 +267,11 @@ union ComboAddress { string toString() const { char host[1024]; - if(sin4.sin_family && !getnameinfo((struct sockaddr*) this, getSocklen(), host, sizeof(host),0, 0, NI_NUMERICHOST)) + int retval; + if(sin4.sin_family && !(retval = getnameinfo((struct sockaddr*) this, getSocklen(), host, sizeof(host),0, 0, NI_NUMERICHOST))) return host; else - return "invalid"; + return "invalid "+string(gai_strerror(retval)); } string toStringWithPort() const @@ -309,6 +310,20 @@ inline ComboAddress makeComboAddress(const string& str) return address; } +inline ComboAddress makeComboAddressFromRaw(uint8_t version, const string &str) +{ + ComboAddress address; + size_t len; + + if (version == 4) { len = 4; address.sin4.sin_family=AF_INET; } + else if (version == 6) { len = 16; address.sin4.sin_family=AF_INET6; } + else throw NetmaskException("invalid address family"); + if(str.size() != len) throw NetmaskException("invalid raw address length"); + memcpy(&address.sin4.sin_addr, str.c_str(), len); + + return address; +} + /** This class represents a netmask and can be queried to see if a certain IP address is matched by this mask */ class Netmask diff --git a/pdns/qtype.hh b/pdns/qtype.hh index 5d3577fcf..dccde072d 100644 --- a/pdns/qtype.hh +++ b/pdns/qtype.hh @@ -125,7 +125,8 @@ public: CAA=257, DLV=32769, ADDR=65400, - ALIAS=65401 + ALIAS=65401, + XPF=65422 }; typedef pair namenum; @@ -217,6 +218,7 @@ private: qtype_insert("DLV", 32769); qtype_insert("ADDR", 65400); qtype_insert("ALIAS", 65401); + qtype_insert("XPF", 65422); } } initializer; diff --git a/pdns/rcpgenerator.cc b/pdns/rcpgenerator.cc index 359009b10..2797955de 100644 --- a/pdns/rcpgenerator.cc +++ b/pdns/rcpgenerator.cc @@ -180,6 +180,28 @@ void RecordTextReader::xfrIP6(std::string &val) d_pos += len; } +void RecordTextReader::xfrCAWithoutPort(uint8_t version, ComboAddress &val) +{ + if (version == 4) { + uint32_t ip; + xfrIP(ip); + val = makeComboAddressFromRaw(4, string((const char*) &ip, 4)); + } + else if (version == 6) { + string ip; + xfrIP6(ip); + val = makeComboAddressFromRaw(6, ip); + } + else throw RecordTextException("invalid address family"); +} + +void RecordTextReader::xfrCAPort(ComboAddress &val) +{ + uint16_t port; + xfr16BitInt(port); + val.sin4.sin_port = port; +} + bool RecordTextReader::eof() { return d_pos==d_end; @@ -506,6 +528,21 @@ void RecordTextWriter::xfrIP6(const std::string& val) d_string += std::string(addrbuf); } +void RecordTextWriter::xfrCAWithoutPort(uint8_t version, ComboAddress &val) +{ + string ip = val.toString(); + + if(!d_string.empty()) + d_string.append(1,' '); + + d_string += ip; +} + +void RecordTextWriter::xfrCAPort(ComboAddress &val) +{ + xfr16BitInt(val.sin4.sin_port); +} + void RecordTextWriter::xfrTime(const uint32_t& val) { if(!d_string.empty()) diff --git a/pdns/rcpgenerator.hh b/pdns/rcpgenerator.hh index 6fb3abf74..efb409397 100644 --- a/pdns/rcpgenerator.hh +++ b/pdns/rcpgenerator.hh @@ -27,6 +27,7 @@ #include "namespaces.hh" #include "dnsname.hh" +#include "iputils.hh" class RecordTextException : public runtime_error { @@ -48,6 +49,8 @@ public: void xfrType(uint16_t& val); void xfrIP(uint32_t& val); void xfrIP6(std::string& val); + void xfrCAWithoutPort(uint8_t version, ComboAddress &val); + void xfrCAPort(ComboAddress &val); void xfrTime(uint32_t& val); void xfrName(DNSName& val, bool compress=false, bool noDot=false); @@ -82,6 +85,8 @@ public: void xfr8BitInt(const uint8_t& val); void xfrIP(const uint32_t& val); void xfrIP6(const std::string& val); + void xfrCAWithoutPort(uint8_t version, ComboAddress &val); + void xfrCAPort(ComboAddress &val); void xfrTime(const uint32_t& val); void xfrBase32HexBlob(const string& val); diff --git a/regression-tests/zones/example.com b/regression-tests/zones/example.com index c73d392e6..be673aaaf 100644 --- a/regression-tests/zones/example.com +++ b/regression-tests/zones/example.com @@ -20193,3 +20193,6 @@ rhs-at-expansion IN CNAME @ google-alias IN ALIAS google-public-dns-a.google.com. ; host-for-auto-ptr IN A 192.0.2.1 +; +xpf IN XPF 4 17 1.2.3.4 5.6.7.8 43707 52445 +xpf6 IN XPF 6 17 1:2:3:4:5:6:7:8 f:e:d:c:b:a:9:8 43707 52445 \ No newline at end of file