Snort_AIPreproc/include/sfPolicyUserData.c

166 lines
4.9 KiB
C

/****************************************************************************
* Copyright (C) 2008-2010 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
****************************************************************************/
#include "stdlib.h"
#include "string.h"
#include "sfPolicy.h"
#include "sfPolicyUserData.h"
tSfPolicyId runtimePolicyId = 0;
tSfPolicyId parserPolicyId = 0;
/** @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 (
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;
}
/** @} */ //