Created
March 20, 2012 12:33
-
-
Save anonymous/2134712 to your computer and use it in GitHub Desktop.
BinPAC generated DNS parser output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace binpac { | |
namespace DNS { | |
ContextDNS::ContextDNS(DNS_Conn * connection, DNS_Flow * flow) | |
{ | |
connection_ = connection; | |
flow_ = flow; | |
} | |
ContextDNS::~ContextDNS() | |
{ | |
} | |
DNS_header::DNS_header() | |
{ | |
id_ = 0; | |
qrop_ = 0; | |
qdcount_ = 0; | |
ancount_ = 0; | |
nscount_ = 0; | |
arcount_ = 0; | |
opcode_ = 0; | |
z_ = 0; | |
rcode_ = 0; | |
} | |
DNS_header::~DNS_header() | |
{ | |
} | |
int DNS_header::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context, int t_byteorder) | |
{ | |
// Checking out-of-bound for "DNS_header" | |
if ( t_begin_of_data + (12) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_header", | |
(0) + (12), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "id" | |
id_ = FixByteOrder(t_byteorder, *((uint16 const *) (t_begin_of_data))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "qrop" | |
qrop_ = FixByteOrder(t_byteorder, *((uint16 const *) ((t_begin_of_data + 2)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "qdcount" | |
qdcount_ = FixByteOrder(t_byteorder, *((uint16 const *) ((t_begin_of_data + 4)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "ancount" | |
ancount_ = FixByteOrder(t_byteorder, *((uint16 const *) ((t_begin_of_data + 6)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "nscount" | |
nscount_ = FixByteOrder(t_byteorder, *((uint16 const *) ((t_begin_of_data + 8)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "arcount" | |
arcount_ = FixByteOrder(t_byteorder, *((uint16 const *) ((t_begin_of_data + 10)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Evaluate 'let' and 'withinput' fields | |
qr_ = qrop() >> 15; | |
opcode_ = ( qrop() >> 11 ) & 0xf; | |
aa_ = ( qrop() >> 10 ) & 0x1; | |
tc_ = ( qrop() >> 9 ) & 0x1; | |
rd_ = ( qrop() >> 8 ) & 0x1; | |
ra_ = ( qrop() >> 7 ) & 0x1; | |
z_ = ( qrop() >> 4 ) & 0x7; | |
rcode_ = qrop() & 0xf; | |
proc_dns_header_ = t_context->flow()->process_dns_header(this); | |
BINPAC_ASSERT(t_begin_of_data + (12) <= t_end_of_data); | |
return 12; | |
} | |
DNS_label::DNS_label(DNS_message * msg) | |
{ | |
length_ = 0; | |
data_case_index_ = -1; | |
ptr_lo_ = 0; | |
msg_ = msg; | |
label_type_ = 0; | |
ptr_ = 0; | |
} | |
DNS_label::~DNS_label() | |
{ | |
switch ( data_case_index() ) | |
{ | |
case 0: | |
// Clean up "label" | |
{ | |
label_.free(); | |
} | |
break; | |
case 3: | |
// Clean up "ptr_lo" | |
{ | |
} | |
break; | |
} | |
delete ptr_; | |
ptr_ = 0; | |
} | |
int DNS_label::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context) | |
{ | |
// Checking out-of-bound for "DNS_label:length" | |
if ( t_begin_of_data + (1) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_label:length", | |
(0) + (1), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "length" | |
length_ = *((uint8 const *) (t_begin_of_data)); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "data" | |
int t_data__size; | |
label_type_ = length() >> 6; | |
data_case_index_ = label_type(); | |
switch ( data_case_index() ) | |
{ | |
case 0: | |
// Parse "label" | |
{ | |
int t_label__size; | |
t_label__size = length(); | |
// Checking out-of-bound for "DNS_label:label" | |
if ( (t_begin_of_data + 1) + (t_label__size) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_label:label", | |
(1) + (t_label__size), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
{ | |
// Setting t_end_of_data with &length | |
const_byteptr t_end_of_data = (t_begin_of_data + 1) + t_label__size; | |
int t_label_string_length; | |
t_label_string_length = length(); | |
// check for negative sizes | |
if ( t_label_string_length < 0 ) | |
throw ExceptionInvalidStringLength("/src/dns-protocol.pac:68", t_label_string_length); | |
label_.init((t_begin_of_data + 1), t_label_string_length); | |
// Evaluate 'let' and 'withinput' fields | |
} | |
t_data__size = t_label__size; | |
} | |
break; | |
case 3: | |
// Parse "ptr_lo" | |
{ | |
// Checking out-of-bound for "DNS_label:ptr_lo" | |
if ( (t_begin_of_data + 1) + (1) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_label:ptr_lo", | |
(1) + (1), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
ptr_lo_ = *((uint8 const *) ((t_begin_of_data + 1))); | |
// Evaluate 'let' and 'withinput' fields | |
t_data__size = 1; | |
} | |
break; | |
default: | |
throw ExceptionInvalidCaseIndex("DNS_label", data_case_index()); | |
break; | |
} | |
// Evaluate 'let' and 'withinput' fields | |
int t_DNS_label__size; | |
const_byteptr const t_dataptr_after_data = (t_begin_of_data + 1) + (t_data__size); | |
BINPAC_ASSERT(t_dataptr_after_data <= t_end_of_data); | |
t_DNS_label__size = t_dataptr_after_data - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
last_ = ( length() == 0 ) || ( label_type() == 3 ) ; | |
// Parse "ptr" | |
has_ptr_ = ( label_type() == 3 ) ; | |
if ( has_ptr() ) | |
{ | |
ptr_ = new DNS_name(msg()); | |
const_byteptr t_begin_of_data, t_end_of_data; | |
get_pointers(t_context->flow()->get_pointer(msg()->sourcedata(), ( ( length() & 0x3f ) << 8 ) | ptr_lo()), &t_begin_of_data, &t_end_of_data); | |
int t_ptr__size; | |
t_ptr__size = ptr_->Parse(t_begin_of_data, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
} | |
has_clear_pointer_set_ = ( last() ) ; | |
if ( has_clear_pointer_set() ) | |
{ | |
clear_pointer_set_ = t_context->flow()->reset_pointer_set(); | |
} | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_label__size) <= t_end_of_data); | |
return t_DNS_label__size; | |
} | |
DNS_name::DNS_name(DNS_message * msg) | |
{ | |
labels_ = 0; | |
labels__elem_ = 0; | |
msg_ = msg; | |
} | |
DNS_name::~DNS_name() | |
{ | |
delete labels__elem_; | |
labels__elem_ = 0; | |
if ( labels() ) | |
{ | |
for ( int i = 0; i < (int) labels()->size(); ++i ) | |
{ | |
DNS_label * labels__elem_ = (*labels_)[i]; | |
delete labels__elem_; | |
labels__elem_ = 0; | |
} | |
} | |
delete labels_; | |
} | |
int DNS_name::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context) | |
{ | |
// Parse "labels" | |
int t_labels__arraylength; | |
labels__elem_ = 0; | |
int t_labels__elem__it; | |
t_labels__elem__it = 0; | |
int t_labels__size; | |
labels_ = new vector<DNS_label *>; | |
const_byteptr t_labels__elem__dataptr = t_begin_of_data; | |
for (; /* forever */; ++t_labels__elem__it) | |
{ | |
// Check &until(labels__elem__dataptr >= end_of_data) | |
if ( t_labels__elem__dataptr >= t_end_of_data ) | |
{ | |
labels__elem_ = 0; | |
goto end_of_labels; | |
} | |
labels__elem_ = new DNS_label(msg()); | |
int t_labels__elem__size; | |
t_labels__elem__size = labels__elem_->Parse(t_labels__elem__dataptr, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
labels_->push_back(labels__elem_); | |
t_labels__elem__dataptr += t_labels__elem__size; | |
BINPAC_ASSERT(t_labels__elem__dataptr <= t_end_of_data); | |
// Check &until( ( @$element->last@ ) ) | |
if ( ( labels__elem_->last() ) ) | |
{ | |
labels__elem_ = 0; | |
goto end_of_labels; | |
} | |
labels__elem_ = 0; | |
} | |
end_of_labels: ; | |
t_labels__size = t_labels__elem__dataptr - (t_begin_of_data); | |
// Evaluate 'let' and 'withinput' fields | |
int t_DNS_name__size; | |
const_byteptr const t_dataptr_after_labels = t_begin_of_data + (t_labels__size); | |
BINPAC_ASSERT(t_dataptr_after_labels <= t_end_of_data); | |
t_DNS_name__size = t_dataptr_after_labels - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_name__size) <= t_end_of_data); | |
return t_DNS_name__size; | |
} | |
DNS_char_string::DNS_char_string() | |
{ | |
length_ = 0; | |
} | |
DNS_char_string::~DNS_char_string() | |
{ | |
data_.free(); | |
} | |
int DNS_char_string::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data) | |
{ | |
// Checking out-of-bound for "DNS_char_string:length" | |
if ( t_begin_of_data + (1) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_char_string:length", | |
(0) + (1), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "length" | |
length_ = *((uint8 const *) (t_begin_of_data)); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "data" | |
int t_data__size; | |
t_data__size = length(); | |
// Checking out-of-bound for "DNS_char_string:data" | |
if ( (t_begin_of_data + 1) + (t_data__size) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_char_string:data", | |
(1) + (t_data__size), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
{ | |
// Setting t_end_of_data with &length | |
const_byteptr t_end_of_data = (t_begin_of_data + 1) + t_data__size; | |
int t_data_string_length; | |
t_data_string_length = length(); | |
// check for negative sizes | |
if ( t_data_string_length < 0 ) | |
throw ExceptionInvalidStringLength("/src/dns-protocol.pac:91", t_data_string_length); | |
data_.init((t_begin_of_data + 1), t_data_string_length); | |
// Evaluate 'let' and 'withinput' fields | |
} | |
int t_DNS_char_string__size; | |
const_byteptr const t_dataptr_after_data = (t_begin_of_data + 1) + (t_data__size); | |
BINPAC_ASSERT(t_dataptr_after_data <= t_end_of_data); | |
t_DNS_char_string__size = t_dataptr_after_data - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_char_string__size) <= t_end_of_data); | |
return t_DNS_char_string__size; | |
} | |
DNS_question::DNS_question(DNS_message * msg) | |
{ | |
qname_ = 0; | |
qtype_ = 0; | |
qclass_ = 0; | |
msg_ = msg; | |
} | |
DNS_question::~DNS_question() | |
{ | |
delete qname_; | |
qname_ = 0; | |
} | |
int DNS_question::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context, int t_byteorder) | |
{ | |
// Parse "qname" | |
qname_ = new DNS_name(msg()); | |
int t_qname__size; | |
t_qname__size = qname_->Parse(t_begin_of_data, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
const_byteptr const t_dataptr_after_qname = t_begin_of_data + (t_qname__size); | |
BINPAC_ASSERT(t_dataptr_after_qname <= t_end_of_data); | |
// Checking out-of-bound for "DNS_question:qclass" | |
if ( (t_dataptr_after_qname + 2) + (2) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_question:qclass", | |
(((t_dataptr_after_qname + 2) - t_begin_of_data)) + (2), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "qtype" | |
qtype_ = FixByteOrder(t_byteorder, *((uint16 const *) (t_dataptr_after_qname))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "qclass" | |
qclass_ = FixByteOrder(t_byteorder, *((uint16 const *) ((t_dataptr_after_qname + 2)))); | |
// Evaluate 'let' and 'withinput' fields | |
int t_DNS_question__size; | |
t_DNS_question__size = (t_dataptr_after_qname + 4) - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
proc_dns_question_ = t_context->flow()->process_dns_question(this); | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_question__size) <= t_end_of_data); | |
return t_DNS_question__size; | |
} | |
DNS_rdata_MX::DNS_rdata_MX(DNS_message * msg) | |
{ | |
preference_ = 0; | |
name_ = 0; | |
msg_ = msg; | |
} | |
DNS_rdata_MX::~DNS_rdata_MX() | |
{ | |
delete name_; | |
name_ = 0; | |
} | |
int DNS_rdata_MX::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context, int t_byteorder) | |
{ | |
// Checking out-of-bound for "DNS_rdata_MX:preference" | |
if ( t_begin_of_data + (2) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_rdata_MX:preference", | |
(0) + (2), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "preference" | |
preference_ = FixByteOrder(t_byteorder, *((uint16 const *) (t_begin_of_data))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "name" | |
name_ = new DNS_name(msg()); | |
int t_name__size; | |
t_name__size = name_->Parse((t_begin_of_data + 2), t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
int t_DNS_rdata_MX__size; | |
const_byteptr const t_dataptr_after_name = (t_begin_of_data + 2) + (t_name__size); | |
BINPAC_ASSERT(t_dataptr_after_name <= t_end_of_data); | |
t_DNS_rdata_MX__size = t_dataptr_after_name - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_rdata_MX__size) <= t_end_of_data); | |
return t_DNS_rdata_MX__size; | |
} | |
DNS_rdata_SOA::DNS_rdata_SOA(DNS_message * msg) | |
{ | |
mname_ = 0; | |
rname_ = 0; | |
serial_ = 0; | |
refresh_ = 0; | |
retry_ = 0; | |
expire_ = 0; | |
minimum_ = 0; | |
msg_ = msg; | |
} | |
DNS_rdata_SOA::~DNS_rdata_SOA() | |
{ | |
delete mname_; | |
mname_ = 0; | |
delete rname_; | |
rname_ = 0; | |
} | |
int DNS_rdata_SOA::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context, int t_byteorder) | |
{ | |
// Parse "mname" | |
mname_ = new DNS_name(msg()); | |
int t_mname__size; | |
t_mname__size = mname_->Parse(t_begin_of_data, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
const_byteptr const t_dataptr_after_mname = t_begin_of_data + (t_mname__size); | |
BINPAC_ASSERT(t_dataptr_after_mname <= t_end_of_data); | |
// Parse "rname" | |
rname_ = new DNS_name(msg()); | |
int t_rname__size; | |
t_rname__size = rname_->Parse(t_dataptr_after_mname, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
const_byteptr const t_dataptr_after_rname = t_dataptr_after_mname + (t_rname__size); | |
BINPAC_ASSERT(t_dataptr_after_rname <= t_end_of_data); | |
// Checking out-of-bound for "DNS_rdata_SOA:minimum" | |
if ( (t_dataptr_after_rname + 16) + (4) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_rdata_SOA:minimum", | |
(((t_dataptr_after_rname + 16) - t_begin_of_data)) + (4), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "serial" | |
serial_ = FixByteOrder(t_byteorder, *((uint32 const *) (t_dataptr_after_rname))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "refresh" | |
refresh_ = FixByteOrder(t_byteorder, *((uint32 const *) ((t_dataptr_after_rname + 4)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "retry" | |
retry_ = FixByteOrder(t_byteorder, *((uint32 const *) ((t_dataptr_after_rname + 8)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "expire" | |
expire_ = FixByteOrder(t_byteorder, *((uint32 const *) ((t_dataptr_after_rname + 12)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "minimum" | |
minimum_ = FixByteOrder(t_byteorder, *((uint32 const *) ((t_dataptr_after_rname + 16)))); | |
// Evaluate 'let' and 'withinput' fields | |
int t_DNS_rdata_SOA__size; | |
t_DNS_rdata_SOA__size = (t_dataptr_after_rname + 20) - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_rdata_SOA__size) <= t_end_of_data); | |
return t_DNS_rdata_SOA__size; | |
} | |
DNS_rdata_WKS::DNS_rdata_WKS() | |
{ | |
address_ = 0; | |
protocol_ = 0; | |
} | |
DNS_rdata_WKS::~DNS_rdata_WKS() | |
{ | |
bitmap_.free(); | |
} | |
int DNS_rdata_WKS::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, int t_byteorder) | |
{ | |
// Checking out-of-bound for "DNS_rdata_WKS:protocol" | |
if ( (t_begin_of_data + 4) + (1) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_rdata_WKS:protocol", | |
(4) + (1), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "address" | |
address_ = FixByteOrder(t_byteorder, *((uint32 const *) (t_begin_of_data))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "protocol" | |
protocol_ = *((uint8 const *) ((t_begin_of_data + 4))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "bitmap" | |
int t_bitmap_string_length; | |
t_bitmap_string_length = (t_end_of_data) - ((t_begin_of_data + 5)); | |
int t_bitmap__size; | |
t_bitmap__size = t_bitmap_string_length; | |
// check for negative sizes | |
if ( t_bitmap_string_length < 0 ) | |
throw ExceptionInvalidStringLength("/src/dns-protocol.pac:130", t_bitmap_string_length); | |
bitmap_.init((t_begin_of_data + 5), t_bitmap_string_length); | |
// Evaluate 'let' and 'withinput' fields | |
int t_DNS_rdata_WKS__size; | |
const_byteptr const t_dataptr_after_bitmap = (t_begin_of_data + 5) + (t_bitmap__size); | |
BINPAC_ASSERT(t_dataptr_after_bitmap <= t_end_of_data); | |
t_DNS_rdata_WKS__size = t_dataptr_after_bitmap - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_rdata_WKS__size) <= t_end_of_data); | |
return t_DNS_rdata_WKS__size; | |
} | |
DNS_rdata_HINFO::DNS_rdata_HINFO() | |
{ | |
cpu_ = 0; | |
os_ = 0; | |
} | |
DNS_rdata_HINFO::~DNS_rdata_HINFO() | |
{ | |
delete cpu_; | |
cpu_ = 0; | |
delete os_; | |
os_ = 0; | |
} | |
int DNS_rdata_HINFO::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data) | |
{ | |
// Parse "cpu" | |
cpu_ = new DNS_char_string(); | |
int t_cpu__size; | |
t_cpu__size = cpu_->Parse(t_begin_of_data, t_end_of_data); | |
// Evaluate 'let' and 'withinput' fields | |
const_byteptr const t_dataptr_after_cpu = t_begin_of_data + (t_cpu__size); | |
BINPAC_ASSERT(t_dataptr_after_cpu <= t_end_of_data); | |
// Parse "os" | |
os_ = new DNS_char_string(); | |
int t_os__size; | |
t_os__size = os_->Parse(t_dataptr_after_cpu, t_end_of_data); | |
// Evaluate 'let' and 'withinput' fields | |
int t_DNS_rdata_HINFO__size; | |
const_byteptr const t_dataptr_after_os = t_dataptr_after_cpu + (t_os__size); | |
BINPAC_ASSERT(t_dataptr_after_os <= t_end_of_data); | |
t_DNS_rdata_HINFO__size = t_dataptr_after_os - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_rdata_HINFO__size) <= t_end_of_data); | |
return t_DNS_rdata_HINFO__size; | |
} | |
DNS_rdata::DNS_rdata(DNS_message * msg, uint16 rr_type, uint16 rr_class) | |
{ | |
val_case_index_ = -1; | |
type_a_ = 0; | |
type_ns_ = 0; | |
type_cname_ = 0; | |
type_soa_ = 0; | |
type_ptr_ = 0; | |
type_mx_ = 0; | |
type_aaaa_ = 0; | |
type_aaaa__elem_ = 0; | |
msg_ = msg; | |
rr_type_ = rr_type; | |
rr_class_ = rr_class; | |
} | |
DNS_rdata::~DNS_rdata() | |
{ | |
switch ( val_case_index() ) | |
{ | |
case 1: | |
// Clean up "type_a" | |
{ | |
} | |
break; | |
case 2: | |
// Clean up "type_ns" | |
{ | |
delete type_ns_; | |
type_ns_ = 0; | |
} | |
break; | |
case 5: | |
// Clean up "type_cname" | |
{ | |
delete type_cname_; | |
type_cname_ = 0; | |
} | |
break; | |
case 6: | |
// Clean up "type_soa" | |
{ | |
delete type_soa_; | |
type_soa_ = 0; | |
} | |
break; | |
case 12: | |
// Clean up "type_ptr" | |
{ | |
delete type_ptr_; | |
type_ptr_ = 0; | |
} | |
break; | |
case 15: | |
// Clean up "type_mx" | |
{ | |
delete type_mx_; | |
type_mx_ = 0; | |
} | |
break; | |
case 28: | |
case 38: | |
// Clean up "type_aaaa" | |
{ | |
delete type_aaaa_; | |
} | |
break; | |
default: | |
// Clean up "unknown" | |
{ | |
unknown_.free(); | |
} | |
break; | |
} | |
} | |
int DNS_rdata::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context, int t_byteorder) | |
{ | |
int t_val__size; | |
val_case_index_ = rr_type(); | |
switch ( val_case_index() ) | |
{ | |
case 1: | |
// Parse "type_a" | |
{ | |
// Checking out-of-bound for "DNS_rdata:type_a" | |
if ( t_begin_of_data + (4) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_rdata:type_a", | |
(0) + (4), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
type_a_ = FixByteOrder(t_byteorder, *((uint32 const *) (t_begin_of_data))); | |
// Evaluate 'let' and 'withinput' fields | |
t_val__size = 4; | |
} | |
break; | |
case 2: | |
// Parse "type_ns" | |
{ | |
type_ns_ = new DNS_name(msg()); | |
int t_type_ns__size; | |
t_type_ns__size = type_ns_->Parse(t_begin_of_data, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
t_val__size = t_type_ns__size; | |
} | |
break; | |
case 5: | |
// Parse "type_cname" | |
{ | |
type_cname_ = new DNS_name(msg()); | |
int t_type_cname__size; | |
t_type_cname__size = type_cname_->Parse(t_begin_of_data, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
t_val__size = t_type_cname__size; | |
} | |
break; | |
case 6: | |
// Parse "type_soa" | |
{ | |
type_soa_ = new DNS_rdata_SOA(msg()); | |
int t_type_soa__size; | |
t_type_soa__size = type_soa_->Parse(t_begin_of_data, t_end_of_data, t_context, t_byteorder); | |
// Evaluate 'let' and 'withinput' fields | |
t_val__size = t_type_soa__size; | |
} | |
break; | |
case 12: | |
// Parse "type_ptr" | |
{ | |
type_ptr_ = new DNS_name(msg()); | |
int t_type_ptr__size; | |
t_type_ptr__size = type_ptr_->Parse(t_begin_of_data, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
t_val__size = t_type_ptr__size; | |
} | |
break; | |
case 15: | |
// Parse "type_mx" | |
{ | |
type_mx_ = new DNS_rdata_MX(msg()); | |
int t_type_mx__size; | |
t_type_mx__size = type_mx_->Parse(t_begin_of_data, t_end_of_data, t_context, t_byteorder); | |
// Evaluate 'let' and 'withinput' fields | |
t_val__size = t_type_mx__size; | |
} | |
break; | |
case 28: | |
case 38: | |
// Parse "type_aaaa" | |
{ | |
int t_type_aaaa__arraylength; | |
t_type_aaaa__arraylength = 4; | |
if ( t_begin_of_data + t_type_aaaa__arraylength > t_end_of_data + 1 ) | |
{ | |
t_type_aaaa__arraylength = t_end_of_data - t_begin_of_data + 1; | |
} | |
if ( t_type_aaaa__arraylength < 0 ) | |
{ | |
t_type_aaaa__arraylength = 0; | |
} | |
type_aaaa__elem_ = 0; | |
int t_type_aaaa__elem__it; | |
t_type_aaaa__elem__it = 0; | |
type_aaaa_ = new vector<uint32>; | |
type_aaaa_->reserve(t_type_aaaa__arraylength); | |
const_byteptr t_type_aaaa__elem__dataptr = t_begin_of_data; | |
for (; t_type_aaaa__elem__it < t_type_aaaa__arraylength; ++t_type_aaaa__elem__it) | |
{ | |
// Check &until(type_aaaa__elem__dataptr >= end_of_data) | |
if ( t_type_aaaa__elem__dataptr >= t_end_of_data ) | |
{ | |
goto end_of_type_aaaa; | |
} | |
// Checking out-of-bound for "DNS_rdata:type_aaaa__elem" | |
if ( t_type_aaaa__elem__dataptr + (4) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_rdata:type_aaaa__elem", | |
((t_type_aaaa__elem__dataptr - t_begin_of_data)) + (4), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
type_aaaa__elem_ = FixByteOrder(t_byteorder, *((uint32 const *) (t_type_aaaa__elem__dataptr))); | |
// Evaluate 'let' and 'withinput' fields | |
type_aaaa_->push_back(type_aaaa__elem_); | |
t_type_aaaa__elem__dataptr += 4; | |
BINPAC_ASSERT(t_type_aaaa__elem__dataptr <= t_end_of_data); | |
} | |
end_of_type_aaaa: ; | |
// Evaluate 'let' and 'withinput' fields | |
t_val__size = 16; | |
} | |
break; | |
default: | |
// Parse "unknown" | |
{ | |
int t_unknown_string_length; | |
t_unknown_string_length = (t_end_of_data) - (t_begin_of_data); | |
int t_unknown__size; | |
t_unknown__size = t_unknown_string_length; | |
// check for negative sizes | |
if ( t_unknown_string_length < 0 ) | |
throw ExceptionInvalidStringLength("/src/dns-protocol.pac:164", t_unknown_string_length); | |
unknown_.init(t_begin_of_data, t_unknown_string_length); | |
// Evaluate 'let' and 'withinput' fields | |
t_val__size = t_unknown__size; | |
} | |
break; | |
} | |
// Evaluate 'let' and 'withinput' fields | |
BINPAC_ASSERT(t_begin_of_data + (t_val__size) <= t_end_of_data); | |
return t_val__size; | |
} | |
DNS_rr::DNS_rr(DNS_message * msg, DNS_answer_type answer_type) | |
{ | |
rr_name_ = 0; | |
rr_type_ = 0; | |
rr_class_ = 0; | |
rr_ttl_ = 0; | |
rr_rdlength_ = 0; | |
rr_rdata_ = 0; | |
msg_ = msg; | |
answer_type_ = answer_type; | |
} | |
DNS_rr::~DNS_rr() | |
{ | |
delete rr_name_; | |
rr_name_ = 0; | |
delete rr_rdata_; | |
rr_rdata_ = 0; | |
} | |
int DNS_rr::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context, int t_byteorder) | |
{ | |
// Parse "rr_name" | |
rr_name_ = new DNS_name(msg()); | |
int t_rr_name__size; | |
t_rr_name__size = rr_name_->Parse(t_begin_of_data, t_end_of_data, t_context); | |
// Evaluate 'let' and 'withinput' fields | |
const_byteptr const t_dataptr_after_rr_name = t_begin_of_data + (t_rr_name__size); | |
BINPAC_ASSERT(t_dataptr_after_rr_name <= t_end_of_data); | |
// Checking out-of-bound for "DNS_rr:rr_rdlength" | |
if ( (t_dataptr_after_rr_name + 8) + (2) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_rr:rr_rdlength", | |
(((t_dataptr_after_rr_name + 8) - t_begin_of_data)) + (2), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "rr_type" | |
rr_type_ = FixByteOrder(t_byteorder, *((uint16 const *) (t_dataptr_after_rr_name))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "rr_class" | |
rr_class_ = FixByteOrder(t_byteorder, *((uint16 const *) ((t_dataptr_after_rr_name + 2)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "rr_ttl" | |
rr_ttl_ = FixByteOrder(t_byteorder, *((uint32 const *) ((t_dataptr_after_rr_name + 4)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "rr_rdlength" | |
rr_rdlength_ = FixByteOrder(t_byteorder, *((uint16 const *) ((t_dataptr_after_rr_name + 8)))); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "rr_rdata" | |
rr_rdata_ = new DNS_rdata(msg(), rr_type(), rr_class()); | |
int t_rr_rdata__size; | |
t_rr_rdata__size = rr_rdlength(); | |
// Checking out-of-bound for "DNS_rr:rr_rdata" | |
if ( (t_dataptr_after_rr_name + 10) + (t_rr_rdata__size) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_rr:rr_rdata", | |
(((t_dataptr_after_rr_name + 10) - t_begin_of_data)) + (t_rr_rdata__size), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
{ | |
// Setting t_end_of_data with &length | |
const_byteptr t_end_of_data = (t_dataptr_after_rr_name + 10) + t_rr_rdata__size; | |
rr_rdata_->Parse((t_dataptr_after_rr_name + 10), t_end_of_data, t_context, t_byteorder); | |
// Evaluate 'let' and 'withinput' fields | |
} | |
int t_DNS_rr__size; | |
const_byteptr const t_dataptr_after_rr_rdata = (t_dataptr_after_rr_name + 10) + (t_rr_rdata__size); | |
BINPAC_ASSERT(t_dataptr_after_rr_rdata <= t_end_of_data); | |
t_DNS_rr__size = t_dataptr_after_rr_rdata - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
proc_dns_rr_ = t_context->flow()->process_dns_rr(this); | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_rr__size) <= t_end_of_data); | |
return t_DNS_rr__size; | |
} | |
DNS_message::DNS_message() | |
{ | |
header_ = 0; | |
question_ = 0; | |
question__elem_ = 0; | |
answer_ = 0; | |
answer__elem_ = 0; | |
authority_ = 0; | |
authority__elem_ = 0; | |
additional_ = 0; | |
additional__elem_ = 0; | |
byteorder_ = bigendian; | |
} | |
DNS_message::~DNS_message() | |
{ | |
delete header_; | |
header_ = 0; | |
delete question__elem_; | |
question__elem_ = 0; | |
if ( question() ) | |
{ | |
for ( int i = 0; i < (int) question()->size(); ++i ) | |
{ | |
DNS_question * question__elem_ = (*question_)[i]; | |
delete question__elem_; | |
question__elem_ = 0; | |
} | |
} | |
delete question_; | |
delete answer__elem_; | |
answer__elem_ = 0; | |
if ( answer() ) | |
{ | |
for ( int i = 0; i < (int) answer()->size(); ++i ) | |
{ | |
DNS_rr * answer__elem_ = (*answer_)[i]; | |
delete answer__elem_; | |
answer__elem_ = 0; | |
} | |
} | |
delete answer_; | |
delete authority__elem_; | |
authority__elem_ = 0; | |
if ( authority() ) | |
{ | |
for ( int i = 0; i < (int) authority()->size(); ++i ) | |
{ | |
DNS_rr * authority__elem_ = (*authority_)[i]; | |
delete authority__elem_; | |
authority__elem_ = 0; | |
} | |
} | |
delete authority_; | |
delete additional__elem_; | |
additional__elem_ = 0; | |
if ( additional() ) | |
{ | |
for ( int i = 0; i < (int) additional()->size(); ++i ) | |
{ | |
DNS_rr * additional__elem_ = (*additional_)[i]; | |
delete additional__elem_; | |
additional__elem_ = 0; | |
} | |
} | |
delete additional_; | |
} | |
int DNS_message::Parse(const_byteptr const t_begin_of_data, const_byteptr const t_end_of_data, ContextDNS * t_context) | |
{ | |
sourcedata_ = const_bytestring(t_begin_of_data, t_end_of_data); | |
// Checking out-of-bound for "DNS_message:header" | |
if ( t_begin_of_data + (12) > t_end_of_data ) | |
{ | |
// Handle out-of-bound condition | |
throw ExceptionOutOfBound("DNS_message:header", | |
(0) + (12), | |
(t_end_of_data) - (t_begin_of_data)); | |
} | |
// Parse "header" | |
header_ = new DNS_header(); | |
header_->Parse(t_begin_of_data, t_end_of_data, t_context, byteorder()); | |
// Evaluate 'let' and 'withinput' fields | |
// Parse "question" | |
int t_question__arraylength; | |
t_question__arraylength = header()->qdcount(); | |
if ( t_begin_of_data + t_question__arraylength > t_end_of_data + 1 ) | |
{ | |
t_question__arraylength = t_end_of_data - t_begin_of_data + 1; | |
} | |
if ( t_question__arraylength < 0 ) | |
{ | |
t_question__arraylength = 0; | |
} | |
question__elem_ = 0; | |
int t_question__elem__it; | |
t_question__elem__it = 0; | |
int t_question__size; | |
question_ = new vector<DNS_question *>; | |
question_->reserve(t_question__arraylength); | |
const_byteptr t_question__elem__dataptr = (t_begin_of_data + 12); | |
for (; t_question__elem__it < t_question__arraylength; ++t_question__elem__it) | |
{ | |
// Check &until(question__elem__dataptr >= end_of_data) | |
if ( t_question__elem__dataptr >= t_end_of_data ) | |
{ | |
question__elem_ = 0; | |
goto end_of_question; | |
} | |
question__elem_ = new DNS_question(this); | |
int t_question__elem__size; | |
t_question__elem__size = question__elem_->Parse(t_question__elem__dataptr, t_end_of_data, t_context, byteorder()); | |
// Evaluate 'let' and 'withinput' fields | |
question_->push_back(question__elem_); | |
t_question__elem__dataptr += t_question__elem__size; | |
BINPAC_ASSERT(t_question__elem__dataptr <= t_end_of_data); | |
question__elem_ = 0; | |
} | |
end_of_question: ; | |
t_question__size = t_question__elem__dataptr - ((t_begin_of_data + 12)); | |
// Evaluate 'let' and 'withinput' fields | |
const_byteptr const t_dataptr_after_question = (t_begin_of_data + 12) + (t_question__size); | |
BINPAC_ASSERT(t_dataptr_after_question <= t_end_of_data); | |
// Parse "answer" | |
int t_answer__arraylength; | |
t_answer__arraylength = header()->ancount(); | |
if ( t_begin_of_data + t_answer__arraylength > t_end_of_data + 1 ) | |
{ | |
t_answer__arraylength = t_end_of_data - t_begin_of_data + 1; | |
} | |
if ( t_answer__arraylength < 0 ) | |
{ | |
t_answer__arraylength = 0; | |
} | |
answer__elem_ = 0; | |
int t_answer__elem__it; | |
t_answer__elem__it = 0; | |
int t_answer__size; | |
answer_ = new vector<DNS_rr *>; | |
answer_->reserve(t_answer__arraylength); | |
const_byteptr t_answer__elem__dataptr = t_dataptr_after_question; | |
for (; t_answer__elem__it < t_answer__arraylength; ++t_answer__elem__it) | |
{ | |
// Check &until(answer__elem__dataptr >= end_of_data) | |
if ( t_answer__elem__dataptr >= t_end_of_data ) | |
{ | |
answer__elem_ = 0; | |
goto end_of_answer; | |
} | |
answer__elem_ = new DNS_rr(this, DNS_ANSWER); | |
int t_answer__elem__size; | |
t_answer__elem__size = answer__elem_->Parse(t_answer__elem__dataptr, t_end_of_data, t_context, byteorder()); | |
// Evaluate 'let' and 'withinput' fields | |
answer_->push_back(answer__elem_); | |
t_answer__elem__dataptr += t_answer__elem__size; | |
BINPAC_ASSERT(t_answer__elem__dataptr <= t_end_of_data); | |
answer__elem_ = 0; | |
} | |
end_of_answer: ; | |
t_answer__size = t_answer__elem__dataptr - (t_dataptr_after_question); | |
// Evaluate 'let' and 'withinput' fields | |
const_byteptr const t_dataptr_after_answer = t_dataptr_after_question + (t_answer__size); | |
BINPAC_ASSERT(t_dataptr_after_answer <= t_end_of_data); | |
// Parse "authority" | |
int t_authority__arraylength; | |
t_authority__arraylength = header()->nscount(); | |
if ( t_begin_of_data + t_authority__arraylength > t_end_of_data + 1 ) | |
{ | |
t_authority__arraylength = t_end_of_data - t_begin_of_data + 1; | |
} | |
if ( t_authority__arraylength < 0 ) | |
{ | |
t_authority__arraylength = 0; | |
} | |
authority__elem_ = 0; | |
int t_authority__elem__it; | |
t_authority__elem__it = 0; | |
int t_authority__size; | |
authority_ = new vector<DNS_rr *>; | |
authority_->reserve(t_authority__arraylength); | |
const_byteptr t_authority__elem__dataptr = t_dataptr_after_answer; | |
for (; t_authority__elem__it < t_authority__arraylength; ++t_authority__elem__it) | |
{ | |
// Check &until(authority__elem__dataptr >= end_of_data) | |
if ( t_authority__elem__dataptr >= t_end_of_data ) | |
{ | |
authority__elem_ = 0; | |
goto end_of_authority; | |
} | |
authority__elem_ = new DNS_rr(this, DNS_AUTHORITY); | |
int t_authority__elem__size; | |
t_authority__elem__size = authority__elem_->Parse(t_authority__elem__dataptr, t_end_of_data, t_context, byteorder()); | |
// Evaluate 'let' and 'withinput' fields | |
authority_->push_back(authority__elem_); | |
t_authority__elem__dataptr += t_authority__elem__size; | |
BINPAC_ASSERT(t_authority__elem__dataptr <= t_end_of_data); | |
authority__elem_ = 0; | |
} | |
end_of_authority: ; | |
t_authority__size = t_authority__elem__dataptr - (t_dataptr_after_answer); | |
// Evaluate 'let' and 'withinput' fields | |
const_byteptr const t_dataptr_after_authority = t_dataptr_after_answer + (t_authority__size); | |
BINPAC_ASSERT(t_dataptr_after_authority <= t_end_of_data); | |
// Parse "additional" | |
int t_additional__arraylength; | |
t_additional__arraylength = header()->arcount(); | |
if ( t_begin_of_data + t_additional__arraylength > t_end_of_data + 1 ) | |
{ | |
t_additional__arraylength = t_end_of_data - t_begin_of_data + 1; | |
} | |
if ( t_additional__arraylength < 0 ) | |
{ | |
t_additional__arraylength = 0; | |
} | |
additional__elem_ = 0; | |
int t_additional__elem__it; | |
t_additional__elem__it = 0; | |
int t_additional__size; | |
additional_ = new vector<DNS_rr *>; | |
additional_->reserve(t_additional__arraylength); | |
const_byteptr t_additional__elem__dataptr = t_dataptr_after_authority; | |
for (; t_additional__elem__it < t_additional__arraylength; ++t_additional__elem__it) | |
{ | |
// Check &until(additional__elem__dataptr >= end_of_data) | |
if ( t_additional__elem__dataptr >= t_end_of_data ) | |
{ | |
additional__elem_ = 0; | |
goto end_of_additional; | |
} | |
additional__elem_ = new DNS_rr(this, DNS_ADDITIONAL); | |
int t_additional__elem__size; | |
t_additional__elem__size = additional__elem_->Parse(t_additional__elem__dataptr, t_end_of_data, t_context, byteorder()); | |
// Evaluate 'let' and 'withinput' fields | |
additional_->push_back(additional__elem_); | |
t_additional__elem__dataptr += t_additional__elem__size; | |
BINPAC_ASSERT(t_additional__elem__dataptr <= t_end_of_data); | |
additional__elem_ = 0; | |
} | |
end_of_additional: ; | |
t_additional__size = t_additional__elem__dataptr - (t_dataptr_after_authority); | |
// Evaluate 'let' and 'withinput' fields | |
int t_DNS_message__size; | |
const_byteptr const t_dataptr_after_additional = t_dataptr_after_authority + (t_additional__size); | |
BINPAC_ASSERT(t_dataptr_after_additional <= t_end_of_data); | |
t_DNS_message__size = t_dataptr_after_additional - t_begin_of_data; | |
// Evaluate 'let' and 'withinput' fields | |
sourcedata_.set_end(t_begin_of_data + t_DNS_message__size); | |
BINPAC_ASSERT(t_begin_of_data + (t_DNS_message__size) <= t_end_of_data); | |
return t_DNS_message__size; | |
} | |
int add_to_name_buffer(DNS_name* name, char* buf, const int buf_n, int buf_i) | |
{ | |
for ( int i = 0; i < int(name->labels()->size()); ++i ) | |
{ | |
DNS_label* label = (*name->labels())[i]; | |
if ( label->label_type() == 0 ) | |
{ | |
bytestring const &label_str = label->label(); | |
if ( buf_i > 0 && buf_i < buf_n ) | |
buf[buf_i++] = '.'; | |
BINPAC_ASSERT(buf_i + label_str.length() <= buf_n); | |
memcpy(buf + buf_i, label_str.begin(), | |
label_str.length()); | |
buf_i += label_str.length(); | |
} | |
else if ( label->label_type() == 3 ) | |
{ | |
return add_to_name_buffer(label->ptr(), buf, | |
buf_n, buf_i); | |
} | |
} | |
return buf_i; | |
} | |
StringVal* name_to_val(DNS_name* name) | |
{ | |
char name_buf[520]; | |
int n = add_to_name_buffer(name, name_buf, sizeof(name_buf), 0); | |
if ( n > 0 ) | |
--n; // remove the trailing '.' | |
BINPAC_ASSERT(n < int(sizeof(name_buf))); | |
name_buf[n] = 0; | |
for ( int i = 0; i < n; ++i ) | |
if ( isupper(name_buf[i]) ) | |
name_buf[i] = tolower(name_buf[i]); | |
return new StringVal(name_buf); | |
} | |
DNS_Conn::DNS_Conn(BroAnalyzer const & bro_analyzer) | |
{ | |
upflow_ = new DNS_Flow(this); | |
downflow_ = new DNS_Flow(this); | |
bro_analyzer_ = bro_analyzer; | |
} | |
DNS_Conn::~DNS_Conn() | |
{ | |
delete upflow_; | |
upflow_ = 0; | |
delete downflow_; | |
downflow_ = 0; | |
} | |
void DNS_Conn::NewData(bool is_orig, const_byteptr begin, const_byteptr end) | |
{ | |
if ( is_orig ) | |
upflow_->NewData(begin, end); | |
else | |
downflow_->NewData(begin, end); | |
} | |
void DNS_Conn::NewGap(bool is_orig, int gap_length) | |
{ | |
if ( is_orig ) | |
upflow_->NewGap(gap_length); | |
else | |
downflow_->NewGap(gap_length); | |
} | |
void DNS_Conn::FlowEOF(bool is_orig) | |
{ | |
if ( is_orig ) | |
upflow_->FlowEOF(); | |
else | |
downflow_->FlowEOF(); | |
} | |
DNS_Flow::DNS_Flow(DNS_Conn * connection) | |
{ | |
connection_ = connection; | |
dns_msg_val_ = 0; | |
dataunit_ = 0; | |
context_ = 0; | |
} | |
DNS_Flow::~DNS_Flow() | |
{ | |
delete dataunit_; | |
dataunit_ = 0; | |
delete context_; | |
context_ = 0; | |
Unref(dns_msg_val_); | |
dns_msg_val_ = 0; | |
} | |
void DNS_Flow::NewData(const_byteptr t_begin_of_data, const_byteptr t_end_of_data) | |
{ | |
try | |
{ | |
dataunit_ = new DNS_message(); | |
context_ = new ContextDNS(connection(), this); | |
int t_dataunit__size; | |
t_dataunit__size = dataunit_->Parse(t_begin_of_data, t_end_of_data, context_); | |
// Evaluate 'let' and 'withinput' fields | |
delete dataunit_; | |
dataunit_ = 0; | |
delete context_; | |
context_ = 0; | |
} | |
catch ( Exception const &e ) | |
{ | |
delete dataunit_; | |
dataunit_ = 0; | |
delete context_; | |
context_ = 0; | |
Unref(dns_msg_val_); | |
dns_msg_val_ = 0; | |
throw e; | |
} | |
} | |
void DNS_Flow::NewGap(int gap_length) | |
{ | |
} | |
void DNS_Flow::FlowEOF() | |
{ | |
} | |
const_bytestring DNS_Flow::get_pointer(const_bytestring const & msgdata, int offset) | |
{ | |
if ( offset < 0 || offset >= msgdata.length() ) | |
return const_bytestring(0, 0); | |
if ( pointer_set.find(offset) != pointer_set.end() ) | |
throw Exception("DNS pointer loop!"); | |
pointer_set.insert(offset); | |
return const_bytestring(msgdata.begin() + offset, msgdata.end()); | |
} | |
bool DNS_Flow::reset_pointer_set() | |
{ | |
pointer_set.clear(); | |
return true; | |
} | |
bool DNS_Flow::process_dns_header(DNS_header * hdr) | |
{ | |
Unref(dns_msg_val_); | |
RecordVal* r = new RecordVal(dns_msg); | |
r->Assign(0, new Val(hdr->id(), TYPE_COUNT)); | |
r->Assign(1, new Val(hdr->opcode(), TYPE_COUNT)); | |
r->Assign(2, new Val(hdr->rcode(), TYPE_COUNT)); | |
r->Assign(3, new Val(hdr->qr(), TYPE_BOOL)); | |
r->Assign(4, new Val(hdr->aa(), TYPE_BOOL)); | |
r->Assign(5, new Val(hdr->tc(), TYPE_BOOL)); | |
r->Assign(6, new Val(hdr->rd(), TYPE_BOOL)); | |
r->Assign(7, new Val(hdr->ra(), TYPE_BOOL)); | |
r->Assign(8, new Val(hdr->z(), TYPE_COUNT)); | |
r->Assign(9, new Val(hdr->qdcount(), TYPE_COUNT)); | |
r->Assign(10, new Val(hdr->ancount(), TYPE_COUNT)); | |
r->Assign(11, new Val(hdr->nscount(), TYPE_COUNT)); | |
r->Assign(12, new Val(hdr->arcount(), TYPE_COUNT)); | |
dns_msg_val_ = r; | |
return true; | |
} | |
bool DNS_Flow::process_dns_question(DNS_question * question) | |
{ | |
DNS_message* msg = question->msg(); | |
if ( msg->header()->qr() == 0 ) | |
{ | |
BifEvent::generate_dns_request( | |
connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), | |
name_to_val(question->qname()), | |
question->qtype(), | |
question->qclass()); | |
} | |
else if ( msg->header()->ancount() == 0 && | |
msg->header()->nscount() == 0 && | |
msg->header()->arcount() == 0 ) | |
{ | |
BifEvent::generate_dns_rejected( | |
connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), | |
name_to_val(question->qname()), | |
question->qtype(), | |
question->qclass()); | |
} | |
return true; | |
} | |
BroVal DNS_Flow::build_dns_answer(DNS_rr * rr) | |
{ | |
RecordVal* r = new RecordVal(dns_answer); | |
r->Assign(0, new Val(rr->answer_type(), TYPE_COUNT)); | |
r->Assign(1, name_to_val(rr->rr_name())); | |
r->Assign(2, new Val(rr->rr_type(), TYPE_COUNT)); | |
r->Assign(3, new Val(rr->rr_class(), TYPE_COUNT)); | |
r->Assign(4, new IntervalVal(double(rr->rr_ttl()), Seconds)); | |
return r; | |
} | |
BroVal DNS_Flow::build_dns_soa(DNS_rdata_SOA * soa) | |
{ | |
RecordVal* r = new RecordVal(dns_soa); | |
r->Assign(0, name_to_val(soa->mname())); | |
r->Assign(1, name_to_val(soa->rname())); | |
r->Assign(2, new Val(soa->serial(), TYPE_COUNT)); | |
r->Assign(3, new IntervalVal(double(soa->refresh()), Seconds)); | |
r->Assign(4, new IntervalVal(double(soa->retry()), Seconds)); | |
r->Assign(5, new IntervalVal(double(soa->expire()), Seconds)); | |
r->Assign(6, new IntervalVal(double(soa->minimum()), Seconds)); | |
return r; | |
} | |
BroVal DNS_Flow::build_edns_additional(DNS_rr * rr) | |
{ | |
// We have to treat the additional record type in EDNS | |
// differently than a regular resource record. | |
RecordVal* r = new RecordVal(dns_edns_additional); | |
r->Assign(0, new Val(int(rr->answer_type()), TYPE_COUNT)); | |
r->Assign(1, name_to_val(rr->rr_name())); | |
// Type = 0x29 or 41 = EDNS | |
r->Assign(2, new Val(rr->rr_type(), TYPE_COUNT)); | |
// Sender's UDP payload size, per RFC 2671 4.3 | |
r->Assign(3, new Val(rr->rr_class(), TYPE_COUNT)); | |
// Need to break the TTL field into three components: | |
// initial: [------------- ttl (32) ---------------------] | |
// after: [DO][ ext rcode (7)][ver # (8)][ Z field (16)] | |
unsigned int ercode = (rr->rr_ttl() & 0xff000000) >> 24; | |
unsigned int version = (rr->rr_ttl() & 0x00ff0000) >> 16; | |
unsigned int z = (rr->rr_ttl() & 0x0000ffff); | |
int rcode = rr->msg()->header()->rcode(); | |
unsigned int return_error = (ercode << 8) | rcode; | |
r->Assign(4, new Val(return_error, TYPE_COUNT)); | |
r->Assign(5, new Val(version, TYPE_COUNT)); | |
r->Assign(6, new Val(z, TYPE_COUNT)); | |
r->Assign(7, new IntervalVal(double(rr->rr_ttl()), Seconds)); | |
r->Assign(8, new Val(rr->msg()->header()->qr() == 0, TYPE_COUNT)); | |
return r; | |
} | |
bool DNS_Flow::process_dns_rr(DNS_rr * rr) | |
{ | |
const DNS_rdata* rd = rr->rr_rdata(); | |
switch ( rr->rr_type() ) { | |
case TYPE_A: | |
if ( dns_A_reply ) | |
{ | |
::uint32 addr = rd->type_a(); | |
BifEvent::generate_dns_A_reply(connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), build_dns_answer(rr), | |
new AddrVal(htonl(addr))); | |
} | |
break; | |
case TYPE_A6: | |
if ( dns_A6_reply ) | |
{ | |
::uint32 addr[4]; | |
for ( unsigned int i = 0; i < 4; ++i ) | |
addr[i] = htonl((*rd->type_aaaa())[i]); | |
BifEvent::generate_dns_A6_reply(connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), build_dns_answer(rr), | |
new AddrVal(addr)); | |
} | |
break; | |
case TYPE_AAAA: | |
if ( dns_AAAA_reply ) | |
{ | |
::uint32 addr[4]; | |
for ( unsigned int i = 0; i < 4; ++i ) | |
addr[i] = htonl((*rd->type_aaaa())[i]); | |
BifEvent::generate_dns_AAAA_reply(connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), build_dns_answer(rr), | |
new AddrVal(addr)); | |
} | |
break; | |
case TYPE_NS: | |
if ( dns_NS_reply ) | |
{ | |
BifEvent::generate_dns_NS_reply(connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), | |
build_dns_answer(rr), | |
name_to_val(rr->rr_rdata()->type_ns())); | |
} | |
break; | |
case TYPE_CNAME: | |
if ( dns_CNAME_reply ) | |
{ | |
BifEvent::generate_dns_CNAME_reply( | |
connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), | |
build_dns_answer(rr), | |
name_to_val(rr->rr_rdata()->type_cname())); | |
} | |
break; | |
case TYPE_SOA: | |
if ( dns_SOA_reply ) | |
{ | |
BifEvent::generate_dns_SOA_reply( | |
connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), | |
build_dns_answer(rr), | |
build_dns_soa(rr->rr_rdata()->type_soa())); | |
} | |
break; | |
case TYPE_PTR: | |
if ( dns_PTR_reply ) | |
{ | |
BifEvent::generate_dns_PTR_reply( | |
connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), | |
build_dns_answer(rr), | |
name_to_val(rr->rr_rdata()->type_ptr())); | |
} | |
break; | |
case TYPE_MX: | |
if ( dns_MX_reply ) | |
{ | |
BifEvent::generate_dns_MX_reply( | |
connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), | |
build_dns_answer(rr), | |
name_to_val(rr->rr_rdata()->type_mx()->name()), | |
rr->rr_rdata()->type_mx()->preference()); | |
} | |
break; | |
case TYPE_EDNS: | |
if ( dns_EDNS_addl ) | |
{ | |
BifEvent::generate_dns_EDNS_addl( | |
connection()->bro_analyzer(), | |
connection()->bro_analyzer()->Conn(), | |
dns_msg_val_->Ref(), | |
build_edns_additional(rr)); | |
} | |
break; | |
} | |
return true; | |
} | |
} // namespace DNS | |
} // namespace binpac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment