diff --git a/src/detection-plugins/sp_dsize_check.c bsrc/detection-plugins/sp_dsize_check.c --- a/src/detection-plugins/sp_dsize_check.c +++ b/src/detection-plugins/sp_dsize_check.c @@ -62,9 +62,9 @@ typedef struct _DsizeCheckData void DsizeCheckInit(char *, OptTreeNode *, int); void ParseDsize(char *, OptTreeNode *); -int CheckDsize(void *option_data, Packet *p); +int DsizeCheckEval(void *option_data, Packet *p); uint32_t DSizeCheckHash(void *d) { uint32_t a,b,c; @@ -176,132 +176,100 @@ void DsizeCheckInit(char *data, OptTreeNode *otn, int protocol) ****************************************************************************/ void ParseDsize(char *data, OptTreeNode *otn) { DsizeCheckData *ds_ptr; /* data struct pointer */ - char *pcEnd; - char *pcTok; - int iDsize = 0; + char *end; + int num = 0, rval = 0; + NumericRange foo; void *ds_ptr_dup; OptFpList *fpl; - /* set the ds pointer to make it easier to reference the option's - particular data struct */ + /* + * Set the ds pointer to make it easier to reference the option's + * particular data struct + */ ds_ptr = (DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK]; while(isspace((int)*data)) data++; - /* If a range is specified, put min in ds_ptr->dsize and max in - ds_ptr->dsize2 */ - - if(isdigit((int)*data) && strchr(data, '<') && strchr(data, '>')) + /* Parse out the operands of the range. */ + rval = SnortStrToNumRng(data, (const char *)"<>", &foo); + if (rval == SNORT_STR2RNG_SUCCESS) { - pcTok = strtok(data, " <>"); - if(!pcTok) - { - /* - ** Fatal - */ - FatalError("%s(%d): Invalid 'dsize' argument.\n", - file_name, file_line); - } - - iDsize = strtol(pcTok, &pcEnd, 10); - if(iDsize < 0 || *pcEnd) - { - FatalError("%s(%d): Invalid 'dsize' argument.\n", - file_name, file_line); - } - - ds_ptr->dsize = (unsigned short)iDsize; - - pcTok = strtok(NULL, " <>"); - if(!pcTok) - { - FatalError("%s(%d): Invalid 'dsize' argument.\n", - file_name, file_line); - } - - iDsize = strtol(pcTok, &pcEnd, 10); - if(iDsize < 0 || *pcEnd) - { - FatalError("%s(%d): Invalid 'dsize' argument.\n", - file_name, file_line); - } - - ds_ptr->dsize2 = (unsigned short)iDsize; + /* dsize is an unsigned int16 value */ + if (((foo.min < 0) || (foo.min > UINT16_MAX)) || + ((foo.max < 0) || (foo.max > UINT16_MAX))) + goto error; + ds_ptr->dsize = (uint16_t)foo.min; + ds_ptr->dsize2 = (uint16_t)foo.max; ds_ptr->operator = DSIZE_RANGE; #ifdef DEBUG_MSGS DebugMessage(DEBUG_PLUGIN, "min dsize: %d\n", ds_ptr->dsize); DebugMessage(DEBUG_PLUGIN, "max dsize: %d\n", ds_ptr->dsize2); #endif - fpl = AddOptFuncToList(CheckDsize, otn); - fpl->type = RULE_OPTION_TYPE_DSIZE; + } - if (add_detection_option(RULE_OPTION_TYPE_DSIZE, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) + /* Not a ranged value. */ + else if (rval == SNORT_STR2RNG_NOTRNG) + { + if (*data == '>') { - free(ds_ptr); - ds_ptr = otn->ds_list[PLUGIN_DSIZE_CHECK] = ds_ptr_dup; + data++; + ds_ptr->operator = DSIZE_GT; } - fpl->context = ds_ptr; - - return; - } - else if(*data == '>') - { - data++; - fpl = AddOptFuncToList(CheckDsize, otn); - ds_ptr->operator = DSIZE_GT; - } - else if(*data == '<') - { - data++; - fpl = AddOptFuncToList(CheckDsize, otn); - ds_ptr->operator = DSIZE_LT; - } - else - { - fpl = AddOptFuncToList(CheckDsize, otn); - ds_ptr->operator = DSIZE_EQ; + else if(*data == '<') + { + data++; + ds_ptr->operator = DSIZE_LT; + } + else + ds_ptr->operator = DSIZE_EQ; } - fpl->type = RULE_OPTION_TYPE_DSIZE; + /* Error. */ + else if (rval == SNORT_STR2RNG_ERROR) + goto error; - while(isspace((int)*data)) data++; + /* Add the eval function to the function pointer list. */ + fpl = AddOptFuncToList(DsizeCheckEval, otn); + fpl->type = RULE_OPTION_TYPE_DSIZE; - iDsize = strtol(data, &pcEnd, 10); - if(iDsize < 0 || *pcEnd) - { - FatalError("%s(%d): Invalid 'dsize' argument.\n", - file_name, file_line); - } + num = strtol(data, &end, 10); + if ((num < 0) || (num > UINT16_MAX) || *end) + goto error; - ds_ptr->dsize = (unsigned short)iDsize; + ds_ptr->dsize = (uint16_t)num; if (add_detection_option(RULE_OPTION_TYPE_DSIZE, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_DSIZE_CHECK] = ds_ptr_dup; - } - fpl->context = ds_ptr; + } + fpl->context = ds_ptr; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Payload length = %d\n", ds_ptr->dsize);); + return; + +error: + FatalError("%s(%d): Invalid 'dsize' argument.\n", file_name, file_line); + return; } /**************************************************************************** * - * Function: CheckDsizeEq(char *, OptTreeNode *) + * Function: DsizeCheckEval(char *, OptTreeNode *) * * Purpose: Test the packet's payload size against the rule payload size value * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: 0 on failure, return value of next list function on success ****************************************************************************/ -int CheckDsize(void *option_data, Packet *p) +int DsizeCheckEval(void *option_data, Packet *p) { DsizeCheckData *ds_ptr = (DsizeCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS;