📄 rules.c
字号:
/* if it doesn't match any of the existing nodes, make a new node and stick
it at the end of the list */
if (!match)
{
#ifdef DEBUG
printf("Building New Chain head node\n");
#endif
head_count++;
/* build a new node */
rtn_idx->right = (RuleTreeNode *) calloc(sizeof(RuleTreeNode), sizeof(char));
/* set the global ptr so we can play with this from anywhere */
rtn_tmp = rtn_idx->right;
/* uh oh */
if (rtn_tmp == NULL)
{
FatalError( "ERROR: Unable to allocate Rule Head Node!!\n");
}
/* copy the prototype header info into the new header block */
XferHeader(test_node, rtn_tmp);
rtn_tmp->head_node_number = head_count;
rtn_tmp->down = NULL;
/* initialize the function list for the new RTN */
SetupRTNFuncList(rtn_tmp);
#ifdef DEBUG
printf("New Chain head flags = 0x%X\n", rtn_tmp->flags);
#endif
}
else
{
rtn_tmp = rtn_idx;
#ifdef DEBUG
printf("Chain head %d flags = 0x%X\n", count, rtn_tmp->flags);
#endif
#ifdef DEBUG
printf("Adding options to chain head %d\n", count);
#endif
}
}
/****************************************************************************
*
* Function: AddRuleFuncToList(int (*func)(), RuleTreeNode *)
*
* Purpose: Adds RuleTreeNode associated detection functions to the
* current rule's function list
*
* Arguments: *func => function pointer to the detection function
* rtn => pointer to the current rule
*
* Returns: void function
*
***************************************************************************/
void AddRuleFuncToList(int (*func)(Packet *,struct _RuleTreeNode*,struct _RuleFpList*), RuleTreeNode *rtn)
{
RuleFpList *idx;
#ifdef DEBUG
printf("Adding new rule to list\n");
#endif
idx = rtn->rule_func;
if (idx == NULL)
{
rtn->rule_func = (RuleFpList *) calloc(sizeof(RuleFpList), sizeof(char));
rtn->rule_func->RuleHeadFunc = func;
}
else
{
while (idx->next != NULL)
idx = idx->next;
idx->next = (RuleFpList *) calloc(sizeof(RuleFpList), sizeof(char));
idx = idx->next;
idx->RuleHeadFunc = func;
}
}
/****************************************************************************
*
* Function: SetupRTNFuncList(RuleTreeNode *)
*
* Purpose: Configures the function list for the rule header detection
* functions (addrs and ports)
*
* Arguments: rtn => the pointer to the current rules list entry to attach to
*
* Returns: void function
*
***************************************************************************/
void SetupRTNFuncList(RuleTreeNode *rtn)
{
#ifdef DEBUG
printf("Initializing RTN function list!\n");
printf("Functions: ");
#endif
if (rtn->flags & BIDIRECTIONAL)
{
#ifdef DEBUG
printf("CheckBidirectional->\n");
#endif
AddRuleFuncToList(CheckBidirectional, rtn);
}
else
{
/* link in the proper IP address detection function */
/* the in-line "if" determines whether or not the negation operator has
been set for this rule and tells the AddrToFunc call which function
it should be linking in */
AddrToFunc(rtn, rtn->sip, rtn->smask, (rtn->flags & EXCEPT_SRC_IP ? 1 : 0), SRC);
/* last verse, same as the first (but for dest IP) ;) */
AddrToFunc(rtn, rtn->dip, rtn->dmask, (rtn->flags & EXCEPT_DST_IP ? 1 : 0), DST);
/* Attach the proper port checking function to the function list */
/* the in-line "if's" check to see if the "any" or "not" flags have been
set so the PortToFunc call can determine which port testing function
to attach to the list */
PortToFunc(rtn, (rtn->flags & ANY_SRC_PORT ? 1 : 0),
(rtn->flags & EXCEPT_SRC_PORT ? 1: 0), SRC);
/* as above */
PortToFunc(rtn, (rtn->flags & ANY_DST_PORT ? 1 : 0),
(rtn->flags & EXCEPT_DST_PORT ? 1: 0), DST);
}
#ifdef DEBUG
printf("RuleListEnd\n");
#endif
/* tack the end (success) function to the list */
AddRuleFuncToList(RuleListEnd, rtn);
}
/****************************************************************************
*
* Function: AddrToFunc(RuleTreeNode *, u_long, u_long, int, int)
*
* Purpose: Links the proper IP address testing function to the current RTN
* based on the address, netmask, and addr flags
*
* Arguments: rtn => the pointer to the current rules list entry to attach to
* ip => IP address of the current rule
* mask => netmask of the current rule
* exception_flag => indicates that a "!" has been set for this
* address
* mode => indicates whether this is a rule for the source
* or destination IP for the rule
*
* Returns: void function
*
***************************************************************************/
void AddrToFunc(RuleTreeNode *rtn, u_long ip, u_long mask, int exception_flag, int mode)
{
/* if IP and mask are both 0, this is a "any" IP and we don't need to
check it */
if ((ip == 0) && (mask == 0))
return;
/* if the exception flag is up, test with the exception function */
if (exception_flag)
{
switch (mode)
{
case SRC:
#ifdef DEBUG
printf("CheckSrcIPNotEq -> ");
#endif
AddRuleFuncToList(CheckSrcIPNotEq, rtn);
break;
case DST:
#ifdef DEBUG
printf("CheckDstIPNotEq -> ");
#endif
AddRuleFuncToList(CheckDstIPNotEq, rtn);
break;
}
return;
}
switch (mode)
{
case SRC:
#ifdef DEBUG
printf("CheckSrcIPEqual -> ");
#endif
AddRuleFuncToList(CheckSrcIPEqual, rtn);
break;
case DST:
#ifdef DEBUG
printf("CheckDstIPEqual -> ");
#endif
AddRuleFuncToList(CheckDstIPEqual, rtn);
break;
}
}
char *ProcessFileOption(char *filespec)
{
char *filename;
char buffer[STD_BUF];
/* look for ".." in the string and complain and exit if it is found */
if(strstr(filespec, "..") != NULL) {
FatalError( "ERROR: file definition contains \"..\". Do not do that!\n");
}
if(filespec[0] == '/') {
/* absolute filespecs are saved as is */
filename = strdup(filespec);
} else {
/* relative filespec is considered relative to the log directory */
/* or /var/log if the log directory has not been set */
if(pv.log_flag) {
strncpy(buffer, pv.log_dir, STD_BUF-1);
} else {
strncpy(buffer, "/var/log", STD_BUF-1);
}
strncat(buffer, "/", STD_BUF-strlen(buffer)-1);
strncat(buffer, filespec, STD_BUF-strlen(buffer)-1);
filename = strdup(buffer);
}
printf("ProcessFileOption: %s\n", filename);
return filename;
}
/****************************************************************************
*
* Function: PortToFunc(RuleTreeNode *, int, int, int)
*
* Purpose: Links in the port analysis function for the current rule
*
* Arguments: rtn => the pointer to the current rules list entry to attach to
* any_flag => accept any port if set
* except_flag => indicates negation (logical NOT) of the test
* mode => indicates whether this is a rule for the source
* or destination port for the rule
*
* Returns: void function
*
***************************************************************************/
void PortToFunc(RuleTreeNode *rtn, int any_flag, int except_flag, int mode)
{
/* if the any flag is set we don't need to perform any test to match on
this port */
if (any_flag)
return;
/* if the except_flag is up, test with the "NotEq" funcs */
if (except_flag)
{
switch (mode)
{
case SRC:
#ifdef DEBUG
printf("CheckSrcPortNotEq -> ");
#endif
AddRuleFuncToList(CheckSrcPortNotEq, rtn);
break;
case DST:
#ifdef DEBUG
printf("CheckDstPortNotEq -> ");
#endif
AddRuleFuncToList(CheckDstPortNotEq, rtn);
break;
}
return;
}
/* default to setting the straight test function */
switch (mode)
{
case SRC:
#ifdef DEBUG
printf("CheckSrcPortEqual -> ");
#endif
AddRuleFuncToList(CheckSrcPortEqual, rtn);
break;
case DST:
#ifdef DEBUG
printf("CheckDstPortEqual -> ");
#endif
AddRuleFuncToList(CheckDstPortEqual, rtn);
break;
}
return;
}
/****************************************************************************
*
* Function: AddOptFuncToList(int (*func)(), OptTreeNode *)
*
* Purpose: Links the option detection module to the OTN
*
* Arguments: (*func)() => function pointer to the detection module
* otn => pointer to the current OptTreeNode
*
* Returns: void function
*
***************************************************************************/
void AddOptFuncToList(int (*func)(Packet *,struct _OptTreeNode*,struct _OptFpList*), OptTreeNode *otn)
{
OptFpList *idx; /* index pointer */
#ifdef DEBUG
printf("Adding new rule to list\n");
#endif
/* set the index pointer to the start of this OTN's function list */
idx = otn->opt_func;
/* if there are no nodes on the function list...*/
if (idx == NULL)
{
/* calloc the list head */
otn->opt_func = (OptFpList *) calloc(sizeof(OptFpList), sizeof(char));
if (otn->opt_func == NULL)
{
FatalError( "ERROR => AddOptFuncToList new node calloc failed: %s\n", strerror(errno));
}
/* set the head function */
otn->opt_func->OptTestFunc = func;
}
else
{
/* walk to the end of the list */
while (idx->next != NULL)
{
idx = idx->next;
}
/* allocate a new node on the end of the list */
idx->next = (OptFpList *) calloc(sizeof(OptFpList), sizeof(char));
if (idx->next == NULL)
{
FatalError( "ERROR => AddOptFuncToList new node calloc failed: %s\n", strerror(errno));
}
/* move up to the new node */
idx = idx->next;
/* link the function to the new node */
idx->OptTestFunc = func;
}
}
/****************************************************************************
*
* Function: ParsePreprocessor(char *)
*
* Purpose: Walks the preprocessor function list looking for the user provided
* keyword. Once found, call the preprocessor's initialization
* function.
*
* Arguments: rule => the preprocessor initialization string from the rules file
*
* Returns: void function
*
***************************************************************************/
void ParsePreprocessor(char *rule)
{
char **toks; /* pointer to the tokenized array parsed from the rules list */
char **pp_head; /* parsed keyword list, with preprocessor keyword being the 2nd element */
char *funcname; /* the ptr to the actual preprocessor keyword */
char *pp_args = NULL; /* parsed list of arguments to the preprocessor */
int num_toks; /* number of tokens returned by the mSplit function */
int found = 0; /* flag var */
PreprocessKeywordList *pl_idx; /* index into the preprocessor keyword/func list */
/* break out the arguments from the keywords */
toks = mSplit(rule, ":", 2, &num_toks,'\\');
if (num_toks >= 1)
{
/* the args are everything after the ":" */
pp_args = toks[1];
}
/* split the head section for the preprocessor keyword */
pp_head = mSplit(toks[0], " ", 2, &num_toks, '\\');
/* set a pointer to the actual keyword */
funcname = pp_head[1];
/* set the index to the head of the keyword list */
pl_idx = PreprocessKeywords;
/* walk the keyword list */
while (pl_idx != NULL)
{
#ifdef DEBUG
printf("comparing: \"%s\" => \"%s\"\n", funcname, pl_idx->entry.keyword);
#endif
/* compare the keyword against the current list element's keyword */
if (!strcasecmp(funcname, pl_idx->entry.keyword))
{
pl_idx->entry.func(pp_args);
found = 1;
}
if (!found)
{
pl_idx = pl_idx->next;
}
else
break;
}
if (!found)
printf("\n*WARNING*: unknown preprocessor \"%s\", ignoring!\n\n",
funcname);
}
void AddFuncToPreprocList(void (*func)(Packet *))
{
PreprocessFuncNode *idx;
idx = PreprocessList;
if (idx == NULL)
{
PreprocessList = (PreprocessFuncNode *) calloc(sizeof(PreprocessFuncNode), sizeof(char));
PreprocessList->func = func;
}
else
{
while (idx->next != NULL)
idx = idx->next;
idx->next = (PreprocessFuncNode *) calloc(sizeof(PreprocessFuncNode), sizeof(char));
idx = idx->next;
idx->func = func;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -