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,17 +16,17 @@
*/
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;
@ -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,
@ -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);
@ -502,13 +511,22 @@ impl DNSState {
}
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);
@ -551,13 +573,22 @@ impl DNSState {
}
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,16 +672,14 @@ 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),
}
}
@ -654,7 +689,7 @@ pub fn probe_tcp(input: &[u8]) -> (bool, bool, bool) {
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);
@ -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,11 +16,11 @@
*/
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);
@ -88,8 +88,7 @@ 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
{
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.
@ -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,35 +615,37 @@ 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,
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(),
@ -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