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::setNetworkErrorResponseCode()
68 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
70 /* special code meaning 'network error', like a timeout */
71 response
->set_rcode(65536);
73 #endif /* HAVE_PROTOBUF */
76 void DNSProtoBufMessage::setTime(time_t sec
, uint32_t usec
)
79 d_message
.set_timesec(sec
);
80 d_message
.set_timeusec(usec
);
81 #endif /* HAVE_PROTOBUF */
84 void DNSProtoBufMessage::setQueryTime(time_t sec
, uint32_t usec
)
87 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
89 response
->set_querytimesec(sec
);
90 response
->set_querytimeusec(usec
);
92 #endif /* HAVE_PROTOBUF */
95 void DNSProtoBufMessage::setEDNSSubnet(const Netmask
& subnet
, uint8_t mask
)
98 if (!subnet
.empty()) {
99 ComboAddress
ca(subnet
.getNetwork());
101 if (ca
.sin4
.sin_family
== AF_INET
) {
102 d_message
.set_originalrequestorsubnet(&ca
.sin4
.sin_addr
.s_addr
, sizeof(ca
.sin4
.sin_addr
.s_addr
));
104 else if (ca
.sin4
.sin_family
== AF_INET6
) {
105 d_message
.set_originalrequestorsubnet(&ca
.sin6
.sin6_addr
.s6_addr
, sizeof(ca
.sin6
.sin6_addr
.s6_addr
));
108 #endif /* HAVE_PROTOBUF */
111 void DNSProtoBufMessage::addTag(const std::string
& strValue
)
115 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
119 response
->add_tags(strValue
);
121 #endif /* HAVE_PROTOBUF */
124 void DNSProtoBufMessage::addRR(const DNSName
& qname
, uint16_t uType
, uint16_t uClass
, uint32_t uTTL
, const std::string
& strBlob
)
128 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
131 PBDNSMessage_DNSResponse_DNSRR
* rr
= response
->add_rrs();
133 rr
->set_name(qname
.toString());
135 rr
->set_class_(uClass
);
137 rr
->set_rdata(strBlob
.c_str(), strBlob
.size());
140 #endif /* HAVE_PROTOBUF */
143 void DNSProtoBufMessage::addRRsFromPacket(const char* packet
, const size_t len
, bool includeCNAME
)
146 if (len
< sizeof(struct dnsheader
))
149 const struct dnsheader
* dh
= (const struct dnsheader
*) packet
;
151 if (ntohs(dh
->ancount
) == 0)
154 if (ntohs(dh
->qdcount
) == 0)
157 PBDNSMessage_DNSResponse
* response
= d_message
.mutable_response();
161 std::string
packetStr(packet
, len
);
162 PacketReader
pr(packetStr
);
166 uint16_t qdcount
= ntohs(dh
->qdcount
);
167 uint16_t ancount
= ntohs(dh
->ancount
);
171 struct dnsrecordheader ah
;
173 rrname
= pr
.getName();
174 rrtype
= pr
.get16BitInt();
175 rrclass
= pr
.get16BitInt();
177 /* consume remaining qd if any */
179 for(idx
= 1; idx
< qdcount
; idx
++) {
180 rrname
= pr
.getName();
181 rrtype
= pr
.get16BitInt();
182 rrclass
= pr
.get16BitInt();
189 for (idx
= 0; idx
< ancount
; idx
++) {
190 rrname
= pr
.getName();
191 pr
.getDnsrecordheader(ah
);
193 if (ah
.d_type
== QType::A
|| ah
.d_type
== QType::AAAA
) {
196 PBDNSMessage_DNSResponse_DNSRR
* rr
= response
->add_rrs();
198 rr
->set_name(rrname
.toString());
199 rr
->set_type(ah
.d_type
);
200 rr
->set_class_(ah
.d_class
);
201 rr
->set_ttl(ah
.d_ttl
);
202 rr
->set_rdata(blob
.c_str(), blob
.length());
204 } else if (ah
.d_type
== QType::CNAME
&& includeCNAME
) {
205 PBDNSMessage_DNSResponse_DNSRR
* rr
= response
->add_rrs();
207 rr
->set_name(rrname
.toString());
208 rr
->set_type(ah
.d_type
);
209 rr
->set_class_(ah
.d_class
);
210 rr
->set_ttl(ah
.d_ttl
);
212 pr
.xfrName(target
, true);
213 rr
->set_rdata(target
.toString());
220 #endif /* HAVE_PROTOBUF */
223 void DNSProtoBufMessage::setRequestor(const std::string
& requestor
)
226 d_message
.set_from(requestor
);
227 #endif /* HAVE_PROTOBUF */
230 void DNSProtoBufMessage::setRequestor(const ComboAddress
& requestor
)
233 if (requestor
.sin4
.sin_family
== AF_INET
) {
234 d_message
.set_from(&requestor
.sin4
.sin_addr
.s_addr
, sizeof(requestor
.sin4
.sin_addr
.s_addr
));
236 else if (requestor
.sin4
.sin_family
== AF_INET6
) {
237 d_message
.set_from(&requestor
.sin6
.sin6_addr
.s6_addr
, sizeof(requestor
.sin6
.sin6_addr
.s6_addr
));
239 #endif /* HAVE_PROTOBUF */
242 void DNSProtoBufMessage::setRequestorId(const std::string
& requestorId
)
245 d_message
.set_requestorid(requestorId
);
246 #endif /* HAVE_PROTOBUF */
249 void DNSProtoBufMessage::setDeviceId(const std::string
& deviceId
)
252 d_message
.set_deviceid(deviceId
);
253 #endif /* HAVE_PROTOBUF */
256 void DNSProtoBufMessage::setDeviceName(const std::string
& deviceName
)
259 d_message
.set_devicename(deviceName
);
260 #endif /* HAVE_PROTOBUF */
263 void DNSProtoBufMessage::setServerIdentity(const std::string
& serverId
)
266 d_message
.set_serveridentity(serverId
);
267 #endif /* HAVE_PROTOBUF */
270 void DNSProtoBufMessage::setResponder(const std::string
& responder
)
273 d_message
.set_to(responder
);
274 #endif /* HAVE_PROTOBUF */
277 void DNSProtoBufMessage::setResponder(const ComboAddress
& responder
)
280 if (responder
.sin4
.sin_family
== AF_INET
) {
281 d_message
.set_to(&responder
.sin4
.sin_addr
.s_addr
, sizeof(responder
.sin4
.sin_addr
.s_addr
));
283 else if (responder
.sin4
.sin_family
== AF_INET6
) {
284 d_message
.set_to(&responder
.sin6
.sin6_addr
.s6_addr
, sizeof(responder
.sin6
.sin6_addr
.s6_addr
));
286 #endif /* HAVE_PROTOBUF */
289 void DNSProtoBufMessage::serialize(std::string
& data
) const
292 d_message
.SerializeToString(&data
);
293 #endif /* HAVE_PROTOBUF */
296 std::string
DNSProtoBufMessage::toDebugString() const
299 return d_message
.DebugString();
301 return std::string();
302 #endif /* HAVE_PROTOBUF */
307 void DNSProtoBufMessage::setUUID(const boost::uuids::uuid
& uuid
)
309 std::string
* messageId
= d_message
.mutable_messageid();
310 messageId
->resize(uuid
.size());
311 std::copy(uuid
.begin(), uuid
.end(), messageId
->begin());
314 void DNSProtoBufMessage::setInitialRequestID(const boost::uuids::uuid
& uuid
)
316 std::string
* messageId
= d_message
.mutable_initialrequestid();
317 messageId
->resize(uuid
.size());
318 std::copy(uuid
.begin(), uuid
.end(), messageId
->begin());
321 void DNSProtoBufMessage::updateTime()
325 setTime(ts
.tv_sec
, ts
.tv_nsec
/ 1000);
328 void DNSProtoBufMessage::update(const boost::uuids::uuid
& uuid
, const ComboAddress
* requestor
, const ComboAddress
* responder
, bool isTCP
, uint16_t id
)
332 d_message
.set_id(ntohs(id
));
335 d_message
.set_socketfamily(requestor
->sin4
.sin_family
== AF_INET
? PBDNSMessage_SocketFamily_INET
: PBDNSMessage_SocketFamily_INET6
);
337 else if (responder
) {
338 d_message
.set_socketfamily(responder
->sin4
.sin_family
== AF_INET
? PBDNSMessage_SocketFamily_INET
: PBDNSMessage_SocketFamily_INET6
);
341 d_message
.set_socketprotocol(isTCP
? PBDNSMessage_SocketProtocol_TCP
: PBDNSMessage_SocketProtocol_UDP
);
344 setResponder(*responder
);
347 setRequestor(*requestor
);
352 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
)
354 update(uuid
, requestor
, responder
, isTCP
, qid
);
359 setQuestion(domain
, qtype
, qclass
);
362 void DNSProtoBufMessage::copyFrom(const DNSProtoBufMessage
& msg
)
364 d_message
.CopyFrom(msg
.d_message
);
367 #endif /* HAVE_PROTOBUF */