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 <string.h>
00027 #include <ctype.h>
00028
00029 #include "rules.h"
00030 #include "decode.h"
00031 #include "plugbase.h"
00032 #include "parser.h"
00033 #include "util.h"
00034 #include "debug.h"
00035 #include "plugin_enum.h"
00036
00037 typedef struct _IcmpCodeCheckData
00038 {
00039
00040 int icmp_code;
00041 int icmp_code2;
00042 u_int8_t operator;
00043 } IcmpCodeCheckData;
00044
00045 #define ICMP_CODE_TEST_EQ 1
00046 #define ICMP_CODE_TEST_GT 2
00047 #define ICMP_CODE_TEST_LT 3
00048 #define ICMP_CODE_TEST_RG 4
00049
00050
00051 void IcmpCodeCheckInit(char *, OptTreeNode *, int);
00052 void ParseIcmpCode(char *, OptTreeNode *);
00053 int IcmpCodeCheck(Packet *, struct _OptTreeNode *, OptFpList *);
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 void SetupIcmpCodeCheck(void)
00071 {
00072
00073 RegisterPlugin("icode", IcmpCodeCheckInit);
00074 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: IcmpCodeCheck Initialized\n"););
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 void IcmpCodeCheckInit(char *data, OptTreeNode *otn, int protocol)
00092 {
00093 if(protocol != IPPROTO_ICMP)
00094 {
00095 FatalError( "%s(%d): ICMP Options on non-ICMP rule\n", file_name, file_line);
00096 }
00097
00098
00099 if(otn->ds_list[PLUGIN_ICMP_CODE])
00100 {
00101 FatalError("%s(%d): Multiple icmp code options in rule\n", file_name,
00102 file_line);
00103 }
00104
00105
00106
00107
00108 otn->ds_list[PLUGIN_ICMP_CODE] = (IcmpCodeCheckData *)
00109 SnortAlloc(sizeof(IcmpCodeCheckData));
00110
00111
00112
00113 ParseIcmpCode(data, otn);
00114
00115
00116
00117
00118 AddOptFuncToList(IcmpCodeCheck, otn);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 void ParseIcmpCode(char *data, OptTreeNode *otn)
00136 {
00137 char *code;
00138 IcmpCodeCheckData *ds_ptr;
00139
00140
00141
00142 ds_ptr = otn->ds_list[PLUGIN_ICMP_CODE];
00143
00144
00145 code = data;
00146
00147 if(!data)
00148 {
00149 FatalError("%s (%d): No ICMP Code Specified\n", file_name,
00150 file_line);
00151 }
00152
00153
00154
00155 while(isspace((int)*data))
00156 data++;
00157
00158 if(data[0] == '\0')
00159 {
00160 FatalError("%s (%d): No ICMP Code Specified\n", file_name,
00161 file_line);
00162 }
00163
00164
00165
00166
00167
00168
00169 if (isdigit((int)*data) && strchr(data, '<') && strchr(data, '>'))
00170 {
00171 ds_ptr->icmp_code = atoi(strtok(data, " <>"));
00172 ds_ptr->icmp_code2 = atoi(strtok(NULL, " <>"));
00173 ds_ptr->operator = ICMP_CODE_TEST_RG;
00174 }
00175
00176 else if (*data == '>')
00177 {
00178 data++;
00179 while(isspace((int)*data)) data++;
00180
00181 ds_ptr->icmp_code = atoi(data);
00182 ds_ptr->operator = ICMP_CODE_TEST_GT;
00183 }
00184
00185 else if (*data == '<')
00186 {
00187 data++;
00188 while(isspace((int)*data)) data++;
00189
00190 ds_ptr->icmp_code = atoi(data);
00191 ds_ptr->operator = ICMP_CODE_TEST_LT;
00192 }
00193
00194 else if (isdigit((int)*data))
00195 {
00196 ds_ptr->icmp_code = atoi(data);
00197 ds_ptr->operator = ICMP_CODE_TEST_EQ;
00198 }
00199
00200 else
00201 {
00202 FatalError("%s(%d): Bad ICMP code: %s\n", file_name,
00203 file_line, code);
00204 }
00205
00206 return;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 int IcmpCodeCheck(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00224 {
00225 IcmpCodeCheckData *ds_ptr;
00226 int success = 0;
00227
00228 ds_ptr = otn->ds_list[PLUGIN_ICMP_CODE];
00229
00230
00231 if(!p->icmph)
00232 return 0;
00233
00234 switch(ds_ptr->operator)
00235 {
00236 case ICMP_CODE_TEST_EQ:
00237 if (ds_ptr->icmp_code == p->icmph->code)
00238 success = 1;
00239 break;
00240 case ICMP_CODE_TEST_GT:
00241 if (p->icmph->code > ds_ptr->icmp_code)
00242 success = 1;
00243 break;
00244 case ICMP_CODE_TEST_LT:
00245 if (p->icmph->code < ds_ptr->icmp_code)
00246 success = 1;
00247 break;
00248 case ICMP_CODE_TEST_RG:
00249 if (p->icmph->code > ds_ptr->icmp_code &&
00250 p->icmph->code < ds_ptr->icmp_code2)
00251 success = 1;
00252 break;
00253 }
00254
00255 if (success)
00256 {
00257 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Got icmp code match!\n"););
00258 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00259 }
00260
00261
00262 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Failed icmp code match!\n"););
00263 return 0;
00264 }