3 #include "dnsparser.hh"
5 #include "dnsparser.hh"
8 void DNSProtoBufMessage::setType(DNSProtoBufMessageType type
)
12 case DNSProtoBufMessage::DNSProtoBufMessageType::Query
:
13 d_message
.set_type(PBDNSMessage_Type_DNSQueryType
);
15 case DNSProtoBufMessage::DNSProtoBufMessageType::Response
:
16 d_message
.set_type(PBDNSMessage_Type_DNSResponseType
);
18 case DNSProtoBufMessage::DNSProtoBufMessageType::OutgoingQuery
:
19 d_message
.set_type(PBDNSMessage_Type_DNSOutgoingQueryType
);
21 case DNSProtoBufMessage::DNSProtoBufMessageType::IncomingResponse
:
22 d_message
.set_type(PBDNSMessage_Type_DNSIncomingResponseType
);
25 throw std::runtime_error("Unsupported protobuf type: "+std::to_string(type
));
27 #endif /* HAVE_PROTOBUF */
30 DNSProtoBufMessage::DNSProtoBufMessage(DNSProtoBufMessageType type
)
35 void DNSProtoBufMessage::setQuestion(const DNSName
& qname
, uint16_t qtype
, uint16_t qclass
)
38 PBDNSMessage_DNSQuestion
* question
= d_message
.mutable_question();
41 question
->set_qname(qname
.toString());
42 question
->set_qtype(qtype
);
43 question
->set_qclass(qclass
);
45 #endif /* HAVE_PROTOBUF */
48 void DNSProtoBufMessage::setBytes(size_t bytes
)
51 d_message
.set_inbytes(bytes
);
52 #endif /* HAVE_PROTOBUF */
55 void DNSProtoBufMessage::setResponseCode(uint8_t rcode
)
58 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
60 response
->set_rcode(rcode
);
62 #endif /* HAVE_PROTOBUF */
65 void DNSProtoBufMessage::setTime(time_t sec
, uint32_t usec
)
68 d_message
.set_timesec(sec
);
69 d_message
.set_timeusec(usec
);
70 #endif /* HAVE_PROTOBUF */
73 void DNSProtoBufMessage::setQueryTime(time_t sec
, uint32_t usec
)
76 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
78 response
->set_querytimesec(sec
);
79 response
->set_querytimeusec(usec
);
81 #endif /* HAVE_PROTOBUF */
84 void DNSProtoBufMessage::setEDNSSubnet(const Netmask
& subnet
, uint8_t mask
)
87 if (!subnet
.empty()) {
88 ComboAddress
ca(subnet
.getNetwork());
90 if (ca
.sin4
.sin_family
== AF_INET
) {
91 d_message
.set_originalrequestorsubnet(&ca
.sin4
.sin_addr
.s_addr
, sizeof(ca
.sin4
.sin_addr
.s_addr
));
93 else if (ca
.sin4
.sin_family
== AF_INET6
) {
94 d_message
.set_originalrequestorsubnet(&ca
.sin6
.sin6_addr
.s6_addr
, sizeof(ca
.sin6
.sin6_addr
.s6_addr
));
97 #endif /* HAVE_PROTOBUF */
100 void DNSProtoBufMessage::addTag(const std::string
& strValue
)
104 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
108 response
->add_tags(strValue
);
110 #endif /* HAVE_PROTOBUF */
113 void DNSProtoBufMessage::addRR(const DNSName
& qname
, uint16_t uType
, uint16_t uClass
, uint32_t uTTL
, const std::string
& strBlob
)
117 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
120 PBDNSMessage_DNSResponse_DNSRR
* rr
= response
->add_rrs();
122 rr
->set_name(qname
.toString());
124 rr
->set_class_(uClass
);
126 rr
->set_rdata(strBlob
.c_str(), strBlob
.size());
129 #endif /* HAVE_PROTOBUF */
132 void DNSProtoBufMessage::addRRsFromPacket(const char* packet
, const size_t len
, bool includeCNAME
)
135 if (len
< sizeof(struct dnsheader
))
138 const struct dnsheader
* dh
= (const struct dnsheader
*) packet
;
140 if (ntohs(dh
->ancount
) == 0)
143 if (ntohs(dh
->qdcount
) == 0)
146 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
150 std::string
packetStr(packet
, len
);
151 PacketReader
pr(packetStr
);
155 uint16_t qdcount
= ntohs(dh
->qdcount
);
156 uint16_t ancount
= ntohs(dh
->ancount
);
160 struct dnsrecordheader ah
;
162 rrname
= pr
.getName();
163 rrtype
= pr
.get16BitInt();
164 rrclass
= pr
.get16BitInt();
166 /* consume remaining qd if any */
168 for(idx
= 1; idx
< qdcount
; idx
++) {
169 rrname
= pr
.getName();
170 rrtype
= pr
.get16BitInt();
171 rrclass
= pr
.get16BitInt();
178 for (idx
= 0; idx
< ancount
; idx
++) {
179 rrname
= pr
.getName();
180 pr
.getDnsrecordheader(ah
);
182 if (ah
.d_type
== QType::A
|| ah
.d_type
== QType::AAAA
) {
185 PBDNSMessage_DNSResponse_DNSRR
* rr
= response
->add_rrs();
187 rr
->set_name(rrname
.toString());
188 rr
->set_type(ah
.d_type
);
189 rr
->set_class_(ah
.d_class
);
190 rr
->set_ttl(ah
.d_ttl
);
191 rr
->set_rdata(blob
.c_str(), blob
.length());
193 } else if (ah
.d_type
== QType::CNAME
&& includeCNAME
) {
194 PBDNSMessage_DNSResponse_DNSRR
* rr
= response
->add_rrs();
196 rr
->set_name(rrname
.toString());
197 rr
->set_type(ah
.d_type
);
198 rr
->set_class_(ah
.d_class
);
199 rr
->set_ttl(ah
.d_ttl
);
201 pr
.xfrName(target
, true);
202 rr
->set_rdata(target
.toString());
209 #endif /* HAVE_PROTOBUF */
212 void DNSProtoBufMessage::setRequestor(const std::string
& requestor
)
215 d_message
.set_from(requestor
);
216 #endif /* HAVE_PROTOBUF */
219 void DNSProtoBufMessage::setRequestor(const ComboAddress
& requestor
)
222 if (requestor
.sin4
.sin_family
== AF_INET
) {
223 d_message
.set_from(&requestor
.sin4
.sin_addr
.s_addr
, sizeof(requestor
.sin4
.sin_addr
.s_addr
));
225 else if (requestor
.sin4
.sin_family
== AF_INET6
) {
226 d_message
.set_from(&requestor
.sin6
.sin6_addr
.s6_addr
, sizeof(requestor
.sin6
.sin6_addr
.s6_addr
));
228 #endif /* HAVE_PROTOBUF */
231 void DNSProtoBufMessage::setRequestorId(const std::string
& requestorId
)
234 d_message
.set_requestorid(requestorId
);
235 #endif /* HAVE_PROTOBUF */
238 void DNSProtoBufMessage::setDeviceId(const std::string
& deviceId
)
241 d_message
.set_deviceid(deviceId
);
242 #endif /* HAVE_PROTOBUF */
245 void DNSProtoBufMessage::setServerIdentity(const std::string
& serverId
)
248 d_message
.set_serveridentity(serverId
);
249 #endif /* HAVE_PROTOBUF */
252 void DNSProtoBufMessage::setResponder(const std::string
& responder
)
255 d_message
.set_to(responder
);
256 #endif /* HAVE_PROTOBUF */
259 void DNSProtoBufMessage::setResponder(const ComboAddress
& responder
)
262 if (responder
.sin4
.sin_family
== AF_INET
) {
263 d_message
.set_to(&responder
.sin4
.sin_addr
.s_addr
, sizeof(responder
.sin4
.sin_addr
.s_addr
));
265 else if (responder
.sin4
.sin_family
== AF_INET6
) {
266 d_message
.set_to(&responder
.sin6
.sin6_addr
.s6_addr
, sizeof(responder
.sin6
.sin6_addr
.s6_addr
));
268 #endif /* HAVE_PROTOBUF */
271 void DNSProtoBufMessage::serialize(std::string
& data
) const
274 d_message
.SerializeToString(&data
);
275 #endif /* HAVE_PROTOBUF */
278 std::string
DNSProtoBufMessage::toDebugString() const
281 return d_message
.DebugString();
283 return std::string();
284 #endif /* HAVE_PROTOBUF */
289 void DNSProtoBufMessage::setUUID(const boost::uuids::uuid
& uuid
)
291 std::string
* messageId
= d_message
.mutable_messageid();
292 messageId
->resize(uuid
.size());
293 std::copy(uuid
.begin(), uuid
.end(), messageId
->begin());
296 void DNSProtoBufMessage::setInitialRequestID(const boost::uuids::uuid
& uuid
)
298 std::string
* messageId
= d_message
.mutable_initialrequestid();
299 messageId
->resize(uuid
.size());
300 std::copy(uuid
.begin(), uuid
.end(), messageId
->begin());
303 void DNSProtoBufMessage::update(const boost::uuids::uuid
& uuid
, const ComboAddress
* requestor
, const ComboAddress
* responder
, bool isTCP
, uint16_t id
)
307 setTime(ts
.tv_sec
, ts
.tv_nsec
/ 1000);
310 d_message
.set_id(ntohs(id
));
313 d_message
.set_socketfamily(requestor
->sin4
.sin_family
== AF_INET
? PBDNSMessage_SocketFamily_INET
: PBDNSMessage_SocketFamily_INET6
);
315 else if (responder
) {
316 d_message
.set_socketfamily(responder
->sin4
.sin_family
== AF_INET
? PBDNSMessage_SocketFamily_INET
: PBDNSMessage_SocketFamily_INET6
);
319 d_message
.set_socketprotocol(isTCP
? PBDNSMessage_SocketProtocol_TCP
: PBDNSMessage_SocketProtocol_UDP
);
322 setResponder(*responder
);
325 setRequestor(*requestor
);
330 DNSProtoBufMessage::DNSProtoBufMessage(DNSProtoBufMessageType type
, const boost::uuids::uuid
& uuid
, const ComboAddress
* requestor
, const ComboAddress
* responder
, const DNSName
& domain
, int qtype
, uint16_t qclass
, uint16_t qid
, bool isTCP
, size_t bytes
)
332 update(uuid
, requestor
, responder
, isTCP
, qid
);
337 setQuestion(domain
, qtype
, qclass
);
340 void DNSProtoBufMessage::copyFrom(const DNSProtoBufMessage
& msg
)
342 d_message
.CopyFrom(msg
.d_message
);
345 #endif /* HAVE_PROTOBUF */