]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnspcap2protobuf.cc
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <boost/uuid/uuid.hpp>
31 #include "dnsparser.hh"
32 #include "protozero.hh"
33 #include "uuid-utils.hh"
40 cerr
<<"This program reads DNS queries and responses from a PCAP file and stores them into our protobuf format."<<endl
;
41 cerr
<<"Usage: dnspcap2protobuf PCAPFILE OUTFILE"<<endl
;
44 int main(int argc
, char **argv
)
46 for(int n
=1 ; n
< argc
; ++n
) {
47 if ((string
) argv
[n
] == "--help") {
52 if ((string
) argv
[n
] == "--version") {
53 cerr
<<"dnspcap2protobuf "<<VERSION
<<endl
;
64 PcapPacketReader
pr(argv
[1]);
66 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): it's argv..
67 auto filePtr
= pdns::openFileForWriting(argv
[2], 0600, true, false);
70 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): it's argv..
71 cerr
<<"Error opening output file "<<argv
[2]<<": "<<stringerror(error
)<<endl
;
79 std::map
<uint16_t,std::pair
<boost::uuids::uuid
,struct timeval
> > ids
;
82 while (pr
.getUDPPacket()) {
83 const dnsheader
* dh
=(dnsheader
*)pr
.d_payload
;
87 if (pr
.d_len
< sizeof(dnsheader
))
93 uint16_t qtype
, qclass
;
96 qname
=DNSName((const char*)pr
.d_payload
, pr
.d_len
, sizeof(dnsheader
), false, &qtype
, &qclass
);
98 catch(const std::exception
& e
) {
99 cerr
<<"Error while parsing qname: "<<e
.what()<<endl
;
103 boost::uuids::uuid uniqueId
;
104 struct timeval queryTime
= { 0, 0 };
105 bool hasQueryTime
= false;
107 queryTime
.tv_sec
= pr
.d_pheader
.ts
.tv_sec
;
108 queryTime
.tv_usec
= pr
.d_pheader
.ts
.tv_usec
;
109 uniqueId
= getUniqueID();
110 ids
[dh
->id
] = {uniqueId
, queryTime
};
113 const auto& it
= ids
.find(dh
->id
);
114 if (it
!= ids
.end()) {
115 uniqueId
= it
->second
.first
;
116 queryTime
= it
->second
.second
;
120 uniqueId
= getUniqueID();
124 const ComboAddress requestor
= dh
->qr
? pr
.getDest() : pr
.getSource();
125 const ComboAddress responder
= dh
->qr
? pr
.getSource() : pr
.getDest();
126 *((char*)&requestor
.sin4
.sin_addr
.s_addr
)|=ind
;
127 *((char*)&responder
.sin4
.sin_addr
.s_addr
)|=ind
;
130 pdns::ProtoZero::Message
pbMessage(pbBuffer
);
131 pbMessage
.setType(dh
->qr
? pdns::ProtoZero::Message::MessageType::DNSResponseType
: pdns::ProtoZero::Message::MessageType::DNSQueryType
);
132 pbMessage
.setRequest(uniqueId
, requestor
, responder
, qname
, qtype
, qclass
, dh
->id
, pdns::ProtoZero::Message::TransportProtocol::UDP
, pr
.d_len
);
133 pbMessage
.setTime(pr
.d_pheader
.ts
.tv_sec
, pr
.d_pheader
.ts
.tv_usec
);
136 pbMessage
.startResponse();
137 pbMessage
.setResponseCode(dh
->rcode
);
139 pbMessage
.setQueryTime(queryTime
.tv_sec
, queryTime
.tv_usec
);
143 pbMessage
.addRRsFromPacket((const char*) dh
, pr
.d_len
, true);
145 catch (const std::exception
& e
)
147 cerr
<<"Error parsing response records: "<<e
.what()<<endl
;
149 catch(const PDNSException
& e
)
151 cerr
<<"Error parsing response records: "<<e
.reason
<<endl
;
155 uint16_t mlen
= htons(pbBuffer
.length());
156 fwrite(&mlen
, 1, sizeof(mlen
), filePtr
.get());
157 fwrite(pbBuffer
.c_str(), 1, pbBuffer
.length(), filePtr
.get());
160 catch (const std::exception
& e
) {
161 cerr
<<"Error while parsing the PCAP file: "<<e
.what()<<endl
;
165 catch(const std::exception
& e
) {
166 cerr
<<"Error opening PCAP file: "<<e
.what()<<endl
;