]> granicus.if.org Git - pdns/commitdiff
sdig correctly shows XPF record from bindbackend for v4; v6 is broken
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Tue, 25 Jul 2017 11:38:42 +0000 (13:38 +0200)
committerPieter Lexis <pieter.lexis@powerdns.com>
Mon, 22 Jan 2018 21:57:34 +0000 (22:57 +0100)
pdns/dnsparser.hh
pdns/dnsrecords.cc
pdns/dnsrecords.hh
pdns/dnswriter.hh
pdns/iputils.hh
pdns/qtype.hh
pdns/rcpgenerator.cc
pdns/rcpgenerator.hh
regression-tests/zones/example.com

index 2df65e2ab17cbc1e7020e8850004d3dc1839ab83..9ddc942ab568e28357900003d16423dd468be675 100644 (file)
@@ -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);
index 6bce4901300adf8897d94a9d2198bc9aa22762bb..0b7e92d54828c081eb12e123ecc06598400ecb1d 100644 (file)
@@ -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();
index f1154b77dbf44cecca0e756db918ce50530a409a..72afd9a6c2041884c565c498a17c5b36ca5ce8c8 100644 (file)
@@ -28,6 +28,7 @@
 #include <set>
 #include <bitset>
 #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:
index 0227b920f0cabd3a77704e9913c69411cae9209e..64b1e35eaf14723670e77b6525195226b98e04fc 100644 (file)
@@ -28,6 +28,7 @@
 #include "dns.hh"
 #include "dnsname.hh"
 #include "namespaces.hh"
+#include "iputils.hh"
 #include <arpa/inet.h>
 
 
@@ -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);
index b6cf7b4bd6213802a8487fb1c80d6978231ea55a..9fb7fa3466407334a085d7b36cc74a81b18346ed 100644 (file)
@@ -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
index 5d3577fcfda5ebe33771ce83f61c2f1740c8a0f5..dccde072d24cc772bf3ec12b195459a660873fdb 100644 (file)
@@ -125,7 +125,8 @@ public:
     CAA=257,
     DLV=32769,
     ADDR=65400,
-    ALIAS=65401
+    ALIAS=65401,
+    XPF=65422
   };
 
   typedef pair<string,uint16_t> namenum;
@@ -217,6 +218,7 @@ private:
       qtype_insert("DLV", 32769);
       qtype_insert("ADDR", 65400);
       qtype_insert("ALIAS", 65401);
+      qtype_insert("XPF", 65422);
     }
   } initializer;
 
index 359009b1016cbc4ffaff2d4d327445143a65bceb..2797955defc1d473db66f603a411bc33cf50a23e 100644 (file)
@@ -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())
index 6fb3abf744b962d1677f4ee656e14507a724429a..efb409397266a7c31fd760e7a78510b6401418ea 100644 (file)
@@ -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);
 
index c73d392e6c903d0f3b1b9b9f5fa01a72f3df86fc..be673aaafcd213af9f0d53c89b590f00f5015017 100644 (file)
@@ -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