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 <sys/types.h>
00025 #include <stdlib.h>
00026 #include <ctype.h>
00027 #include <string.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
00037
00038 typedef struct _IpOptionData
00039 {
00040 u_char ip_option;
00041 u_char any_flag;
00042
00043 } IpOptionData;
00044
00045 void IpOptionInit(char *, OptTreeNode *, int);
00046 void ParseIpOptionData(char *, OptTreeNode *);
00047 int CheckIpOptions(Packet *, struct _OptTreeNode *, OptFpList *);
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 void SetupIpOptionCheck(void)
00062 {
00063
00064 RegisterPlugin("ipopts", IpOptionInit);
00065 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: IpOptionCheck Initialized\n"););
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 void IpOptionInit(char *data, OptTreeNode *otn, int protocol)
00084 {
00085
00086 if(otn->ds_list[PLUGIN_IPOPTION_CHECK])
00087 {
00088 FatalError("%s(%d): Multiple ipopts options in rule\n", file_name,
00089 file_line);
00090 }
00091
00092
00093
00094 otn->ds_list[PLUGIN_IPOPTION_CHECK] = (IpOptionData *)
00095 SnortAlloc(sizeof(IpOptionData));
00096
00097
00098
00099 ParseIpOptionData(data, otn);
00100
00101
00102
00103 AddOptFuncToList(CheckIpOptions, otn);
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 void ParseIpOptionData(char *data, OptTreeNode *otn)
00122 {
00123 IpOptionData *ds_ptr;
00124
00125
00126
00127 ds_ptr = otn->ds_list[PLUGIN_IPOPTION_CHECK];
00128
00129 if(data == NULL)
00130 {
00131 FatalError("%s(%d): IP Option keyword missing argument!\n", file_name, file_line);
00132 }
00133
00134 while(isspace((u_char)*data))
00135 data++;
00136
00137
00138 if(!strncasecmp(data, "rr", 2))
00139 {
00140 ds_ptr->ip_option = IPOPT_RR;
00141 return;
00142 }
00143 else if(!strncasecmp(data, "eol", 3))
00144 {
00145 ds_ptr->ip_option = IPOPT_EOL;
00146 return;
00147 }
00148 else if(!strncasecmp(data, "nop", 3))
00149 {
00150 ds_ptr->ip_option = IPOPT_NOP;
00151 return;
00152 }
00153 else if(!strncasecmp(data, "ts", 2))
00154 {
00155 ds_ptr->ip_option = IPOPT_TS;
00156 return;
00157 }
00158 else if(!strncasecmp(data, "sec", 3))
00159 {
00160 ds_ptr->ip_option = IPOPT_SECURITY;
00161 return;
00162 }
00163 else if(!strncasecmp(data, "lsrr", 4))
00164 {
00165 ds_ptr->ip_option = IPOPT_LSRR;
00166 return;
00167 }
00168 else if(!strncasecmp(data, "lsrre", 5))
00169 {
00170 ds_ptr->ip_option = IPOPT_LSRR_E;
00171 return;
00172 }
00173 else if(!strncasecmp(data, "satid", 5))
00174 {
00175 ds_ptr->ip_option = IPOPT_SATID;
00176 return;
00177 }
00178 else if(!strncasecmp(data, "ssrr", 4))
00179 {
00180 ds_ptr->ip_option = IPOPT_SSRR;
00181 return;
00182 }
00183 else if(!strncasecmp(data, "any", 3))
00184 {
00185 ds_ptr->ip_option = 0;
00186 ds_ptr->any_flag = 1;
00187 return;
00188 }
00189 else
00190 {
00191 FatalError("%s(%d) => Unknown IP option argument: %s!\n",
00192 file_name, file_line, data);
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 int CheckIpOptions(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00211 {
00212 int i;
00213 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "CheckIpOptions:"););
00214 if(!p->iph)
00215 return 0;
00216
00217
00218
00219 if((((IpOptionData *)otn->ds_list[PLUGIN_IPOPTION_CHECK])->any_flag == 1)
00220 && (p->ip_option_count > 0))
00221 {
00222 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Matched any ip options!\n"););
00223
00224 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00225 }
00226
00227 for(i=0; i< (int) p->ip_option_count; i++)
00228 {
00229 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "testing pkt(%d):rule(%d)\n",
00230 ((IpOptionData *)otn->ds_list[PLUGIN_IPOPTION_CHECK])->ip_option,
00231 p->ip_options[i].code); );
00232
00233 if(((IpOptionData *)otn->ds_list[PLUGIN_IPOPTION_CHECK])->ip_option == p->ip_options[i].code)
00234 {
00235
00236 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00237 }
00238 }
00239
00240
00241 return 0;
00242 }