00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00057
00058
00059
00060
00061
00062
00063
00064
00065 void SetupDsizeCheck(void)
00066 {
00067
00068 RegisterPlugin("dsize", DsizeCheckInit);
00069 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: DsizeCheck Initialized\n"););
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 void DsizeCheckInit(char *data, OptTreeNode *otn, int protocol)
00087 {
00088
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
00096
00097
00098 otn->ds_list[PLUGIN_DSIZE_CHECK] = (DsizeCheckData *)
00099 SnortAlloc(sizeof(DsizeCheckData));
00100
00101
00102
00103 ParseDsize(data, otn);
00104
00105
00106
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 void ParseDsize(char *data, OptTreeNode *otn)
00125 {
00126 DsizeCheckData *ds_ptr;
00127 char *pcEnd;
00128 char *pcTok;
00129 int iDsize = 0;
00130
00131
00132
00133 ds_ptr = (DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK];
00134
00135 while(isspace((int)*data)) data++;
00136
00137
00138
00139
00140 if(isdigit((int)*data) && strchr(data, '<') && strchr(data, '>'))
00141 {
00142 pcTok = strtok(data, " <>");
00143 if(!pcTok)
00144 {
00145
00146
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
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 int CheckDsizeEq(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00228 {
00229
00230
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
00239 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00240 }
00241 else
00242 {
00243
00244 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not equal\n"););
00245 }
00246
00247
00248 return 0;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 int CheckDsizeGT(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00268 {
00269
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
00278 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00279 }
00280 else
00281 {
00282
00283 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not equal\n"););
00284 }
00285
00286
00287 return 0;
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 int CheckDsizeLT(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00308 {
00309
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
00318 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00319 }
00320 else
00321 {
00322
00323 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Not equal\n"););
00324 }
00325
00326
00327 return 0;
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 int CheckDsizeRange(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00346 {
00347
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
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 }