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 vector
<uint8_t> content(len
- sizeof(dnsheader
));
151 copy(packet
+ sizeof(dnsheader
), packet
+ len
, content
.begin());
152 PacketReader
pr(content
);
156 uint16_t qdcount
= ntohs(dh
->qdcount
);
157 uint16_t ancount
= ntohs(dh
->ancount
);
161 struct dnsrecordheader ah
;
163 rrname
= pr
.getName();
164 rrtype
= pr
.get16BitInt();
165 rrclass
= pr
.get16BitInt();
167 /* consume remaining qd if any */
169 for(idx
= 1; idx
< qdcount
; idx
++) {
170 rrname
= pr
.getName();
171 rrtype
= pr
.get16BitInt();
172 rrclass
= pr
.get16BitInt();
179 for (idx
= 0; idx
< ancount
; idx
++) {
180 rrname
= pr
.getName();
181 pr
.getDnsrecordheader(ah
);
183 if (ah
.d_type
== QType::A
|| ah
.d_type
== QType::AAAA
) {
186 PBDNSMessage_DNSResponse_DNSRR
* rr
= response
->add_rrs();
188 rr
->set_name(rrname
.toString());
189 rr
->set_type(ah
.d_type
);
190 rr
->set_class_(ah
.d_class
);
191 rr
->set_ttl(ah
.d_ttl
);
192 rr
->set_rdata(blob
.c_str(), blob
.length());
194 } else if (ah
.d_type
== QType::CNAME
&& includeCNAME
) {
195 PBDNSMessage_DNSResponse_DNSRR
* rr
= response
->add_rrs();
197 rr
->set_name(rrname
.toString());
198 rr
->set_type(ah
.d_type
);
199 rr
->set_class_(ah
.d_class
);
200 rr
->set_ttl(ah
.d_ttl
);
202 pr
.xfrName(target
, true);
203 rr
->set_rdata(target
.toString());
210 #endif /* HAVE_PROTOBUF */
213 void DNSProtoBufMessage::setRequestor(const std::string
& requestor
)
216 d_message
.set_from(requestor
);
217 #endif /* HAVE_PROTOBUF */
220 void DNSProtoBufMessage::setRequestor(const ComboAddress
& requestor
)
223 if (requestor
.sin4
.sin_family
== AF_INET
) {
224 d_message
.set_from(&requestor
.sin4
.sin_addr
.s_addr
, sizeof(requestor
.sin4
.sin_addr
.s_addr
));
226 else if (requestor
.sin4
.sin_family
== AF_INET6
) {
227 d_message
.set_from(&requestor
.sin6
.sin6_addr
.s6_addr
, sizeof(requestor
.sin6
.sin6_addr
.s6_addr
));
229 #endif /* HAVE_PROTOBUF */
232 void DNSProtoBufMessage::setRequestorId(const std::string
& requestorId
)
235 d_message
.set_requestorid(requestorId
);
236 #endif /* HAVE_PROTOBUF */
239 void DNSProtoBufMessage::setDeviceId(const std::string
& deviceId
)
242 d_message
.set_deviceid(deviceId
);
243 #endif /* HAVE_PROTOBUF */
246 void DNSProtoBufMessage::setResponder(const std::string
& responder
)
249 d_message
.set_to(responder
);
250 #endif /* HAVE_PROTOBUF */
253 void DNSProtoBufMessage::setResponder(const ComboAddress
& responder
)
256 if (responder
.sin4
.sin_family
== AF_INET
) {
257 d_message
.set_to(&responder
.sin4
.sin_addr
.s_addr
, sizeof(responder
.sin4
.sin_addr
.s_addr
));
259 else if (responder
.sin4
.sin_family
== AF_INET6
) {
260 d_message
.set_to(&responder
.sin6
.sin6_addr
.s6_addr
, sizeof(responder
.sin6
.sin6_addr
.s6_addr
));
262 #endif /* HAVE_PROTOBUF */
265 void DNSProtoBufMessage::serialize(std::string
& data
) const
268 d_message
.SerializeToString(&data
);
269 #endif /* HAVE_PROTOBUF */
272 std::string
DNSProtoBufMessage::toDebugString() const
275 return d_message
.DebugString();
277 return std::string();
278 #endif /* HAVE_PROTOBUF */
283 void DNSProtoBufMessage::setUUID(const boost::uuids::uuid
& uuid
)
285 std::string
* messageId
= d_message
.mutable_messageid();
286 messageId
->resize(uuid
.size());
287 std::copy(uuid
.begin(), uuid
.end(), messageId
->begin());
290 void DNSProtoBufMessage::setInitialRequestID(const boost::uuids::uuid
& uuid
)
292 std::string
* messageId
= d_message
.mutable_initialrequestid();
293 messageId
->resize(uuid
.size());
294 std::copy(uuid
.begin(), uuid
.end(), messageId
->begin());
297 void DNSProtoBufMessage::update(const boost::uuids::uuid
& uuid
, const ComboAddress
* requestor
, const ComboAddress
* responder
, bool isTCP
, uint16_t id
)
301 setTime(ts
.tv_sec
, ts
.tv_nsec
/ 1000);
304 d_message
.set_id(ntohs(id
));
307 d_message
.set_socketfamily(requestor
->sin4
.sin_family
== AF_INET
? PBDNSMessage_SocketFamily_INET
: PBDNSMessage_SocketFamily_INET6
);
309 else if (responder
) {
310 d_message
.set_socketfamily(responder
->sin4
.sin_family
== AF_INET
? PBDNSMessage_SocketFamily_INET
: PBDNSMessage_SocketFamily_INET6
);
313 d_message
.set_socketprotocol(isTCP
? PBDNSMessage_SocketProtocol_TCP
: PBDNSMessage_SocketProtocol_UDP
);
316 setResponder(*responder
);
319 setRequestor(*requestor
);
324 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
)
326 update(uuid
, requestor
, responder
, isTCP
, qid
);
331 setQuestion(domain
, qtype
, qclass
);
334 #endif /* HAVE_PROTOBUF */