(No support for Auth-Name + Add-Name for simplicity)
This page hosts a formal specification of DNS (Domain Name Service) packet using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All parsing code for C++11/STL generated by Kaitai Struct depends on the C++/STL runtime library. You have to install it before you can parse data.
For C++, the easiest way is to clone the runtime library sources and build them along with your project.
Using Kaitai Struct in C++/STL usually consists of 3 steps.
std::istream
). One can open local file for that, or use existing std::string
or char*
buffer.
#include <fstream>
std::ifstream is("path/to/local/file.bin", std::ifstream::binary);
#include <sstream>
std::istringstream is(str);
#include <sstream>
const char buf[] = { ... };
std::string str(buf, sizeof buf);
std::istringstream is(str);
#include "kaitai/kaitaistream.h"
kaitai::kstream ks(&is);
dns_packet_t data(&ks);
After that, one can get various attributes from the structure by invoking getter methods like:
data.transaction_id() // => ID to keep track of request/responces
#pragma once
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "kaitai/kaitaistruct.h"
#include <stdint.h>
#include <memory>
#include <vector>
#if KAITAI_STRUCT_VERSION < 9000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required"
#endif
/**
* (No support for Auth-Name + Add-Name for simplicity)
*/
class dns_packet_t : public kaitai::kstruct {
public:
class mx_info_t;
class pointer_struct_t;
class label_t;
class query_t;
class domain_name_t;
class address_v6_t;
class service_t;
class txt_t;
class txt_body_t;
class address_t;
class answer_t;
class packet_flags_t;
class authority_info_t;
enum class_type_t {
CLASS_TYPE_IN_CLASS = 1,
CLASS_TYPE_CS = 2,
CLASS_TYPE_CH = 3,
CLASS_TYPE_HS = 4
};
enum type_type_t {
TYPE_TYPE_A = 1,
TYPE_TYPE_NS = 2,
TYPE_TYPE_MD = 3,
TYPE_TYPE_MF = 4,
TYPE_TYPE_CNAME = 5,
TYPE_TYPE_SOA = 6,
TYPE_TYPE_MB = 7,
TYPE_TYPE_MG = 8,
TYPE_TYPE_MR = 9,
TYPE_TYPE_NULL = 10,
TYPE_TYPE_WKS = 11,
TYPE_TYPE_PTR = 12,
TYPE_TYPE_HINFO = 13,
TYPE_TYPE_MINFO = 14,
TYPE_TYPE_MX = 15,
TYPE_TYPE_TXT = 16,
TYPE_TYPE_AAAA = 28,
TYPE_TYPE_SRV = 33
};
dns_packet_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~dns_packet_t();
class mx_info_t : public kaitai::kstruct {
public:
mx_info_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~mx_info_t();
private:
uint16_t m_preference;
std::unique_ptr<domain_name_t> m_mx;
dns_packet_t* m__root;
dns_packet_t::answer_t* m__parent;
public:
uint16_t preference() const { return m_preference; }
domain_name_t* mx() const { return m_mx.get(); }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::answer_t* _parent() const { return m__parent; }
};
class pointer_struct_t : public kaitai::kstruct {
public:
pointer_struct_t(kaitai::kstream* p__io, dns_packet_t::label_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~pointer_struct_t();
private:
bool f_contents;
std::unique_ptr<domain_name_t> m_contents;
public:
domain_name_t* contents();
private:
uint8_t m_value;
dns_packet_t* m__root;
dns_packet_t::label_t* m__parent;
public:
/**
* Read one byte, then offset to that position, read one domain-name and return
*/
uint8_t value() const { return m_value; }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::label_t* _parent() const { return m__parent; }
};
class label_t : public kaitai::kstruct {
public:
label_t(kaitai::kstream* p__io, dns_packet_t::domain_name_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~label_t();
private:
bool f_is_pointer;
bool m_is_pointer;
public:
bool is_pointer();
private:
uint8_t m_length;
std::unique_ptr<pointer_struct_t> m_pointer;
bool n_pointer;
public:
bool _is_null_pointer() { pointer(); return n_pointer; };
private:
std::string m_name;
bool n_name;
public:
bool _is_null_name() { name(); return n_name; };
private:
dns_packet_t* m__root;
dns_packet_t::domain_name_t* m__parent;
public:
/**
* RFC1035 4.1.4: If the first two bits are raised it's a pointer-offset to a previously defined name
*/
uint8_t length() const { return m_length; }
pointer_struct_t* pointer() const { return m_pointer.get(); }
/**
* Otherwise its a string the length of the length value
*/
std::string name() const { return m_name; }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::domain_name_t* _parent() const { return m__parent; }
};
class query_t : public kaitai::kstruct {
public:
query_t(kaitai::kstream* p__io, dns_packet_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~query_t();
private:
std::unique_ptr<domain_name_t> m_name;
type_type_t m_type;
class_type_t m_query_class;
dns_packet_t* m__root;
dns_packet_t* m__parent;
public:
domain_name_t* name() const { return m_name.get(); }
type_type_t type() const { return m_type; }
class_type_t query_class() const { return m_query_class; }
dns_packet_t* _root() const { return m__root; }
dns_packet_t* _parent() const { return m__parent; }
};
class domain_name_t : public kaitai::kstruct {
public:
domain_name_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~domain_name_t();
private:
std::unique_ptr<std::vector<std::unique_ptr<label_t>>> m_name;
dns_packet_t* m__root;
kaitai::kstruct* m__parent;
public:
/**
* Repeat until the length is 0 or it is a pointer (bit-hack to get around lack of OR operator)
*/
std::vector<std::unique_ptr<label_t>>* name() const { return m_name.get(); }
dns_packet_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
class address_v6_t : public kaitai::kstruct {
public:
address_v6_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~address_v6_t();
private:
std::string m_ip_v6;
dns_packet_t* m__root;
dns_packet_t::answer_t* m__parent;
public:
std::string ip_v6() const { return m_ip_v6; }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::answer_t* _parent() const { return m__parent; }
};
class service_t : public kaitai::kstruct {
public:
service_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~service_t();
private:
uint16_t m_priority;
uint16_t m_weight;
uint16_t m_port;
std::unique_ptr<domain_name_t> m_target;
dns_packet_t* m__root;
dns_packet_t::answer_t* m__parent;
public:
uint16_t priority() const { return m_priority; }
uint16_t weight() const { return m_weight; }
uint16_t port() const { return m_port; }
domain_name_t* target() const { return m_target.get(); }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::answer_t* _parent() const { return m__parent; }
};
class txt_t : public kaitai::kstruct {
public:
txt_t(kaitai::kstream* p__io, dns_packet_t::txt_body_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~txt_t();
private:
uint8_t m_length;
std::string m_text;
dns_packet_t* m__root;
dns_packet_t::txt_body_t* m__parent;
public:
uint8_t length() const { return m_length; }
std::string text() const { return m_text; }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::txt_body_t* _parent() const { return m__parent; }
};
class txt_body_t : public kaitai::kstruct {
public:
txt_body_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~txt_body_t();
private:
std::unique_ptr<std::vector<std::unique_ptr<txt_t>>> m_data;
dns_packet_t* m__root;
dns_packet_t::answer_t* m__parent;
public:
std::vector<std::unique_ptr<txt_t>>* data() const { return m_data.get(); }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::answer_t* _parent() const { return m__parent; }
};
class address_t : public kaitai::kstruct {
public:
address_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~address_t();
private:
std::string m_ip;
dns_packet_t* m__root;
dns_packet_t::answer_t* m__parent;
public:
std::string ip() const { return m_ip; }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::answer_t* _parent() const { return m__parent; }
};
class answer_t : public kaitai::kstruct {
public:
answer_t(kaitai::kstream* p__io, dns_packet_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~answer_t();
private:
std::unique_ptr<domain_name_t> m_name;
type_type_t m_type;
class_type_t m_answer_class;
int32_t m_ttl;
uint16_t m_rdlength;
std::unique_ptr<kaitai::kstruct> m_payload;
bool n_payload;
public:
bool _is_null_payload() { payload(); return n_payload; };
private:
dns_packet_t* m__root;
dns_packet_t* m__parent;
std::string m__raw_payload;
std::unique_ptr<kaitai::kstream> m__io__raw_payload;
public:
domain_name_t* name() const { return m_name.get(); }
type_type_t type() const { return m_type; }
class_type_t answer_class() const { return m_answer_class; }
/**
* Time to live (in seconds)
*/
int32_t ttl() const { return m_ttl; }
/**
* Length in octets of the following payload
*/
uint16_t rdlength() const { return m_rdlength; }
kaitai::kstruct* payload() const { return m_payload.get(); }
dns_packet_t* _root() const { return m__root; }
dns_packet_t* _parent() const { return m__parent; }
std::string _raw_payload() const { return m__raw_payload; }
kaitai::kstream* _io__raw_payload() const { return m__io__raw_payload.get(); }
};
class packet_flags_t : public kaitai::kstruct {
public:
packet_flags_t(kaitai::kstream* p__io, dns_packet_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~packet_flags_t();
private:
bool f_qr;
int32_t m_qr;
public:
int32_t qr();
private:
bool f_ra;
int32_t m_ra;
public:
int32_t ra();
private:
bool f_tc;
int32_t m_tc;
public:
int32_t tc();
private:
bool f_is_opcode_valid;
bool m_is_opcode_valid;
public:
bool is_opcode_valid();
private:
bool f_rcode;
int32_t m_rcode;
public:
int32_t rcode();
private:
bool f_opcode;
int32_t m_opcode;
public:
int32_t opcode();
private:
bool f_aa;
int32_t m_aa;
public:
int32_t aa();
private:
bool f_z;
int32_t m_z;
public:
int32_t z();
private:
bool f_rd;
int32_t m_rd;
public:
int32_t rd();
private:
bool f_cd;
int32_t m_cd;
public:
int32_t cd();
private:
bool f_ad;
int32_t m_ad;
public:
int32_t ad();
private:
uint16_t m_flag;
dns_packet_t* m__root;
dns_packet_t* m__parent;
public:
uint16_t flag() const { return m_flag; }
dns_packet_t* _root() const { return m__root; }
dns_packet_t* _parent() const { return m__parent; }
};
class authority_info_t : public kaitai::kstruct {
public:
authority_info_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent = nullptr, dns_packet_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~authority_info_t();
private:
std::unique_ptr<domain_name_t> m_primary_ns;
std::unique_ptr<domain_name_t> m_resoponsible_mailbox;
uint32_t m_serial;
uint32_t m_refresh_interval;
uint32_t m_retry_interval;
uint32_t m_expire_limit;
uint32_t m_min_ttl;
dns_packet_t* m__root;
dns_packet_t::answer_t* m__parent;
public:
domain_name_t* primary_ns() const { return m_primary_ns.get(); }
domain_name_t* resoponsible_mailbox() const { return m_resoponsible_mailbox.get(); }
uint32_t serial() const { return m_serial; }
uint32_t refresh_interval() const { return m_refresh_interval; }
uint32_t retry_interval() const { return m_retry_interval; }
uint32_t expire_limit() const { return m_expire_limit; }
uint32_t min_ttl() const { return m_min_ttl; }
dns_packet_t* _root() const { return m__root; }
dns_packet_t::answer_t* _parent() const { return m__parent; }
};
private:
uint16_t m_transaction_id;
std::unique_ptr<packet_flags_t> m_flags;
uint16_t m_qdcount;
bool n_qdcount;
public:
bool _is_null_qdcount() { qdcount(); return n_qdcount; };
private:
uint16_t m_ancount;
bool n_ancount;
public:
bool _is_null_ancount() { ancount(); return n_ancount; };
private:
uint16_t m_nscount;
bool n_nscount;
public:
bool _is_null_nscount() { nscount(); return n_nscount; };
private:
uint16_t m_arcount;
bool n_arcount;
public:
bool _is_null_arcount() { arcount(); return n_arcount; };
private:
std::unique_ptr<std::vector<std::unique_ptr<query_t>>> m_queries;
bool n_queries;
public:
bool _is_null_queries() { queries(); return n_queries; };
private:
std::unique_ptr<std::vector<std::unique_ptr<answer_t>>> m_answers;
bool n_answers;
public:
bool _is_null_answers() { answers(); return n_answers; };
private:
std::unique_ptr<std::vector<std::unique_ptr<answer_t>>> m_authorities;
bool n_authorities;
public:
bool _is_null_authorities() { authorities(); return n_authorities; };
private:
std::unique_ptr<std::vector<std::unique_ptr<answer_t>>> m_additionals;
bool n_additionals;
public:
bool _is_null_additionals() { additionals(); return n_additionals; };
private:
dns_packet_t* m__root;
kaitai::kstruct* m__parent;
public:
/**
* ID to keep track of request/responces
*/
uint16_t transaction_id() const { return m_transaction_id; }
packet_flags_t* flags() const { return m_flags.get(); }
/**
* How many questions are there
*/
uint16_t qdcount() const { return m_qdcount; }
/**
* Number of resource records answering the question
*/
uint16_t ancount() const { return m_ancount; }
/**
* Number of resource records pointing toward an authority
*/
uint16_t nscount() const { return m_nscount; }
/**
* Number of resource records holding additional information
*/
uint16_t arcount() const { return m_arcount; }
std::vector<std::unique_ptr<query_t>>* queries() const { return m_queries.get(); }
std::vector<std::unique_ptr<answer_t>>* answers() const { return m_answers.get(); }
std::vector<std::unique_ptr<answer_t>>* authorities() const { return m_authorities.get(); }
std::vector<std::unique_ptr<answer_t>>* additionals() const { return m_additionals.get(); }
dns_packet_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "dns_packet.h"
dns_packet_t::dns_packet_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = this;
m_flags = nullptr;
m_queries = nullptr;
m_answers = nullptr;
m_authorities = nullptr;
m_additionals = nullptr;
_read();
}
void dns_packet_t::_read() {
m_transaction_id = m__io->read_u2be();
m_flags = std::unique_ptr<packet_flags_t>(new packet_flags_t(m__io, this, m__root));
n_qdcount = true;
if (flags()->is_opcode_valid()) {
n_qdcount = false;
m_qdcount = m__io->read_u2be();
}
n_ancount = true;
if (flags()->is_opcode_valid()) {
n_ancount = false;
m_ancount = m__io->read_u2be();
}
n_nscount = true;
if (flags()->is_opcode_valid()) {
n_nscount = false;
m_nscount = m__io->read_u2be();
}
n_arcount = true;
if (flags()->is_opcode_valid()) {
n_arcount = false;
m_arcount = m__io->read_u2be();
}
n_queries = true;
if (flags()->is_opcode_valid()) {
n_queries = false;
m_queries = std::unique_ptr<std::vector<std::unique_ptr<query_t>>>(new std::vector<std::unique_ptr<query_t>>());
const int l_queries = qdcount();
for (int i = 0; i < l_queries; i++) {
m_queries->push_back(std::move(std::unique_ptr<query_t>(new query_t(m__io, this, m__root))));
}
}
n_answers = true;
if (flags()->is_opcode_valid()) {
n_answers = false;
m_answers = std::unique_ptr<std::vector<std::unique_ptr<answer_t>>>(new std::vector<std::unique_ptr<answer_t>>());
const int l_answers = ancount();
for (int i = 0; i < l_answers; i++) {
m_answers->push_back(std::move(std::unique_ptr<answer_t>(new answer_t(m__io, this, m__root))));
}
}
n_authorities = true;
if (flags()->is_opcode_valid()) {
n_authorities = false;
m_authorities = std::unique_ptr<std::vector<std::unique_ptr<answer_t>>>(new std::vector<std::unique_ptr<answer_t>>());
const int l_authorities = nscount();
for (int i = 0; i < l_authorities; i++) {
m_authorities->push_back(std::move(std::unique_ptr<answer_t>(new answer_t(m__io, this, m__root))));
}
}
n_additionals = true;
if (flags()->is_opcode_valid()) {
n_additionals = false;
m_additionals = std::unique_ptr<std::vector<std::unique_ptr<answer_t>>>(new std::vector<std::unique_ptr<answer_t>>());
const int l_additionals = arcount();
for (int i = 0; i < l_additionals; i++) {
m_additionals->push_back(std::move(std::unique_ptr<answer_t>(new answer_t(m__io, this, m__root))));
}
}
}
dns_packet_t::~dns_packet_t() {
_clean_up();
}
void dns_packet_t::_clean_up() {
if (!n_qdcount) {
}
if (!n_ancount) {
}
if (!n_nscount) {
}
if (!n_arcount) {
}
if (!n_queries) {
}
if (!n_answers) {
}
if (!n_authorities) {
}
if (!n_additionals) {
}
}
dns_packet_t::mx_info_t::mx_info_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_mx = nullptr;
_read();
}
void dns_packet_t::mx_info_t::_read() {
m_preference = m__io->read_u2be();
m_mx = std::unique_ptr<domain_name_t>(new domain_name_t(m__io, this, m__root));
}
dns_packet_t::mx_info_t::~mx_info_t() {
_clean_up();
}
void dns_packet_t::mx_info_t::_clean_up() {
}
dns_packet_t::pointer_struct_t::pointer_struct_t(kaitai::kstream* p__io, dns_packet_t::label_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_contents = nullptr;
f_contents = false;
_read();
}
void dns_packet_t::pointer_struct_t::_read() {
m_value = m__io->read_u1();
}
dns_packet_t::pointer_struct_t::~pointer_struct_t() {
_clean_up();
}
void dns_packet_t::pointer_struct_t::_clean_up() {
if (f_contents) {
}
}
dns_packet_t::domain_name_t* dns_packet_t::pointer_struct_t::contents() {
if (f_contents)
return m_contents.get();
kaitai::kstream *io = _root()->_io();
std::streampos _pos = io->pos();
io->seek((value() + ((_parent()->length() - 192) << 8)));
m_contents = std::unique_ptr<domain_name_t>(new domain_name_t(io, this, m__root));
io->seek(_pos);
f_contents = true;
return m_contents.get();
}
dns_packet_t::label_t::label_t(kaitai::kstream* p__io, dns_packet_t::domain_name_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_pointer = nullptr;
f_is_pointer = false;
_read();
}
void dns_packet_t::label_t::_read() {
m_length = m__io->read_u1();
n_pointer = true;
if (is_pointer()) {
n_pointer = false;
m_pointer = std::unique_ptr<pointer_struct_t>(new pointer_struct_t(m__io, this, m__root));
}
n_name = true;
if (!(is_pointer())) {
n_name = false;
m_name = kaitai::kstream::bytes_to_str(m__io->read_bytes(length()), std::string("utf-8"));
}
}
dns_packet_t::label_t::~label_t() {
_clean_up();
}
void dns_packet_t::label_t::_clean_up() {
if (!n_pointer) {
}
if (!n_name) {
}
}
bool dns_packet_t::label_t::is_pointer() {
if (f_is_pointer)
return m_is_pointer;
m_is_pointer = length() >= 192;
f_is_pointer = true;
return m_is_pointer;
}
dns_packet_t::query_t::query_t(kaitai::kstream* p__io, dns_packet_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_name = nullptr;
_read();
}
void dns_packet_t::query_t::_read() {
m_name = std::unique_ptr<domain_name_t>(new domain_name_t(m__io, this, m__root));
m_type = static_cast<dns_packet_t::type_type_t>(m__io->read_u2be());
m_query_class = static_cast<dns_packet_t::class_type_t>(m__io->read_u2be());
}
dns_packet_t::query_t::~query_t() {
_clean_up();
}
void dns_packet_t::query_t::_clean_up() {
}
dns_packet_t::domain_name_t::domain_name_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_name = nullptr;
_read();
}
void dns_packet_t::domain_name_t::_read() {
m_name = std::unique_ptr<std::vector<std::unique_ptr<label_t>>>(new std::vector<std::unique_ptr<label_t>>());
{
int i = 0;
label_t* _;
do {
_ = new label_t(m__io, this, m__root);
m_name->push_back(std::move(std::unique_ptr<label_t>(_)));
i++;
} while (!( ((_->length() == 0) || (_->length() >= 192)) ));
}
}
dns_packet_t::domain_name_t::~domain_name_t() {
_clean_up();
}
void dns_packet_t::domain_name_t::_clean_up() {
}
dns_packet_t::address_v6_t::address_v6_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void dns_packet_t::address_v6_t::_read() {
m_ip_v6 = m__io->read_bytes(16);
}
dns_packet_t::address_v6_t::~address_v6_t() {
_clean_up();
}
void dns_packet_t::address_v6_t::_clean_up() {
}
dns_packet_t::service_t::service_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_target = nullptr;
_read();
}
void dns_packet_t::service_t::_read() {
m_priority = m__io->read_u2be();
m_weight = m__io->read_u2be();
m_port = m__io->read_u2be();
m_target = std::unique_ptr<domain_name_t>(new domain_name_t(m__io, this, m__root));
}
dns_packet_t::service_t::~service_t() {
_clean_up();
}
void dns_packet_t::service_t::_clean_up() {
}
dns_packet_t::txt_t::txt_t(kaitai::kstream* p__io, dns_packet_t::txt_body_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void dns_packet_t::txt_t::_read() {
m_length = m__io->read_u1();
m_text = kaitai::kstream::bytes_to_str(m__io->read_bytes(length()), std::string("utf-8"));
}
dns_packet_t::txt_t::~txt_t() {
_clean_up();
}
void dns_packet_t::txt_t::_clean_up() {
}
dns_packet_t::txt_body_t::txt_body_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_data = nullptr;
_read();
}
void dns_packet_t::txt_body_t::_read() {
m_data = std::unique_ptr<std::vector<std::unique_ptr<txt_t>>>(new std::vector<std::unique_ptr<txt_t>>());
{
int i = 0;
while (!m__io->is_eof()) {
m_data->push_back(std::move(std::unique_ptr<txt_t>(new txt_t(m__io, this, m__root))));
i++;
}
}
}
dns_packet_t::txt_body_t::~txt_body_t() {
_clean_up();
}
void dns_packet_t::txt_body_t::_clean_up() {
}
dns_packet_t::address_t::address_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void dns_packet_t::address_t::_read() {
m_ip = m__io->read_bytes(4);
}
dns_packet_t::address_t::~address_t() {
_clean_up();
}
void dns_packet_t::address_t::_clean_up() {
}
dns_packet_t::answer_t::answer_t(kaitai::kstream* p__io, dns_packet_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_name = nullptr;
m__io__raw_payload = nullptr;
_read();
}
void dns_packet_t::answer_t::_read() {
m_name = std::unique_ptr<domain_name_t>(new domain_name_t(m__io, this, m__root));
m_type = static_cast<dns_packet_t::type_type_t>(m__io->read_u2be());
m_answer_class = static_cast<dns_packet_t::class_type_t>(m__io->read_u2be());
m_ttl = m__io->read_s4be();
m_rdlength = m__io->read_u2be();
n_payload = true;
switch (type()) {
case dns_packet_t::TYPE_TYPE_SRV: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<service_t>(new service_t(m__io__raw_payload.get(), this, m__root));
break;
}
case dns_packet_t::TYPE_TYPE_A: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<address_t>(new address_t(m__io__raw_payload.get(), this, m__root));
break;
}
case dns_packet_t::TYPE_TYPE_CNAME: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<domain_name_t>(new domain_name_t(m__io__raw_payload.get(), this, m__root));
break;
}
case dns_packet_t::TYPE_TYPE_NS: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<domain_name_t>(new domain_name_t(m__io__raw_payload.get(), this, m__root));
break;
}
case dns_packet_t::TYPE_TYPE_SOA: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<authority_info_t>(new authority_info_t(m__io__raw_payload.get(), this, m__root));
break;
}
case dns_packet_t::TYPE_TYPE_MX: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<mx_info_t>(new mx_info_t(m__io__raw_payload.get(), this, m__root));
break;
}
case dns_packet_t::TYPE_TYPE_TXT: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<txt_body_t>(new txt_body_t(m__io__raw_payload.get(), this, m__root));
break;
}
case dns_packet_t::TYPE_TYPE_PTR: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<domain_name_t>(new domain_name_t(m__io__raw_payload.get(), this, m__root));
break;
}
case dns_packet_t::TYPE_TYPE_AAAA: {
n_payload = false;
m__raw_payload = m__io->read_bytes(rdlength());
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<address_v6_t>(new address_v6_t(m__io__raw_payload.get(), this, m__root));
break;
}
default: {
m__raw_payload = m__io->read_bytes(rdlength());
break;
}
}
}
dns_packet_t::answer_t::~answer_t() {
_clean_up();
}
void dns_packet_t::answer_t::_clean_up() {
if (!n_payload) {
}
}
dns_packet_t::packet_flags_t::packet_flags_t(kaitai::kstream* p__io, dns_packet_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_qr = false;
f_ra = false;
f_tc = false;
f_is_opcode_valid = false;
f_rcode = false;
f_opcode = false;
f_aa = false;
f_z = false;
f_rd = false;
f_cd = false;
f_ad = false;
_read();
}
void dns_packet_t::packet_flags_t::_read() {
m_flag = m__io->read_u2be();
}
dns_packet_t::packet_flags_t::~packet_flags_t() {
_clean_up();
}
void dns_packet_t::packet_flags_t::_clean_up() {
}
int32_t dns_packet_t::packet_flags_t::qr() {
if (f_qr)
return m_qr;
m_qr = ((flag() & 32768) >> 15);
f_qr = true;
return m_qr;
}
int32_t dns_packet_t::packet_flags_t::ra() {
if (f_ra)
return m_ra;
m_ra = ((flag() & 128) >> 7);
f_ra = true;
return m_ra;
}
int32_t dns_packet_t::packet_flags_t::tc() {
if (f_tc)
return m_tc;
m_tc = ((flag() & 512) >> 9);
f_tc = true;
return m_tc;
}
bool dns_packet_t::packet_flags_t::is_opcode_valid() {
if (f_is_opcode_valid)
return m_is_opcode_valid;
m_is_opcode_valid = ((opcode() == 0) || (opcode() == 1) || (opcode() == 2)) ;
f_is_opcode_valid = true;
return m_is_opcode_valid;
}
int32_t dns_packet_t::packet_flags_t::rcode() {
if (f_rcode)
return m_rcode;
m_rcode = ((flag() & 15) >> 0);
f_rcode = true;
return m_rcode;
}
int32_t dns_packet_t::packet_flags_t::opcode() {
if (f_opcode)
return m_opcode;
m_opcode = ((flag() & 30720) >> 11);
f_opcode = true;
return m_opcode;
}
int32_t dns_packet_t::packet_flags_t::aa() {
if (f_aa)
return m_aa;
m_aa = ((flag() & 1024) >> 10);
f_aa = true;
return m_aa;
}
int32_t dns_packet_t::packet_flags_t::z() {
if (f_z)
return m_z;
m_z = ((flag() & 64) >> 6);
f_z = true;
return m_z;
}
int32_t dns_packet_t::packet_flags_t::rd() {
if (f_rd)
return m_rd;
m_rd = ((flag() & 256) >> 8);
f_rd = true;
return m_rd;
}
int32_t dns_packet_t::packet_flags_t::cd() {
if (f_cd)
return m_cd;
m_cd = ((flag() & 16) >> 4);
f_cd = true;
return m_cd;
}
int32_t dns_packet_t::packet_flags_t::ad() {
if (f_ad)
return m_ad;
m_ad = ((flag() & 32) >> 5);
f_ad = true;
return m_ad;
}
dns_packet_t::authority_info_t::authority_info_t(kaitai::kstream* p__io, dns_packet_t::answer_t* p__parent, dns_packet_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_primary_ns = nullptr;
m_resoponsible_mailbox = nullptr;
_read();
}
void dns_packet_t::authority_info_t::_read() {
m_primary_ns = std::unique_ptr<domain_name_t>(new domain_name_t(m__io, this, m__root));
m_resoponsible_mailbox = std::unique_ptr<domain_name_t>(new domain_name_t(m__io, this, m__root));
m_serial = m__io->read_u4be();
m_refresh_interval = m__io->read_u4be();
m_retry_interval = m__io->read_u4be();
m_expire_limit = m__io->read_u4be();
m_min_ttl = m__io->read_u4be();
}
dns_packet_t::authority_info_t::~authority_info_t() {
_clean_up();
}
void dns_packet_t::authority_info_t::_clean_up() {
}