00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024
00025 #include <stdlib.h>
00026 #include <ctype.h>
00027
00028 #include "rules.h"
00029 #include "decode.h"
00030 #include "debug.h"
00031 #include "plugbase.h"
00032 #include "parser.h"
00033 #include "plugin_enum.h"
00034 #include "util.h"
00035
00036
00037 typedef struct _TtlCheckData
00038 {
00039 int ttl;
00040 int h_ttl;
00041
00042 } TtlCheckData;
00043
00044 void TtlCheckInit(char *, OptTreeNode *, int);
00045 void ParseTtl(char *, OptTreeNode *);
00046 int CheckTtlEq(Packet *, struct _OptTreeNode *, OptFpList *);
00047 int CheckTtlGT(Packet *, struct _OptTreeNode *, OptFpList *);
00048 int CheckTtlLT(Packet *, struct _OptTreeNode *, OptFpList *);
00049 int CheckTtlRG(Packet *, struct _OptTreeNode *, OptFpList *);
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void SetupTtlCheck(void)
00065 {
00066
00067 RegisterPlugin("ttl", TtlCheckInit);
00068
00069 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: TTLCheck Initialized\n"););
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 void TtlCheckInit(char *data, OptTreeNode *otn, int protocol)
00087 {
00088
00089 if(otn->ds_list[PLUGIN_TTL_CHECK])
00090 {
00091 FatalError("%s(%d): Multiple IP ttl options in rule\n", file_name,
00092 file_line);
00093 }
00094
00095
00096
00097 otn->ds_list[PLUGIN_TTL_CHECK] = (TtlCheckData *)
00098 SnortAlloc(sizeof(TtlCheckData));
00099
00100
00101
00102 ParseTtl(data, otn);
00103
00104
00105
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 void ParseTtl(char *data, OptTreeNode *otn)
00123 {
00124 TtlCheckData *ds_ptr;
00125 char ttlrel;
00126
00127
00128
00129 ds_ptr = (TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK];
00130
00131 while(isspace((int)*data)) data++;
00132
00133 ttlrel = *data;
00134
00135 switch (ttlrel) {
00136 case '-':
00137 ds_ptr->h_ttl = -1;
00138 case '>':
00139 case '<':
00140 case '=':
00141 data++;
00142 break;
00143 default:
00144 ttlrel = '=';
00145 }
00146 while(isspace((int)*data)) data++;
00147
00148 ds_ptr->ttl = atoi(data);
00149
00150
00151 while(isdigit((int)*data)) data++;
00152
00153 while(isspace((int)*data)) data++;
00154 if (*data == '-')
00155 {
00156 data++;
00157 ttlrel = '-';
00158 }
00159 switch (ttlrel) {
00160 case '>':
00161 AddOptFuncToList(CheckTtlGT, otn);
00162 break;
00163 case '<':
00164 AddOptFuncToList(CheckTtlLT, otn);
00165 break;
00166 case '=':
00167 AddOptFuncToList(CheckTtlEq, otn);
00168 break;
00169 case '-':
00170 while(isspace((int)*data)) data++;
00171 if (ds_ptr->h_ttl != -1 && atoi(data) == 0)
00172 {
00173 ds_ptr->h_ttl = 255;
00174 }
00175 else
00176 {
00177 ds_ptr->h_ttl = atoi(data);
00178 }
00179
00180 if (ds_ptr->h_ttl < ds_ptr->ttl)
00181 {
00182 ds_ptr->h_ttl = ds_ptr->ttl;
00183 ds_ptr->ttl = atoi(data);
00184 }
00185 AddOptFuncToList(CheckTtlRG, otn);
00186 break;
00187 default:
00188
00189
00190 break;
00191 }
00192
00193
00194 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Set TTL check value to %c%d (%d)\n", ttlrel, ds_ptr->ttl, ds_ptr->h_ttl););
00195
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 int CheckTtlEq(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00212 {
00213 if(p->iph &&
00214 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl == p->iph->ip_ttl)
00215 {
00216
00217 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00218 }
00219 #ifdef DEBUG
00220 else
00221 {
00222
00223 DebugMessage(DEBUG_PLUGIN, "CheckTtlEq: Not equal to %d\n",
00224 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl);
00225 }
00226 #endif
00227
00228
00229 return 0;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 int CheckTtlGT(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00249 {
00250 if(p->iph &&
00251 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl < p->iph->ip_ttl)
00252 {
00253
00254 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00255 }
00256 #ifdef DEBUG
00257 else
00258 {
00259
00260 DebugMessage(DEBUG_PLUGIN, "CheckTtlGt: Not greater than %d\n",
00261 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl);
00262 }
00263 #endif
00264
00265
00266 return 0;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 int CheckTtlLT(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00287 {
00288 if(p->iph &&
00289 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl > p->iph->ip_ttl)
00290 {
00291
00292 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00293 }
00294 #ifdef DEBUG
00295 else
00296 {
00297
00298 DebugMessage(DEBUG_PLUGIN, "CheckTtlLT: Not Less than %d\n",
00299 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl);
00300 }
00301 #endif
00302
00303
00304 return 0;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 int CheckTtlRG(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00326 {
00327 if(p->iph &&
00328 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl <= p->iph->ip_ttl &&
00329 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->h_ttl >= p->iph->ip_ttl)
00330 {
00331
00332 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00333 }
00334 #ifdef DEBUG
00335 else
00336 {
00337
00338 DebugMessage(DEBUG_PLUGIN, "CheckTtlLT: Not Within the range %d - %d (%d)\n",
00339 ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl,
00340 ((TtlCheckData
00341 *)otn->ds_list[PLUGIN_TTL_CHECK])->h_ttl,
00342 p->iph->ip_ttl);
00343 }
00344 #endif
00345
00346
00347 return 0;
00348 }