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.
suricata/src/app-layer-register.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;
};
}