]>
Commit | Line | Data |
---|---|---|
ab06937b BH |
1 | /** two modes: |
2 | ||
3 | anonymizing and stripping tcpdumps of irrelevant traffic, so operators can send non-privacy violating dumps | |
4 | for analysis. | |
5 | ||
6 | algorithm: | |
7 | ||
9be88092 | 8 | read a packet, check if it has the QR bit set. |
ab06937b BH |
9 | |
10 | If the question has the response bit set, obfuscate the destination IP address | |
11 | otherwise, obfuscate the response IP address | |
ab06937b BH |
12 | */ |
13 | ||
11212b81 | 14 | |
870a0fe4 AT |
15 | #ifdef HAVE_CONFIG_H |
16 | #include "config.h" | |
17 | #endif | |
ab06937b | 18 | #include "statbag.hh" |
ab06937b BH |
19 | #include "dnspcap.hh" |
20 | ||
61b26744 | 21 | #include "namespaces.hh" |
10f4eea8 | 22 | #include "namespaces.hh" |
ab06937b BH |
23 | |
24 | StatBag S; | |
25 | ||
26 | ||
27 | class IPObfuscator | |
28 | { | |
29 | public: | |
cbb0be81 | 30 | IPObfuscator() : d_romap(d_ipmap), d_ro6map(d_ip6map), d_counter(0) |
ab06937b BH |
31 | { |
32 | } | |
33 | ||
cbb0be81 | 34 | uint32_t obf4(uint32_t orig) |
ab06937b BH |
35 | { |
36 | if(d_romap.count(orig)) | |
37 | return d_ipmap[orig]; | |
38 | else { | |
39 | return d_ipmap[orig]=d_counter++; | |
40 | } | |
41 | } | |
42 | ||
cbb0be81 PL |
43 | uint64_t obf6(uint64_t orig) |
44 | { | |
cbb0be81 PL |
45 | if(d_ro6map.count(orig)) |
46 | return d_ip6map[orig]; | |
47 | else { | |
48 | return d_ip6map[orig]=d_counter++; | |
49 | } | |
50 | } | |
51 | ||
ab06937b BH |
52 | private: |
53 | map<uint32_t, uint32_t> d_ipmap; | |
54 | const map<uint32_t, uint32_t>& d_romap; | |
cbb0be81 PL |
55 | // For IPv6 addresses |
56 | map<uint64_t, uint32_t> d_ip6map; | |
57 | const map<uint64_t, uint32_t>& d_ro6map; | |
58 | // The counter that we'll convert to an IP address | |
ab06937b BH |
59 | uint32_t d_counter; |
60 | }; | |
61 | ||
62 | int main(int argc, char** argv) | |
63 | try | |
64 | { | |
e2928fdb BH |
65 | if(argc!=3) { |
66 | cerr<<"Syntax: dnswasher infile outfile\n"; | |
67 | exit(1); | |
68 | } | |
ab06937b BH |
69 | PcapPacketReader pr(argv[1]); |
70 | PcapPacketWriter pw(argv[2], pr); | |
71 | IPObfuscator ipo; | |
72 | ||
73 | while(pr.getUDPPacket()) { | |
fa0c611e | 74 | if(ntohs(pr.d_udp->uh_dport)==53 || (ntohs(pr.d_udp->uh_sport)==53 && pr.d_len > sizeof(dnsheader))) { |
49f61cba | 75 | dnsheader* dh=(dnsheader*)pr.d_payload; |
11212b81 | 76 | |
cbb0be81 PL |
77 | if (pr.d_ip->ip_v == 4){ |
78 | uint32_t *src=(uint32_t*)&pr.d_ip->ip_src; | |
79 | uint32_t *dst=(uint32_t*)&pr.d_ip->ip_dst; | |
80 | ||
81 | if(dh->qr) | |
82 | *dst=htonl(ipo.obf4(*dst)); | |
83 | else | |
84 | *src=htonl(ipo.obf4(*src)); | |
a8b9d939 RE |
85 | |
86 | pr.d_ip->ip_sum=0; | |
cbb0be81 | 87 | } else if (pr.d_ip->ip_v == 6) { |
a78b2983 RE |
88 | uint64_t *src=(uint64_t*)&pr.d_ip6->ip6_src; |
89 | uint64_t *dst=(uint64_t*)&pr.d_ip6->ip6_dst; | |
cbb0be81 PL |
90 | |
91 | if(dh->qr) | |
92 | *dst=ipo.obf6(*dst); | |
93 | else | |
94 | *src=ipo.obf6(*src); | |
95 | } | |
d24de0d1 | 96 | pw.write(); |
ab06937b | 97 | } |
ab06937b | 98 | } |
11212b81 BH |
99 | cerr<<"Saw "<<pr.d_correctpackets<<" correct packets, "<<pr.d_runts<<" runts, "<< pr.d_oversized<<" oversize, "<< |
100 | pr.d_nonetheripudp<<" unknown encaps"<<endl; | |
ab06937b | 101 | } |
adc10f99 | 102 | catch(std::exception& e) |
ab06937b BH |
103 | { |
104 | cerr<<"Fatal: "<<e.what()<<endl; | |
105 | } |