00001 /* 00002 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 /* $Id$ */ 00020 00021 #ifdef HAVE_CONFIG_H 00022 #include "config.h" 00023 #endif 00024 00025 #include <sys/types.h> 00026 #include <stdlib.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 00038 00039 typedef struct _TcpSeqCheckData 00040 { 00041 u_long tcp_seq; 00042 00043 } TcpSeqCheckData; 00044 00045 void TcpSeqCheckInit(char *, OptTreeNode *, int); 00046 void ParseTcpSeq(char *, OptTreeNode *); 00047 int CheckTcpSeqEq(Packet *, struct _OptTreeNode *, OptFpList *); 00048 00049 00050 00051 /**************************************************************************** 00052 * 00053 * Function: SetupTcpSeqCheck() 00054 * 00055 * Purpose: Link the seq keyword to the initialization function 00056 * 00057 * Arguments: None. 00058 * 00059 * Returns: void function 00060 * 00061 ****************************************************************************/ 00062 void SetupTcpSeqCheck(void) 00063 { 00064 /* map the keyword to an initialization/processing function */ 00065 RegisterPlugin("seq", TcpSeqCheckInit); 00066 00067 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: TcpSeqCheck Initialized\n");); 00068 } 00069 00070 00071 /**************************************************************************** 00072 * 00073 * Function: TcpSeqCheckInit(char *, OptTreeNode *) 00074 * 00075 * Purpose: Attach the option data to the rule data struct and link in the 00076 * detection function to the function pointer list. 00077 * 00078 * Arguments: data => rule arguments/data 00079 * otn => pointer to the current rule option list node 00080 * 00081 * Returns: void function 00082 * 00083 ****************************************************************************/ 00084 void TcpSeqCheckInit(char *data, OptTreeNode *otn, int protocol) 00085 { 00086 if(protocol != IPPROTO_TCP) 00087 { 00088 FatalError("Line %s (%d): TCP Options on non-TCP rule\n", file_name, file_line); 00089 } 00090 00091 /* multiple declaration check */ 00092 if(otn->ds_list[PLUGIN_TCP_SEQ_CHECK]) 00093 { 00094 FatalError("%s(%d): Multiple TCP seq options in rule\n", file_name, 00095 file_line); 00096 } 00097 00098 /* allocate the data structure and attach it to the 00099 rule's data struct list */ 00100 otn->ds_list[PLUGIN_TCP_SEQ_CHECK] = (TcpSeqCheckData *) 00101 SnortAlloc(sizeof(TcpSeqCheckData)); 00102 00103 /* this is where the keyword arguments are processed and placed into the 00104 rule option's data structure */ 00105 ParseTcpSeq(data, otn); 00106 00107 /* finally, attach the option's detection function to the rule's 00108 detect function pointer list */ 00109 AddOptFuncToList(CheckTcpSeqEq, otn); 00110 } 00111 00112 00113 00114 /**************************************************************************** 00115 * 00116 * Function: ParseTcpSeq(char *, OptTreeNode *) 00117 * 00118 * Purpose: Attach the option rule's argument to the data struct. 00119 * 00120 * Arguments: data => argument data 00121 * otn => pointer to the current rule's OTN 00122 * 00123 * Returns: void function 00124 * 00125 ****************************************************************************/ 00126 void ParseTcpSeq(char *data, OptTreeNode *otn) 00127 { 00128 char **ep = NULL; 00129 TcpSeqCheckData *ds_ptr; /* data struct pointer */ 00130 00131 /* set the ds pointer to make it easier to reference the option's 00132 particular data struct */ 00133 ds_ptr = otn->ds_list[PLUGIN_TCP_SEQ_CHECK]; 00134 00135 ds_ptr->tcp_seq = strtoul(data, ep, 0); 00136 ds_ptr->tcp_seq = htonl(ds_ptr->tcp_seq); 00137 00138 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Seq set to %lX\n", ds_ptr->tcp_seq);); 00139 00140 } 00141 00142 00143 /**************************************************************************** 00144 * 00145 * Function: CheckTcpSeqEq(char *, OptTreeNode *) 00146 * 00147 * Purpose: Check to see if the packet's TCP ack field is equal to the rule 00148 * ack value. 00149 * 00150 * Arguments: data => argument data 00151 * otn => pointer to the current rule's OTN 00152 * 00153 * Returns: void function 00154 * 00155 ****************************************************************************/ 00156 int CheckTcpSeqEq(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list) 00157 { 00158 if(!p->tcph) 00159 return 0; /* if error appeared when tcp header was processed, 00160 * test fails automagically */ 00161 00162 if(((TcpSeqCheckData *)otn->ds_list[PLUGIN_TCP_SEQ_CHECK])->tcp_seq == 00163 p->tcph->th_seq) 00164 { 00165 /* call the next function in the function list recursively */ 00166 return fp_list->next->OptTestFunc(p, otn, fp_list->next); 00167 } 00168 #ifdef DEBUG 00169 else 00170 { 00171 /* you can put debug comments here or not */ 00172 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); 00173 } 00174 #endif 00175 00176 /* if the test isn't successful, return 0 */ 00177 return 0; 00178 }