* ipproto. It should be allocated to contain ALPROTO_MAX
* protocols. */
const char **alproto_names;
+ size_t alproto_names_len;
/* Protocol expectations, like ftp-data on tcp.
* It should be allocated to contain ALPROTO_MAX
* app-layer protocols. For each protocol, an iptype
* is referenced (or 0 if there is no expectation). */
uint8_t *expectation_proto;
+ size_t expectation_proto_len;
} AppLayerProtoDetectCtx;
typedef struct AppLayerProtoDetectAliases_ {
if (unlikely(alpd_ctx.alproto_names == NULL)) {
FatalError("Unable to alloc alproto_names.");
}
+ alpd_ctx.alproto_names_len = g_alproto_max;
// to realloc when dynamic protos are added
alpd_ctx.expectation_proto = SCCalloc(g_alproto_max, sizeof(uint8_t));
if (unlikely(alpd_ctx.expectation_proto == NULL)) {
FatalError("Unable to alloc expectation_proto.");
}
+ alpd_ctx.expectation_proto_len = g_alproto_max;
AppLayerExpectationSetup();
SCReturnInt(0);
SCFree(alpd_ctx.alproto_names);
alpd_ctx.alproto_names = NULL;
+ alpd_ctx.alproto_names_len = 0;
SCFree(alpd_ctx.expectation_proto);
alpd_ctx.expectation_proto = NULL;
+ alpd_ctx.expectation_proto_len = 0;
SpmDestroyGlobalThreadCtx(alpd_ctx.spm_global_thread_ctx);
{
SCEnter();
- // should have just been realloced when dynamic protos is added
+ if (alpd_ctx.alproto_names_len <= alproto && alproto < g_alproto_max) {
+ void *tmp = SCRealloc(alpd_ctx.alproto_names, sizeof(char *) * g_alproto_max);
+ if (unlikely(tmp == NULL)) {
+ FatalError("Unable to realloc alproto_names.");
+ }
+ alpd_ctx.alproto_names = tmp;
+ memset(&alpd_ctx.alproto_names[alpd_ctx.alproto_names_len], 0,
+ sizeof(char *) * (g_alproto_max - alpd_ctx.alproto_names_len));
+ alpd_ctx.alproto_names_len = g_alproto_max;
+ }
if (alpd_ctx.alproto_names[alproto] == NULL)
alpd_ctx.alproto_names[alproto] = alproto_name;
static void AppLayerProtoDetectPEGetIpprotos(AppProto alproto,
uint8_t *ipprotos)
{
+ if (alproto >= alpd_ctx.expectation_proto_len) {
+ return;
+ }
if (alpd_ctx.expectation_proto[alproto] == IPPROTO_TCP) {
ipprotos[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8);
}
typedef struct AppLayerParserCtx_ {
AppLayerParserProtoCtx (*ctxs)[FLOW_PROTO_MAX];
+ size_t ctxs_len;
} AppLayerParserCtx;
struct AppLayerParserState_ {
if (unlikely(alp_ctx.ctxs == NULL)) {
FatalError("Unable to alloc alp_ctx.ctxs.");
}
+ alp_ctx.ctxs_len = g_alproto_max;
SCReturnInt(0);
}
{
SCEnter();
+ if (alp_ctx.ctxs_len <= alproto && alproto < g_alproto_max) {
+ // Realloc now as AppLayerParserRegisterStateFuncs is called first
+ void *tmp = SCRealloc(
+ alp_ctx.ctxs, sizeof(AppLayerParserProtoCtx[FLOW_PROTO_MAX]) * g_alproto_max);
+ if (unlikely(tmp == NULL)) {
+ FatalError("Unable to realloc alp_ctx.ctxs.");
+ }
+ alp_ctx.ctxs = tmp;
+ memset(&alp_ctx.ctxs[alp_ctx.ctxs_len], 0,
+ sizeof(AppLayerParserProtoCtx[FLOW_PROTO_MAX]) *
+ (g_alproto_max - alp_ctx.ctxs_len));
+ alp_ctx.ctxs_len = g_alproto_max;
+ }
+
alp_ctx.ctxs[alproto][FlowGetProtoMapping(ipproto)].StateAlloc = StateAlloc;
alp_ctx.ctxs[alproto][FlowGetProtoMapping(ipproto)].StateFree = StateFree;
}
#undef BOTH_SET
#undef BOTH_SET_OR_BOTH_UNSET
-#undef THREE_SET_OR_THREE_UNSET
#undef THREE_SET
static void ValidateParser(AppProto alproto)