| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- #include "Packet.h"
- #include "MalformedPacket.h"
- namespace Network {
- namespace Dns {
- Packet::Packet() :
- m_identifier(0),
- m_query(0),
- m_authorativeAnswer(0),
- m_truncation(0),
- m_recursionDesired(0),
- m_recursionAvailable(0),
- m_zero(0),
- m_operationCode(OperationCode::QUERY),
- m_responseCode(ResponseCode::NO_ERROR)
- {
- }
- Packet::Packet(DataReader reader, unsigned pos)
- {
- try
- {
- m_identifier = reader.Read16(pos);
- uint8_t flags = reader.Read8(pos);
- m_query = (flags & (1 << 7)) >> 7; // 10000000
- m_operationCode = static_cast<OperationCode::type>(((flags & (((1 << 4) - 1) << 3)) >> 3)); // 01111000
- m_authorativeAnswer = (flags & (1 << 2)) >> 2; // 00000100
- m_truncation = (flags & (1 << 1)) >> 1; // 00000010
- m_recursionDesired = (flags & (1 << 0)) >> 0; // 00000001
- flags = reader.Read8(pos);
- m_recursionAvailable = (flags & (1 << 7)) >> 7; // 10000000
- m_zero = (flags & (((1 << 3) - 1) << 4)) >> 4; // 01110000
- m_responseCode = static_cast<ResponseCode::type>((flags & ((1 << 4) - 1))); // 00001111
- unsigned queryCount = reader.Read16(pos);
- unsigned answerCount = reader.Read16(pos);
- unsigned authorityCount = reader.Read16(pos);
- unsigned additionalRecordsCount = reader.Read16(pos);
- for (size_t i = 0; i < queryCount; i++)
- {
- m_queries.emplace_back();
- pos = m_queries.back().ReadFromData(reader, pos);
- }
- for (size_t i = 0; i < answerCount; i++)
- {
- m_answers.emplace_back();
- pos = m_answers.back().ReadFromData(reader, pos);
- }
- for (size_t i = 0; i < authorityCount; i++)
- {
- m_authorities.emplace_back();
- pos = m_authorities.back().ReadFromData(reader, pos);
- }
- for (size_t i = 0; i < additionalRecordsCount; i++)
- {
- m_additionalRecords.emplace_back();
- pos = m_additionalRecords.back().ReadFromData(reader, pos);
- }
- }
- catch (const DataReaderOutOfBounds& droob)
- {
- throw MalformedPacket();
- }
- }
- Data Packet::GetData() const
- {
- Data data;
- data.append(static_cast<uint16_t>(m_identifier));
- uint8_t flags =
- (static_cast<uint8_t>(m_query) << 7) |
- (static_cast<uint8_t>(m_operationCode) << 3) |
- (static_cast<uint8_t>(m_authorativeAnswer) << 2) |
- (static_cast<uint8_t>(m_truncation) << 1) |
- (static_cast<uint8_t>(m_recursionDesired) << 0);
- data.append(flags);
- flags =
- (static_cast<uint8_t>(m_recursionAvailable) << 7) |
- (static_cast<uint8_t>(m_zero) << 4) |
- (static_cast<uint8_t>(m_responseCode) << 0);
- data.append(flags);
- data.append(static_cast<uint16_t>(GetQueryCount()));
- data.append(static_cast<uint16_t>(GetAnswerCount()));
- data.append(static_cast<uint16_t>(GetAuthorityCount()));
- data.append(static_cast<uint16_t>(GetAdditionalRecordsCount()));
- for (const QueryImpl& q : m_queries)
- data.append(q.GetData());
- for (const ResourceRecordImpl& r : m_answers)
- data.append(r.GetData());
- for (const ResourceRecordImpl& r : m_authorities)
- data.append(r.GetData());
- for (const ResourceRecordImpl& r : m_additionalRecords)
- data.append(r.GetData());
- return data;
- }
- uint16_t Packet::GetIdentifier() const
- {
- return m_identifier;
- }
- bool Packet::GetQuery() const
- {
- return m_query;
- }
- OperationCode::type Packet::GetOperationCode() const
- {
- return m_operationCode;
- }
- bool Packet::GetAuthorativeAnswer() const
- {
- return m_authorativeAnswer;
- }
- bool Packet::GetTruncation() const
- {
- return m_truncation;
- }
- bool Packet::GetRecursionDesired() const
- {
- return m_recursionDesired;
- }
- bool Packet::GetRecursionAvailable() const
- {
- return m_recursionAvailable;
- }
- uint8_t Packet::GetZero() const
- {
- return m_zero;
- }
- ResponseCode::type Packet::GetResponseCode() const
- {
- return m_responseCode;
- }
- std::vector<QueryImpl> Packet::GetQueries() const
- {
- return m_queries;
- }
- std::vector<ResourceRecordImpl> Packet::GetAnswers() const
- {
- return m_answers;
- }
- std::vector<ResourceRecordImpl> Packet::GetAuthorities() const
- {
- return m_authorities;
- }
- std::vector<ResourceRecordImpl> Packet::GetAdditionalRecords() const
- {
- return m_additionalRecords;
- }
- unsigned Packet::GetQueryCount() const
- {
- return static_cast<unsigned>(m_queries.size());
- }
- unsigned Packet::GetAnswerCount() const
- {
- return static_cast<unsigned>(m_answers.size());
- }
- unsigned Packet::GetAuthorityCount() const
- {
- return static_cast<unsigned>(m_authorities.size());
- }
- unsigned Packet::GetAdditionalRecordsCount() const
- {
- return static_cast<unsigned>(m_additionalRecords.size());
- }
- void Packet::SetIdentifier(uint16_t identifier)
- {
- m_identifier = identifier;
- }
- void Packet::SetQuery(bool query)
- {
- m_query = query;
- }
- void Packet::SetOperationCode(OperationCode::type operationCode)
- {
- m_operationCode = operationCode;
- }
- void Packet::SetAuthorativeAnswer(bool authorativeAnswer)
- {
- m_authorativeAnswer = authorativeAnswer;
- }
- void Packet::SetTruncation(bool truncation)
- {
- m_truncation = truncation;
- }
- void Packet::SetRecursionDesired(bool recursionDesired)
- {
- m_recursionDesired = recursionDesired;
- }
- void Packet::SetRecursionAvailable(bool recursionAvailable)
- {
- m_recursionAvailable = recursionAvailable;
- }
- void Packet::SetZero(uint8_t zero)
- {
- m_zero = zero;
- }
- void Packet::SetResponseCode(ResponseCode::type responseCode)
- {
- m_responseCode = responseCode;
- }
- void Packet::AddQuery(const QueryImpl& query)
- {
- m_queries.emplace_back(query);
- }
- void Packet::AddAnswer(const ResourceRecordImpl& record)
- {
- m_answers.emplace_back(record);
- }
- void Packet::AddAuthority(const ResourceRecordImpl& record)
- {
- m_authorities.emplace_back(record);
- }
- void Packet::AddAdditionalRecords(const ResourceRecordImpl& record)
- {
- m_additionalRecords.emplace_back(record);
- }
- std::ostream& operator<<(std::ostream& stream, const Packet& packet)
- {
- stream << "Packet (\n";
- stream << " identifier = " << packet.m_identifier
- << ", query = " << packet.m_query
- << ", operationCode = " << static_cast<int>(packet.m_operationCode)
- << ", authorativeAnswer = " << packet.m_authorativeAnswer
- << ", truncation = " << packet.m_truncation
- << ", recursionDesired = " << packet.m_recursionDesired << "\n";
- stream << " recursionAvailable = " << packet.m_recursionAvailable
- << ", zero = " << packet.m_zero
- << ", responseCode = " << static_cast<int>(packet.m_responseCode) << "\n";
- for (const QueryImpl& q : packet.m_queries)
- stream << " Query: " << q << "\n";
- for (const ResourceRecordImpl& r : packet.m_answers)
- stream << " Answer: " << r << "\n";
- for (const ResourceRecordImpl& r : packet.m_authorities)
- stream << " Authority: " << r << "\n";
- for (const ResourceRecordImpl& r : packet.m_additionalRecords)
- stream << " AdditionalRecord: " << r << "\n";
- stream << ")\n";
- return stream;
- }
- } // namespace Dns
- } // namespace Network
|