Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

sp_dsize_check.c

Go to the documentation of this file.
00001 /* $Id$ */
00002 /*
00003 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
00004 **
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 **
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 **
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023 
00024 #include <ctype.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 
00028 #include "rules.h"
00029 #include "decode.h"
00030 #include "plugbase.h"
00031 #include "debug.h"
00032 #include "parser.h"
00033 #include "plugin_enum.h"
00034 #include "util.h"
00035 
00036 #define EQ                   0
00037 #define GT                   1
00038 #define LT                   2
00039 
00040 typedef struct _DsizeCheckData
00041 {
00042     int dsize;
00043     int dsize2;
00044 
00045 } DsizeCheckData;
00046 
00047 void DsizeCheckInit(char *, OptTreeNode *, int);
00048 void ParseDsize(char *, OptTreeNode *);
00049 int CheckDsizeEq(Packet *, struct _OptTreeNode *, OptFpList *);
00050 int CheckDsizeGT(Packet *, struct _OptTreeNode *, OptFpList *);
00051 int CheckDsizeLT(Packet *, struct _OptTreeNode *, OptFpList *);
00052 int CheckDsizeRange(Packet *, struct _OptTreeNode *, OptFpList *);
00053 
00054 /****************************************************************************
00055  * 
00056  * Function: SetupDsizeCheck()
00057  *
00058  * Purpose: Attach the dsize keyword to the rule parse function
00059  *
00060  * Arguments: None.
00061  *
00062  * Returns: void function
00063  *
00064  ****************************************************************************/
00065 void SetupDsizeCheck(void)
00066 {
00067     /* map the keyword to an initialization/processing function */
00068     RegisterPlugin("dsize", DsizeCheckInit);
00069     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: DsizeCheck Initialized\n"););
00070 }
00071 
00072 
00073 /****************************************************************************
00074  * 
00075  * Function: DsizeCheckInit(char *, OptTreeNode *)
00076  *
00077  * Purpose: Parse the rule argument and attach it to the rule data struct, 
00078  *          then attach the detection function to the function list
00079  *
00080  * Arguments: data => rule arguments/data
00081  *            otn => pointer to the current rule option list node
00082  *
00083  * Returns: void function
00084  *
00085  ****************************************************************************/
00086 void DsizeCheckInit(char *data, OptTreeNode *otn, int protocol)
00087 {
00088     /* multiple declaration check */
00089     if(otn->ds_list[PLUGIN_DSIZE_CHECK])
00090     {
00091         FatalError("%s(%d): Multiple dsize options in rule\n", file_name,
00092                 file_line);
00093     }
00094 
00095     /* allocate the data structure and attach it to the
00096        rule's data struct list */
00097 
00098     otn->ds_list[PLUGIN_DSIZE_CHECK] = (DsizeCheckData *)
00099         SnortAlloc(sizeof(DsizeCheckData));
00100 
00101     /* this is where the keyword arguments are processed and placed into the 
00102        rule option's data structure */
00103     ParseDsize(data, otn);
00104 
00105     /* NOTE: I moved the AddOptFuncToList call to the parsing function since
00106        the linking is best determined within that function */
00107 }
00108 
00109 
00110 
00111 /****************************************************************************
00112  * 
00113  * Function: ParseDsize(char *, OptTreeNode *)
00114  *
00115  * Purpose: Parse the dsize function argument and attach the detection
00116  *          function to the rule list as well.  
00117  *
00118  * Arguments: data => argument data
00119  *            otn => pointer to the current rule's OTN
00120  *
00121  * Returns: void function
00122  *
00123  ****************************************************************************/
00124 void ParseDsize(char *data, OptTreeNode *otn)
00125 {
00126     DsizeCheckData *ds_ptr;  /* data struct pointer */
00127     char *pcEnd;
00128     char *pcTok;
00129     int  iDsize = 0;
00130 
00131     /* set the ds pointer to make it easier to reference the option's
00132        particular data struct */
00133     ds_ptr = (DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK];
00134 
00135     while(isspace((int)*data)) data++;
00136 
00137     /* If a range is specified, put min in ds_ptr->dsize and max in
00138        ds_ptr->dsize2 */
00139     
00140     if(isdigit((int)*data) && strchr(data, '<') && strchr(data, '>'))
00141     {
00142         pcTok = strtok(data, " <>");
00143         if(!pcTok)
00144         {
00145             /*
00146             **  Fatal
00147             */
00148             FatalError("%s(%d): Invalid 'dsize' argument.\n",
00149                        file_name, file_line);
00150         }
00151 
00152         iDsize = strtol(pcTok, &pcEnd, 10);
00153         if(iDsize < 0 || *pcEnd)
00154         {
00155             FatalError("%s(%d): Invalid 'dsize' argument.\n",
00156                        file_name, file_line);
00157         }
00158 
00159         ds_ptr->dsize = (unsigned short)iDsize;
00160 
00161         pcTok = strtok(NULL, " <>");
00162         if(!pcTok)
00163         {
00164             FatalError("%s(%d): Invalid 'dsize' argument.\n",
00165                        file_name, file_line);
00166         }
00167 
00168         iDsize = strtol(pcTok, &pcEnd, 10);
00169         if(iDsize < 0 || *pcEnd)
00170         {
00171             FatalError("%s(%d): Invalid 'dsize' argument.\n",
00172                        file_name, file_line);
00173         }
00174 
00175         ds_ptr->dsize2 = (unsigned short)iDsize;
00176 
00177 #ifdef DEBUG
00178         printf("min dsize: %d\n", ds_ptr->dsize);
00179         printf("max dsize: %d\n", ds_ptr->dsize2);
00180 #endif
00181         AddOptFuncToList(CheckDsizeRange, otn);
00182         return;
00183     }
00184     else if(*data == '>')
00185     {
00186         data++;
00187         AddOptFuncToList(CheckDsizeGT, otn);
00188     }
00189     else if(*data == '<')
00190     {
00191         data++;
00192         AddOptFuncToList(CheckDsizeLT, otn);
00193     }
00194     else
00195     {
00196         AddOptFuncToList(CheckDsizeEq, otn);
00197     }
00198 
00199     while(isspace((int)*data)) data++;
00200 
00201     iDsize = strtol(data, &pcEnd, 10);
00202     if(iDsize < 0 || *pcEnd)
00203     {
00204         FatalError("%s(%d): Invalid 'dsize' argument.\n",
00205                    file_name, file_line);
00206     }
00207 
00208     ds_ptr->dsize = (unsigned short)iDsize;
00209 
00210     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Payload length = %d\n", ds_ptr->dsize););
00211 
00212 }
00213 
00214 
00215 /****************************************************************************
00216  * 
00217  * Function: CheckDsizeEq(char *, OptTreeNode *)
00218  *
00219  * Purpose: Test the packet's payload size against the rule payload size value
00220  *
00221  * Arguments: data => argument data
00222  *            otn => pointer to the current rule's OTN
00223  *
00224  * Returns:  0 on failure, return value of next list function on success
00225  *
00226  ****************************************************************************/
00227 int CheckDsizeEq(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00228 {
00229 
00230     /* fake packet dsizes are always wrong */
00231     if(p->packet_flags & PKT_REBUILT_STREAM)
00232     {
00233         return 0;
00234     }
00235     
00236     if(((DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK])->dsize == p->dsize)
00237     {
00238         /* call the next function in the function list recursively */
00239         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00240     }
00241     else
00242     {
00243         /* you can put debug comments here or not */
00244         DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not equal\n"););
00245     }
00246 
00247     /* if the test isn't successful, return 0 */
00248     return 0;
00249 }
00250 
00251 
00252 
00253 /****************************************************************************
00254  * 
00255  * Function: CheckDsizeGT(char *, OptTreeNode *)
00256  *
00257  * Purpose: Test the packet's payload size against the rule payload size 
00258  *          value.  This test determines if the packet payload size is 
00259  *          greater than the rule dsize.
00260  *
00261  * Arguments: data => argument data
00262  *            otn => pointer to the current rule's OTN
00263  *
00264  * Returns:  0 on failure, return value of next list function on success
00265  *
00266  ****************************************************************************/
00267 int CheckDsizeGT(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00268 {
00269     /* fake packet dsizes are always wrong */
00270     if(p->packet_flags & PKT_REBUILT_STREAM)
00271     {
00272         return 0;
00273     }
00274 
00275     if(((DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK])->dsize < p->dsize)
00276     {
00277         /* call the next function in the function list recursively */
00278         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00279     }
00280     else
00281     {
00282         /* you can put debug comments here or not */
00283         DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not equal\n"););
00284     }
00285 
00286     /* if the test isn't successful, return 0 */
00287     return 0;
00288 }
00289 
00290 
00291 
00292 
00293 /****************************************************************************
00294  * 
00295  * Function: CheckDsizeLT(char *, OptTreeNode *)
00296  *
00297  * Purpose: Test the packet's payload size against the rule payload size 
00298  *          value.  This test determines if the packet payload size is 
00299  *          less than the rule dsize.
00300  *
00301  * Arguments: data => argument data
00302  *            otn => pointer to the current rule's OTN
00303  *
00304  * Returns:  0 on failure, return value of next list function on success
00305  *
00306  ****************************************************************************/
00307 int CheckDsizeLT(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00308 {
00309     /* fake packet dsizes are always wrong */
00310     if(p->packet_flags & PKT_REBUILT_STREAM)
00311     {
00312         return 0;
00313     }
00314     
00315     if(((DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK])->dsize > p->dsize)
00316     {
00317         /* call the next function in the function list recursively */
00318         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00319     }
00320     else
00321     {
00322         /* you can put debug comments here or not */
00323         DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not equal\n"););
00324     }
00325 
00326     /* if the test isn't successful, return 0 */
00327     return 0;
00328 }
00329 
00330 
00331 /****************************************************************************
00332  *
00333  * Function: CheckDsizeRange(char *, OptTreeNode *)
00334  *
00335  * Purpose: Test the packet's payload size against the rule payload size
00336  *          values.  This test determines if the packet payload size is
00337  *          in the range of the rule dsize min and max.
00338  *
00339  * Arguments: data => argument data
00340  *            otn => pointer to the current rule's OTN
00341  *
00342  * Returns:  0 on failure, return value of next list function on success
00343  *
00344  ****************************************************************************/
00345 int CheckDsizeRange(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00346 {
00347     /* fake packet dsizes are always wrong */
00348     if(p->packet_flags & PKT_REBUILT_STREAM)
00349     {
00350         return 0;
00351     }
00352 
00353     if(((DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK])->dsize <= p->dsize &&
00354      ((DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK])->dsize2 >= p->dsize)
00355     {
00356         /* call the next function in the function list recursively */
00357         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00358     }
00359     else
00360     {
00361         DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,
00362                                 "CheckDsizeRange(): not in range\n"););
00363     }
00364 
00365     return 0;
00366 }

Generated on Sun May 14 14:51:13 2006 by  doxygen 1.4.2