dns: add dns.response sticky buffer

Feature: 7012
Add dns.response sticky buffer to match on dns response fields.
Add rust functions to return dns response packet data.
Unit tests verifying signature matching.
pull/12717/head
Nathan Scrivens 2 years ago committed by Victor Julien
parent f68e2f5537
commit 07632fdf4e

@ -1023,6 +1023,121 @@ pub unsafe extern "C" fn SCDnsTxGetAnswerName(
false
}
/// Get the DNS response authority name at index i.
#[no_mangle]
pub unsafe extern "C" fn SCDnsTxGetAuthorityName(
tx: &mut DNSTransaction, i: u32, buf: *mut *const u8, len: *mut u32,
) -> bool {
let index = i as usize;
if let Some(response) = &tx.response {
if let Some(record) = response.authorities.get(index) {
if !record.name.value.is_empty() {
*buf = record.name.value.as_ptr();
*len = record.name.value.len() as u32;
return true;
}
}
}
false
}
/// Get the DNS response additional name at index i.
#[no_mangle]
pub unsafe extern "C" fn SCDnsTxGetAdditionalName(
tx: &mut DNSTransaction, i: u32, buf: *mut *const u8, len: *mut u32,
) -> bool {
let index = i as usize;
if let Some(response) = &tx.response {
if let Some(record) = response.additionals.get(index) {
if !record.name.value.is_empty() {
*buf = record.name.value.as_ptr();
*len = record.name.value.len() as u32;
return true;
}
}
}
false
}
#[inline]
unsafe fn dns_get_record_rdata(data: &DNSRData, buf: *mut *const u8, len: *mut u32) -> bool {
match data {
DNSRData::CNAME(bytes)
| DNSRData::PTR(bytes)
| DNSRData::MX(bytes)
| DNSRData::NS(bytes) => {
if !bytes.value.is_empty() {
*len = bytes.value.len() as u32;
*buf = bytes.value.as_ptr();
return true;
}
}
DNSRData::SOA(soa) => {
if !soa.mname.value.is_empty() {
*len = soa.mname.value.len() as u32;
*buf = soa.mname.value.as_ptr();
return true;
}
}
_ => {
return false;
}
}
return false;
}
/// Get the DNS response answer rdata at index i that could be a domain name.
#[no_mangle]
pub unsafe extern "C" fn SCDnsTxGetAnswerRdata(
tx: &mut DNSTransaction, i: u32, buf: *mut *const u8, len: *mut u32,
) -> bool {
let index = i as usize;
if let Some(response) = &tx.response {
if let Some(record) = response.answers.get(index) {
return dns_get_record_rdata(&record.data, buf, len);
}
}
false
}
/// Get the DNS response authority rdata at index i that could be a domain name.
#[no_mangle]
pub unsafe extern "C" fn SCDnsTxGetAuthorityRdata(
tx: &mut DNSTransaction, i: u32, buf: *mut *const u8, len: *mut u32,
) -> bool {
let index = i as usize;
if let Some(response) = &tx.response {
if let Some(record) = response.authorities.get(index) {
return dns_get_record_rdata(&record.data, buf, len);
}
}
false
}
/// Get the DNS response additional rdata at index i that could be a domain name.
#[no_mangle]
pub unsafe extern "C" fn SCDnsTxGetAdditionalRdata(
tx: &mut DNSTransaction, i: u32, buf: *mut *const u8, len: *mut u32,
) -> bool {
let index = i as usize;
if let Some(response) = &tx.response {
if let Some(record) = response.additionals.get(index) {
return dns_get_record_rdata(&record.data, buf, len);
}
}
false
}
/// Get the DNS response flags for a transaction.
///
/// extern uint16_t SCDnsTxGetResponseFlags(RSDNSTransaction *);

@ -115,6 +115,7 @@ noinst_HEADERS = \
detect-dns-answer-name.h \
detect-dns-opcode.h \
detect-dns-rcode.h \
detect-dns-response.h \
detect-dns-rrtype.h \
detect-dns-query.h \
detect-dns-query-name.h \
@ -691,6 +692,7 @@ libsuricata_c_a_SOURCES = \
detect-dns-answer-name.c \
detect-dns-opcode.c \
detect-dns-rcode.c \
detect-dns-response.c \
detect-dns-rrtype.c \
detect-dns-query.c \
detect-dns-query-name.c \

File diff suppressed because it is too large Load Diff

@ -0,0 +1,23 @@
/* Copyright (C) 2024 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef SURICATA_DETECT_DNS_RESPONSE_H
#define SURICATA_DETECT_DNS_RESPONSE_H
void DetectDnsResponseRegister(void);
#endif /* SURICATA_DETECT_DNS_RESPONSE_H */

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2017 Open Information Security Foundation
/* Copyright (C) 2007-2024 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
@ -53,6 +53,7 @@
#include "detect-dns-query.h"
#include "detect-dns-answer-name.h"
#include "detect-dns-query-name.h"
#include "detect-dns-response.h"
#include "detect-tls-sni.h"
#include "detect-tls-certs.h"
#include "detect-tls-cert-fingerprint.h"
@ -559,6 +560,7 @@ void SigTableSetup(void)
DetectDnsRrtypeRegister();
DetectDnsAnswerNameRegister();
DetectDnsQueryNameRegister();
DetectDnsResponseRegister();
DetectModbusRegister();
DetectDNP3Register();

@ -246,6 +246,7 @@ enum DetectKeywordId {
DETECT_DNS_QUERY,
DETECT_DNS_OPCODE,
DETECT_DNS_RCODE,
DETECT_DNS_RESPONSE,
DETECT_DNS_RRTYPE,
DETECT_DNS_ANSWER_NAME,
DETECT_DNS_QUERY_NAME,

Loading…
Cancel
Save