**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
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)
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()
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
#include "dnspcap.hh"
#include "iputils.hh"
-#include "namespaces.hh"
#include "namespaces.hh"
StatBag S;
-
class IPObfuscator
{
public:
};
void usage() {
- cerr<<"Syntax: dnswasher INFILE OUTFILE"<<endl;
+ cerr<<"Syntax: dnswasher INFILE1 [INFILE2..] OUTFILE"<<endl;
}
int main(int argc, char** argv)
}
}
- if(argc!=3) {
+ if(argc < 3) {
usage();
exit(1);
}
- PcapPacketReader pr(argv[1]);
- PcapPacketWriter pw(argv[2], pr);
+ PcapPacketWriter pw(argv[argc-1]);
IPObfuscator ipo;
-
- 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));
+ // 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 "<<pr.d_correctpackets<<" correct packets, "<<pr.d_runts<<" runts, "<< pr.d_oversized<<" oversize, "<<
+ pr.d_nonetheripudp<<" unknown encaps"<<endl;
}
- cerr<<"Saw "<<pr.d_correctpackets<<" correct packets, "<<pr.d_runts<<" runts, "<< pr.d_oversized<<" oversize, "<<
- pr.d_nonetheripudp<<" unknown encaps"<<endl;
}
catch(std::exception& e)
{