]> granicus.if.org Git - pdns/commitdiff
Add dnspcap2calidns, to convert PCAP to the calidns format
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 2 May 2018 20:49:31 +0000 (21:49 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 2 May 2018 20:49:31 +0000 (21:49 +0100)
pdns/Makefile.am
pdns/dnspcap2calidns.cc [new file with mode: 0644]

index 75eda10e44ccb11cd6b2a901f5f0f8a0bf28787d..641743705e55a202a1568e5da813e9911728ca2c 100644 (file)
@@ -88,6 +88,7 @@ bin_PROGRAMS = \
 if TOOLS
 bin_PROGRAMS += \
        dnsgram \
+       dnspcap2calidns \
        dnsreplay \
        dnsscan \
        dnsscope \
@@ -120,6 +121,7 @@ EXTRA_PROGRAMS = \
        dnsbulktest \
        dnsdemog \
        dnsgram \
+       dnspcap2calidns \
        dnsreplay \
        dnsscan \
        dnsscope \
@@ -1149,6 +1151,38 @@ dnsdemog_LDFLAGS = \
 dnsdemog_LDADD = \
        $(LIBCRYPTO_LIBS)
 
+dnspcap2calidns_SOURCES = \
+       base32.cc \
+       base64.cc base64.hh \
+       dnslabeltext.cc \
+       dnsname.cc dnsname.hh \
+       dnsparser.cc dnsparser.hh \
+       dnspcap.cc dnspcap.hh \
+       dnspcap2calidns.cc \
+       dnsrecords.cc \
+       dnswriter.cc dnswriter.hh \
+       ednsoptions.cc ednsoptions.hh \
+       ednssubnet.cc ednssubnet.hh \
+       iputils.cc \
+       logger.cc \
+       misc.cc \
+       nsecrecords.cc \
+       qtype.cc \
+       rcpgenerator.cc rcpgenerator.hh \
+       sillyrecords.cc \
+       statbag.cc \
+       unix_utility.cc \
+       utility.hh
+
+dnspcap2calidns_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       $(LIBCRYPTO_LDFLAGS) \
+       $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
+
+dnspcap2calidns_LDADD = \
+       $(LIBCRYPTO_LIBS) \
+       $(BOOST_PROGRAM_OPTIONS_LIBS)
+
 if HAVE_PROTOBUF
 if HAVE_PROTOC
 bin_PROGRAMS += dnspcap2protobuf
diff --git a/pdns/dnspcap2calidns.cc b/pdns/dnspcap2calidns.cc
new file mode 100644 (file)
index 0000000..c64b1ae
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fstream>
+
+#include "iputils.hh"
+#include "misc.hh"
+#include "dns.hh"
+#include "dnspcap.hh"
+#include "dnsparser.hh"
+
+#include "statbag.hh"
+StatBag S;
+
+static void usage()
+{
+  cerr<<"This program reads DNS queries from a PCAP file and outputs them in the calidns format."<<endl;
+  cerr<<"Usage: dnspcap2calidns PCAPFILE OUTFILE"<<endl;
+}
+
+int main(int argc, char **argv)
+{
+  try {
+    for(int n=1 ; n < argc; ++n) {
+      if ((string) argv[n] == "--help") {
+        usage();
+        return EXIT_SUCCESS;
+      }
+
+      if ((string) argv[n] == "--version") {
+        cerr<<"dnspcap2calidns "<<VERSION<<endl;
+        return EXIT_SUCCESS;
+      }
+    }
+
+    if(argc < 3) {
+      usage();
+      exit(EXIT_FAILURE);
+    }
+
+
+    PcapPacketReader pr(argv[1]);
+    ofstream fp(argv[2]);
+
+    if (!fp) {
+      cerr<<"Error opening output file "<<argv[2]<<": "<<strerror(errno)<<endl;
+      exit(EXIT_FAILURE);
+    }
+
+    try {
+      while (pr.getUDPPacket()) {
+        if (pr.d_len < sizeof(dnsheader)) {
+          continue;
+        }
+
+        const dnsheader* dh=reinterpret_cast<const dnsheader*>(pr.d_payload);
+        if (!dh->qdcount) {
+          continue;
+        }
+
+        if (!dh->rd) {
+          continue;
+        }
+
+        if (dh->qr) {
+          continue;
+        }
+
+        uint16_t qtype, qclass;
+        DNSName qname;
+        try {
+          qname=DNSName(reinterpret_cast<const char*>(pr.d_payload), pr.d_len, sizeof(dnsheader), false, &qtype, &qclass);
+        }
+        catch(const std::exception& e) {
+          cerr<<"Error while parsing qname: "<<e.what()<<endl;
+          continue;
+        }
+
+        const ComboAddress requestor = pr.getSource();
+
+        fp << qname << " " << QType(qtype).getName() << " " << requestor.toString() << endl;
+      }
+    }
+    catch (const std::exception& e) {
+      cerr<<"Error while parsing the PCAP file: "<<e.what()<<endl;
+      fp.close();
+      exit(EXIT_FAILURE);
+    }
+
+    fp.flush();
+    fp.close();
+  }
+  catch(const std::exception& e) {
+    cerr<<"Error opening PCAP file: "<<e.what()<<endl;
+    exit(EXIT_FAILURE);
+  }
+
+  return EXIT_SUCCESS;
+}