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