mirror of https://github.com/OISF/suricata
parent
0af9a3a5f7
commit
a0e3e2d7b4
@ -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__ */
|
||||
Loading…
Reference in New Issue