📄 rules.c
字号:
/* get rid of the trailing ")" */ if(aux == NULL) { ErrorMessage("Problem rule: %s\n", rule); FatalError("ERROR %s(%d): Missing trailing ')' in rule options.\n", file_name, file_line); } *aux = 0; /* seperate all the options out, the seperation token is a semicolon */ /* * NOTE: if you want to include a semicolon in the content of your * rule, it must be preceeded with a '\' */ toks = mSplit(idx, ";", 64, &num_toks, '\\');#ifdef DEBUG printf(" Got %d tokens\n", num_toks);#endif /* decrement the number of toks */ num_toks--;#ifdef DEBUG printf("Parsing options list: ");#endif while(num_toks) {#ifdef DEBUG printf(" option: %s\n", toks[i]);#endif /* break out the option name from its data */ opts = mSplit(toks[i], ":", 4, &num_opts, '\\');#ifdef DEBUG printf(" option name: %s\n", opts[0]); printf(" option args: %s\n", opts[1]);#endif /* advance to the beginning of the data (past the whitespace) */ while(isspace((int) *opts[0])) opts[0]++; /* figure out which option tag we're looking at */ if(!strncasecmp(opts[0], "msg", 3)) { ParseMessage(opts[1]); } else if(!strncasecmp(opts[0], "logto", 5)) { ParseLogto(opts[1]); } else if(!strncasecmp(opts[0], "activates", 9)) { ParseActivates(opts[1]); dynamic_rules_present++; } else if(!strncasecmp(opts[0], "activated_by", 12)) { ParseActivatedBy(opts[1]); dynamic_rules_present++; } else if(!strncasecmp(opts[0], "count", 5)) { if(otn_tmp->type != RULE_DYNAMIC) FatalError("The \"count\" option may only be used with the dynamic rule type!\n"); ParseCount(opts[1]); } else { kw_idx = KeywordList; found = 0; while(kw_idx != NULL) {#ifdef DEBUG printf("comparing: \"%s\" => \"%s\"\n", opts[0], kw_idx->entry.keyword);#endif if(!strcasecmp(opts[0], kw_idx->entry.keyword)) { kw_idx->entry.func(opts[1], otn_tmp, protocol); found = 1;#ifdef DEBUG printf("%s->", kw_idx->entry.keyword);#endif } if(!found) { kw_idx = kw_idx->next; } else { break; } } if(!found) { if(!strcasecmp(opts[0], "minfrag")) { FatalError("\nERROR: %s (%d) => Minfrag is no longer a rule option, it is a\npreprocessor (please remove it from your rules file). See RULES.SAMPLE or\nsnort-lib for examples of using the new preprocessors!\n", file_name, file_line); } else { FatalError("\nERROR: %s (%d) => Unknown keyword \"%s\" in rule!\n", file_name, file_line, opts[0]); } } } free(opts); --num_toks; i++; }#ifdef DEBUG printf("OptListEnd\n");#endif AddOptFuncToList(OptListEnd, otn_tmp); } else {#ifdef DEBUG printf("OptListEnd\n");#endif AddOptFuncToList(OptListEnd, otn_tmp); } if(idx != NULL) for(i=0;i<num_toks;i++) free(toks[i]);}/**************************************************************************** * * Function: RuleType(char *) * * Purpose: Determine what type of rule is being processed and return its * equivalent value * * Arguments: func => string containing the rule type * * Returns: The rule type designation * ***************************************************************************/int RuleType(char *func){ if(func == NULL) { FatalError("ERROR line %s (%d) => Unknown rule type (%s)\n", file_name, file_line, func); } if(!strncasecmp(func, "log", 3)) return RULE_LOG; if(!strncasecmp(func, "alert", 5)) return RULE_ALERT; if(!strncasecmp(func, "pass", 4)) return RULE_PASS; if(!strncasecmp(func, "var", 3)) return RULE_VAR; if(!strncasecmp(func, "include", 7)) return RULE_INCLUDE; if(!strncasecmp(func, "preprocessor", 12)) return RULE_PREPROCESS; if(!strncasecmp(func, "output", 6)) return RULE_OUTPUT; if(!strncasecmp(func, "activate", 8)) return RULE_ACTIVATE; if(!strncasecmp(func, "dynamic", 7)) return RULE_DYNAMIC; if(!strncasecmp(func, "config", 6)) return RULE_CONFIG; if(!strncasecmp(func, "ruletype", 8)) return RULE_DECLARE; return RULE_UNKNOWN;}/**************************************************************************** * * Function: WhichProto(char *) * * Purpose: Figure out which protocol the current rule is talking about * * Arguments: proto_str => the protocol string * * Returns: The integer value of the protocol * ***************************************************************************/int WhichProto(char *proto_str){ if(!strncasecmp(proto_str, "tcp", 3)) return IPPROTO_TCP; if(!strncasecmp(proto_str, "udp", 3)) return IPPROTO_UDP; if(!strncasecmp(proto_str, "icmp", 4)) return IPPROTO_ICMP; /* * if we've gotten here, we have a protocol string we din't recognize and * should exit */ FatalError("ERROR %s (%d) => Bad protocol: %s\n", file_name, file_line, proto_str); return 0;}int ProcessIP(char *addr, RuleTreeNode *rtn, int mode){ char **toks = NULL; int num_toks; int i; IpAddrSet *tmp_addr; char *tmp;#ifdef DEBUG printf("Got address string: %s\n", addr);#endif if(*addr == '!') { switch(mode) { case SRC: rtn->flags |= EXCEPT_SRC_IP; break; case DST: rtn->flags |= EXCEPT_DST_IP; break; } addr++; } if(*addr == '$') { if((tmp = VarGet(addr + 1)) == NULL) { FatalError("ERROR %s (%d) => Undefined variable %s\n", file_name, file_line, addr); } } else { tmp = addr; } /* check to see if the first char is a * bracket, which signifies a list */ if(*tmp == '[') {#ifdef DEBUG printf("Found IP list!\n");#endif /* *(tmp+strlen(tmp)) = ' ';*/ *(strrchr(tmp, (int)']')) = 0; /* null out the en-bracket */ toks = mSplit(tmp+1, ",", 128, &num_toks, 0);#ifdef DEBUG printf("mSplit got %d tokens...\n", num_toks);#endif for(i=0; i< num_toks; i++) {#ifdef DEBUG printf("adding %s to IP address list\n", toks[i]);#endif tmp = toks[i]; while (isspace((int)*tmp)) tmp++; if (strlen(tmp) == 0) continue; tmp_addr = AllocAddrNode(rtn, mode); ParseIP(tmp, tmp_addr); if(tmp_addr->ip_addr == 0 && tmp_addr->netmask == 0) { switch(mode) { case SRC: rtn->flags |= ANY_SRC_IP; break; case DST: rtn->flags |= ANY_DST_IP; break; } } }#ifdef DEBUG printf("Freeing %d tokens...\n", num_toks);#endif for(i=0;i<num_toks;i++) { free(toks[i]); } } else {#ifdef DEBUG printf("regular IP address, processing...\n");#endif tmp_addr = AllocAddrNode(rtn, mode); ParseIP(tmp, tmp_addr); if(tmp_addr->ip_addr == 0 && tmp_addr->netmask == 0) { switch(mode) { case SRC: rtn->flags |= ANY_SRC_IP; break; case DST: rtn->flags |= ANY_DST_IP; break; } } } return 0;}IpAddrSet *AllocAddrNode(RuleTreeNode *rtn, int mode){ IpAddrSet *idx; /* indexing pointer */ switch(mode) { case SRC: if(rtn->sip == NULL) { rtn->sip = (IpAddrSet *)calloc(sizeof(IpAddrSet), sizeof(char)); if(rtn->sip == NULL) { FatalError("[!] ERROR: Unable to allocate node for IP list\n"); } return rtn->sip; } else { idx = rtn->sip; while(idx->next != NULL) { idx = idx->next; } idx->next = (IpAddrSet *)calloc(sizeof(IpAddrSet), sizeof(char)); if(idx->next == NULL) { FatalError("[!] ERROR: Unable to allocate node for IP list\n"); } return idx->next; } break; case DST: if(rtn->dip == NULL) { rtn->dip = (IpAddrSet *)calloc(sizeof(IpAddrSet), sizeof(char)); if(rtn->dip == NULL) { FatalError("[!] ERROR: Unable to allocate node for IP list\n"); } return rtn->dip; } else { idx = rtn->dip; while(idx->next) { idx = idx->next; } idx->next = (IpAddrSet *)calloc(sizeof(IpAddrSet), sizeof(char)); if(idx->next == NULL) { FatalError("[!] ERROR: Unable to allocate node for IP list\n"); } return idx->next; } break; } return NULL;}/* * Function: ParseIP(char *, u_long *, u_long *) * * Purpose: Convert a supplied IP address to it's network order 32-bit long value. Also convert the CIDR block notation into a real * netmask. * * Arguments: addr => address string to convert * ip_addr => storage point for the converted ip address * netmask => storage point for the converted netmask * * Returns: 0 for normal addresses, 1 for an "any" address */int ParseIP(char *paddr, IpAddrSet *address_data){ int i; char **toks; /* token dbl buffer */ int num_toks; /* number of tokens found by mSplit() */ int cidr = 1; /* is network expressed in CIDR format */ int nmask; /* netmask temporary storage */ char *addr; /* string to parse, eventually a * variable-contents */ struct hostent *host_info; /* various struct pointers for stuff */ struct sockaddr_in sin; /* addr struct */ addr = paddr; if(*addr == '!') { address_data->addr_flags |= EXCEPT_IP; addr++; /* inc past the '!' */ } /* check for wildcards */ if(!strncasecmp(addr, "any", 3)) { address_data->ip_addr = 0; address_data->netmask = 0; return 1; } /* break out the CIDR notation from the IP address */ toks = mSplit(addr, "/", 2, &num_toks, 0); /* "/" was not used as a delimeter, try ":" */ if(num_toks == 1) toks = mSplit(addr, ":", 2, &num_toks, 0); /* * if we have a mask spec and it is more than two characters long, assume * it is netmask format */ if((num_toks > 1) && strlen(toks[1]) > 2) { cidr = 0; } switch(num_toks) { case 1: address_data->netmask = netmasks[32]; break; case 2: if(cidr) { /* convert the CIDR notation into a real live netmask */ nmask = atoi(toks[1]); /* it's pain to differ whether toks[1] is correct if netmask */ /* is /0, so we deploy some sort of evil hack with isdigit */ if(!isdigit((int) toks[1][0])) nmask = -1; if((nmask > -1) && (nmask < 33)) { address_data->netmask = netmasks[nmask]; } else { FatalError("ERROR %s (%d) => Invalid CIDR block for IP addr %s\n", file_name, file_line, addr); } } else { /* convert the netmask into its 32-bit value */ /* broadcast address fix from
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -