mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
6.8 KiB
C
218 lines
6.8 KiB
C
/* Copyright (C) 2017-2020 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 Pierre Chifflier <chifflier@wzdftpd.net>
|
|
*
|
|
* Parser registration functions.
|
|
*/
|
|
|
|
#include "suricata-common.h"
|
|
#include "suricata.h"
|
|
#include "stream.h"
|
|
#include "conf.h"
|
|
|
|
#include "app-layer-detect-proto.h"
|
|
#include "app-layer-parser.h"
|
|
|
|
#include "app-layer-register.h"
|
|
|
|
static const char * IpProtoToString(int ip_proto);
|
|
|
|
AppProto AppLayerRegisterProtocolDetection(const struct AppLayerParser *p, int enable_default)
|
|
{
|
|
AppProto alproto;
|
|
const char *ip_proto_str = NULL;
|
|
|
|
if (p == NULL)
|
|
FatalError("Call to %s with NULL pointer.", __FUNCTION__);
|
|
|
|
alproto = StringToAppProto(p->name);
|
|
if (alproto == ALPROTO_UNKNOWN || alproto == ALPROTO_FAILED)
|
|
FatalError("Unknown or invalid AppProto '%s'.", p->name);
|
|
|
|
BUG_ON(strcmp(p->name, AppProtoToString(alproto)) != 0);
|
|
|
|
ip_proto_str = IpProtoToString(p->ip_proto);
|
|
if (ip_proto_str == NULL)
|
|
FatalError("Unknown or unsupported ip_proto field in parser '%s'", p->name);
|
|
|
|
SCLogDebug("%s %s protocol detection enabled.", ip_proto_str, p->name);
|
|
|
|
AppLayerProtoDetectRegisterProtocol(alproto, p->name);
|
|
|
|
if (p->ProbeTS == NULL && p->ProbeTC == NULL) {
|
|
BUG_ON(p->default_port != NULL);
|
|
return alproto;
|
|
}
|
|
|
|
if (RunmodeIsUnittests()) {
|
|
|
|
SCLogDebug("Unittest mode, registering default configuration.");
|
|
AppLayerProtoDetectPPRegister(p->ip_proto, p->default_port,
|
|
alproto, p->min_depth, p->max_depth, STREAM_TOSERVER,
|
|
p->ProbeTS, p->ProbeTC);
|
|
|
|
}
|
|
else {
|
|
|
|
if (!AppLayerProtoDetectPPParseConfPorts(ip_proto_str, p->ip_proto,
|
|
p->name, alproto, p->min_depth, p->max_depth,
|
|
p->ProbeTS, p->ProbeTC)) {
|
|
if (enable_default != 0) {
|
|
SCLogDebug("No %s app-layer configuration, enabling %s"
|
|
" detection %s detection on port %s.",
|
|
p->name, p->name, ip_proto_str, p->default_port);
|
|
AppLayerProtoDetectPPRegister(p->ip_proto,
|
|
p->default_port, alproto,
|
|
p->min_depth, p->max_depth, STREAM_TOSERVER,
|
|
p->ProbeTS, p->ProbeTC);
|
|
} else {
|
|
SCLogDebug("No %s app-layer configuration for detection port (%s).",
|
|
p->name, ip_proto_str);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return alproto;
|
|
}
|
|
|
|
int AppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto)
|
|
{
|
|
const char *ip_proto_str = NULL;
|
|
|
|
if (p == NULL)
|
|
FatalError("Call to %s with NULL pointer.", __FUNCTION__);
|
|
|
|
if (!AppProtoIsValid(alproto))
|
|
FatalError("Unknown or invalid AppProto '%s'.", p->name);
|
|
|
|
BUG_ON(strcmp(p->name, AppProtoToString(alproto)) != 0);
|
|
|
|
ip_proto_str = IpProtoToString(p->ip_proto);
|
|
if (ip_proto_str == NULL)
|
|
FatalError("Unknown or unsupported ip_proto field in parser '%s'", p->name);
|
|
|
|
SCLogDebug("Registering %s protocol parser.", p->name);
|
|
|
|
/* Register functions for state allocation and freeing. A
|
|
* state is allocated for every new flow. */
|
|
AppLayerParserRegisterStateFuncs(p->ip_proto, alproto,
|
|
p->StateAlloc, p->StateFree);
|
|
|
|
/* Register request parser for parsing frame from server to server. */
|
|
AppLayerParserRegisterParser(p->ip_proto, alproto,
|
|
STREAM_TOSERVER, p->ParseTS);
|
|
|
|
/* Register response parser for parsing frames from server to client. */
|
|
AppLayerParserRegisterParser(p->ip_proto, alproto,
|
|
STREAM_TOCLIENT, p->ParseTC);
|
|
|
|
/* Register a function to be called by the application layer
|
|
* when a transaction is to be freed. */
|
|
AppLayerParserRegisterTxFreeFunc(p->ip_proto, alproto,
|
|
p->StateTransactionFree);
|
|
|
|
/* Register a function to return the current transaction count. */
|
|
AppLayerParserRegisterGetTxCnt(p->ip_proto, alproto,
|
|
p->StateGetTxCnt);
|
|
|
|
/* Transaction handling. */
|
|
AppLayerParserRegisterStateProgressCompletionStatus(alproto, p->complete_ts, p->complete_tc);
|
|
|
|
AppLayerParserRegisterGetStateProgressFunc(p->ip_proto, alproto,
|
|
p->StateGetProgress);
|
|
AppLayerParserRegisterGetTx(p->ip_proto, alproto,
|
|
p->StateGetTx);
|
|
|
|
if (p->StateGetEventInfo) {
|
|
AppLayerParserRegisterGetEventInfo(p->ip_proto, alproto,
|
|
p->StateGetEventInfo);
|
|
}
|
|
if (p->StateGetEventInfoById) {
|
|
AppLayerParserRegisterGetEventInfoById(p->ip_proto, alproto,
|
|
p->StateGetEventInfoById);
|
|
}
|
|
if (p->LocalStorageAlloc && p->LocalStorageFree) {
|
|
AppLayerParserRegisterLocalStorageFunc(p->ip_proto, alproto,
|
|
p->LocalStorageAlloc, p->LocalStorageFree);
|
|
}
|
|
if (p->GetTxFiles) {
|
|
AppLayerParserRegisterGetTxFilesFunc(p->ip_proto, alproto, p->GetTxFiles);
|
|
}
|
|
|
|
if (p->GetTxIterator) {
|
|
AppLayerParserRegisterGetTxIterator(p->ip_proto, alproto,
|
|
p->GetTxIterator);
|
|
}
|
|
|
|
if (p->GetTxData) {
|
|
AppLayerParserRegisterTxDataFunc(p->ip_proto, alproto,
|
|
p->GetTxData);
|
|
}
|
|
|
|
if (p->GetStateData) {
|
|
AppLayerParserRegisterStateDataFunc(p->ip_proto, alproto, p->GetStateData);
|
|
}
|
|
|
|
if (p->ApplyTxConfig) {
|
|
AppLayerParserRegisterApplyTxConfigFunc(p->ip_proto, alproto,
|
|
p->ApplyTxConfig);
|
|
}
|
|
|
|
if (p->flags) {
|
|
AppLayerParserRegisterOptionFlags(p->ip_proto, alproto,
|
|
p->flags);
|
|
|
|
}
|
|
|
|
if (p->GetFrameIdByName && p->GetFrameNameById) {
|
|
AppLayerParserRegisterGetFrameFuncs(
|
|
p->ip_proto, alproto, p->GetFrameIdByName, p->GetFrameNameById);
|
|
}
|
|
|
|
if (p->GetStateIdByName && p->GetStateNameById) {
|
|
AppLayerParserRegisterGetStateFuncs(
|
|
p->ip_proto, alproto, p->GetStateIdByName, p->GetStateNameById);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int AppLayerRegisterParserAlias(const char *proto_name, const char *proto_alias)
|
|
{
|
|
AppLayerProtoDetectRegisterAlias(proto_name, proto_alias);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const char * IpProtoToString(int ip_proto)
|
|
{
|
|
switch (ip_proto) {
|
|
case IPPROTO_TCP:
|
|
return "tcp";
|
|
case IPPROTO_UDP:
|
|
return "udp";
|
|
default:
|
|
return NULL;
|
|
};
|
|
|
|
}
|