libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
dnspacket.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_NETWORK
13#include <cstdint>
14#include <promeki/namespace.h>
15#include <promeki/buffer.h>
16#include <promeki/dnsrecord.h>
17#include <promeki/error.h>
18#include <promeki/list.h>
19#include <promeki/result.h>
20
21PROMEKI_NAMESPACE_BEGIN
22
63class DnsPacket {
64 public:
66 static constexpr int HeaderSize = 12;
67
69 class Builder;
70
71 DnsPacket() = default;
72
86 static Result<DnsPacket> parse(const Buffer &b);
87
89 static Result<DnsPacket> parse(const uint8_t *data, size_t len);
90
107 static Result<DnsPacket> parseMdns(const Buffer &b);
109 static Result<DnsPacket> parseMdns(const uint8_t *data, size_t len);
110
112 uint16_t transactionId() const { return _id; }
113
115 void setTransactionId(uint16_t id) { _id = id; }
116
118 uint16_t flags() const { return _flags; }
119
121 void setFlags(uint16_t f) { _flags = f; }
122
124 bool isResponse() const { return (_flags & 0x8000) != 0; }
125
127 bool isAuthoritative() const { return (_flags & 0x0400) != 0; }
128
130 bool isTruncated() const { return (_flags & 0x0200) != 0; }
131
133 bool isRecursionDesired() const { return (_flags & 0x0100) != 0; }
134
136 bool isRecursionAvailable() const { return (_flags & 0x0080) != 0; }
137
139 uint8_t rcode() const { return static_cast<uint8_t>(_flags & 0x000F); }
140
142 uint8_t opcode() const { return static_cast<uint8_t>((_flags >> 11) & 0x0F); }
143
145 const List<DnsQuestion> &questions() const { return _questions; }
147 List<DnsQuestion> &questions() { return _questions; }
148
150 const List<DnsRecord> &records() const { return _records; }
152 List<DnsRecord> &records() { return _records; }
153
155 List<DnsRecord> recordsInSection(DnsRecord::Section section) const;
156
157 private:
158 uint16_t _id = 0;
159 uint16_t _flags = 0;
160 List<DnsQuestion> _questions;
161 List<DnsRecord> _records;
162};
163
183class DnsPacket::Builder {
184 public:
185 Builder();
186
188 Builder &setTransactionId(uint16_t id);
189
191 Builder &setResponse(bool r);
192
194 Builder &setAuthoritative(bool aa);
195
197 Builder &setTruncated(bool tc);
198
200 Builder &setRecursionDesired(bool rd);
201
203 Builder &setRecursionAvailable(bool ra);
204
206 Builder &setOpcode(uint8_t opcode);
207
209 Builder &setRcode(uint8_t rcode);
210
212 Builder &setCompressionEnabled(bool enable);
213
223 Builder &addQuestion(const String &name, DnsRecord::Type type,
224 uint16_t klass = 1, bool unicastResponse = false);
225
227 Builder &addQuestion(const DnsQuestion &q);
228
237 Builder &addAnswer(const DnsRecord &r);
238
240 Builder &addAuthority(const DnsRecord &r);
241
243 Builder &addAdditional(const DnsRecord &r);
244
264 Builder &addEdns0(uint16_t udpPayloadSize = 1232, bool doBit = false);
265
274 Buffer finish() const;
275
277 bool lastEncodeFailed() const { return _lastEncodeFailed; }
278
279 private:
280 uint16_t _id = 0;
281 uint16_t _flags = 0;
282 bool _compress = true;
283 mutable bool _lastEncodeFailed = false;
284 List<DnsQuestion> _questions;
285 List<DnsRecord> _answers;
286 List<DnsRecord> _authority;
287 List<DnsRecord> _additional;
288};
289
290#if PROMEKI_ENABLE_MDNS
301using MdnsPacket = DnsPacket;
302#endif
303
304PROMEKI_NAMESPACE_END
305
306#endif // PROMEKI_ENABLE_NETWORK