From e795f5909b706bec857eeeee33cf9a655820318a Mon Sep 17 00:00:00 2001 From: bert hubert Date: Wed, 4 May 2016 15:49:00 +0200 Subject: [PATCH] make dnswasher be able to wash multiple files, retaining consistent IP address mapping --- docs/manpages/dnswasher.1.md | 11 +++--- pdns/dnspcap.cc | 17 ++++++--- pdns/dnspcap.hh | 8 +++-- pdns/dnswasher.cc | 67 +++++++++++++++++++----------------- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/docs/manpages/dnswasher.1.md b/docs/manpages/dnswasher.1.md index 94c495629f..3becee814a 100644 --- a/docs/manpages/dnswasher.1.md +++ b/docs/manpages/dnswasher.1.md @@ -6,17 +6,20 @@ **dnswasher** - A PowerDNS nameserver debugging tool # SYNOPSIS -**dnswasher** *INFILE* *OUTFILE* +**dnswasher** *INFILE* [*INFILE*] *OUTFILE* # DESCRIPTION -dnswasher takes an *INFILE* in PCAP format and writes out *OUTFILE* also in -PCAP format, while obfuscating end-user IP addresses. +dnswasher takes one or more *INFILE*s in PCAP format and writes out +*OUTFILE* also in PCAP format, while obfuscating end-user IP addresses. This is useful to share data with third parties while attempting to protect the privacy of your users. +The INFILEs must be of identical PCAP type. + Please check the output of **dnswasher** to make sure no customer IP -addresses remain. +addresses remain. Also realize that sufficient data could allow +individuals to be re-identified based on the domain names they care about. # OPTIONS None diff --git a/pdns/dnspcap.cc b/pdns/dnspcap.cc index d69244e829..c9a4bd41ae 100644 --- a/pdns/dnspcap.cc +++ b/pdns/dnspcap.cc @@ -155,7 +155,12 @@ ComboAddress PcapPacketReader::getDest() const return ret; } -PcapPacketWriter::PcapPacketWriter(const string& fname, PcapPacketReader& ppr) : d_fname(fname), d_ppr(ppr) +PcapPacketWriter::PcapPacketWriter(const string& fname, const PcapPacketReader& ppr) : PcapPacketWriter(fname) +{ + setPPR(ppr); +} + +PcapPacketWriter::PcapPacketWriter(const string& fname) : d_fname(fname) { d_fp=fopen(fname.c_str(),"w"); if(!d_fp) @@ -163,14 +168,16 @@ PcapPacketWriter::PcapPacketWriter(const string& fname, PcapPacketReader& ppr) : int flags=fcntl(fileno(d_fp),F_GETFL,0); fcntl(fileno(d_fp), F_SETFL,flags&(~O_NONBLOCK)); // bsd needs this in stdin (??) - - fwrite(&ppr.d_pfh, 1, sizeof(ppr.d_pfh), d_fp); } void PcapPacketWriter::write() { - fwrite(&d_ppr.d_pheader, 1, sizeof(d_ppr.d_pheader), d_fp); - fwrite(d_ppr.d_buffer, 1, d_ppr.d_pheader.caplen, d_fp); + if(d_first) { + fwrite(&d_ppr->d_pfh, 1, sizeof(d_ppr->d_pfh), d_fp); + d_first=false; + } + fwrite(&d_ppr->d_pheader, 1, sizeof(d_ppr->d_pheader), d_fp); + fwrite(d_ppr->d_buffer, 1, d_ppr->d_pheader.caplen, d_fp); } PcapPacketWriter::~PcapPacketWriter() diff --git a/pdns/dnspcap.hh b/pdns/dnspcap.hh index d18b69a7f2..99365720e6 100644 --- a/pdns/dnspcap.hh +++ b/pdns/dnspcap.hh @@ -108,17 +108,19 @@ private: class PcapPacketWriter { public: - PcapPacketWriter(const string& fname, PcapPacketReader& ppr); + PcapPacketWriter(const string& fname, const PcapPacketReader& ppr); + PcapPacketWriter(const string& fname); void write(); - + void setPPR(const PcapPacketReader& ppr) { d_ppr = &ppr; } ~PcapPacketWriter(); private: string d_fname; - const PcapPacketReader& d_ppr; + const PcapPacketReader* d_ppr; FILE *d_fp; + bool d_first{true}; }; #endif // DNSPCAP_HH diff --git a/pdns/dnswasher.cc b/pdns/dnswasher.cc index c29c69d24e..6f79ee31f5 100644 --- a/pdns/dnswasher.cc +++ b/pdns/dnswasher.cc @@ -19,12 +19,10 @@ otherwise, obfuscate the response IP address #include "dnspcap.hh" #include "iputils.hh" -#include "namespaces.hh" #include "namespaces.hh" StatBag S; - class IPObfuscator { public: @@ -61,7 +59,7 @@ private: }; void usage() { - cerr<<"Syntax: dnswasher INFILE OUTFILE"<uh_dport)==53 || (ntohs(pr.d_udp->uh_sport)==53 && pr.d_len > sizeof(dnsheader))) { - dnsheader* dh=(dnsheader*)pr.d_payload; - - if (pr.d_ip->ip_v == 4){ - uint32_t *src=(uint32_t*)&pr.d_ip->ip_src; - uint32_t *dst=(uint32_t*)&pr.d_ip->ip_dst; - - if(dh->qr) - *dst=htonl(ipo.obf4(*dst)); - else - *src=htonl(ipo.obf4(*src)); - - pr.d_ip->ip_sum=0; - } else if (pr.d_ip->ip_v == 6) { - uint64_t *src=(uint64_t*)&pr.d_ip6->ip6_src; - uint64_t *dst=(uint64_t*)&pr.d_ip6->ip6_dst; - - if(dh->qr) - *dst=htobe64(ipo.obf6(*dst)); - else - *src=htobe64(ipo.obf6(*src)); + // 0 1 2 3 - argc == 4 + // dnswasher in1 in2 out + for(int n=1; n < argc -1; ++n) { + PcapPacketReader pr(argv[n]); + pw.setPPR(pr); + + while(pr.getUDPPacket()) { + if(ntohs(pr.d_udp->uh_dport)==53 || (ntohs(pr.d_udp->uh_sport)==53 && pr.d_len > sizeof(dnsheader))) { + dnsheader* dh=(dnsheader*)pr.d_payload; + + if (pr.d_ip->ip_v == 4){ + uint32_t *src=(uint32_t*)&pr.d_ip->ip_src; + uint32_t *dst=(uint32_t*)&pr.d_ip->ip_dst; + + if(dh->qr) + *dst=htonl(ipo.obf4(*dst)); + else + *src=htonl(ipo.obf4(*src)); + + pr.d_ip->ip_sum=0; + } else if (pr.d_ip->ip_v == 6) { + uint64_t *src=(uint64_t*)&pr.d_ip6->ip6_src; + uint64_t *dst=(uint64_t*)&pr.d_ip6->ip6_dst; + + if(dh->qr) + *dst=htobe64(ipo.obf6(*dst)); + else + *src=htobe64(ipo.obf6(*src)); + } + pw.write(); } - pw.write(); } + cerr<<"Saw "<