@ -794,22 +794,22 @@ const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_
}
const DNSAnswerHeader * head = ( DNSAnswerHeader * ) data ;
switch ( ntohs ( head - > type ) ) {
case DNS_RECORD_TYPE_A :
case DNS_RECORD_TYPE_AAAA :
case DNS_RECORD_TYPE_CNAME :
{
data + = sizeof ( DNSAnswerHeader ) ;
SCLogDebug ( " head->len %u " , ntohs ( head - > len ) ) ;
data + = sizeof ( DNSAnswerHeader ) ;
if ( input + input_len < data + ntohs ( head - > len ) ) {
SCLogDebug ( " input buffer too small for data of len %u " , ntohs ( head - > len ) ) ;
goto insufficient_data ;
}
SCLogDebug ( " TTL %u " , ntohl ( head - > ttl ) ) ;
SCLogDebug ( " head->len %u " , ntohs ( head - > len ) ) ;
if ( input + input_len < data + ntohs ( head - > len ) ) {
SCLogDebug ( " input buffer too small for data of len %u " , ntohs ( head - > len ) ) ;
goto insufficient_data ;
}
if ( ntohs ( head - > type ) = = DNS_RECORD_TYPE_A & & ntohs ( head - > len ) = = 4 ) {
SCLogDebug ( " TTL %u " , ntohl ( head - > ttl ) ) ;
switch ( ntohs ( head - > type ) ) {
case DNS_RECORD_TYPE_A :
{
if ( ntohs ( head - > len ) = = 4 ) {
//PrintRawDataFp(stdout, data, ntohs(head->len));
//char a[16];
//PrintInet(AF_INET, (const void *)data, a, sizeof(a));
@ -818,7 +818,17 @@ const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_
DNSStoreAnswerInState ( dns_state , list , fqdn , fqdn_len ,
ntohs ( head - > type ) , ntohs ( head - > class ) , ntohl ( head - > ttl ) ,
data , 4 , ntohs ( dns_header - > tx_id ) ) ;
} else if ( ntohs ( head - > type ) = = DNS_RECORD_TYPE_AAAA & & ntohs ( head - > len ) = = 16 ) {
} else {
SCLogDebug ( " invalid length for A response data: %u " , ntohs ( head - > len ) ) ;
goto bad_data ;
}
data + = ntohs ( head - > len ) ;
break ;
}
case DNS_RECORD_TYPE_AAAA :
{
if ( ntohs ( head - > len ) = = 16 ) {
//char a[46];
//PrintInet(AF_INET6, (const void *)data, a, sizeof(a));
//SCLogInfo("AAAA %s TTL %u", a, ntohl(head->ttl));
@ -826,46 +836,29 @@ const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_
DNSStoreAnswerInState ( dns_state , list , fqdn , fqdn_len ,
ntohs ( head - > type ) , ntohs ( head - > class ) , ntohl ( head - > ttl ) ,
data , 16 , ntohs ( dns_header - > tx_id ) ) ;
} else if ( ntohs ( head - > type ) = = DNS_RECORD_TYPE_CNAME ) {
uint8_t cname [ DNS_MAX_SIZE ] ;
uint16_t cname_len = 0 ;
if ( ( cname_len = DNSResponseGetNameByOffset ( input , input_len ,
data - input , cname , sizeof ( cname ) ) ) = = 0 )
{
# if DEBUG
PrintRawDataFp ( stdout , ( uint8_t * ) input , input_len ) ;
BUG_ON ( 1 ) ;
# endif
goto insufficient_data ;
}
DNSStoreAnswerInState ( dns_state , list , fqdn , fqdn_len ,
ntohs ( head - > type ) , ntohs ( head - > class ) , ntohl ( head - > ttl ) ,
cname , cname_len , ntohs ( dns_header - > tx_id ) ) ;
} else {
SCLogDebug ( " invalid length for AAAA response data: %u " , ntohs ( head - > len ) ) ;
goto bad_data ;
}
data + = ntohs ( head - > len ) ;
break ;
}
case DNS_RECORD_TYPE_MX :
case DNS_RECORD_TYPE_CNAME :
case DNS_RECORD_TYPE_PTR :
{
data + = sizeof ( DNSAnswerHeader ) ;
uint8_t name [ DNS_MAX_SIZE ] ;
uint16_t name_len = 0 ;
uint8_t skip = 0 ;
SCLogDebug ( " head->len %u " , ntohs ( head - > len ) ) ;
if ( input + input_len < data + ntohs ( head - > len ) ) {
SCLogDebug ( " input buffer too small for data of len %u " , ntohs ( head - > len ) ) ;
goto insufficient_data ;
if ( ntohs ( head - > type ) = = DNS_RECORD_TYPE_MX ) {
// Skip the preference header
skip = 2 ;
}
SCLogDebug ( " TTL %u " , ntohl ( head - > ttl ) ) ;
uint8_t mxname [ DNS_MAX_SIZE ] ;
uint16_t mxname_len = 0 ;
if ( ( mxname_len = DNSResponseGetNameByOffset ( input , input_len ,
data - input + 2 , mxname , sizeof ( mxname ) ) ) = = 0 ) {
if ( ( name_len = DNSResponseGetNameByOffset ( input , input_len ,
data - input + skip , name , sizeof ( name ) ) ) = = 0 ) {
# if DEBUG
PrintRawDataFp ( stdout , ( uint8_t * ) input , input_len ) ;
BUG_ON ( 1 ) ;
@ -875,7 +868,7 @@ const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_
DNSStoreAnswerInState ( dns_state , list , fqdn , fqdn_len ,
ntohs ( head - > type ) , ntohs ( head - > class ) , ntohl ( head - > ttl ) ,
mx name, mx name_len, ntohs ( dns_header - > tx_id ) ) ;
name, name_len, ntohs ( dns_header - > tx_id ) ) ;
data + = ntohs ( head - > len ) ;
break ;
@ -883,15 +876,6 @@ const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_
case DNS_RECORD_TYPE_NS :
case DNS_RECORD_TYPE_SOA :
{
data + = sizeof ( DNSAnswerHeader ) ;
if ( input + input_len < data + ntohs ( head - > len ) ) {
SCLogDebug ( " input buffer too small for data of len %u " , ntohs ( head - > len ) ) ;
goto insufficient_data ;
}
SCLogDebug ( " TTL %u " , ntohl ( head - > ttl ) ) ;
uint8_t pname [ DNS_MAX_SIZE ] ;
uint16_t pname_len = 0 ;
@ -960,13 +944,6 @@ const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_
}
case DNS_RECORD_TYPE_TXT :
{
data + = sizeof ( DNSAnswerHeader ) ;
if ( input + input_len < data + ntohs ( head - > len ) ) {
SCLogDebug ( " input buffer too small for data of len %u " , ntohs ( head - > len ) ) ;
goto insufficient_data ;
}
uint16_t datalen = ntohs ( head - > len ) ;
uint8_t txtlen = * data ;
const uint8_t * tdata = data + 1 ;
@ -996,13 +973,6 @@ const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_
}
default : /* unsupported record */
{
data + = sizeof ( DNSAnswerHeader ) ;
if ( input + input_len < data + ntohs ( head - > len ) ) {
SCLogDebug ( " input buffer too small for data of len %u " , ntohs ( head - > len ) ) ;
goto insufficient_data ;
}
DNSStoreAnswerInState ( dns_state , list , NULL , 0 ,
ntohs ( head - > type ) , ntohs ( head - > class ) , ntohl ( head - > ttl ) ,
NULL , 0 , ntohs ( dns_header - > tx_id ) ) ;
@ -1076,3 +1046,68 @@ void DNSCreateTypeString(uint16_t type, char *str, size_t str_size)
snprintf ( str , str_size , " %04x/%u " , type , type ) ;
}
}
void DNSCreateRcodeString ( uint8_t rcode , char * str , size_t str_size )
{
switch ( rcode ) {
case DNS_RCODE_NOERROR :
snprintf ( str , str_size , " NOERROR " ) ;
break ;
case DNS_RCODE_FORMERR :
snprintf ( str , str_size , " FORMERR " ) ;
break ;
case DNS_RCODE_SERVFAIL :
snprintf ( str , str_size , " SERVFAIL " ) ;
break ;
case DNS_RCODE_NXDOMAIN :
snprintf ( str , str_size , " NXDOMAIN " ) ;
break ;
case DNS_RCODE_NOTIMP :
snprintf ( str , str_size , " NOTIMP " ) ;
break ;
case DNS_RCODE_REFUSED :
snprintf ( str , str_size , " REFUSED " ) ;
break ;
case DNS_RCODE_YXDOMAIN :
snprintf ( str , str_size , " YXDOMAIN " ) ;
break ;
case DNS_RCODE_YXRRSET :
snprintf ( str , str_size , " YXRRSET " ) ;
break ;
case DNS_RCODE_NXRRSET :
snprintf ( str , str_size , " NXRRSET " ) ;
break ;
case DNS_RCODE_NOTAUTH :
snprintf ( str , str_size , " NOTAUTH " ) ;
break ;
case DNS_RCODE_NOTZONE :
snprintf ( str , str_size , " NOTZONE " ) ;
break ;
/* these are the same, need more logic */
case DNS_RCODE_BADVERS :
//case DNS_RCODE_BADSIG:
snprintf ( str , str_size , " BADVERS/BADSIG " ) ;
break ;
case DNS_RCODE_BADKEY :
snprintf ( str , str_size , " BADKEY " ) ;
break ;
case DNS_RCODE_BADTIME :
snprintf ( str , str_size , " BADTIME " ) ;
break ;
case DNS_RCODE_BADMODE :
snprintf ( str , str_size , " BADMODE " ) ;
break ;
case DNS_RCODE_BADNAME :
snprintf ( str , str_size , " BADNAME " ) ;
break ;
case DNS_RCODE_BADALG :
snprintf ( str , str_size , " BADALG " ) ;
break ;
case DNS_RCODE_BADTRUNC :
snprintf ( str , str_size , " BADTRUNC " ) ;
break ;
default :
SCLogDebug ( " could not map DNS rcode to name, bug! " ) ;
snprintf ( str , str_size , " %04x/%u " , rcode , rcode ) ;
}
}