mirror of https://github.com/OISF/suricata
rust: DNS app-layer.
A DNS application layer in Rust. This is different than the C based one, as it is partially stateless by not matching up responses to replies.pull/2746/head
parent
9449739dd5
commit
73388042b2
@ -0,0 +1,211 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
extern crate libc;
|
||||
|
||||
use std;
|
||||
use std::string::String;
|
||||
|
||||
use json::*;
|
||||
use dns::dns::*;
|
||||
use log::*;
|
||||
|
||||
fn dns_rrtype_string(rrtype: u16) -> String {
|
||||
match rrtype {
|
||||
DNS_RTYPE_A => "A",
|
||||
DNS_RTYPE_CNAME => "CNAME",
|
||||
DNS_RTYPE_SOA => "SOA",
|
||||
DNS_RTYPE_PTR => "PTR",
|
||||
DNS_RTYPE_MX => "MX",
|
||||
DNS_RTYPE_SSHFP => "SSHFP",
|
||||
DNS_RTYPE_RRSIG => "RRSIG",
|
||||
_ => {
|
||||
return rrtype.to_string();
|
||||
}
|
||||
}.to_string()
|
||||
}
|
||||
|
||||
fn dns_rcode_string(flags: u16) -> String {
|
||||
match flags & 0x000f {
|
||||
DNS_RCODE_NOERROR => "NOERROR",
|
||||
DNS_RCODE_FORMERR => "FORMERR",
|
||||
DNS_RCODE_NXDOMAIN => "NXDOMAIN",
|
||||
_ => {
|
||||
return (flags & 0x000f).to_string();
|
||||
}
|
||||
}.to_string()
|
||||
}
|
||||
|
||||
/// Format bytes as an IP address string.
|
||||
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 {
|
||||
return format!("{}{}:{}{}:{}{}:{}{}:{}{}:{}{}:{}{}:{}{}",
|
||||
addr[0],
|
||||
addr[1],
|
||||
addr[2],
|
||||
addr[3],
|
||||
addr[4],
|
||||
addr[5],
|
||||
addr[6],
|
||||
addr[7],
|
||||
addr[8],
|
||||
addr[9],
|
||||
addr[10],
|
||||
addr[11],
|
||||
addr[12],
|
||||
addr[13],
|
||||
addr[14],
|
||||
addr[15]);
|
||||
}
|
||||
else {
|
||||
return "".to_string();
|
||||
}
|
||||
}
|
||||
|
||||
/// Log the SSHPF in an DNSAnswerEntry.
|
||||
fn dns_log_sshfp(js: &Json, answer: &DNSAnswerEntry)
|
||||
{
|
||||
// Need at least 3 bytes - TODO: log something if we don't?
|
||||
if answer.data_len < 3 {
|
||||
return;
|
||||
}
|
||||
|
||||
let sshfp = Json::object();
|
||||
|
||||
let mut hex = Vec::new();
|
||||
for byte in &answer.data[2..] {
|
||||
hex.push(format!("{:02x}", byte));
|
||||
}
|
||||
sshfp.set_string("fingerprint", &hex.join(":"));
|
||||
sshfp.set_integer("algo", answer.data[0] as u64);
|
||||
sshfp.set_integer("type", answer.data[1] as u64);
|
||||
|
||||
js.set("sshfp", sshfp);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_dns_log_json_query(tx: &mut DNSTransaction,
|
||||
i: libc::uint16_t)
|
||||
-> *mut JsonT
|
||||
{
|
||||
SCLogDebug!("rs_dns_log_json_query: tx_id={}, i={}", tx.id, i);
|
||||
let index = i as usize;
|
||||
for request in &tx.request {
|
||||
if index < request.queries.len() {
|
||||
let query = &request.queries[index];
|
||||
let js = Json::object();
|
||||
js.set_string("type", "query");
|
||||
js.set_integer("id", request.header.tx_id as u64);
|
||||
js.set_string("rrname", query.name());
|
||||
js.set_string("rrtype", &dns_rrtype_string(query.rrtype));
|
||||
js.set_integer("tx_id", tx.id - 1);
|
||||
return js.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
fn dns_log_json_answer(header: &DNSHeader, answer: &DNSAnswerEntry)
|
||||
-> Json
|
||||
{
|
||||
let js = Json::object();
|
||||
|
||||
js.set_string("type", "answer");
|
||||
js.set_integer("id", header.tx_id as u64);
|
||||
js.set_string("rcode", &dns_rcode_string(header.flags));
|
||||
js.set_string("rrname", answer.name());
|
||||
js.set_string("rrtype", &dns_rrtype_string(answer.rrtype));
|
||||
js.set_integer("ttl", answer.ttl as u64);
|
||||
|
||||
match answer.rrtype {
|
||||
DNS_RTYPE_A | DNS_RTYPE_AAAA => {
|
||||
js.set_string("rdata", &dns_print_addr(&answer.data));
|
||||
}
|
||||
DNS_RTYPE_CNAME |
|
||||
DNS_RTYPE_MX |
|
||||
DNS_RTYPE_PTR => {
|
||||
js.set_string("rdata", answer.data_to_string());
|
||||
},
|
||||
DNS_RTYPE_SSHFP => {
|
||||
dns_log_sshfp(&js, &answer);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
return js;
|
||||
}
|
||||
|
||||
fn dns_log_json_failure(r: &DNSResponse, index: usize) -> * mut JsonT {
|
||||
if index >= r.queries.len() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
let ref query = r.queries[index];
|
||||
|
||||
let js = Json::object();
|
||||
|
||||
js.set_string("type", "answer");
|
||||
js.set_integer("id", r.header.tx_id as u64);
|
||||
js.set_string("rcode", &dns_rcode_string(r.header.flags));
|
||||
js.set_string("rrname", std::str::from_utf8(&query.name[..]).unwrap());
|
||||
|
||||
return js.unwrap();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_dns_log_json_answer(tx: &mut DNSTransaction,
|
||||
i: libc::uint16_t)
|
||||
-> *mut JsonT
|
||||
{
|
||||
let index = i as usize;
|
||||
for response in &tx.response {
|
||||
if response.header.flags & 0x000f > 0 {
|
||||
if index == 0 {
|
||||
return dns_log_json_failure(response, index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if index >= response.answers.len() {
|
||||
break;
|
||||
}
|
||||
let answer = &response.answers[index];
|
||||
let js = dns_log_json_answer(&response.header, answer);
|
||||
return js.unwrap();
|
||||
}
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_dns_log_json_authority(tx: &mut DNSTransaction,
|
||||
i: libc::uint16_t)
|
||||
-> *mut JsonT
|
||||
{
|
||||
let index = i as usize;
|
||||
for response in &tx.response {
|
||||
if index >= response.authorities.len() {
|
||||
break;
|
||||
}
|
||||
let answer = &response.authorities[index];
|
||||
let js = dns_log_json_answer(&response.header, answer);
|
||||
return js.unwrap();
|
||||
}
|
||||
return std::ptr::null_mut();
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
/* 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"
|
||||
|
||||
#ifdef HAVE_RUST
|
||||
|
||||
#include "app-layer-dns-tcp-rust.h"
|
||||
#include "rust-dns-dns-gen.h"
|
||||
|
||||
static void RustDNSTCPParserRegisterTests(void);
|
||||
|
||||
static int RustDNSTCPParseRequest(Flow *f, void *state,
|
||||
AppLayerParserState *pstate, uint8_t *input, uint32_t input_len,
|
||||
void *local_data)
|
||||
{
|
||||
SCLogDebug("RustDNSTCPParseRequest");
|
||||
return rs_dns_parse_request_tcp(f, state, pstate, input, input_len,
|
||||
local_data);
|
||||
}
|
||||
|
||||
static int RustDNSTCPParseResponse(Flow *f, void *state,
|
||||
AppLayerParserState *pstate, uint8_t *input, uint32_t input_len,
|
||||
void *local_data)
|
||||
{
|
||||
SCLogDebug("RustDNSTCPParseResponse");
|
||||
return rs_dns_parse_response_tcp(f, state, pstate, input, input_len,
|
||||
local_data);
|
||||
}
|
||||
|
||||
static uint16_t RustDNSTCPProbe(uint8_t *input, uint32_t len, uint32_t *offset)
|
||||
{
|
||||
SCLogDebug("RustDNSTCPProbe");
|
||||
if (len == 0 || len < sizeof(DNSHeader)) {
|
||||
return ALPROTO_UNKNOWN;
|
||||
}
|
||||
|
||||
// Validate and return ALPROTO_FAILED if needed.
|
||||
if (!rs_dns_probe_tcp(input, len)) {
|
||||
return ALPROTO_FAILED;
|
||||
}
|
||||
|
||||
return ALPROTO_DNS;
|
||||
}
|
||||
|
||||
static int RustDNSGetAlstateProgress(void *tx, uint8_t direction)
|
||||
{
|
||||
return rs_dns_tx_get_alstate_progress(tx, direction);
|
||||
}
|
||||
|
||||
static uint64_t RustDNSGetTxCnt(void *alstate)
|
||||
{
|
||||
return rs_dns_state_get_tx_count(alstate);
|
||||
}
|
||||
|
||||
static void *RustDNSGetTx(void *alstate, uint64_t tx_id)
|
||||
{
|
||||
return rs_dns_state_get_tx(alstate, tx_id);
|
||||
}
|
||||
|
||||
static void RustDNSSetTxLogged(void *alstate, void *tx, uint32_t logger)
|
||||
{
|
||||
rs_dns_tx_set_logged(alstate, tx, logger);
|
||||
}
|
||||
|
||||
static int RustDNSGetTxLogged(void *alstate, void *tx, uint32_t logger)
|
||||
{
|
||||
return rs_dns_tx_get_logged(alstate, tx, logger);
|
||||
}
|
||||
|
||||
static void RustDNSStateTransactionFree(void *state, uint64_t tx_id)
|
||||
{
|
||||
rs_dns_state_tx_free(state, tx_id);
|
||||
}
|
||||
|
||||
static int RustDNSStateHasTxDetectState(void *state)
|
||||
{
|
||||
return rs_dns_state_has_detect_state(state);
|
||||
}
|
||||
|
||||
static DetectEngineState *RustDNSGetTxDetectState(void *tx)
|
||||
{
|
||||
return rs_dns_state_get_tx_detect_state(tx);
|
||||
}
|
||||
|
||||
static int RustDNSSetTxDetectState(void *state, void *tx,
|
||||
DetectEngineState *s)
|
||||
{
|
||||
rs_dns_state_set_tx_detect_state(state, tx, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int RustDNSHasEvents(void *state)
|
||||
{
|
||||
return rs_dns_state_has_events(state);
|
||||
}
|
||||
|
||||
static AppLayerDecoderEvents *RustDNSGetEvents(void *state, uint64_t id)
|
||||
{
|
||||
return rs_dns_state_get_events(state, id);
|
||||
}
|
||||
|
||||
void RegisterRustDNSTCPParsers(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,
|
||||
NULL);
|
||||
} 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) {
|
||||
SCLogWarning(SC_ERR_DNS_CONFIG, "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 {
|
||||
SCLogInfo("Protocol detection and parser disabled for %s protocol.",
|
||||
proto_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AppLayerParserConfParserEnabled("tcp", proto_name)) {
|
||||
AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DNS, STREAM_TOSERVER,
|
||||
RustDNSTCPParseRequest);
|
||||
AppLayerParserRegisterParser(IPPROTO_TCP , ALPROTO_DNS, STREAM_TOCLIENT,
|
||||
RustDNSTCPParseResponse);
|
||||
AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_DNS,
|
||||
rs_dns_state_tcp_new, rs_dns_state_free);
|
||||
AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_DNS,
|
||||
RustDNSStateTransactionFree);
|
||||
AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_DNS,
|
||||
RustDNSGetEvents);
|
||||
AppLayerParserRegisterHasEventsFunc(IPPROTO_TCP, ALPROTO_DNS,
|
||||
RustDNSHasEvents);
|
||||
AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DNS,
|
||||
RustDNSStateHasTxDetectState, RustDNSGetTxDetectState,
|
||||
RustDNSSetTxDetectState);
|
||||
AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNS, RustDNSGetTx);
|
||||
AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNS,
|
||||
RustDNSGetTxCnt);
|
||||
AppLayerParserRegisterLoggerFuncs(IPPROTO_TCP, ALPROTO_DNS,
|
||||
RustDNSGetTxLogged, RustDNSSetTxLogged);
|
||||
AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_DNS,
|
||||
RustDNSGetAlstateProgress);
|
||||
AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_DNS,
|
||||
rs_dns_state_progress_completion_status);
|
||||
DNSAppLayerRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_DNS);
|
||||
} else {
|
||||
SCLogInfo("Parsed disabled for %s protocol. Protocol detection"
|
||||
"still on.", proto_name);
|
||||
}
|
||||
|
||||
#ifdef UNITTESTS
|
||||
AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_DNS,
|
||||
RustDNSTCPParserRegisterTests);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UNITTESTS
|
||||
#endif /* UNITTESTS */
|
||||
|
||||
void RustDNSTCPParserRegisterTests(void)
|
||||
{
|
||||
#if 0
|
||||
UtRegisterTest("DNSTCPParserTestMultiRecord", DNSTCPParserTestMultiRecord);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* HAVE_RUST */
|
@ -0,0 +1,23 @@
|
||||
/* 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_RUST_H__
|
||||
#define __APP_LAYER_DNS_TCP_RUST_H__
|
||||
|
||||
void RegisterRustDNSTCPParsers(void);
|
||||
|
||||
#endif /* !__APP_LAYER_DNS_TCP_RUST_H__ */
|
@ -0,0 +1,197 @@
|
||||
/* 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"
|
||||
|
||||
#ifdef HAVE_RUST
|
||||
|
||||
#include "app-layer-dns-udp-rust.h"
|
||||
#include "rust-dns-dns-gen.h"
|
||||
|
||||
static int RustDNSUDPParseRequest(Flow *f, void *state,
|
||||
AppLayerParserState *pstate, uint8_t *input, uint32_t input_len,
|
||||
void *local_data)
|
||||
{
|
||||
return rs_dns_parse_request(f, state, pstate, input, input_len,
|
||||
local_data);
|
||||
}
|
||||
|
||||
static int RustDNSUDPParseResponse(Flow *f, void *state,
|
||||
AppLayerParserState *pstate, uint8_t *input, uint32_t input_len,
|
||||
void *local_data)
|
||||
{
|
||||
return rs_dns_parse_response(f, state, pstate, input, input_len,
|
||||
local_data);
|
||||
}
|
||||
|
||||
static uint16_t DNSUDPProbe(uint8_t *input, uint32_t len, uint32_t *offset)
|
||||
{
|
||||
if (len == 0 || len < sizeof(DNSHeader)) {
|
||||
return ALPROTO_UNKNOWN;
|
||||
}
|
||||
|
||||
// Validate and return ALPROTO_FAILED if needed.
|
||||
if (!rs_dns_probe(input, len)) {
|
||||
return ALPROTO_FAILED;
|
||||
}
|
||||
|
||||
return ALPROTO_DNS;
|
||||
}
|
||||
|
||||
static int RustDNSGetAlstateProgress(void *tx, uint8_t direction)
|
||||
{
|
||||
return rs_dns_tx_get_alstate_progress(tx, direction);
|
||||
}
|
||||
|
||||
static uint64_t RustDNSGetTxCnt(void *alstate)
|
||||
{
|
||||
return rs_dns_state_get_tx_count(alstate);
|
||||
}
|
||||
|
||||
static void *RustDNSGetTx(void *alstate, uint64_t tx_id)
|
||||
{
|
||||
return rs_dns_state_get_tx(alstate, tx_id);
|
||||
}
|
||||
|
||||
static void RustDNSSetTxLogged(void *alstate, void *tx, uint32_t logger)
|
||||
{
|
||||
rs_dns_tx_set_logged(alstate, tx, logger);
|
||||
}
|
||||
|
||||
static int RustDNSGetTxLogged(void *alstate, void *tx, uint32_t logger)
|
||||
{
|
||||
return rs_dns_tx_get_logged(alstate, tx, logger);
|
||||
}
|
||||
|
||||
static void RustDNSStateTransactionFree(void *state, uint64_t tx_id)
|
||||
{
|
||||
rs_dns_state_tx_free(state, tx_id);
|
||||
}
|
||||
|
||||
static int RustDNSStateHasTxDetectState(void *state)
|
||||
{
|
||||
return rs_dns_state_has_detect_state(state);
|
||||
}
|
||||
|
||||
static DetectEngineState *RustDNSGetTxDetectState(void *tx)
|
||||
{
|
||||
return rs_dns_state_get_tx_detect_state(tx);
|
||||
}
|
||||
|
||||
static int RustDNSSetTxDetectState(void *state, void *tx,
|
||||
DetectEngineState *s)
|
||||
{
|
||||
rs_dns_state_set_tx_detect_state(state, tx, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int RustDNSHasEvents(void *state)
|
||||
{
|
||||
return rs_dns_state_has_events(state);
|
||||
}
|
||||
|
||||
static AppLayerDecoderEvents *RustDNSGetEvents(void *state, uint64_t id)
|
||||
{
|
||||
return rs_dns_state_get_events(state, id);
|
||||
}
|
||||
|
||||
void RegisterRustDNSUDPParsers(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,
|
||||
NULL);
|
||||
} else {
|
||||
int have_cfg = AppLayerProtoDetectPPParseConfPorts("udp",
|
||||
IPPROTO_UDP, proto_name, ALPROTO_DNS, 0, sizeof(DNSHeader),
|
||||
DNSUDPProbe, NULL);
|
||||
|
||||
/* If no config, enable on port 53. */
|
||||
if (!have_cfg) {
|
||||
#ifndef AFLFUZZ_APPLAYER
|
||||
SCLogWarning(SC_ERR_DNS_CONFIG, "no DNS UDP config found, "
|
||||
"enabling DNS detection on port 53.");
|
||||
#endif
|
||||
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "53", ALPROTO_DNS,
|
||||
0, sizeof(DNSHeader), STREAM_TOSERVER,
|
||||
DNSUDPProbe, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SCLogInfo("Protocol detection and parser disabled for %s protocol.",
|
||||
proto_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AppLayerParserConfParserEnabled("udp", proto_name)) {
|
||||
AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DNS, STREAM_TOSERVER,
|
||||
RustDNSUDPParseRequest);
|
||||
AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DNS, STREAM_TOCLIENT,
|
||||
RustDNSUDPParseResponse);
|
||||
AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_DNS,
|
||||
rs_dns_state_new, rs_dns_state_free);
|
||||
AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_DNS,
|
||||
RustDNSStateTransactionFree);
|
||||
AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_DNS,
|
||||
RustDNSGetEvents);
|
||||
AppLayerParserRegisterHasEventsFunc(IPPROTO_UDP, ALPROTO_DNS,
|
||||
RustDNSHasEvents);
|
||||
AppLayerParserRegisterDetectStateFuncs(IPPROTO_UDP, ALPROTO_DNS,
|
||||
RustDNSStateHasTxDetectState, RustDNSGetTxDetectState,
|
||||
RustDNSSetTxDetectState);
|
||||
|
||||
AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_DNS, RustDNSGetTx);
|
||||
AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_DNS,
|
||||
RustDNSGetTxCnt);
|
||||
AppLayerParserRegisterLoggerFuncs(IPPROTO_UDP, ALPROTO_DNS,
|
||||
RustDNSGetTxLogged, RustDNSSetTxLogged);
|
||||
AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, ALPROTO_DNS,
|
||||
RustDNSGetAlstateProgress);
|
||||
|
||||
AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_DNS,
|
||||
rs_dns_state_progress_completion_status);
|
||||
|
||||
DNSAppLayerRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_DNS);
|
||||
|
||||
#if 0
|
||||
DNSUDPConfigure();
|
||||
#endif
|
||||
} else {
|
||||
SCLogInfo("Parsed disabled for %s protocol. Protocol detection"
|
||||
"still on.", proto_name);
|
||||
}
|
||||
#if 0
|
||||
#ifdef UNITTESTS
|
||||
AppLayerParserRegisterProtocolUnittests(IPPROTO_UDP, ALPROTO_DNS,
|
||||
DNSUDPParserRegisterTests);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* HAVE_RUST */
|
@ -0,0 +1,23 @@
|
||||
/* 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_RUST_H__
|
||||
#define __APP_LAYER_DNS_UDP_RUST_H__
|
||||
|
||||
void RegisterRustDNSUDPParsers(void);
|
||||
|
||||
#endif /* !__APP_LAYER_DNS_UDP_RUST_H__ */
|
Loading…
Reference in New Issue