dns: rustfmt

pull/8430/head
Jason Ish 4 years ago committed by Victor Julien
parent 39d2524bf6
commit 7afc2e3aed

@ -58,9 +58,7 @@ fn parse_opcode(opcode: &str) -> Result<DetectDnsOpcode, ()> {
/// 1 will be returned on match, otherwise 0 will be returned.
#[no_mangle]
pub extern "C" fn rs_dns_opcode_match(
tx: &mut DNSTransaction,
detect: &mut DetectDnsOpcode,
flags: u8,
tx: &mut DNSTransaction, detect: &mut DetectDnsOpcode, flags: u8,
) -> u8 {
let header_flags = if flags & Direction::ToServer as u8 != 0 {
if let Some(request) = &tx.request {

@ -16,78 +16,78 @@
*/
use std;
use std::ffi::CString;
use std::collections::HashMap;
use std::collections::VecDeque;
use std::ffi::CString;
use crate::applayer::*;
use crate::core::{self, *};
use crate::dns::parser;
use crate::frames::Frame;
use nom7::{Err, IResult};
use nom7::number::streaming::be_u16;
use nom7::{Err, IResult};
/// DNS record types.
pub const DNS_RECORD_TYPE_A : u16 = 1;
pub const DNS_RECORD_TYPE_NS : u16 = 2;
pub const DNS_RECORD_TYPE_MD : u16 = 3; // Obsolete
pub const DNS_RECORD_TYPE_MF : u16 = 4; // Obsolete
pub const DNS_RECORD_TYPE_CNAME : u16 = 5;
pub const DNS_RECORD_TYPE_SOA : u16 = 6;
pub const DNS_RECORD_TYPE_MB : u16 = 7; // Experimental
pub const DNS_RECORD_TYPE_MG : u16 = 8; // Experimental
pub const DNS_RECORD_TYPE_MR : u16 = 9; // Experimental
pub const DNS_RECORD_TYPE_NULL : u16 = 10; // Experimental
pub const DNS_RECORD_TYPE_WKS : u16 = 11;
pub const DNS_RECORD_TYPE_PTR : u16 = 12;
pub const DNS_RECORD_TYPE_HINFO : u16 = 13;
pub const DNS_RECORD_TYPE_MINFO : u16 = 14;
pub const DNS_RECORD_TYPE_MX : u16 = 15;
pub const DNS_RECORD_TYPE_TXT : u16 = 16;
pub const DNS_RECORD_TYPE_RP : u16 = 17;
pub const DNS_RECORD_TYPE_AFSDB : u16 = 18;
pub const DNS_RECORD_TYPE_X25 : u16 = 19;
pub const DNS_RECORD_TYPE_ISDN : u16 = 20;
pub const DNS_RECORD_TYPE_RT : u16 = 21;
pub const DNS_RECORD_TYPE_NSAP : u16 = 22;
pub const DNS_RECORD_TYPE_NSAPPTR : u16 = 23;
pub const DNS_RECORD_TYPE_SIG : u16 = 24;
pub const DNS_RECORD_TYPE_KEY : u16 = 25;
pub const DNS_RECORD_TYPE_PX : u16 = 26;
pub const DNS_RECORD_TYPE_GPOS : u16 = 27;
pub const DNS_RECORD_TYPE_AAAA : u16 = 28;
pub const DNS_RECORD_TYPE_LOC : u16 = 29;
pub const DNS_RECORD_TYPE_NXT : u16 = 30; // Obsolete
pub const DNS_RECORD_TYPE_SRV : u16 = 33;
pub const DNS_RECORD_TYPE_ATMA : u16 = 34;
pub const DNS_RECORD_TYPE_NAPTR : u16 = 35;
pub const DNS_RECORD_TYPE_KX : u16 = 36;
pub const DNS_RECORD_TYPE_CERT : u16 = 37;
pub const DNS_RECORD_TYPE_A6 : u16 = 38; // Obsolete
pub const DNS_RECORD_TYPE_DNAME : u16 = 39;
pub const DNS_RECORD_TYPE_OPT : u16 = 41;
pub const DNS_RECORD_TYPE_APL : u16 = 42;
pub const DNS_RECORD_TYPE_DS : u16 = 43;
pub const DNS_RECORD_TYPE_SSHFP : u16 = 44;
pub const DNS_RECORD_TYPE_IPSECKEY : u16 = 45;
pub const DNS_RECORD_TYPE_RRSIG : u16 = 46;
pub const DNS_RECORD_TYPE_NSEC : u16 = 47;
pub const DNS_RECORD_TYPE_DNSKEY : u16 = 48;
pub const DNS_RECORD_TYPE_DHCID : u16 = 49;
pub const DNS_RECORD_TYPE_NSEC3 : u16 = 50;
pub const DNS_RECORD_TYPE_NSEC3PARAM : u16 = 51;
pub const DNS_RECORD_TYPE_TLSA : u16 = 52;
pub const DNS_RECORD_TYPE_HIP : u16 = 55;
pub const DNS_RECORD_TYPE_CDS : u16 = 59;
pub const DNS_RECORD_TYPE_CDNSKEY : u16 = 60;
pub const DNS_RECORD_TYPE_HTTPS : u16 = 65;
pub const DNS_RECORD_TYPE_SPF : u16 = 99; // Obsolete
pub const DNS_RECORD_TYPE_TKEY : u16 = 249;
pub const DNS_RECORD_TYPE_TSIG : u16 = 250;
pub const DNS_RECORD_TYPE_MAILA : u16 = 254; // Obsolete
pub const DNS_RECORD_TYPE_ANY : u16 = 255;
pub const DNS_RECORD_TYPE_URI : u16 = 256;
pub const DNS_RECORD_TYPE_A: u16 = 1;
pub const DNS_RECORD_TYPE_NS: u16 = 2;
pub const DNS_RECORD_TYPE_MD: u16 = 3; // Obsolete
pub const DNS_RECORD_TYPE_MF: u16 = 4; // Obsolete
pub const DNS_RECORD_TYPE_CNAME: u16 = 5;
pub const DNS_RECORD_TYPE_SOA: u16 = 6;
pub const DNS_RECORD_TYPE_MB: u16 = 7; // Experimental
pub const DNS_RECORD_TYPE_MG: u16 = 8; // Experimental
pub const DNS_RECORD_TYPE_MR: u16 = 9; // Experimental
pub const DNS_RECORD_TYPE_NULL: u16 = 10; // Experimental
pub const DNS_RECORD_TYPE_WKS: u16 = 11;
pub const DNS_RECORD_TYPE_PTR: u16 = 12;
pub const DNS_RECORD_TYPE_HINFO: u16 = 13;
pub const DNS_RECORD_TYPE_MINFO: u16 = 14;
pub const DNS_RECORD_TYPE_MX: u16 = 15;
pub const DNS_RECORD_TYPE_TXT: u16 = 16;
pub const DNS_RECORD_TYPE_RP: u16 = 17;
pub const DNS_RECORD_TYPE_AFSDB: u16 = 18;
pub const DNS_RECORD_TYPE_X25: u16 = 19;
pub const DNS_RECORD_TYPE_ISDN: u16 = 20;
pub const DNS_RECORD_TYPE_RT: u16 = 21;
pub const DNS_RECORD_TYPE_NSAP: u16 = 22;
pub const DNS_RECORD_TYPE_NSAPPTR: u16 = 23;
pub const DNS_RECORD_TYPE_SIG: u16 = 24;
pub const DNS_RECORD_TYPE_KEY: u16 = 25;
pub const DNS_RECORD_TYPE_PX: u16 = 26;
pub const DNS_RECORD_TYPE_GPOS: u16 = 27;
pub const DNS_RECORD_TYPE_AAAA: u16 = 28;
pub const DNS_RECORD_TYPE_LOC: u16 = 29;
pub const DNS_RECORD_TYPE_NXT: u16 = 30; // Obsolete
pub const DNS_RECORD_TYPE_SRV: u16 = 33;
pub const DNS_RECORD_TYPE_ATMA: u16 = 34;
pub const DNS_RECORD_TYPE_NAPTR: u16 = 35;
pub const DNS_RECORD_TYPE_KX: u16 = 36;
pub const DNS_RECORD_TYPE_CERT: u16 = 37;
pub const DNS_RECORD_TYPE_A6: u16 = 38; // Obsolete
pub const DNS_RECORD_TYPE_DNAME: u16 = 39;
pub const DNS_RECORD_TYPE_OPT: u16 = 41;
pub const DNS_RECORD_TYPE_APL: u16 = 42;
pub const DNS_RECORD_TYPE_DS: u16 = 43;
pub const DNS_RECORD_TYPE_SSHFP: u16 = 44;
pub const DNS_RECORD_TYPE_IPSECKEY: u16 = 45;
pub const DNS_RECORD_TYPE_RRSIG: u16 = 46;
pub const DNS_RECORD_TYPE_NSEC: u16 = 47;
pub const DNS_RECORD_TYPE_DNSKEY: u16 = 48;
pub const DNS_RECORD_TYPE_DHCID: u16 = 49;
pub const DNS_RECORD_TYPE_NSEC3: u16 = 50;
pub const DNS_RECORD_TYPE_NSEC3PARAM: u16 = 51;
pub const DNS_RECORD_TYPE_TLSA: u16 = 52;
pub const DNS_RECORD_TYPE_HIP: u16 = 55;
pub const DNS_RECORD_TYPE_CDS: u16 = 59;
pub const DNS_RECORD_TYPE_CDNSKEY: u16 = 60;
pub const DNS_RECORD_TYPE_HTTPS: u16 = 65;
pub const DNS_RECORD_TYPE_SPF: u16 = 99; // Obsolete
pub const DNS_RECORD_TYPE_TKEY: u16 = 249;
pub const DNS_RECORD_TYPE_TSIG: u16 = 250;
pub const DNS_RECORD_TYPE_MAILA: u16 = 254; // Obsolete
pub const DNS_RECORD_TYPE_ANY: u16 = 255;
pub const DNS_RECORD_TYPE_URI: u16 = 256;
/// DNS error codes.
pub const DNS_RCODE_NOERROR: u16 = 0;
@ -112,7 +112,6 @@ pub const DNS_RCODE_BADNAME: u16 = 20;
pub const DNS_RCODE_BADALG: u16 = 21;
pub const DNS_RCODE_BADTRUNC: u16 = 22;
static mut ALPROTO_DNS: AppProto = ALPROTO_UNKNOWN;
#[derive(AppLayerFrameType)]
@ -123,7 +122,6 @@ pub enum DnsFrameType {
Pdu,
}
#[derive(Debug, PartialEq, Eq, AppLayerEvent)]
pub enum DNSEvent {
MalformedData,
@ -132,7 +130,7 @@ pub enum DNSEvent {
ZFlagSet,
}
#[derive(Debug,PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
#[repr(C)]
pub struct DNSHeader {
pub tx_id: u16,
@ -150,7 +148,7 @@ pub struct DNSQueryEntry {
pub rrclass: u16,
}
#[derive(Debug,PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub struct DNSRDataSOA {
/// Primary name server for this zone
pub mname: Vec<u8>,
@ -168,7 +166,7 @@ pub struct DNSRDataSOA {
pub minimum: u32,
}
#[derive(Debug,PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub struct DNSRDataSSHFP {
/// Algorithm number
pub algo: u8,
@ -178,7 +176,7 @@ pub struct DNSRDataSSHFP {
pub fingerprint: Vec<u8>,
}
#[derive(Debug,PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub struct DNSRDataSRV {
/// Priority
pub priority: u16,
@ -191,7 +189,7 @@ pub struct DNSRDataSRV {
}
/// Represents RData of various formats
#[derive(Debug,PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub enum DNSRData {
// RData is an address
A(Vec<u8>),
@ -212,7 +210,7 @@ pub enum DNSRData {
Unknown(Vec<u8>),
}
#[derive(Debug,PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub struct DNSAnswerEntry {
pub name: Vec<u8>,
pub rrtype: u16,
@ -275,7 +273,6 @@ impl DNSTransaction {
}
return 0;
}
}
struct ConfigTracker {
@ -334,7 +331,6 @@ impl State<DNSTransaction> for DNSState {
}
impl DNSState {
pub fn new() -> Self {
Default::default()
}
@ -425,20 +421,31 @@ impl DNSState {
fn parse_request_udp(&mut self, flow: *const core::Flow, stream_slice: StreamSlice) -> bool {
let input = stream_slice.as_slice();
let _pdu = Frame::new(flow, &stream_slice, input, input.len() as i64, DnsFrameType::Pdu as u8);
let _pdu = Frame::new(
flow,
&stream_slice,
input,
input.len() as i64,
DnsFrameType::Pdu as u8,
);
self.parse_request(input)
}
fn parse_response_udp(&mut self, flow: *const core::Flow, stream_slice: StreamSlice) -> bool {
let input = stream_slice.as_slice();
let _pdu = Frame::new(flow, &stream_slice, input, input.len() as i64, DnsFrameType::Pdu as u8);
let _pdu = Frame::new(
flow,
&stream_slice,
input,
input.len() as i64,
DnsFrameType::Pdu as u8,
);
self.parse_response(input)
}
pub fn parse_response(&mut self, input: &[u8]) -> bool {
match parser::dns_parse_response(input) {
Ok((_, response)) => {
SCLogDebug!("Response header flags: {}", response.header.flags);
if response.header.flags & 0x8000 == 0 {
@ -483,7 +490,9 @@ impl DNSState {
/// prefix.
///
/// Returns the number of messages parsed.
pub fn parse_request_tcp(&mut self, flow: *const core::Flow, stream_slice: StreamSlice) -> AppLayerResult {
pub fn parse_request_tcp(
&mut self, flow: *const core::Flow, stream_slice: StreamSlice,
) -> AppLayerResult {
let input = stream_slice.as_slice();
if self.gap {
let (is_dns, _, is_incomplete) = probe_tcp(input);
@ -500,15 +509,24 @@ impl DNSState {
if cur_i.len() == 1 {
return AppLayerResult::incomplete(consumed as u32, 2_u32);
}
let size = match be_u16(cur_i) as IResult<&[u8],u16> {
let size = match be_u16(cur_i) as IResult<&[u8], u16> {
Ok((_, len)) => len,
_ => 0
_ => 0,
} as usize;
SCLogDebug!("[request] Have {} bytes, need {} to parse",
cur_i.len(), size + 2);
SCLogDebug!(
"[request] Have {} bytes, need {} to parse",
cur_i.len(),
size + 2
);
if size > 0 && cur_i.len() >= size + 2 {
let msg = &cur_i[2..(size + 2)];
let _pdu = Frame::new(flow, &stream_slice, msg, msg.len() as i64, DnsFrameType::Pdu as u8);
let _pdu = Frame::new(
flow,
&stream_slice,
msg,
msg.len() as i64,
DnsFrameType::Pdu as u8,
);
if self.parse_request(msg) {
cur_i = &cur_i[(size + 2)..];
consumed += size + 2;
@ -519,10 +537,12 @@ impl DNSState {
cur_i = &cur_i[2..];
consumed += 2;
} else {
SCLogDebug!("[request]Not enough DNS traffic to parse. Returning {}/{}",
consumed as u32, (size + 2) as u32);
return AppLayerResult::incomplete(consumed as u32,
(size + 2) as u32);
SCLogDebug!(
"[request]Not enough DNS traffic to parse. Returning {}/{}",
consumed as u32,
(size + 2) as u32
);
return AppLayerResult::incomplete(consumed as u32, (size + 2) as u32);
}
}
AppLayerResult::ok()
@ -532,7 +552,9 @@ impl DNSState {
/// prefix.
///
/// Returns the number of messages parsed.
pub fn parse_response_tcp(&mut self, flow: *const core::Flow, stream_slice: StreamSlice) -> AppLayerResult {
pub fn parse_response_tcp(
&mut self, flow: *const core::Flow, stream_slice: StreamSlice,
) -> AppLayerResult {
let input = stream_slice.as_slice();
if self.gap {
let (is_dns, _, is_incomplete) = probe_tcp(input);
@ -549,15 +571,24 @@ impl DNSState {
if cur_i.len() == 1 {
return AppLayerResult::incomplete(consumed as u32, 2_u32);
}
let size = match be_u16(cur_i) as IResult<&[u8],u16> {
let size = match be_u16(cur_i) as IResult<&[u8], u16> {
Ok((_, len)) => len,
_ => 0
_ => 0,
} as usize;
SCLogDebug!("[response] Have {} bytes, need {} to parse",
cur_i.len(), size + 2);
SCLogDebug!(
"[response] Have {} bytes, need {} to parse",
cur_i.len(),
size + 2
);
if size > 0 && cur_i.len() >= size + 2 {
let msg = &cur_i[2..(size + 2)];
let _pdu = Frame::new(flow, &stream_slice, msg, msg.len() as i64, DnsFrameType::Pdu as u8);
let _pdu = Frame::new(
flow,
&stream_slice,
msg,
msg.len() as i64,
DnsFrameType::Pdu as u8,
);
if self.parse_response(msg) {
cur_i = &cur_i[(size + 2)..];
consumed += size + 2;
@ -568,10 +599,12 @@ impl DNSState {
cur_i = &cur_i[2..];
consumed += 2;
} else {
SCLogDebug!("[response]Not enough DNS traffic to parse. Returning {}/{}",
consumed as u32, (cur_i.len() - consumed) as u32);
return AppLayerResult::incomplete(consumed as u32,
(size + 2) as u32);
SCLogDebug!(
"[response]Not enough DNS traffic to parse. Returning {}/{}",
consumed as u32,
(cur_i.len() - consumed) as u32
);
return AppLayerResult::incomplete(consumed as u32, (size + 2) as u32);
}
}
AppLayerResult::ok()
@ -620,7 +653,11 @@ fn probe_header_validity(header: DNSHeader, rlen: usize) -> (bool, bool, bool) {
/// Returns a tuple of booleans: (is_dns, is_request, incomplete)
fn probe(input: &[u8], dlen: usize) -> (bool, bool, bool) {
// Trim input to dlen if larger.
let input = if input.len() <= dlen { input } else { &input[..dlen] };
let input = if input.len() <= dlen {
input
} else {
&input[..dlen]
};
// If input is less than dlen then we know we don't have enough data to
// parse a complete message, so perform header validation only.
@ -635,26 +672,24 @@ fn probe(input: &[u8], dlen: usize) -> (bool, bool, bool) {
match parser::dns_parse_request(input) {
Ok((_, request)) => {
return probe_header_validity(request.header, dlen);
},
Err(Err::Incomplete(_)) => {
match parser::dns_parse_header(input) {
}
Err(Err::Incomplete(_)) => match parser::dns_parse_header(input) {
Ok((_, header)) => {
return probe_header_validity(header, dlen);
}
Err(Err::Incomplete(_)) => (false, false, true),
Err(_) => (false, false, false),
}
}
},
Err(_) => (false, false, false),
}
}
/// Probe TCP input to see if it looks like DNS.
pub fn probe_tcp(input: &[u8]) -> (bool, bool, bool) {
match be_u16(input) as IResult<&[u8],u16> {
match be_u16(input) as IResult<&[u8], u16> {
Ok((rem, dlen)) => {
return probe(rem, dlen as usize);
},
}
Err(Err::Incomplete(_)) => {
return (false, false, true);
}
@ -665,7 +700,9 @@ pub fn probe_tcp(input: &[u8]) -> (bool, bool, bool) {
/// Returns *mut DNSState
#[no_mangle]
pub extern "C" fn rs_dns_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
pub extern "C" fn rs_dns_state_new(
_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto,
) -> *mut std::os::raw::c_void {
let state = DNSState::new();
let boxed = Box::new(state);
return Box::into_raw(boxed) as *mut _;
@ -688,22 +725,17 @@ pub extern "C" fn rs_dns_state_free(state: *mut std::os::raw::c_void) {
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_state_tx_free(state: *mut std::os::raw::c_void,
tx_id: u64)
{
pub unsafe extern "C" fn rs_dns_state_tx_free(state: *mut std::os::raw::c_void, tx_id: u64) {
let state = cast_pointer!(state, DNSState);
state.free_tx(tx_id);
}
/// C binding parse a DNS request. Returns 1 on success, -1 on failure.
#[no_mangle]
pub unsafe extern "C" fn rs_dns_parse_request(flow: *const core::Flow,
state: *mut std::os::raw::c_void,
_pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice,
_data: *const std::os::raw::c_void,
)
-> AppLayerResult {
pub unsafe extern "C" fn rs_dns_parse_request(
flow: *const core::Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice, _data: *const std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state, DNSState);
if state.parse_request_udp(flow, stream_slice) {
AppLayerResult::ok()
@ -713,13 +745,10 @@ pub unsafe extern "C" fn rs_dns_parse_request(flow: *const core::Flow,
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_parse_response(flow: *const core::Flow,
state: *mut std::os::raw::c_void,
_pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice,
_data: *const std::os::raw::c_void,
)
-> AppLayerResult {
pub unsafe extern "C" fn rs_dns_parse_response(
flow: *const core::Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice, _data: *const std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state, DNSState);
if state.parse_response_udp(flow, stream_slice) {
AppLayerResult::ok()
@ -730,13 +759,10 @@ pub unsafe extern "C" fn rs_dns_parse_response(flow: *const core::Flow,
/// C binding parse a DNS request. Returns 1 on success, -1 on failure.
#[no_mangle]
pub unsafe extern "C" fn rs_dns_parse_request_tcp(flow: *const core::Flow,
state: *mut std::os::raw::c_void,
_pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice,
_data: *const std::os::raw::c_void,
)
-> AppLayerResult {
pub unsafe extern "C" fn rs_dns_parse_request_tcp(
flow: *const core::Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice, _data: *const std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state, DNSState);
if stream_slice.is_gap() {
state.request_gap(stream_slice.gap_size());
@ -747,13 +773,10 @@ pub unsafe extern "C" fn rs_dns_parse_request_tcp(flow: *const core::Flow,
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_parse_response_tcp(flow: *const core::Flow,
state: *mut std::os::raw::c_void,
_pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice,
_data: *const std::os::raw::c_void,
)
-> AppLayerResult {
pub unsafe extern "C" fn rs_dns_parse_response_tcp(
flow: *const core::Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice, _data: *const std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state, DNSState);
if stream_slice.is_gap() {
state.response_gap(stream_slice.gap_size());
@ -764,10 +787,9 @@ pub unsafe extern "C" fn rs_dns_parse_response_tcp(flow: *const core::Flow,
}
#[no_mangle]
pub extern "C" fn rs_dns_tx_get_alstate_progress(_tx: *mut std::os::raw::c_void,
_direction: u8)
-> std::os::raw::c_int
{
pub extern "C" fn rs_dns_tx_get_alstate_progress(
_tx: *mut std::os::raw::c_void, _direction: u8,
) -> std::os::raw::c_int {
// This is a stateless parser, just the existence of a transaction
// means its complete.
SCLogDebug!("rs_dns_tx_get_alstate_progress");
@ -775,19 +797,16 @@ pub extern "C" fn rs_dns_tx_get_alstate_progress(_tx: *mut std::os::raw::c_void,
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_state_get_tx_count(state: *mut std::os::raw::c_void)
-> u64
{
pub unsafe extern "C" fn rs_dns_state_get_tx_count(state: *mut std::os::raw::c_void) -> u64 {
let state = cast_pointer!(state, DNSState);
SCLogDebug!("rs_dns_state_get_tx_count: returning {}", state.tx_id);
return state.tx_id;
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_state_get_tx(state: *mut std::os::raw::c_void,
tx_id: u64)
-> *mut std::os::raw::c_void
{
pub unsafe extern "C" fn rs_dns_state_get_tx(
state: *mut std::os::raw::c_void, tx_id: u64,
) -> *mut std::os::raw::c_void {
let state = cast_pointer!(state, DNSState);
match state.get_tx(tx_id) {
Some(tx) => {
@ -810,9 +829,8 @@ pub extern "C" fn rs_dns_tx_is_response(tx: &mut DNSTransaction) -> bool {
}
pub unsafe extern "C" fn rs_dns_state_get_tx_data(
tx: *mut std::os::raw::c_void)
-> *mut AppLayerTxData
{
tx: *mut std::os::raw::c_void,
) -> *mut AppLayerTxData {
let tx = cast_pointer!(tx, DNSTransaction);
return &mut tx.tx_data;
}
@ -820,12 +838,9 @@ pub unsafe extern "C" fn rs_dns_state_get_tx_data(
export_state_data_get!(rs_dns_get_state_data, DNSState);
#[no_mangle]
pub unsafe extern "C" fn rs_dns_tx_get_query_name(tx: &mut DNSTransaction,
i: u32,
buf: *mut *const u8,
len: *mut u32)
-> u8
{
pub unsafe extern "C" fn rs_dns_tx_get_query_name(
tx: &mut DNSTransaction, i: u32, buf: *mut *const u8, len: *mut u32,
) -> u8 {
if let &Some(ref request) = &tx.request {
if (i as usize) < request.queries.len() {
let query = &request.queries[i as usize];
@ -843,27 +858,22 @@ pub unsafe extern "C" fn rs_dns_tx_get_query_name(tx: &mut DNSTransaction,
//
/// extern uint16_t rs_dns_tx_get_tx_id(RSDNSTransaction *);
#[no_mangle]
pub extern "C" fn rs_dns_tx_get_tx_id(tx: &mut DNSTransaction) -> u16
{
return tx.tx_id()
pub extern "C" fn rs_dns_tx_get_tx_id(tx: &mut DNSTransaction) -> u16 {
return tx.tx_id();
}
/// Get the DNS response flags for a transaction.
///
/// extern uint16_t rs_dns_tx_get_response_flags(RSDNSTransaction *);
#[no_mangle]
pub extern "C" fn rs_dns_tx_get_response_flags(tx: &mut DNSTransaction)
-> u16
{
pub extern "C" fn rs_dns_tx_get_response_flags(tx: &mut DNSTransaction) -> u16 {
return tx.rcode();
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_tx_get_query_rrtype(tx: &mut DNSTransaction,
i: u16,
rrtype: *mut u16)
-> u8
{
pub unsafe extern "C" fn rs_dns_tx_get_query_rrtype(
tx: &mut DNSTransaction, i: u16, rrtype: *mut u16,
) -> u8 {
if let &Some(ref request) = &tx.request {
if (i as usize) < request.queries.len() {
let query = &request.queries[i as usize];
@ -878,11 +888,7 @@ pub unsafe extern "C" fn rs_dns_tx_get_query_rrtype(tx: &mut DNSTransaction,
#[no_mangle]
pub unsafe extern "C" fn rs_dns_probe(
_flow: *const core::Flow,
_dir: u8,
input: *const u8,
len: u32,
rdir: *mut u8,
_flow: *const core::Flow, _dir: u8, input: *const u8, len: u32, rdir: *mut u8,
) -> AppProto {
if len == 0 || len < std::mem::size_of::<DNSHeader>() as u32 {
return core::ALPROTO_UNKNOWN;
@ -903,11 +909,7 @@ pub unsafe extern "C" fn rs_dns_probe(
#[no_mangle]
pub unsafe extern "C" fn rs_dns_probe_tcp(
_flow: *const core::Flow,
direction: u8,
input: *const u8,
len: u32,
rdir: *mut u8
_flow: *const core::Flow, direction: u8, input: *const u8, len: u32, rdir: *mut u8,
) -> AppProto {
if len == 0 || len < std::mem::size_of::<DNSHeader>() as u32 + 2 {
return core::ALPROTO_UNKNOWN;
@ -931,8 +933,8 @@ pub unsafe extern "C" fn rs_dns_probe_tcp(
#[no_mangle]
pub unsafe extern "C" fn rs_dns_apply_tx_config(
_state: *mut std::os::raw::c_void, _tx: *mut std::os::raw::c_void,
_mode: std::os::raw::c_int, config: AppLayerTxConfig
_state: *mut std::os::raw::c_void, _tx: *mut std::os::raw::c_void, _mode: std::os::raw::c_int,
config: AppLayerTxConfig,
) {
let tx = cast_pointer!(_tx, DNSTransaction);
let state = cast_pointer!(_state, DNSState);
@ -949,7 +951,7 @@ pub unsafe extern "C" fn rs_dns_apply_tx_config(
#[no_mangle]
pub unsafe extern "C" fn rs_dns_udp_register_parser() {
let default_port = std::ffi::CString::new("[53]").unwrap();
let parser = RustParser{
let parser = RustParser {
name: b"dns\0".as_ptr() as *const std::os::raw::c_char,
default_port: default_port.as_ptr(),
ipproto: IPPROTO_UDP,
@ -995,7 +997,7 @@ pub unsafe extern "C" fn rs_dns_udp_register_parser() {
#[no_mangle]
pub unsafe extern "C" fn rs_dns_tcp_register_parser() {
let default_port = std::ffi::CString::new("53").unwrap();
let parser = RustParser{
let parser = RustParser {
name: b"dns\0".as_ptr() as *const std::os::raw::c_char,
default_port: default_port.as_ptr(),
ipproto: IPPROTO_TCP,
@ -1075,7 +1077,10 @@ mod tests {
let mut state = DNSState::new();
assert_eq!(
AppLayerResult::ok(),
state.parse_request_tcp(std::ptr::null(), StreamSlice::from_slice(&request, STREAM_TOSERVER, 0))
state.parse_request_tcp(
std::ptr::null(),
StreamSlice::from_slice(&request, STREAM_TOSERVER, 0)
)
);
}
@ -1112,7 +1117,10 @@ mod tests {
let mut state = DNSState::new();
assert_eq!(
AppLayerResult::incomplete(0, 52),
state.parse_request_tcp(std::ptr::null(), StreamSlice::from_slice(&request, STREAM_TOSERVER, 0))
state.parse_request_tcp(
std::ptr::null(),
StreamSlice::from_slice(&request, STREAM_TOSERVER, 0)
)
);
}
@ -1154,7 +1162,10 @@ mod tests {
let mut state = DNSState::new();
assert_eq!(
AppLayerResult::ok(),
state.parse_response_tcp(std::ptr::null(), StreamSlice::from_slice(&request, STREAM_TOCLIENT, 0))
state.parse_response_tcp(
std::ptr::null(),
StreamSlice::from_slice(&request, STREAM_TOCLIENT, 0)
)
);
}
@ -1199,7 +1210,10 @@ mod tests {
let mut state = DNSState::new();
assert_eq!(
AppLayerResult::incomplete(0, 103),
state.parse_response_tcp(std::ptr::null(), StreamSlice::from_slice(&request, STREAM_TOCLIENT, 0))
state.parse_response_tcp(
std::ptr::null(),
StreamSlice::from_slice(&request, STREAM_TOCLIENT, 0)
)
);
}

@ -16,80 +16,79 @@
*/
use std;
use std::string::String;
use std::collections::HashMap;
use std::string::String;
use crate::jsonbuilder::{JsonBuilder, JsonError};
use crate::dns::dns::*;
use crate::jsonbuilder::{JsonBuilder, JsonError};
pub const LOG_QUERIES : u64 = BIT_U64!(0);
pub const LOG_ANSWER : u64 = BIT_U64!(1);
pub const LOG_A : u64 = BIT_U64!(2);
pub const LOG_NS : u64 = BIT_U64!(3);
pub const LOG_MD : u64 = BIT_U64!(4);
pub const LOG_MF : u64 = BIT_U64!(5);
pub const LOG_CNAME : u64 = BIT_U64!(6);
pub const LOG_SOA : u64 = BIT_U64!(7);
pub const LOG_MB : u64 = BIT_U64!(8);
pub const LOG_MG : u64 = BIT_U64!(9);
pub const LOG_MR : u64 = BIT_U64!(10);
pub const LOG_NULL : u64 = BIT_U64!(11);
pub const LOG_WKS : u64 = BIT_U64!(12);
pub const LOG_PTR : u64 = BIT_U64!(13);
pub const LOG_HINFO : u64 = BIT_U64!(14);
pub const LOG_MINFO : u64 = BIT_U64!(15);
pub const LOG_MX : u64 = BIT_U64!(16);
pub const LOG_TXT : u64 = BIT_U64!(17);
pub const LOG_RP : u64 = BIT_U64!(18);
pub const LOG_AFSDB : u64 = BIT_U64!(19);
pub const LOG_X25 : u64 = BIT_U64!(20);
pub const LOG_ISDN : u64 = BIT_U64!(21);
pub const LOG_RT : u64 = BIT_U64!(22);
pub const LOG_NSAP : u64 = BIT_U64!(23);
pub const LOG_NSAPPTR : u64 = BIT_U64!(24);
pub const LOG_SIG : u64 = BIT_U64!(25);
pub const LOG_KEY : u64 = BIT_U64!(26);
pub const LOG_PX : u64 = BIT_U64!(27);
pub const LOG_GPOS : u64 = BIT_U64!(28);
pub const LOG_AAAA : u64 = BIT_U64!(29);
pub const LOG_LOC : u64 = BIT_U64!(30);
pub const LOG_NXT : u64 = BIT_U64!(31);
pub const LOG_SRV : u64 = BIT_U64!(32);
pub const LOG_ATMA : u64 = BIT_U64!(33);
pub const LOG_NAPTR : u64 = BIT_U64!(34);
pub const LOG_KX : u64 = BIT_U64!(35);
pub const LOG_CERT : u64 = BIT_U64!(36);
pub const LOG_A6 : u64 = BIT_U64!(37);
pub const LOG_DNAME : u64 = BIT_U64!(38);
pub const LOG_OPT : u64 = BIT_U64!(39);
pub const LOG_APL : u64 = BIT_U64!(40);
pub const LOG_DS : u64 = BIT_U64!(41);
pub const LOG_SSHFP : u64 = BIT_U64!(42);
pub const LOG_IPSECKEY : u64 = BIT_U64!(43);
pub const LOG_RRSIG : u64 = BIT_U64!(44);
pub const LOG_NSEC : u64 = BIT_U64!(45);
pub const LOG_DNSKEY : u64 = BIT_U64!(46);
pub const LOG_DHCID : u64 = BIT_U64!(47);
pub const LOG_NSEC3 : u64 = BIT_U64!(48);
pub const LOG_NSEC3PARAM : u64 = BIT_U64!(49);
pub const LOG_TLSA : u64 = BIT_U64!(50);
pub const LOG_HIP : u64 = BIT_U64!(51);
pub const LOG_CDS : u64 = BIT_U64!(52);
pub const LOG_CDNSKEY : u64 = BIT_U64!(53);
pub const LOG_SPF : u64 = BIT_U64!(54);
pub const LOG_TKEY : u64 = BIT_U64!(55);
pub const LOG_TSIG : u64 = BIT_U64!(56);
pub const LOG_MAILA : u64 = BIT_U64!(57);
pub const LOG_ANY : u64 = BIT_U64!(58);
pub const LOG_URI : u64 = BIT_U64!(59);
pub const LOG_FORMAT_GROUPED : u64 = BIT_U64!(60);
pub const LOG_FORMAT_DETAILED : u64 = BIT_U64!(61);
pub const LOG_HTTPS : u64 = BIT_U64!(62);
fn dns_log_rrtype_enabled(rtype: u16, flags: u64) -> bool
{
pub const LOG_QUERIES: u64 = BIT_U64!(0);
pub const LOG_ANSWER: u64 = BIT_U64!(1);
pub const LOG_A: u64 = BIT_U64!(2);
pub const LOG_NS: u64 = BIT_U64!(3);
pub const LOG_MD: u64 = BIT_U64!(4);
pub const LOG_MF: u64 = BIT_U64!(5);
pub const LOG_CNAME: u64 = BIT_U64!(6);
pub const LOG_SOA: u64 = BIT_U64!(7);
pub const LOG_MB: u64 = BIT_U64!(8);
pub const LOG_MG: u64 = BIT_U64!(9);
pub const LOG_MR: u64 = BIT_U64!(10);
pub const LOG_NULL: u64 = BIT_U64!(11);
pub const LOG_WKS: u64 = BIT_U64!(12);
pub const LOG_PTR: u64 = BIT_U64!(13);
pub const LOG_HINFO: u64 = BIT_U64!(14);
pub const LOG_MINFO: u64 = BIT_U64!(15);
pub const LOG_MX: u64 = BIT_U64!(16);
pub const LOG_TXT: u64 = BIT_U64!(17);
pub const LOG_RP: u64 = BIT_U64!(18);
pub const LOG_AFSDB: u64 = BIT_U64!(19);
pub const LOG_X25: u64 = BIT_U64!(20);
pub const LOG_ISDN: u64 = BIT_U64!(21);
pub const LOG_RT: u64 = BIT_U64!(22);
pub const LOG_NSAP: u64 = BIT_U64!(23);
pub const LOG_NSAPPTR: u64 = BIT_U64!(24);
pub const LOG_SIG: u64 = BIT_U64!(25);
pub const LOG_KEY: u64 = BIT_U64!(26);
pub const LOG_PX: u64 = BIT_U64!(27);
pub const LOG_GPOS: u64 = BIT_U64!(28);
pub const LOG_AAAA: u64 = BIT_U64!(29);
pub const LOG_LOC: u64 = BIT_U64!(30);
pub const LOG_NXT: u64 = BIT_U64!(31);
pub const LOG_SRV: u64 = BIT_U64!(32);
pub const LOG_ATMA: u64 = BIT_U64!(33);
pub const LOG_NAPTR: u64 = BIT_U64!(34);
pub const LOG_KX: u64 = BIT_U64!(35);
pub const LOG_CERT: u64 = BIT_U64!(36);
pub const LOG_A6: u64 = BIT_U64!(37);
pub const LOG_DNAME: u64 = BIT_U64!(38);
pub const LOG_OPT: u64 = BIT_U64!(39);
pub const LOG_APL: u64 = BIT_U64!(40);
pub const LOG_DS: u64 = BIT_U64!(41);
pub const LOG_SSHFP: u64 = BIT_U64!(42);
pub const LOG_IPSECKEY: u64 = BIT_U64!(43);
pub const LOG_RRSIG: u64 = BIT_U64!(44);
pub const LOG_NSEC: u64 = BIT_U64!(45);
pub const LOG_DNSKEY: u64 = BIT_U64!(46);
pub const LOG_DHCID: u64 = BIT_U64!(47);
pub const LOG_NSEC3: u64 = BIT_U64!(48);
pub const LOG_NSEC3PARAM: u64 = BIT_U64!(49);
pub const LOG_TLSA: u64 = BIT_U64!(50);
pub const LOG_HIP: u64 = BIT_U64!(51);
pub const LOG_CDS: u64 = BIT_U64!(52);
pub const LOG_CDNSKEY: u64 = BIT_U64!(53);
pub const LOG_SPF: u64 = BIT_U64!(54);
pub const LOG_TKEY: u64 = BIT_U64!(55);
pub const LOG_TSIG: u64 = BIT_U64!(56);
pub const LOG_MAILA: u64 = BIT_U64!(57);
pub const LOG_ANY: u64 = BIT_U64!(58);
pub const LOG_URI: u64 = BIT_U64!(59);
pub const LOG_FORMAT_GROUPED: u64 = BIT_U64!(60);
pub const LOG_FORMAT_DETAILED: u64 = BIT_U64!(61);
pub const LOG_HTTPS: u64 = BIT_U64!(62);
fn dns_log_rrtype_enabled(rtype: u16, flags: u64) -> bool {
if flags == !0 {
return true;
}
@ -233,9 +232,7 @@ fn dns_log_rrtype_enabled(rtype: u16, flags: u64) -> bool
DNS_RECORD_TYPE_DHCID => {
return flags & LOG_DHCID != 0;
}
DNS_RECORD_TYPE_NSEC3 => {
return flags & LOG_NSEC3 != 0
}
DNS_RECORD_TYPE_NSEC3 => return flags & LOG_NSEC3 != 0,
DNS_RECORD_TYPE_NSEC3PARAM => {
return flags & LOG_NSEC3PARAM != 0;
}
@ -342,7 +339,8 @@ pub fn dns_rrtype_string(rrtype: u16) -> String {
_ => {
return rrtype.to_string();
}
}.to_string()
}
.to_string()
}
pub fn dns_rcode_string(flags: u16) -> String {
@ -368,15 +366,15 @@ pub fn dns_rcode_string(flags: u16) -> String {
_ => {
return (flags & 0x000f).to_string();
}
}.to_string()
}
.to_string()
}
/// Format bytes as an IP address string.
pub fn dns_print_addr(addr: &Vec<u8>) -> std::string::String {
if addr.len() == 4 {
return format!("{}.{}.{}.{}", addr[0], addr[1], addr[2], addr[3]);
}
else if addr.len() == 16 {
} else if addr.len() == 16 {
return format!("{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}",
addr[0],
addr[1],
@ -394,8 +392,7 @@ pub fn dns_print_addr(addr: &Vec<u8>) -> std::string::String {
addr[13],
addr[14],
addr[15]);
}
else {
} else {
return "".to_string();
}
}
@ -417,8 +414,7 @@ fn dns_log_soa(soa: &DNSRDataSOA) -> Result<JsonBuilder, JsonError> {
}
/// Log SSHFP section fields.
fn dns_log_sshfp(sshfp: &DNSRDataSSHFP) -> Result<JsonBuilder, JsonError>
{
fn dns_log_sshfp(sshfp: &DNSRDataSSHFP) -> Result<JsonBuilder, JsonError> {
let mut js = JsonBuilder::new_object();
let mut hex = Vec::new();
@ -435,8 +431,7 @@ fn dns_log_sshfp(sshfp: &DNSRDataSSHFP) -> Result<JsonBuilder, JsonError>
}
/// Log SRV section fields.
fn dns_log_srv(srv: &DNSRDataSRV) -> Result<JsonBuilder, JsonError>
{
fn dns_log_srv(srv: &DNSRDataSRV) -> Result<JsonBuilder, JsonError> {
let mut js = JsonBuilder::new_object();
js.set_uint("priority", srv.priority as u64)?;
@ -448,8 +443,7 @@ fn dns_log_srv(srv: &DNSRDataSRV) -> Result<JsonBuilder, JsonError>
return Ok(js);
}
fn dns_log_json_answer_detail(answer: &DNSAnswerEntry) -> Result<JsonBuilder, JsonError>
{
fn dns_log_json_answer_detail(answer: &DNSAnswerEntry) -> Result<JsonBuilder, JsonError> {
let mut jsa = JsonBuilder::new_object();
jsa.set_string_from_bytes("rrname", &answer.name)?;
@ -460,12 +454,12 @@ fn dns_log_json_answer_detail(answer: &DNSAnswerEntry) -> Result<JsonBuilder, Js
DNSRData::A(addr) | DNSRData::AAAA(addr) => {
jsa.set_string("rdata", &dns_print_addr(addr))?;
}
DNSRData::CNAME(bytes) |
DNSRData::MX(bytes) |
DNSRData::NS(bytes) |
DNSRData::TXT(bytes) |
DNSRData::NULL(bytes) |
DNSRData::PTR(bytes) => {
DNSRData::CNAME(bytes)
| DNSRData::MX(bytes)
| DNSRData::NS(bytes)
| DNSRData::TXT(bytes)
| DNSRData::NULL(bytes)
| DNSRData::PTR(bytes) => {
jsa.set_string_from_bytes("rdata", bytes)?;
}
DNSRData::SOA(soa) => {
@ -484,9 +478,9 @@ fn dns_log_json_answer_detail(answer: &DNSAnswerEntry) -> Result<JsonBuilder, Js
return Ok(jsa);
}
fn dns_log_json_answer(js: &mut JsonBuilder, response: &DNSResponse, flags: u64)
-> Result<(), JsonError>
{
fn dns_log_json_answer(
js: &mut JsonBuilder, response: &DNSResponse, flags: u64,
) -> Result<(), JsonError> {
let header = &response.header;
js.set_uint("version", 2)?;
@ -525,60 +519,54 @@ fn dns_log_json_answer(js: &mut JsonBuilder, response: &DNSResponse, flags: u64)
let mut answer_types = HashMap::new();
for answer in &response.answers {
if flags & LOG_FORMAT_GROUPED != 0 {
let type_string = dns_rrtype_string(answer.rrtype);
match &answer.data {
DNSRData::A(addr) | DNSRData::AAAA(addr) => {
if !answer_types.contains_key(&type_string) {
answer_types.insert(type_string.to_string(),
JsonBuilder::new_array());
answer_types.insert(type_string.to_string(), JsonBuilder::new_array());
}
if let Some(a) = answer_types.get_mut(&type_string) {
a.append_string(&dns_print_addr(addr))?;
}
}
DNSRData::CNAME(bytes) |
DNSRData::MX(bytes) |
DNSRData::NS(bytes) |
DNSRData::TXT(bytes) |
DNSRData::NULL(bytes) |
DNSRData::PTR(bytes) => {
DNSRData::CNAME(bytes)
| DNSRData::MX(bytes)
| DNSRData::NS(bytes)
| DNSRData::TXT(bytes)
| DNSRData::NULL(bytes)
| DNSRData::PTR(bytes) => {
if !answer_types.contains_key(&type_string) {
answer_types.insert(type_string.to_string(),
JsonBuilder::new_array());
answer_types.insert(type_string.to_string(), JsonBuilder::new_array());
}
if let Some(a) = answer_types.get_mut(&type_string) {
a.append_string_from_bytes(bytes)?;
}
},
}
DNSRData::SOA(soa) => {
if !answer_types.contains_key(&type_string) {
answer_types.insert(type_string.to_string(),
JsonBuilder::new_array());
answer_types.insert(type_string.to_string(), JsonBuilder::new_array());
}
if let Some(a) = answer_types.get_mut(&type_string) {
a.append_object(&dns_log_soa(soa)?)?;
}
},
}
DNSRData::SSHFP(sshfp) => {
if !answer_types.contains_key(&type_string) {
answer_types.insert(type_string.to_string(),
JsonBuilder::new_array());
answer_types.insert(type_string.to_string(), JsonBuilder::new_array());
}
if let Some(a) = answer_types.get_mut(&type_string) {
a.append_object(&dns_log_sshfp(sshfp)?)?;
}
},
}
DNSRData::SRV(srv) => {
if !answer_types.contains_key(&type_string) {
answer_types.insert(type_string.to_string(),
JsonBuilder::new_array());
answer_types.insert(type_string.to_string(), JsonBuilder::new_array());
}
if let Some(a) = answer_types.get_mut(&type_string) {
a.append_object(&dns_log_srv(srv)?)?;
}
},
}
_ => {}
}
}
@ -602,7 +590,6 @@ fn dns_log_json_answer(js: &mut JsonBuilder, response: &DNSResponse, flags: u64)
}
js.close()?;
}
}
if !response.authorities.is_empty() {
@ -617,12 +604,9 @@ fn dns_log_json_answer(js: &mut JsonBuilder, response: &DNSResponse, flags: u64)
Ok(())
}
fn dns_log_query(tx: &mut DNSTransaction,
i: u16,
flags: u64,
jb: &mut JsonBuilder)
-> Result<bool, JsonError>
{
fn dns_log_query(
tx: &mut DNSTransaction, i: u16, flags: u64, jb: &mut JsonBuilder,
) -> Result<bool, JsonError> {
let index = i as usize;
if let &Some(ref request) = &tx.request {
if index < request.queries.len() {
@ -645,12 +629,9 @@ fn dns_log_query(tx: &mut DNSTransaction,
}
#[no_mangle]
pub extern "C" fn rs_dns_log_json_query(tx: &mut DNSTransaction,
i: u16,
flags: u64,
jb: &mut JsonBuilder)
-> bool
{
pub extern "C" fn rs_dns_log_json_query(
tx: &mut DNSTransaction, i: u16, flags: u64, jb: &mut JsonBuilder,
) -> bool {
match dns_log_query(tx, i, flags, jb) {
Ok(false) | Err(_) => {
return false;
@ -662,10 +643,9 @@ pub extern "C" fn rs_dns_log_json_query(tx: &mut DNSTransaction,
}
#[no_mangle]
pub extern "C" fn rs_dns_log_json_answer(tx: &mut DNSTransaction,
flags: u64, js: &mut JsonBuilder)
-> bool
{
pub extern "C" fn rs_dns_log_json_answer(
tx: &mut DNSTransaction, flags: u64, js: &mut JsonBuilder,
) -> bool {
if let &Some(ref response) = &tx.response {
for query in &response.queries {
if dns_log_rrtype_enabled(query.rrtype, flags) {
@ -677,9 +657,7 @@ pub extern "C" fn rs_dns_log_json_answer(tx: &mut DNSTransaction,
}
#[no_mangle]
pub extern "C" fn rs_dns_do_log_answer(tx: &mut DNSTransaction,
flags: u64) -> bool
{
pub extern "C" fn rs_dns_do_log_answer(tx: &mut DNSTransaction, flags: u64) -> bool {
if let &Some(ref response) = &tx.response {
for query in &response.queries {
if dns_log_rrtype_enabled(query.rrtype, flags) {

@ -17,29 +17,20 @@
use std::os::raw::c_int;
use crate::lua::*;
use crate::dns::dns::*;
use crate::dns::log::*;
use crate::lua::*;
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_tx_id(clua: &mut CLuaState,
tx: &mut DNSTransaction)
{
let lua = LuaState{
lua: clua,
};
pub extern "C" fn rs_dns_lua_get_tx_id(clua: &mut CLuaState, tx: &mut DNSTransaction) {
let lua = LuaState { lua: clua };
lua.pushinteger(tx.tx_id() as i64);
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_rrname(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
pub extern "C" fn rs_dns_lua_get_rrname(clua: &mut CLuaState, tx: &mut DNSTransaction) -> c_int {
let lua = LuaState { lua: clua };
if let &Some(ref request) = &tx.request {
if let Some(query) = request.queries.first() {
@ -57,13 +48,8 @@ pub extern "C" fn rs_dns_lua_get_rrname(clua: &mut CLuaState,
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_rcode(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
pub extern "C" fn rs_dns_lua_get_rcode(clua: &mut CLuaState, tx: &mut DNSTransaction) -> c_int {
let lua = LuaState { lua: clua };
let rcode = tx.rcode();
if rcode > 0 {
@ -75,13 +61,10 @@ pub extern "C" fn rs_dns_lua_get_rcode(clua: &mut CLuaState,
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_query_table(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
pub extern "C" fn rs_dns_lua_get_query_table(
clua: &mut CLuaState, tx: &mut DNSTransaction,
) -> c_int {
let lua = LuaState { lua: clua };
let mut i: i64 = 0;
@ -133,13 +116,10 @@ pub extern "C" fn rs_dns_lua_get_query_table(clua: &mut CLuaState,
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_answer_table(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
pub extern "C" fn rs_dns_lua_get_answer_table(
clua: &mut CLuaState, tx: &mut DNSTransaction,
) -> c_int {
let lua = LuaState { lua: clua };
let mut i: i64 = 0;
@ -173,37 +153,37 @@ pub extern "C" fn rs_dns_lua_get_answer_table(clua: &mut CLuaState,
lua.pushstring(&dns_print_addr(bytes));
lua.settable(-3);
}
},
DNSRData::CNAME(ref bytes) |
DNSRData::MX(ref bytes) |
DNSRData::NS(ref bytes) |
DNSRData::TXT(ref bytes) |
DNSRData::NULL(ref bytes) |
DNSRData::PTR(ref bytes) |
DNSRData::Unknown(ref bytes) => {
}
DNSRData::CNAME(ref bytes)
| DNSRData::MX(ref bytes)
| DNSRData::NS(ref bytes)
| DNSRData::TXT(ref bytes)
| DNSRData::NULL(ref bytes)
| DNSRData::PTR(ref bytes)
| DNSRData::Unknown(ref bytes) => {
if !bytes.is_empty() {
lua.pushstring("addr");
lua.pushstring(&String::from_utf8_lossy(bytes));
lua.settable(-3);
}
},
}
DNSRData::SOA(ref soa) => {
if !soa.mname.is_empty() {
lua.pushstring("addr");
lua.pushstring(&String::from_utf8_lossy(&soa.mname));
lua.settable(-3);
}
},
}
DNSRData::SSHFP(ref sshfp) => {
lua.pushstring("addr");
lua.pushstring(&String::from_utf8_lossy(&sshfp.fingerprint));
lua.settable(-3);
},
}
DNSRData::SRV(ref srv) => {
lua.pushstring("addr");
lua.pushstring(&String::from_utf8_lossy(&srv.target));
lua.settable(-3);
},
}
}
lua.settable(-3);
}
@ -215,13 +195,10 @@ pub extern "C" fn rs_dns_lua_get_answer_table(clua: &mut CLuaState,
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_authority_table(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
pub extern "C" fn rs_dns_lua_get_authority_table(
clua: &mut CLuaState, tx: &mut DNSTransaction,
) -> c_int {
let lua = LuaState { lua: clua };
let mut i: i64 = 0;

@ -15,10 +15,10 @@
* 02110-1301, USA.
*/
pub mod parser;
pub mod detect;
pub mod dns;
pub mod log;
pub mod detect;
pub mod parser;
#[cfg(feature = "lua")]
pub mod lua;

@ -128,9 +128,7 @@ fn dns_parse_answer<'a>(
data: &'a [u8],
}
fn subparser<'a>(
i: &'a [u8], message: &'a [u8],
) -> IResult<&'a [u8], Answer<'a>> {
fn subparser<'a>(i: &'a [u8], message: &'a [u8]) -> IResult<&'a [u8], Answer<'a>> {
let (i, name) = dns_parse_name(i, message)?;
let (i, rrtype) = be_u16(i)?;
let (i, rrclass) = be_u16(i)?;
@ -357,7 +355,7 @@ pub fn dns_parse_request(input: &[u8]) -> IResult<&[u8], DNSRequest> {
#[cfg(test)]
mod tests {
use crate::dns::dns::{DNSHeader,DNSAnswerEntry};
use crate::dns::dns::{DNSAnswerEntry, DNSHeader};
use crate::dns::parser::*;
/// Parse a simple name with no pointers.
@ -370,7 +368,7 @@ mod tests {
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, /* .com.... */
];
let expected_remainder: &[u8] = &[0x00, 0x01, 0x00];
let (remainder,name) = dns_parse_name(buf, buf).unwrap();
let (remainder, name) = dns_parse_name(buf, buf).unwrap();
assert_eq!("client-cf.dropbox.com".as_bytes(), &name[..]);
assert_eq!(remainder, expected_remainder);
}
@ -379,23 +377,23 @@ mod tests {
#[test]
fn test_dns_parse_name_with_pointer() {
let buf: &[u8] = &[
0xd8, 0xcb, 0x8a, 0xed, 0xa1, 0x46, 0x00, 0x15 /* 0 - .....F.. */,
0x17, 0x0d, 0x06, 0xf7, 0x08, 0x00, 0x45, 0x00 /* 8 - ......E. */,
0x00, 0x7b, 0x71, 0x6e, 0x00, 0x00, 0x39, 0x11 /* 16 - .{qn..9. */,
0xf4, 0xd9, 0x08, 0x08, 0x08, 0x08, 0x0a, 0x10 /* 24 - ........ */,
0x01, 0x0b, 0x00, 0x35, 0xe1, 0x8e, 0x00, 0x67 /* 32 - ...5...g */,
0x60, 0x00, 0xef, 0x08, 0x81, 0x80, 0x00, 0x01 /* 40 - `....... */,
0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x03, 0x77 /* 48 - .......w */,
0x77, 0x77, 0x0c, 0x73, 0x75, 0x72, 0x69, 0x63 /* 56 - ww.suric */,
0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, 0x73, 0x03 /* 64 - ata-ids. */,
0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01 /* 72 - org..... */,
0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00 /* 80 - ........ */,
0x0e, 0x0f, 0x00, 0x02, 0xc0, 0x10, 0xc0, 0x10 /* 88 - ........ */,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2b /* 96 - .......+ */,
0x00, 0x04, 0xc0, 0x00, 0x4e, 0x19, 0xc0, 0x10 /* 104 - ....N... */,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2b /* 112 - .......+ */,
0x00, 0x04, 0xc0, 0x00, 0x4e, 0x18, 0x00, 0x00 /* 120 - ....N... */,
0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 128 - )....... */,
0xd8, 0xcb, 0x8a, 0xed, 0xa1, 0x46, 0x00, 0x15, /* 0 - .....F.. */
0x17, 0x0d, 0x06, 0xf7, 0x08, 0x00, 0x45, 0x00, /* 8 - ......E. */
0x00, 0x7b, 0x71, 0x6e, 0x00, 0x00, 0x39, 0x11, /* 16 - .{qn..9. */
0xf4, 0xd9, 0x08, 0x08, 0x08, 0x08, 0x0a, 0x10, /* 24 - ........ */
0x01, 0x0b, 0x00, 0x35, 0xe1, 0x8e, 0x00, 0x67, /* 32 - ...5...g */
0x60, 0x00, 0xef, 0x08, 0x81, 0x80, 0x00, 0x01, /* 40 - `....... */
0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x03, 0x77, /* 48 - .......w */
0x77, 0x77, 0x0c, 0x73, 0x75, 0x72, 0x69, 0x63, /* 56 - ww.suric */
0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, 0x73, 0x03, /* 64 - ata-ids. */
0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, /* 72 - org..... */
0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, /* 80 - ........ */
0x0e, 0x0f, 0x00, 0x02, 0xc0, 0x10, 0xc0, 0x10, /* 88 - ........ */
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2b, /* 96 - .......+ */
0x00, 0x04, 0xc0, 0x00, 0x4e, 0x19, 0xc0, 0x10, /* 104 - ....N... */
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2b, /* 112 - .......+ */
0x00, 0x04, 0xc0, 0x00, 0x4e, 0x18, 0x00, 0x00, /* 120 - ....N... */
0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - )....... */
0x00, /* 136 - . */
];
@ -405,53 +403,57 @@ mod tests {
// The name at offset 54 is the complete name.
let start1 = &buf[54..];
let res1 = dns_parse_name(start1, message);
assert_eq!(res1,
Ok((&start1[22..],
"www.suricata-ids.org".as_bytes().to_vec())));
assert_eq!(
res1,
Ok((&start1[22..], "www.suricata-ids.org".as_bytes().to_vec()))
);
// The second name starts at offset 80, but is just a pointer
// to the first.
let start2 = &buf[80..];
let res2 = dns_parse_name(start2, message);
assert_eq!(res2,
Ok((&start2[2..],
"www.suricata-ids.org".as_bytes().to_vec())));
assert_eq!(
res2,
Ok((&start2[2..], "www.suricata-ids.org".as_bytes().to_vec()))
);
// The third name starts at offset 94, but is a pointer to a
// portion of the first.
let start3 = &buf[94..];
let res3 = dns_parse_name(start3, message);
assert_eq!(res3,
Ok((&start3[2..],
"suricata-ids.org".as_bytes().to_vec())));
assert_eq!(
res3,
Ok((&start3[2..], "suricata-ids.org".as_bytes().to_vec()))
);
// The fourth name starts at offset 110, but is a pointer to a
// portion of the first.
let start4 = &buf[110..];
let res4 = dns_parse_name(start4, message);
assert_eq!(res4,
Ok((&start4[2..],
"suricata-ids.org".as_bytes().to_vec())));
assert_eq!(
res4,
Ok((&start4[2..], "suricata-ids.org".as_bytes().to_vec()))
);
}
#[test]
fn test_dns_parse_name_double_pointer() {
let buf: &[u8] = &[
0xd8, 0xcb, 0x8a, 0xed, 0xa1, 0x46, 0x00, 0x15 /* 0: .....F.. */,
0x17, 0x0d, 0x06, 0xf7, 0x08, 0x00, 0x45, 0x00 /* 8: ......E. */,
0x00, 0x66, 0x5e, 0x20, 0x40, 0x00, 0x40, 0x11 /* 16: .f^ @.@. */,
0xc6, 0x3b, 0x0a, 0x10, 0x01, 0x01, 0x0a, 0x10 /* 24: .;...... */,
0x01, 0x0b, 0x00, 0x35, 0xc2, 0x21, 0x00, 0x52 /* 32: ...5.!.R */,
0x35, 0xc5, 0x0d, 0x4f, 0x81, 0x80, 0x00, 0x01 /* 40: 5..O.... */,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x62 /* 48: .......b */,
0x6c, 0x6f, 0x63, 0x6b, 0x07, 0x64, 0x72, 0x6f /* 56: lock.dro */,
0x70, 0x62, 0x6f, 0x78, 0x03, 0x63, 0x6f, 0x6d /* 64: pbox.com */,
0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00 /* 72: ........ */,
0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00 /* 80: ........ */,
0x0b, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x02 /* 88: ..block. */,
0x67, 0x31, 0xc0, 0x12, 0xc0, 0x2f, 0x00, 0x01 /* 96: g1.../.. */,
0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04 /* 104: ........ */,
0x2d, 0x3a, 0x46, 0x21 /* 112: -:F! */
0xd8, 0xcb, 0x8a, 0xed, 0xa1, 0x46, 0x00, 0x15, /* 0: .....F.. */
0x17, 0x0d, 0x06, 0xf7, 0x08, 0x00, 0x45, 0x00, /* 8: ......E. */
0x00, 0x66, 0x5e, 0x20, 0x40, 0x00, 0x40, 0x11, /* 16: .f^ @.@. */
0xc6, 0x3b, 0x0a, 0x10, 0x01, 0x01, 0x0a, 0x10, /* 24: .;...... */
0x01, 0x0b, 0x00, 0x35, 0xc2, 0x21, 0x00, 0x52, /* 32: ...5.!.R */
0x35, 0xc5, 0x0d, 0x4f, 0x81, 0x80, 0x00, 0x01, /* 40: 5..O.... */
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x62, /* 48: .......b */
0x6c, 0x6f, 0x63, 0x6b, 0x07, 0x64, 0x72, 0x6f, /* 56: lock.dro */
0x70, 0x62, 0x6f, 0x78, 0x03, 0x63, 0x6f, 0x6d, /* 64: pbox.com */
0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, /* 72: ........ */
0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, /* 80: ........ */
0x0b, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x02, /* 88: ..block. */
0x67, 0x31, 0xc0, 0x12, 0xc0, 0x2f, 0x00, 0x01, /* 96: g1.../.. */
0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, /* 104: ........ */
0x2d, 0x3a, 0x46, 0x21, /* 112: -:F! */
];
// The start of the DNS message in the above packet.
@ -463,9 +465,10 @@ mod tests {
let start: &[u8] = &buf[100..];
let res = dns_parse_name(start, message);
assert_eq!(res,
Ok((&start[2..],
"block.g1.dropbox.com".as_bytes().to_vec())));
assert_eq!(
res,
Ok((&start[2..], "block.g1.dropbox.com".as_bytes().to_vec()))
);
}
#[test]
@ -478,31 +481,32 @@ mod tests {
0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, 0x73, 0x03, /* ata-ids. */
0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, /* org..... */
0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, /* ..)..... */
0x00, 0x00, 0x00 /* ... */
0x00, 0x00, 0x00, /* ... */
];
let res = dns_parse_request(pkt);
match res {
Ok((rem, request)) => {
// For now we have some remainder data as there is an
// additional record type we don't parse yet.
assert!(!rem.is_empty());
assert_eq!(request.header, DNSHeader {
assert_eq!(
request.header,
DNSHeader {
tx_id: 0x8d32,
flags: 0x0120,
questions: 1,
answer_rr: 0,
authority_rr: 0,
additional_rr: 1,
});
}
);
assert_eq!(request.queries.len(), 1);
let query = &request.queries[0];
assert_eq!(query.name,
"www.suricata-ids.org".as_bytes().to_vec());
assert_eq!(query.name, "www.suricata-ids.org".as_bytes().to_vec());
assert_eq!(query.rrtype, 1);
assert_eq!(query.rrclass, 1);
}
@ -528,55 +532,63 @@ mod tests {
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf4, /* ........ */
0x00, 0x04, 0xc0, 0x00, 0x4e, 0x18, 0xc0, 0x32, /* ....N..2 */
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf4, /* ........ */
0x00, 0x04, 0xc0, 0x00, 0x4e, 0x19 /* ....N. */
0x00, 0x04, 0xc0, 0x00, 0x4e, 0x19, /* ....N. */
];
let res = dns_parse_response(pkt);
match res {
Ok((rem, response)) => {
// The response should be full parsed.
assert_eq!(rem.len(), 0);
assert_eq!(response.header, DNSHeader{
assert_eq!(
response.header,
DNSHeader {
tx_id: 0x8d32,
flags: 0x81a0,
questions: 1,
answer_rr: 3,
authority_rr: 0,
additional_rr: 0,
});
}
);
assert_eq!(response.answers.len(), 3);
let answer1 = &response.answers[0];
assert_eq!(answer1.name,
"www.suricata-ids.org".as_bytes().to_vec());
assert_eq!(answer1.name, "www.suricata-ids.org".as_bytes().to_vec());
assert_eq!(answer1.rrtype, 5);
assert_eq!(answer1.rrclass, 1);
assert_eq!(answer1.ttl, 3544);
assert_eq!(answer1.data,
DNSRData::CNAME("suricata-ids.org".as_bytes().to_vec()));
assert_eq!(
answer1.data,
DNSRData::CNAME("suricata-ids.org".as_bytes().to_vec())
);
let answer2 = &response.answers[1];
assert_eq!(answer2, &DNSAnswerEntry{
assert_eq!(
answer2,
&DNSAnswerEntry {
name: "suricata-ids.org".as_bytes().to_vec(),
rrtype: 1,
rrclass: 1,
ttl: 244,
data: DNSRData::A([192, 0, 78, 24].to_vec()),
});
}
);
let answer3 = &response.answers[2];
assert_eq!(answer3, &DNSAnswerEntry{
assert_eq!(
answer3,
&DNSAnswerEntry {
name: "suricata-ids.org".as_bytes().to_vec(),
rrtype: 1,
rrclass: 1,
ttl: 244,
data: DNSRData::A([192, 0, 78, 25].to_vec()),
})
},
}
)
}
_ => {
assert!(false);
}
@ -603,36 +615,38 @@ mod tests {
0x01, 0x00, 0x00, 0x1c, 0x20, 0x00, 0x00, 0x03, /* .... ... */
0x84, 0x00, 0x12, 0x75, 0x00, 0x00, 0x01, 0x51, /* ...u...Q */
0x80, 0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, /* ...).... */
0x00, 0x00, 0x00, 0x00 /* .... */
0x00, 0x00, 0x00, 0x00, /* .... */
];
let res = dns_parse_response(pkt);
match res {
Ok((rem, response)) => {
// For now we have some remainder data as there is an
// additional record type we don't parse yet.
assert!(!rem.is_empty());
assert_eq!(response.header, DNSHeader{
assert_eq!(
response.header,
DNSHeader {
tx_id: 0x8295,
flags: 0x8183,
questions: 1,
answer_rr: 0,
authority_rr: 1,
additional_rr: 1,
});
}
);
assert_eq!(response.authorities.len(), 1);
let authority = &response.authorities[0];
assert_eq!(authority.name,
"oisf.net".as_bytes().to_vec());
assert_eq!(authority.name, "oisf.net".as_bytes().to_vec());
assert_eq!(authority.rrtype, 6);
assert_eq!(authority.rrclass, 1);
assert_eq!(authority.ttl, 899);
assert_eq!(authority.data,
DNSRData::SOA(DNSRDataSOA{
assert_eq!(
authority.data,
DNSRData::SOA(DNSRDataSOA {
mname: "ns-110.awsdns-13.com".as_bytes().to_vec(),
rname: "awsdns-hostmaster.amazon.com".as_bytes().to_vec(),
serial: 1,
@ -640,15 +654,15 @@ mod tests {
retry: 900,
expire: 1209600,
minimum: 86400,
}));
},
})
);
}
_ => {
assert!(false);
}
}
}
#[test]
fn test_dns_parse_response_null() {
// DNS response with a NULL record from
@ -671,59 +685,59 @@ mod tests {
// The response should be fully parsed.
assert_eq!(rem.len(), 0);
assert_eq!(response.header, DNSHeader {
assert_eq!(
response.header,
DNSHeader {
tx_id: 0x12b0,
flags: 0x8400,
questions: 1,
answer_rr: 1,
authority_rr: 0,
additional_rr: 0,
});
}
);
assert_eq!(response.queries.len(), 1);
let query = &response.queries[0];
assert_eq!(query.name,
"vaaaakardli.pirate.sea".as_bytes().to_vec());
assert_eq!(query.name, "vaaaakardli.pirate.sea".as_bytes().to_vec());
assert_eq!(query.rrtype, DNS_RECORD_TYPE_NULL);
assert_eq!(query.rrclass, 1);
assert_eq!(response.answers.len(), 1);
let answer = &response.answers[0];
assert_eq!(answer.name,
"vaaaakardli.pirate.sea".as_bytes().to_vec());
assert_eq!(answer.name, "vaaaakardli.pirate.sea".as_bytes().to_vec());
assert_eq!(answer.rrtype, DNS_RECORD_TYPE_NULL);
assert_eq!(answer.rrclass, 1);
assert_eq!(answer.ttl, 0);
assert_eq!(answer.data, DNSRData::NULL(vec![
assert_eq!(
answer.data,
DNSRData::NULL(vec![
0x56, 0x41, 0x43, 0x4b, /* VACK */
0x44, 0x03, 0xc5, 0xe9, 0x01, /* D.... */
]));
},
])
);
}
_ => {
assert!(false);
}
}
}
#[test]
fn test_dns_parse_rdata_sshfp() {
// Dummy data since we don't have a pcap sample.
let data: &[u8] = &[
// algo: DSS
0x02,
// fp_type: SHA-1
0x01,
// fingerprint: 123456789abcdef67890123456789abcdef67890
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf6, 0x78, 0x90,
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf6, 0x78, 0x90
0x02, // fp_type: SHA-1
0x01, // fingerprint: 123456789abcdef67890123456789abcdef67890
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf6, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
0x9a, 0xbc, 0xde, 0xf6, 0x78, 0x90,
];
let res = dns_parse_rdata_sshfp(data);
match res {
Ok((rem, rdata)) => {
// The data should be fully parsed.
assert_eq!(rem.len(), 0);
@ -732,12 +746,12 @@ mod tests {
assert_eq!(sshfp.algo, 2);
assert_eq!(sshfp.fp_type, 1);
assert_eq!(sshfp.fingerprint, &data[2..]);
},
}
_ => {
assert!(false);
}
}
},
}
_ => {
assert!(false);
}
@ -764,27 +778,22 @@ mod tests {
;; MSG SIZE rcvd: 191 */
let pkt: &[u8] = &[
0xeb, 0x56, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00,
0x00, 0x01, 0x04, 0x5f, 0x73, 0x69, 0x70, 0x04, 0x5f, 0x75,
0x64, 0x70, 0x03, 0x73, 0x69, 0x70, 0x05, 0x76, 0x6f, 0x69,
0x63, 0x65, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c,
0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x01, 0x13, 0x00, 0x26,
0x00, 0x14, 0x00, 0x01, 0x13, 0xc4, 0x0d, 0x73, 0x69, 0x70,
0x2d, 0x61, 0x6e, 0x79, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x32,
0x05, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x06, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x0c,
0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x01, 0x13, 0x00, 0x26,
0x00, 0x0a, 0x00, 0x01, 0x13, 0xc4, 0x0d, 0x73, 0x69, 0x70,
0x2d, 0x61, 0x6e, 0x79, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x31,
0x05, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x06, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00
0xeb, 0x56, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x04, 0x5f,
0x73, 0x69, 0x70, 0x04, 0x5f, 0x75, 0x64, 0x70, 0x03, 0x73, 0x69, 0x70, 0x05, 0x76,
0x6f, 0x69, 0x63, 0x65, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f,
0x6d, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00,
0x01, 0x13, 0x00, 0x26, 0x00, 0x14, 0x00, 0x01, 0x13, 0xc4, 0x0d, 0x73, 0x69, 0x70,
0x2d, 0x61, 0x6e, 0x79, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x32, 0x05, 0x76, 0x6f, 0x69,
0x63, 0x65, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x01, 0x13, 0x00, 0x26, 0x00, 0x0a,
0x00, 0x01, 0x13, 0xc4, 0x0d, 0x73, 0x69, 0x70, 0x2d, 0x61, 0x6e, 0x79, 0x63, 0x61,
0x73, 0x74, 0x2d, 0x31, 0x05, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x06, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
];
let res = dns_parse_response(pkt);
match res {
Ok((rem, response)) => {
// The data should be fully parsed.
assert_eq!(rem.len(), 0);
@ -796,8 +805,10 @@ mod tests {
assert_eq!(srv.priority, 20);
assert_eq!(srv.weight, 1);
assert_eq!(srv.port, 5060);
assert_eq!(srv.target,
"sip-anycast-2.voice.google.com".as_bytes().to_vec());
assert_eq!(
srv.target,
"sip-anycast-2.voice.google.com".as_bytes().to_vec()
);
}
_ => {
assert!(false);
@ -809,14 +820,16 @@ mod tests {
assert_eq!(srv.priority, 10);
assert_eq!(srv.weight, 1);
assert_eq!(srv.port, 5060);
assert_eq!(srv.target,
"sip-anycast-1.voice.google.com".as_bytes().to_vec());
assert_eq!(
srv.target,
"sip-anycast-1.voice.google.com".as_bytes().to_vec()
);
}
_ => {
assert!(false);
}
}
},
}
_ => {
assert!(false);
}

Loading…
Cancel
Save