Snort_AIPreproc/sfPolicyUserData.c

191 lines
5.6 KiB
C
Raw Normal View History

/****************************************************************************
* Copyright (C) 2014-2016 Cisco and/or its affiliates. All rights reserved.
* Copyright (C) 2008-2013 Sourcefire, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License Version 2 as
* published by the Free Software Foundation. You may not use, modify or
* distribute this program under any other version of the GNU General
* Public License.
*
* 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
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
****************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "stdlib.h"
#include "string.h"
#include "sf_types.h"
#include "sfPolicy.h"
#include "sfPolicyUserData.h"
/** @defgroup sfPolicyConfig Sourcefire policy configuration module
*
* Create a user policy configuration context. A context provides facility for creating
* policy specific data instances. User can create as many policy instances as memory
* resources will allow. User can create/delete context, set/clear/get user date for a
* specific policy, default policy or current policy. User can also iterate over all instances
* user data.
*
* In current design, preprocessor use this module directly to manage policy specific data
* instances. A future enhancement can be to extract policy management code from each processor
* and put it in a new policy management module. Policy management module will set a single
* pointer to user data before calling appropriate callback function in a preprocessor. As
* an example, policy module will iterate over all policies and call CleanExit functions in every
* preprocessor for each policy. This will make policy management module will hide policies from
* preprocessors and make them policy agnostic.
* @{
*/
/**Create a user context.
* Allocates a new context and return it to user. All transactions within a context are independent from
* any other transactions in a different context.
*
* @returns tSfPolicyUserContextId
*/
tSfPolicyUserContextId sfPolicyConfigCreate(void)
{
tSfPolicyUserContext *pTmp = NULL;
pTmp = calloc(1, sizeof(tSfPolicyUserContext));
return pTmp;
}
/**Delete a user policy data context.
* @param pContext
*/
void sfPolicyConfigDelete(
tSfPolicyUserContextId pContext
)
{
if (pContext == NULL)
return;
if (pContext->userConfig != NULL)
free(pContext->userConfig);
free(pContext);
}
/**Store a pointer to user data.
* @param pContext
* @param policyId is 0 based.
* @param config - pointer to user configuration.
*/
int sfPolicyUserDataSet (
tSfPolicyUserContextId pContext,
tSfPolicyId policyId,
void *config
)
{
void **ppTmp;
if (policyId >= pContext->numAllocatedPolicies)
{
//expand the array
ppTmp = (void **)calloc(policyId+POLICY_ALLOCATION_CHUNK, sizeof(void *));
if (!(ppTmp))
{
return -1;
}
if (pContext->numAllocatedPolicies)
{
memcpy(ppTmp, pContext->userConfig, sizeof(void*)*(pContext->numAllocatedPolicies));
free(pContext->userConfig);
}
pContext->userConfig = ppTmp;
pContext->numAllocatedPolicies = policyId + POLICY_ALLOCATION_CHUNK;
}
if (pContext->userConfig[policyId])
{
//dont overwrite existing configuration
return -1;
}
pContext->userConfig[policyId] = config;
pContext->numActivePolicies++;
return 0;
}
/**user is responsible for freeing any memory.
*/
void * sfPolicyUserDataClear (
tSfPolicyUserContextId pContext,
tSfPolicyId policyId
)
{
void *pTmp = NULL;
if (policyId < pContext->numAllocatedPolicies)
{
pTmp = pContext->userConfig[policyId];
pContext->userConfig[policyId] = NULL;
pContext->numActivePolicies--;
}
return pTmp;
}
int sfPolicyUserDataIterate (
struct _SnortConfig *sc,
tSfPolicyUserContextId pContext,
int (*callback)(struct _SnortConfig *sc, tSfPolicyUserContextId pContext, tSfPolicyId policyId, void* config)
)
{
tSfPolicyId policyId;
int ret = 0;
//must not use numActivePolicies because the callback may delete a policy
for (policyId = 0; policyId < pContext->numAllocatedPolicies; policyId++)
{
if (pContext->userConfig[policyId])
{
ret = callback(sc, pContext, policyId, pContext->userConfig[policyId]);
if (ret != 0)
break;
}
}
return ret;
}
int sfPolicyUserDataFreeIterate (
tSfPolicyUserContextId pContext,
int (*callback)(tSfPolicyUserContextId pContext, tSfPolicyId policyId, void* config)
)
{
tSfPolicyId policyId;
int ret = 0;
//must not use numActivePolicies because the callback may delete a policy
for (policyId = 0; policyId < pContext->numAllocatedPolicies; policyId++)
{
if (pContext->userConfig[policyId])
{
ret = callback(pContext, policyId, pContext->userConfig[policyId]);
if (ret != 0)
break;
}
}
return ret;
}
/** @} */ //