📄 rules.c
字号:
} /* do the same for the port */ if(ParsePort(toks[3], (u_short *) & proto_node.hsp, (u_short *) & proto_node.lsp, toks[1], (int *) &proto_node.not_sp_flag)) { proto_node.flags |= ANY_SRC_PORT; } if(proto_node.not_sp_flag) proto_node.flags |= EXCEPT_SRC_PORT; /* New in version 1.3: support for bidirectional rules */ /* * this checks the rule "direction" token and sets the bidirectional flag * if the token = '<>' */ if(!strncmp("<>", toks[4], 2)) {#ifdef DEBUG printf("Bidirectional rule!\n");#endif proto_node.flags |= BIDIRECTIONAL; } /* changed version 1.2.1 */ /* * "any" IP's are now set to addr 0, netmask 0, and the normal rules are * applied instead of checking the flag */ /* * if we see a "!<ip number>" we need to set a flag so that we can * properly deal with it when we are processing packets */ /* we found a negated address */ /* if( *toks[5] == '!' ) { #ifdef DEBUG printf("setting exception flag for dest IP\n"); #endif proto_node.flags |= EXCEPT_DST_IP; ProcessIP(&toks[5][1], &proto_node, DST); } else {*/ ProcessIP(toks[5], &proto_node, DST); /*}*/ if(ParsePort(toks[6], (u_short *) & proto_node.hdp, (u_short *) & proto_node.ldp, toks[1], (int *) &proto_node.not_dp_flag)) { proto_node.flags |= ANY_DST_PORT; } if(proto_node.not_dp_flag) proto_node.flags |= EXCEPT_DST_PORT;#ifdef DEBUG printf("proto_node.flags = 0x%X\n", proto_node.flags); printf("Processing Head Node....\n");#endif switch(rule_type) { case RULE_ALERT: ProcessHeadNode(&proto_node, &Alert, protocol); break; case RULE_LOG: ProcessHeadNode(&proto_node, &Log, protocol); break; case RULE_PASS: ProcessHeadNode(&proto_node, &Pass, protocol); break; case RULE_ACTIVATE: ProcessHeadNode(&proto_node, &Activation, protocol); break; case RULE_DYNAMIC: ProcessHeadNode(&proto_node, &Dynamic, protocol); break; default: FatalError("Unable to determine rule type (%s) for processing, exiting!\n", toks[0]); } rule_count++;#ifdef DEBUG printf("Parsing Rule Options...\n");#endif ParseRuleOptions(rule, rule_type, protocol);#ifdef PARSERULE_BIFURCATE if(bid) { char *iptemp = toks[2]; char *porttemp = toks[3]; toks[2] = toks[5]; toks[3] = toks[6]; toks[5] = iptemp; toks[6] = porttemp; bid = 0; goto bidog; }#endif for(i=0;i<num_toks;i++) { free(toks[i]); } return;}/**************************************************************************** * * Function: ProcessHeadNode(RuleTreeNode *, ListHead *, int) * * Purpose: Process the header block info and add to the block list if * necessary * * Arguments: test_node => data generated by the rules parsers * list => List Block Header refernece * protocol => ip protocol * * Returns: void function * ***************************************************************************/void ProcessHeadNode(RuleTreeNode * test_node, ListHead * list, int protocol){ int match = 0; RuleTreeNode *rtn_idx; int count = 0; /* select the proper protocol list to attach the current rule to */ switch(protocol) { case IPPROTO_TCP: rtn_idx = list->TcpList; break; case IPPROTO_UDP: rtn_idx = list->UdpList; break; case IPPROTO_ICMP: rtn_idx = list->IcmpList; break; default: rtn_idx = NULL; break; } /* * if the list head is NULL (empty), make a new one and attach the * ListHead to it */ if(rtn_idx == NULL) { head_count++; switch(protocol) { case IPPROTO_TCP: list->TcpList = (RuleTreeNode *) calloc(sizeof(RuleTreeNode), sizeof(char)); rtn_tmp = list->TcpList; break; case IPPROTO_UDP: list->UdpList = (RuleTreeNode *) calloc(sizeof(RuleTreeNode), sizeof(char)); rtn_tmp = list->UdpList; break; case IPPROTO_ICMP: list->IcmpList = (RuleTreeNode *) calloc(sizeof(RuleTreeNode), sizeof(char)); rtn_tmp = list->IcmpList; break; } /* copy the prototype header data into the new node */ XferHeader(test_node, rtn_tmp); rtn_tmp->head_node_number = head_count; /* null out the down (options) pointer */ rtn_tmp->down = NULL; /* add the function list to the new rule */ SetupRTNFuncList(rtn_tmp); /* add link to parent listhead */ rtn_tmp->listhead = list; return; } /* see if this prototype node matches any of the existing header nodes */ match = TestHeader(rtn_idx, test_node); while((rtn_idx->right != NULL) && !match) { count++; match = TestHeader(rtn_idx, test_node); if(!match) rtn_idx = rtn_idx->right; else break; } /* * have to check this twice since my loop above exits early, which sucks * but it's not performance critical */ match = TestHeader(rtn_idx, test_node); /* * 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); /* add link to parent listhead */ rtn_tmp->listhead = list;#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, SRC); /* last verse, same as the first (but for dest IP) ;) */ AddrToFunc(rtn, 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, int mode){ /* * if IP and mask are both 0, this is a "any" IP and we don't need to * check it */ switch(mode) { case SRC:#ifdef DEBUG printf("CheckSrcIP -> ");#endif if((rtn->flags & ANY_SRC_IP) == 0) { AddRuleFuncToList(CheckSrcIP, rtn); } break; case DST:#ifdef DEBUG printf("CheckDstIP -> ");#endif if((rtn->flags & ANY_DST_IP) == 0) { AddRuleFuncToList(CheckDstIP, rtn); } break; }}/**************************************************************************** * * 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -