dns: register parsers from Rust

And port the C DNS tests to Rust.
pull/4679/head
Jason Ish 6 years ago committed by Victor Julien
parent 0af9a3a5f7
commit a0e3e2d7b4

@ -18,6 +18,8 @@
use std;
use crate::core::{STREAM_TOSERVER};
pub const APP_LAYER_PARSER_OPT_ACCEPT_GAPS: u32 = BIT_U32!(0);
#[repr(C)]
pub struct AppLayerGetTxIterTuple {
tx_ptr: *mut std::os::raw::c_void,

@ -48,6 +48,10 @@ pub static mut ALPROTO_FAILED : AppProto = 0; // updated during init
pub const IPPROTO_TCP : i32 = 6;
pub const IPPROTO_UDP : i32 = 17;
macro_rules!BIT_U32 {
($x:expr) => (1 << $x);
}
macro_rules!BIT_U64 {
($x:expr) => (1 << $x);
}

@ -18,12 +18,14 @@
extern crate nom;
use std;
use std::ffi::CString;
use std::mem::transmute;
use crate::log::*;
use crate::applayer::LoggerFlags;
use crate::core;
use crate::core::{self, AppProto, ALPROTO_UNKNOWN, IPPROTO_UDP, IPPROTO_TCP};
use crate::dns::parser;
use crate::parser::*;
use nom::IResult;
use nom::number::streaming::be_u16;
@ -125,6 +127,8 @@ pub const DNS_RCODE_BADTRUNC: u16 = 22;
/// gets logged.
const MAX_TRANSACTIONS: usize = 32;
static mut ALPROTO_DNS: AppProto = ALPROTO_UNKNOWN;
#[repr(u32)]
pub enum DNSEvent {
MalformedData = 0,
@ -165,21 +169,23 @@ impl DNSEvent {
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_state_get_event_info_by_id(
pub extern "C" fn rs_dns_state_get_event_info_by_id(
event_id: std::os::raw::c_int,
event_name: *mut *const std::os::raw::c_char,
event_type: *mut core::AppLayerEventType,
) -> std::os::raw::c_int {
) -> i8 {
if let Some(e) = DNSEvent::from_id(event_id as u32) {
*event_name = e.to_cstring().as_ptr() as *const std::os::raw::c_char;
*event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
unsafe {
*event_name = e.to_cstring().as_ptr() as *const std::os::raw::c_char;
*event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
}
return 0;
}
return -1;
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_state_get_event_info(
pub extern "C" fn rs_dns_state_get_event_info(
event_name: *const std::os::raw::c_char,
event_id: *mut std::os::raw::c_int,
event_type: *mut core::AppLayerEventType
@ -188,11 +194,13 @@ pub unsafe extern "C" fn rs_dns_state_get_event_info(
return -1;
}
let event_name = std::ffi::CStr::from_ptr(event_name);
let event_name = unsafe { std::ffi::CStr::from_ptr(event_name) };
if let Ok(event_name) = event_name.to_str() {
if let Some(event) = DNSEvent::from_string(event_name) {
*event_id = event as std::os::raw::c_int;
*event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
unsafe {
*event_id = event as std::os::raw::c_int;
*event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
}
} else {
// Unknown event...
return -1;
@ -206,6 +214,7 @@ pub unsafe extern "C" fn rs_dns_state_get_event_info(
}
#[derive(Debug,PartialEq)]
#[repr(C)]
pub struct DNSHeader {
pub tx_id: u16,
pub flags: u16,
@ -648,12 +657,12 @@ pub extern "C" fn rs_dns_state_tx_free(state: *mut std::os::raw::c_void,
/// C binding parse a DNS request. Returns 1 on success, -1 on failure.
#[no_mangle]
pub extern "C" fn rs_dns_parse_request(_flow: *mut core::Flow,
pub extern "C" fn rs_dns_parse_request(_flow: *const core::Flow,
state: *mut std::os::raw::c_void,
_pstate: *mut core::AppLayerParserState,
_pstate: *mut std::os::raw::c_void,
input: *const u8,
input_len: u32,
_data: *mut std::os::raw::c_void,
_data: *const std::os::raw::c_void,
_flags: u8)
-> std::os::raw::c_int {
let state = cast_pointer!(state, DNSState);
@ -666,12 +675,12 @@ pub extern "C" fn rs_dns_parse_request(_flow: *mut core::Flow,
}
#[no_mangle]
pub extern "C" fn rs_dns_parse_response(_flow: *mut core::Flow,
pub extern "C" fn rs_dns_parse_response(_flow: *const core::Flow,
state: *mut std::os::raw::c_void,
_pstate: *mut core::AppLayerParserState,
_pstate: *mut std::os::raw::c_void,
input: *const u8,
input_len: u32,
_data: *mut std::os::raw::c_void,
_data: *const std::os::raw::c_void,
_flags: u8)
-> std::os::raw::c_int {
let state = cast_pointer!(state, DNSState);
@ -685,12 +694,12 @@ pub extern "C" fn rs_dns_parse_response(_flow: *mut core::Flow,
/// C binding parse a DNS request. Returns 1 on success, -1 on failure.
#[no_mangle]
pub extern "C" fn rs_dns_parse_request_tcp(_flow: *mut core::Flow,
pub extern "C" fn rs_dns_parse_request_tcp(_flow: *const core::Flow,
state: *mut std::os::raw::c_void,
_pstate: *mut core::AppLayerParserState,
_pstate: *mut std::os::raw::c_void,
input: *const u8,
input_len: u32,
_data: *mut std::os::raw::c_void,
_data: *const std::os::raw::c_void,
_flags: u8)
-> std::os::raw::c_int {
let state = cast_pointer!(state, DNSState);
@ -706,12 +715,12 @@ pub extern "C" fn rs_dns_parse_request_tcp(_flow: *mut core::Flow,
}
#[no_mangle]
pub extern "C" fn rs_dns_parse_response_tcp(_flow: *mut core::Flow,
pub extern "C" fn rs_dns_parse_response_tcp(_flow: *const core::Flow,
state: *mut std::os::raw::c_void,
_pstate: *mut core::AppLayerParserState,
_pstate: *mut std::os::raw::c_void,
input: *const u8,
input_len: u32,
_data: *mut std::os::raw::c_void,
_data: *const std::os::raw::c_void,
_flags: u8)
-> std::os::raw::c_int {
let state = cast_pointer!(state, DNSState);
@ -911,9 +920,16 @@ pub extern "C" fn rs_dns_tx_get_query_rrtype(tx: &mut DNSTransaction,
}
#[no_mangle]
pub extern "C" fn rs_dns_probe(input: *const u8, len: u32, rdir: *mut u8)
-> u8
{
pub extern "C" fn rs_dns_probe(
_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;
}
let slice: &[u8] = unsafe {
std::slice::from_raw_parts(input as *mut u8, len as usize)
};
@ -924,20 +940,25 @@ pub extern "C" fn rs_dns_probe(input: *const u8, len: u32, rdir: *mut u8)
} else {
core::STREAM_TOCLIENT
};
unsafe { *rdir = dir };
return 1;
unsafe {
*rdir = dir;
return ALPROTO_DNS;
}
}
return 0;
}
#[no_mangle]
pub extern "C" fn rs_dns_probe_tcp(direction: u8,
input: *const u8,
len: u32,
rdir: *mut u8)
-> u8
{
pub extern "C" fn rs_dns_probe_tcp(
_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;
}
let slice: &[u8] = unsafe {
std::slice::from_raw_parts(input as *mut u8, len as usize)
};
@ -951,15 +972,116 @@ pub extern "C" fn rs_dns_probe_tcp(direction: u8,
if direction & (core::STREAM_TOSERVER|core::STREAM_TOCLIENT) != dir {
unsafe { *rdir = dir };
}
return 1;
return unsafe { ALPROTO_DNS };
}
return 0;
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_init(proto: AppProto) {
ALPROTO_DNS = proto;
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_udp_register_parser() {
let default_port = std::ffi::CString::new("[53]").unwrap();
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,
probe_ts: Some(rs_dns_probe),
probe_tc: Some(rs_dns_probe),
min_depth: 0,
max_depth: std::mem::size_of::<DNSHeader>() as u16,
state_new: rs_dns_state_new,
state_free: rs_dns_state_free,
tx_free: rs_dns_state_tx_free,
parse_ts: rs_dns_parse_request,
parse_tc: rs_dns_parse_response,
get_tx_count: rs_dns_state_get_tx_count,
get_tx: rs_dns_state_get_tx,
tx_get_comp_st: rs_dns_state_progress_completion_status,
tx_get_progress: rs_dns_tx_get_alstate_progress,
get_tx_logged: Some(rs_dns_tx_get_logged),
set_tx_logged: Some(rs_dns_tx_set_logged),
get_events: Some(rs_dns_state_get_events),
get_eventinfo: Some(rs_dns_state_get_event_info),
get_eventinfo_byid: Some(rs_dns_state_get_event_info_by_id),
localstorage_new: None,
localstorage_free: None,
get_tx_mpm_id: None,
set_tx_mpm_id: None,
get_files: None,
get_tx_iterator: None,
get_tx_detect_flags: Some(rs_dns_tx_get_detect_flags),
set_tx_detect_flags: Some(rs_dns_tx_set_detect_flags),
get_de_state: rs_dns_state_get_tx_detect_state,
set_de_state: rs_dns_state_set_tx_detect_state,
};
let ip_proto_str = CString::new("udp").unwrap();
if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
ALPROTO_DNS = alproto;
if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
let _ = AppLayerRegisterParser(&parser, alproto);
}
}
}
#[no_mangle]
pub unsafe extern "C" fn rs_dns_tcp_register_parser() {
let default_port = std::ffi::CString::new("53").unwrap();
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,
probe_ts: Some(rs_dns_probe_tcp),
probe_tc: Some(rs_dns_probe_tcp),
min_depth: 0,
max_depth: std::mem::size_of::<DNSHeader>() as u16 + 2,
state_new: rs_dns_state_new,
state_free: rs_dns_state_free,
tx_free: rs_dns_state_tx_free,
parse_ts: rs_dns_parse_request_tcp,
parse_tc: rs_dns_parse_response_tcp,
get_tx_count: rs_dns_state_get_tx_count,
get_tx: rs_dns_state_get_tx,
tx_get_comp_st: rs_dns_state_progress_completion_status,
tx_get_progress: rs_dns_tx_get_alstate_progress,
get_tx_logged: Some(rs_dns_tx_get_logged),
set_tx_logged: Some(rs_dns_tx_set_logged),
get_events: Some(rs_dns_state_get_events),
get_eventinfo: Some(rs_dns_state_get_event_info),
get_eventinfo_byid: Some(rs_dns_state_get_event_info_by_id),
localstorage_new: None,
localstorage_free: None,
get_tx_mpm_id: None,
set_tx_mpm_id: None,
get_files: None,
get_tx_iterator: None,
get_tx_detect_flags: Some(rs_dns_tx_get_detect_flags),
set_tx_detect_flags: Some(rs_dns_tx_set_detect_flags),
get_de_state: rs_dns_state_get_tx_detect_state,
set_de_state: rs_dns_state_set_tx_detect_state,
};
let ip_proto_str = CString::new("tcp").unwrap();
if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
ALPROTO_DNS = alproto;
if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
let _ = AppLayerRegisterParser(&parser, alproto);
}
AppLayerParserRegisterOptionFlags(IPPROTO_TCP as u8, ALPROTO_DNS,
crate::applayer::APP_LAYER_PARSER_OPT_ACCEPT_GAPS);
}
}
#[cfg(test)]
mod tests {
use crate::dns::dns::DNSState;
use super::*;
#[test]
fn test_dns_parse_request_tcp_valid() {
@ -1104,4 +1226,203 @@ mod tests {
let mut state = DNSState::new();
assert_eq!(0, state.parse_response_tcp(&request));
}
// Port of the C RustDNSUDPParserTest02 unit test.
#[test]
fn test_dns_udp_parser_test_01() {
/* query: abcdefghijk.com
* TTL: 86400
* serial 20130422 refresh 28800 retry 7200 exp 604800 min ttl 86400
* ns, hostmaster */
let buf: &[u8] = &[
0x00, 0x3c, 0x85, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x0b, 0x61, 0x62, 0x63,
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x0f, 0x00,
0x01, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01,
0x51, 0x80, 0x00, 0x25, 0x02, 0x6e, 0x73, 0x00,
0x0a, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x73,
0x74, 0x65, 0x72, 0xc0, 0x2f, 0x01, 0x33, 0x2a,
0x76, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x1c,
0x20, 0x00, 0x09, 0x3a, 0x80, 0x00, 0x01, 0x51,
0x80,
];
let mut state = DNSState::new();
assert!(state.parse_response(buf));
}
// Port of the C RustDNSUDPParserTest02 unit test.
#[test]
fn test_dns_udp_parser_test_02() {
let buf: &[u8] = &[
0x6D,0x08,0x84,0x80,0x00,0x01,0x00,0x08,0x00,0x00,0x00,0x01,0x03,0x57,0x57,0x57,
0x04,0x54,0x54,0x54,0x54,0x03,0x56,0x56,0x56,0x03,0x63,0x6F,0x6D,0x02,0x79,0x79,
0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,
0x02,0xC0,0x0C,0xC0,0x31,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,
0x31,0xC0,0x3F,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x3F,0xC0,
0x4D,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x4D,0xC0,0x5B,0x00,
0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x5B,0xC0,0x69,0x00,0x05,0x00,
0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x69,0xC0,0x77,0x00,0x05,0x00,0x01,0x00,
0x00,0x0E,0x10,0x00,0x02,0xC0,0x77,0xC0,0x85,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,
0x10,0x00,0x02,0xC0,0x85,0x00,0x00,0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
];
let mut state = DNSState::new();
assert!(state.parse_response(buf));
}
// Port of the C RustDNSUDPParserTest03 unit test.
#[test]
fn test_dns_udp_parser_test_03() {
let buf: &[u8] = &[
0x6F,0xB4,0x84,0x80,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x03,0x57,0x57,0x77,
0x0B,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x03,0x55,0x55,0x55,
0x02,0x79,0x79,0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,
0x0E,0x10,0x00,0x02,0xC0,0x10,0xC0,0x34,0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,
0x00,0x04,0xC3,0xEA,0x04,0x19,0xC0,0x34,0x00,0x02,0x00,0x01,0x00,0x00,0x0E,0x10,
0x00,0x0A,0x03,0x6E,0x73,0x31,0x03,0x61,0x67,0x62,0xC0,0x20,0xC0,0x46,0x00,0x02,
0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x06,0x03,0x6E,0x73,0x32,0xC0,0x56,0xC0,0x52,
0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x04,0x0A,0xC0,0x68,
0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x05,0x14,0x00,0x00,
0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00
];
let mut state = DNSState::new();
assert!(state.parse_response(buf));
}
// Port of the C RustDNSUDPParserTest04 unit test.
//
// Test the TXT records in an answer.
#[test]
fn test_dns_udp_parser_test_04() {
let buf: &[u8] = &[
0xc2,0x2f,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x0a,0x41,0x41,0x41,
0x41,0x41,0x4f,0x31,0x6b,0x51,0x41,0x05,0x3d,0x61,0x75,0x74,0x68,0x03,0x73,0x72,
0x76,0x06,0x74,0x75,0x6e,0x6e,0x65,0x6c,0x03,0x63,0x6f,0x6d,0x00,0x00,0x10,0x00,
0x01,
/* answer record start */
0xc0,0x0c,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x22,
/* txt record starts: */
0x20, /* <txt len 32 */ 0x41,0x68,0x76,0x4d,0x41,0x41,0x4f,0x31,0x6b,0x41,0x46,
0x45,0x35,0x54,0x45,0x39,0x51,0x54,0x6a,0x46,0x46,0x4e,0x30,0x39,0x52,0x4e,0x31,
0x6c,0x59,0x53,0x44,0x6b,0x00, /* <txt len 0 */ 0xc0,0x1d,0x00,0x02,0x00,0x01,
0x00,0x09,0x3a,0x80,0x00,0x09,0x06,0x69,0x6f,0x64,0x69,0x6e,0x65,0xc0,0x21,0xc0,
0x6b,0x00,0x01,0x00,0x01,0x00,0x09,0x3a,0x80,0x00,0x04,0x0a,0x1e,0x1c,0x5f
];
let mut state = DNSState::new();
assert!(state.parse_response(buf));
}
// Port of the C RustDNSUDPParserTest05 unit test.
//
// Test TXT records in answer with a bad length.
#[test]
fn test_dns_udp_parser_test_05() {
let buf: &[u8] = &[
0xc2,0x2f,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x0a,0x41,0x41,0x41,
0x41,0x41,0x4f,0x31,0x6b,0x51,0x41,0x05,0x3d,0x61,0x75,0x74,0x68,0x03,0x73,0x72,
0x76,0x06,0x74,0x75,0x6e,0x6e,0x65,0x6c,0x03,0x63,0x6f,0x6d,0x00,0x00,0x10,0x00,
0x01,
/* answer record start */
0xc0,0x0c,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x22,
/* txt record starts: */
0x40, /* <txt len 64 */ 0x41,0x68,0x76,0x4d,0x41,0x41,0x4f,0x31,0x6b,0x41,0x46,
0x45,0x35,0x54,0x45,0x39,0x51,0x54,0x6a,0x46,0x46,0x4e,0x30,0x39,0x52,0x4e,0x31,
0x6c,0x59,0x53,0x44,0x6b,0x00, /* <txt len 0 */ 0xc0,0x1d,0x00,0x02,0x00,0x01,
0x00,0x09,0x3a,0x80,0x00,0x09,0x06,0x69,0x6f,0x64,0x69,0x6e,0x65,0xc0,0x21,0xc0,
0x6b,0x00,0x01,0x00,0x01,0x00,0x09,0x3a,0x80,0x00,0x04,0x0a,0x1e,0x1c,0x5f
];
let mut state = DNSState::new();
assert!(!state.parse_response(buf));
}
// Port of the C RustDNSTCPParserTestMultiRecord unit test.
#[test]
fn test_dns_tcp_parser_multi_record() {
let buf: &[u8] = &[
0x00, 0x1e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x32,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x03, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x33,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x34,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x05, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x35,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x06, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x07, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x37,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x08, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x09, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x39,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1f, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31,
0x30, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
0x01, 0x00, 0x1f, 0x00, 0x0b, 0x01, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x31, 0x31, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
0x00, 0x01, 0x00, 0x1f, 0x00, 0x0c, 0x01, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x31, 0x32, 0x06, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0d, 0x01,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x31, 0x33, 0x06, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
0x00, 0x01, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0e,
0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x31, 0x34, 0x06, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d,
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x1f, 0x00,
0x0f, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x31, 0x35, 0x06, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f,
0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x1f,
0x00, 0x10, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x36, 0x06,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x1f, 0x00, 0x11, 0x01, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x37,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1f, 0x00, 0x12, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31,
0x38, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
0x01, 0x00, 0x1f, 0x00, 0x13, 0x01, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x31, 0x39, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
0x00, 0x01
];
let mut state = DNSState::new();
assert_eq!(state.parse_request_tcp(buf), 20);
}
}

@ -199,4 +199,5 @@ extern {
GetTxDetectFlats: GetTxDetectFlagsFn,
SetTxDetectFlags: SetTxDetectFlagsFn,
);
pub fn AppLayerParserRegisterOptionFlags(ipproto: u8, alproto: AppProto, flags: u32);
}

@ -18,9 +18,6 @@ app-layer-dcerpc-udp.c app-layer-dcerpc-udp.h \
app-layer-detect-proto.c app-layer-detect-proto.h \
app-layer-dnp3.c app-layer-dnp3.h \
app-layer-dnp3-objects.c app-layer-dnp3-objects.h \
app-layer-dns-common.h \
app-layer-dns-tcp.c app-layer-dns-tcp.h \
app-layer-dns-udp.c app-layer-dns-udp.h \
app-layer-enip.c app-layer-enip.h \
app-layer-enip-common.c app-layer-enip-common.h \
app-layer-events.c app-layer-events.h \

@ -1,37 +0,0 @@
/* Copyright (C) 2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Victor Julien <victor@inliniac.net>
*/
#ifndef __APP_LAYER_DNS_COMMON_H__
#define __APP_LAYER_DNS_COMMON_H__
/** \brief DNS packet header */
typedef struct DNSHeader_ {
uint16_t tx_id;
uint16_t flags;
uint16_t questions;
uint16_t answer_rr;
uint16_t authority_rr;
uint16_t additional_rr;
} __attribute__((__packed__)) DNSHeader;
#endif /* __APP_LAYER_DNS_COMMON_H__ */

@ -1,246 +0,0 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "suricata-common.h"
#include "suricata.h"
#include "app-layer-protos.h"
#include "app-layer-detect-proto.h"
#include "app-layer-parser.h"
#include "app-layer-dns-common.h"
#include "util-unittest.h"
#include "app-layer-dns-tcp.h"
#include "rust.h"
#ifdef UNITTESTS
static void RustDNSTCPParserRegisterTests(void);
#endif
static uint16_t RustDNSTCPProbe(Flow *f, uint8_t direction,
const uint8_t *input, uint32_t len, uint8_t *rdir)
{
SCLogDebug("RustDNSTCPProbe");
if (len == 0 || len < sizeof(DNSHeader)) {
return ALPROTO_UNKNOWN;
}
// Validate and return ALPROTO_FAILED if needed.
if (!rs_dns_probe_tcp(direction, input, len, rdir)) {
return ALPROTO_FAILED;
}
return ALPROTO_DNS;
}
void RegisterDNSTCPParsers(void)
{
const char *proto_name = "dns";
/** DNS */
if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) {
AppLayerProtoDetectRegisterProtocol(ALPROTO_DNS, proto_name);
if (RunmodeIsUnittests()) {
AppLayerProtoDetectPPRegister(IPPROTO_TCP, "53", ALPROTO_DNS, 0,
sizeof(DNSHeader) + 2, STREAM_TOSERVER, RustDNSTCPProbe,
RustDNSTCPProbe);
} else {
int have_cfg = AppLayerProtoDetectPPParseConfPorts("tcp",
IPPROTO_TCP, proto_name, ALPROTO_DNS, 0,
sizeof(DNSHeader) + 2, RustDNSTCPProbe, RustDNSTCPProbe);
/* if we have no config, we enable the default port 53 */
if (!have_cfg) {
SCLogConfig("no DNS TCP config found, enabling DNS detection "
"on port 53.");
AppLayerProtoDetectPPRegister(IPPROTO_TCP, "53", ALPROTO_DNS, 0,
sizeof(DNSHeader) + 2, STREAM_TOSERVER, RustDNSTCPProbe,
RustDNSTCPProbe);
}
}
} else {
SCLogConfig("Protocol detection and parser disabled for %s protocol.",
proto_name);
return;
}
if (AppLayerParserConfParserEnabled("tcp", proto_name)) {
AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DNS, STREAM_TOSERVER,
rs_dns_parse_request_tcp);
AppLayerParserRegisterParser(IPPROTO_TCP , ALPROTO_DNS, STREAM_TOCLIENT,
rs_dns_parse_response_tcp);
AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_state_tcp_new, rs_dns_state_free);
AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_state_tx_free);
AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_state_get_events);
AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_state_get_tx_detect_state, rs_dns_state_set_tx_detect_state);
AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNS, rs_dns_state_get_tx);
AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_state_get_tx_count);
AppLayerParserRegisterLoggerFuncs(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_tx_get_logged, rs_dns_tx_set_logged);
AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_tx_get_alstate_progress);
AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_DNS,
rs_dns_state_progress_completion_status);
AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_state_get_event_info);
AppLayerParserRegisterGetEventInfoById(IPPROTO_TCP, ALPROTO_DNS,
rs_dns_state_get_event_info_by_id);
/* This parser accepts gaps. */
AppLayerParserRegisterOptionFlags(IPPROTO_TCP, ALPROTO_DNS,
APP_LAYER_PARSER_OPT_ACCEPT_GAPS);
} else {
SCLogConfig("Parsed disabled for %s protocol. Protocol detection"
"still on.", proto_name);
}
#ifdef UNITTESTS
AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_DNS,
RustDNSTCPParserRegisterTests);
#endif
return;
}
#ifdef UNITTESTS
#include "util-unittest-helper.h"
static int RustDNSTCPParserTestMultiRecord(void)
{
/* This is a buffer containing 20 DNS requests each prefixed by
* the request length for transport over TCP. It was generated with Scapy,
* where each request is:
* DNS(id=i, rd=1, qd=DNSQR(qname="%d.google.com" % i, qtype="A"))
* where i is 0 to 19.
*/
uint8_t req[] = {
0x00, 0x1e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x32,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x03, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x33,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x34,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x05, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x35,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x06, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x07, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x37,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x08, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1e, 0x00, 0x09, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x39,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1f, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31,
0x30, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
0x01, 0x00, 0x1f, 0x00, 0x0b, 0x01, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x31, 0x31, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
0x00, 0x01, 0x00, 0x1f, 0x00, 0x0c, 0x01, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x31, 0x32, 0x06, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0d, 0x01,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x31, 0x33, 0x06, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
0x00, 0x01, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0e,
0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x31, 0x34, 0x06, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d,
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x1f, 0x00,
0x0f, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x31, 0x35, 0x06, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f,
0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x1f,
0x00, 0x10, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x36, 0x06,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x1f, 0x00, 0x11, 0x01, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x37,
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x1f, 0x00, 0x12, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31,
0x38, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
0x01, 0x00, 0x1f, 0x00, 0x13, 0x01, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x31, 0x39, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
0x00, 0x01
};
size_t reqlen = sizeof(req);
void *state = rs_dns_state_new();
Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53);
FAIL_IF_NULL(f);
f->proto = IPPROTO_TCP;
f->alproto = ALPROTO_DNS;
f->alstate = state;
FAIL_IF(rs_dns_parse_request_tcp(f, f->alstate, NULL, req, reqlen,
NULL, STREAM_START) < 0);
FAIL_IF(rs_dns_state_get_tx_count(state) != 20);
UTHFreeFlow(f);
PASS;
}
static void RustDNSTCPParserRegisterTests(void)
{
UtRegisterTest("RustDNSTCPParserTestMultiRecord",
RustDNSTCPParserTestMultiRecord);
}
#endif /* UNITTESTS */

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

@ -1,302 +0,0 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "suricata-common.h"
#include "suricata.h"
#include "app-layer-protos.h"
#include "app-layer-detect-proto.h"
#include "app-layer-parser.h"
#include "app-layer-dns-common.h"
#include "util-unittest.h"
#include "app-layer-dns-udp.h"
#include "rust.h"
#ifdef UNITTESTS
static void RustDNSUDPParserRegisterTests(void);
#endif
static uint16_t DNSUDPProbe(Flow *f, uint8_t direction,
const uint8_t *input, uint32_t len, uint8_t *rdir)
{
if (len == 0 || len < sizeof(DNSHeader)) {
return ALPROTO_UNKNOWN;
}
// Validate and return ALPROTO_FAILED if needed.
if (!rs_dns_probe(input, len, rdir)) {
return ALPROTO_FAILED;
}
return ALPROTO_DNS;
}
void RegisterDNSUDPParsers(void)
{
const char *proto_name = "dns";
/** DNS */
if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) {
AppLayerProtoDetectRegisterProtocol(ALPROTO_DNS, proto_name);
if (RunmodeIsUnittests()) {
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "53", ALPROTO_DNS, 0,
sizeof(DNSHeader), STREAM_TOSERVER, DNSUDPProbe,
DNSUDPProbe);
} else {
int have_cfg = AppLayerProtoDetectPPParseConfPorts("udp",
IPPROTO_UDP, proto_name, ALPROTO_DNS, 0, sizeof(DNSHeader),
DNSUDPProbe, DNSUDPProbe);
/* If no config, enable on port 53. */
if (!have_cfg) {
#ifndef AFLFUZZ_APPLAYER
SCLogConfig("no DNS UDP config found, "
"enabling DNS detection on port 53.");
#endif
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "53", ALPROTO_DNS,
0, sizeof(DNSHeader), STREAM_TOSERVER,
DNSUDPProbe, DNSUDPProbe);
}
}
} else {
SCLogConfig("Protocol detection and parser disabled for %s protocol.",
proto_name);
return;
}
if (AppLayerParserConfParserEnabled("udp", proto_name)) {
AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DNS, STREAM_TOSERVER,
rs_dns_parse_request);
AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DNS, STREAM_TOCLIENT,
rs_dns_parse_response);
AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_state_new, rs_dns_state_free);
AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_state_tx_free);
AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_state_get_events);
AppLayerParserRegisterDetectStateFuncs(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_state_get_tx_detect_state, rs_dns_state_set_tx_detect_state);
AppLayerParserRegisterDetectFlagsFuncs(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_tx_get_detect_flags, rs_dns_tx_set_detect_flags);
AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_DNS, rs_dns_state_get_tx);
AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_state_get_tx_count);
AppLayerParserRegisterLoggerFuncs(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_tx_get_logged, rs_dns_tx_set_logged);
AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_tx_get_alstate_progress);
AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_DNS,
rs_dns_state_progress_completion_status);
AppLayerParserRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_state_get_event_info);
AppLayerParserRegisterGetEventInfoById(IPPROTO_UDP, ALPROTO_DNS,
rs_dns_state_get_event_info_by_id);
} else {
SCLogConfig("Parsed disabled for %s protocol. Protocol detection"
"still on.", proto_name);
}
#ifdef UNITTESTS
AppLayerParserRegisterProtocolUnittests(IPPROTO_UDP, ALPROTO_DNS,
RustDNSUDPParserRegisterTests);
#endif
}
#ifdef UNITTESTS
#include "util-unittest-helper.h"
static int RustDNSUDPParserTest01 (void)
{
/* query: abcdefghijk.com
* TTL: 86400
* serial 20130422 refresh 28800 retry 7200 exp 604800 min ttl 86400
* ns, hostmaster */
uint8_t buf[] = { 0x00, 0x3c, 0x85, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x0b, 0x61, 0x62, 0x63,
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x0f, 0x00,
0x01, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01,
0x51, 0x80, 0x00, 0x25, 0x02, 0x6e, 0x73, 0x00,
0x0a, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x73,
0x74, 0x65, 0x72, 0xc0, 0x2f, 0x01, 0x33, 0x2a,
0x76, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x1c,
0x20, 0x00, 0x09, 0x3a, 0x80, 0x00, 0x01, 0x51,
0x80};
size_t buflen = sizeof(buf);
Flow *f = NULL;
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53);
FAIL_IF_NULL(f);
f->proto = IPPROTO_UDP;
f->alproto = ALPROTO_DNS;
f->alstate = rs_dns_state_new();
FAIL_IF_NULL(f->alstate);
FAIL_IF_NOT(rs_dns_parse_response(f, f->alstate, NULL, buf, buflen,
NULL, STREAM_START));
UTHFreeFlow(f);
PASS;
}
static int RustDNSUDPParserTest02 (void)
{
uint8_t buf[] = {
0x6D,0x08,0x84,0x80,0x00,0x01,0x00,0x08,0x00,0x00,0x00,0x01,0x03,0x57,0x57,0x57,
0x04,0x54,0x54,0x54,0x54,0x03,0x56,0x56,0x56,0x03,0x63,0x6F,0x6D,0x02,0x79,0x79,
0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,
0x02,0xC0,0x0C,0xC0,0x31,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,
0x31,0xC0,0x3F,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x3F,0xC0,
0x4D,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x4D,0xC0,0x5B,0x00,
0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x5B,0xC0,0x69,0x00,0x05,0x00,
0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x69,0xC0,0x77,0x00,0x05,0x00,0x01,0x00,
0x00,0x0E,0x10,0x00,0x02,0xC0,0x77,0xC0,0x85,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,
0x10,0x00,0x02,0xC0,0x85,0x00,0x00,0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
size_t buflen = sizeof(buf);
Flow *f = NULL;
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53);
FAIL_IF_NULL(f);
f->proto = IPPROTO_UDP;
f->alproto = ALPROTO_DNS;
f->alstate = rs_dns_state_new();
FAIL_IF_NULL(f->alstate);
FAIL_IF_NOT(rs_dns_parse_response(f, f->alstate, NULL, buf, buflen,
NULL, STREAM_START));
UTHFreeFlow(f);
PASS;
}
static int RustDNSUDPParserTest03 (void)
{
uint8_t buf[] = {
0x6F,0xB4,0x84,0x80,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x03,0x57,0x57,0x77,
0x0B,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x03,0x55,0x55,0x55,
0x02,0x79,0x79,0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,
0x0E,0x10,0x00,0x02,0xC0,0x10,0xC0,0x34,0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,
0x00,0x04,0xC3,0xEA,0x04,0x19,0xC0,0x34,0x00,0x02,0x00,0x01,0x00,0x00,0x0E,0x10,
0x00,0x0A,0x03,0x6E,0x73,0x31,0x03,0x61,0x67,0x62,0xC0,0x20,0xC0,0x46,0x00,0x02,
0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x06,0x03,0x6E,0x73,0x32,0xC0,0x56,0xC0,0x52,
0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x04,0x0A,0xC0,0x68,
0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x05,0x14,0x00,0x00,
0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
size_t buflen = sizeof(buf);
Flow *f = NULL;
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53);
FAIL_IF_NULL(f);
f->proto = IPPROTO_UDP;
f->alproto = ALPROTO_DNS;
f->alstate = rs_dns_state_new();
FAIL_IF_NULL(f->alstate);
FAIL_IF_NOT(rs_dns_parse_response(f, f->alstate, NULL, buf, buflen,
NULL, STREAM_START));
UTHFreeFlow(f);
PASS;
}
/** \test TXT records in answer */
static int RustDNSUDPParserTest04 (void)
{
uint8_t buf[] = {
0xc2,0x2f,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x0a,0x41,0x41,0x41,
0x41,0x41,0x4f,0x31,0x6b,0x51,0x41,0x05,0x3d,0x61,0x75,0x74,0x68,0x03,0x73,0x72,
0x76,0x06,0x74,0x75,0x6e,0x6e,0x65,0x6c,0x03,0x63,0x6f,0x6d,0x00,0x00,0x10,0x00,
0x01,
/* answer record start */
0xc0,0x0c,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x22,
/* txt record starts: */
0x20, /* <txt len 32 */ 0x41,0x68,0x76,0x4d,0x41,0x41,0x4f,0x31,0x6b,0x41,0x46,
0x45,0x35,0x54,0x45,0x39,0x51,0x54,0x6a,0x46,0x46,0x4e,0x30,0x39,0x52,0x4e,0x31,
0x6c,0x59,0x53,0x44,0x6b,0x00, /* <txt len 0 */ 0xc0,0x1d,0x00,0x02,0x00,0x01,
0x00,0x09,0x3a,0x80,0x00,0x09,0x06,0x69,0x6f,0x64,0x69,0x6e,0x65,0xc0,0x21,0xc0,
0x6b,0x00,0x01,0x00,0x01,0x00,0x09,0x3a,0x80,0x00,0x04,0x0a,0x1e,0x1c,0x5f
};
size_t buflen = sizeof(buf);
Flow *f = NULL;
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53);
FAIL_IF_NULL(f);
f->proto = IPPROTO_UDP;
f->alproto = ALPROTO_DNS;
f->alstate = rs_dns_state_new();
FAIL_IF_NULL(f->alstate);
FAIL_IF_NOT(rs_dns_parse_response(f, f->alstate, NULL, buf, buflen,
NULL, STREAM_START));
UTHFreeFlow(f);
PASS;
}
/** \test TXT records in answer, bad txtlen */
static int RustDNSUDPParserTest05 (void)
{
uint8_t buf[] = {
0xc2,0x2f,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x0a,0x41,0x41,0x41,
0x41,0x41,0x4f,0x31,0x6b,0x51,0x41,0x05,0x3d,0x61,0x75,0x74,0x68,0x03,0x73,0x72,
0x76,0x06,0x74,0x75,0x6e,0x6e,0x65,0x6c,0x03,0x63,0x6f,0x6d,0x00,0x00,0x10,0x00,
0x01,
/* answer record start */
0xc0,0x0c,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x22,
/* txt record starts: */
0x40, /* <txt len 64 */ 0x41,0x68,0x76,0x4d,0x41,0x41,0x4f,0x31,0x6b,0x41,0x46,
0x45,0x35,0x54,0x45,0x39,0x51,0x54,0x6a,0x46,0x46,0x4e,0x30,0x39,0x52,0x4e,0x31,
0x6c,0x59,0x53,0x44,0x6b,0x00, /* <txt len 0 */ 0xc0,0x1d,0x00,0x02,0x00,0x01,
0x00,0x09,0x3a,0x80,0x00,0x09,0x06,0x69,0x6f,0x64,0x69,0x6e,0x65,0xc0,0x21,0xc0,
0x6b,0x00,0x01,0x00,0x01,0x00,0x09,0x3a,0x80,0x00,0x04,0x0a,0x1e,0x1c,0x5f
};
size_t buflen = sizeof(buf);
Flow *f = NULL;
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53);
FAIL_IF_NULL(f);
f->proto = IPPROTO_UDP;
f->alproto = ALPROTO_DNS;
f->alstate = rs_dns_state_new();
FAIL_IF_NULL(f->alstate);
FAIL_IF(rs_dns_parse_response(f, f->alstate, NULL, buf, buflen,
NULL, STREAM_START) != -1);
UTHFreeFlow(f);
PASS;
}
static void RustDNSUDPParserRegisterTests(void)
{
UtRegisterTest("RustDNSUDPParserTest01", RustDNSUDPParserTest01);
UtRegisterTest("RustDNSUDPParserTest02", RustDNSUDPParserTest02);
UtRegisterTest("RustDNSUDPParserTest03", RustDNSUDPParserTest03);
UtRegisterTest("RustDNSUDPParserTest04", RustDNSUDPParserTest04);
UtRegisterTest("RustDNSUDPParserTest05", RustDNSUDPParserTest05);
}
#endif

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

@ -54,8 +54,6 @@
#include "app-layer-ssl.h"
#include "app-layer-ssh.h"
#include "app-layer-smtp.h"
#include "app-layer-dns-udp.h"
#include "app-layer-dns-tcp.h"
#include "app-layer-modbus.h"
#include "app-layer-enip.h"
#include "app-layer-dnp3.h"
@ -1535,8 +1533,8 @@ void AppLayerParserRegisterProtocolParsers(void)
RegisterFTPParsers();
RegisterSSHParsers();
RegisterSMTPParsers();
RegisterDNSUDPParsers();
RegisterDNSTCPParsers();
rs_dns_udp_register_parser();
rs_dns_tcp_register_parser();
RegisterModbusParsers();
RegisterENIPUDPParsers();
RegisterENIPTCPParsers();

@ -48,7 +48,6 @@
#include "decode-events.h"
#include "app-layer-htp-mem.h"
#include "app-layer-dns-common.h"
/**
* \brief This is for the app layer in general and it contains per thread

@ -20,7 +20,6 @@
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-dns-opcode.h"
#include "app-layer-dns-common.h"
#include "rust.h"
static int dns_opcode_list_id = 0;

@ -24,8 +24,6 @@
#ifndef __DETECT_DNS_QUERY_H__
#define __DETECT_DNS_QUERY_H__
#include "app-layer-dns-common.h"
void DetectDnsQueryRegister (void);
#endif /* __DETECT_DNS_QUERY_H__ */

@ -41,7 +41,6 @@
#include "app-layer.h"
#include "app-layer-parser.h"
#include "app-layer-protos.h"
#include "app-layer-dns-common.h"
#include "detect-engine-dns.h"
#include "util-unittest.h"

@ -58,7 +58,6 @@
#include "app-layer-htp.h"
#include "app-layer-dcerpc-common.h"
#include "app-layer-dcerpc.h"
#include "app-layer-dns-common.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"

@ -46,7 +46,6 @@
#include "detect-metadata.h"
#include "app-layer-parser.h"
#include "app-layer-dnp3.h"
#include "app-layer-dns-common.h"
#include "app-layer-htp.h"
#include "app-layer-htp-xff.h"
#include "app-layer-ftp.h"

@ -40,7 +40,6 @@
#include "util-mem.h"
#include "app-layer-parser.h"
#include "output.h"
#include "app-layer-dns-udp.h"
#include "app-layer.h"
#include "util-privs.h"
#include "util-buffer.h"

@ -26,8 +26,6 @@
void JsonDnsLogRegister(void);
#include "app-layer-dns-common.h"
json_t *JsonDNSLogQuery(void *txptr, uint64_t tx_id) __attribute__((nonnull));
json_t *JsonDNSLogAnswer(void *txptr, uint64_t tx_id) __attribute__((nonnull));

@ -121,8 +121,6 @@
#include "app-layer-parser.h"
#include "app-layer-htp.h"
#include "app-layer-ssl.h"
#include "app-layer-dns-tcp.h"
#include "app-layer-dns-udp.h"
#include "app-layer-ssh.h"
#include "app-layer-ftp.h"
#include "app-layer-smtp.h"

@ -39,7 +39,6 @@
#include "util-debug.h"
#include "output.h"
#include "app-layer-dns-common.h"
#include "app-layer.h"
#include "app-layer-parser.h"
#include "util-privs.h"

Loading…
Cancel
Save