4 #include <boost/uuid/uuid.hpp>
5 #include <boost/uuid/uuid_generators.hpp>
11 #include "dnsparser.hh"
12 #include "protobuf.hh"
19 cerr
<<"This program reads DNS queries and responses from a PCAP file and stores them into our protobuf format."<<endl
;
20 cerr
<<"Usage: dnspcap2protobuf PCAPFILE OUTFILE"<<endl
;
23 int main(int argc
, char **argv
)
25 for(int n
=1 ; n
< argc
; ++n
) {
26 if ((string
) argv
[n
] == "--help") {
31 if ((string
) argv
[n
] == "--version") {
32 cerr
<<"dnspcap2protobuf "<<VERSION
<<endl
;
43 PcapPacketReader
pr(argv
[1]);
45 FILE* fp
= fopen(argv
[2], "w");
47 cerr
<<"Error opening output file "<<argv
[2]<<": "<<strerror(errno
)<<endl
;
55 std::map
<uint16_t,std::pair
<boost::uuids::uuid
,struct timeval
> > ids
;
56 boost::uuids::random_generator uuidGenerator
;
58 while (pr
.getUDPPacket()) {
59 const dnsheader
* dh
=(dnsheader
*)pr
.d_payload
;
63 if (pr
.d_len
< sizeof(dnsheader
))
69 uint16_t qtype
, qclass
;
72 qname
=DNSName((const char*)pr
.d_payload
, pr
.d_len
, sizeof(dnsheader
), false, &qtype
, &qclass
);
74 catch(const std::exception
& e
) {
75 cerr
<<"Error while parsing qname: "<<e
.what()<<endl
;
79 boost::uuids::uuid uniqueId
;
80 struct timeval queryTime
= { 0, 0 };
81 bool hasQueryTime
= false;
83 queryTime
.tv_sec
= pr
.d_pheader
.ts
.tv_sec
;
84 queryTime
.tv_usec
= pr
.d_pheader
.ts
.tv_usec
;
85 uniqueId
= uuidGenerator();
86 ids
[dh
->id
] = std::make_pair(uniqueId
, queryTime
);
89 const auto& it
= ids
.find(dh
->id
);
90 if (it
!= ids
.end()) {
91 uniqueId
= it
->second
.first
;
92 queryTime
= it
->second
.second
;
96 uniqueId
= uuidGenerator();
100 const ComboAddress requestor
= dh
->qr
? pr
.getDest() : pr
.getSource();
101 const ComboAddress responder
= dh
->qr
? pr
.getSource() : pr
.getDest();
102 *((char*)&requestor
.sin4
.sin_addr
.s_addr
)|=ind
;
103 *((char*)&responder
.sin4
.sin_addr
.s_addr
)|=ind
;
105 DNSProtoBufMessage
message(dh
->qr
? DNSProtoBufMessage::DNSProtoBufMessageType::Response
: DNSProtoBufMessage::DNSProtoBufMessageType::Query
, uniqueId
, &requestor
, &responder
, qname
, qtype
, qclass
, dh
->id
, false, pr
.d_len
);
106 message
.setTime(pr
.d_pheader
.ts
.tv_sec
, pr
.d_pheader
.ts
.tv_usec
);
109 message
.setResponseCode(dh
->rcode
);
111 message
.setQueryTime(queryTime
.tv_sec
, queryTime
.tv_usec
);
115 message
.addRRsFromPacket((const char*) dh
, pr
.d_len
);
117 catch(std::exception
& e
)
119 cerr
<<"Error parsing response records: "<<e
.what()<<endl
;
121 catch(const PDNSException
& e
)
123 cerr
<<"Error parsing response records: "<<e
.reason
<<endl
;
128 message
.serialize(str
);
130 uint16_t mlen
= htons(str
.length());
131 fwrite(&mlen
, 1, sizeof(mlen
), fp
);
132 fwrite(str
.c_str(), 1, str
.length(), fp
);
135 catch (const std::exception
& e
) {
136 cerr
<<"Error while parsing the PCAP file: "<<e
.what()<<endl
;
143 catch(const std::exception
& e
) {
144 cerr
<<"Error opening PCAP file: "<<e
.what()<<endl
;