Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

sp_ttl_check.c

Go to the documentation of this file.
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 <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  * Function: SetupTtlCheck()
00056  *
00057  * Purpose: Register the ttl option keyword with its setup function
00058  *
00059  * Arguments: None.
00060  *
00061  * Returns: void function
00062  *
00063  ****************************************************************************/
00064 void SetupTtlCheck(void)
00065 {
00066     /* map the keyword to an initialization/processing function */
00067     RegisterPlugin("ttl", TtlCheckInit);
00068 
00069     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: TTLCheck Initialized\n"););
00070 }
00071 
00072 
00073 /****************************************************************************
00074  * 
00075  * Function: TtlCheckInit(char *, OptTreeNode *)
00076  *
00077  * Purpose: Parse the ttl keyword arguments and link the detection module
00078  *          into the function list
00079  *
00080  * Arguments: data => rule arguments/data
00081  *            otn => pointer to the current rule option list node
00082  *
00083  * Returns: void function
00084  *
00085  ****************************************************************************/
00086 void TtlCheckInit(char *data, OptTreeNode *otn, int protocol)
00087 {
00088     /* multiple declaration check */ 
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     /* allocate the data structure and attach it to the
00096        rule's data struct list */
00097     otn->ds_list[PLUGIN_TTL_CHECK] = (TtlCheckData *)
00098             SnortAlloc(sizeof(TtlCheckData));
00099 
00100     /* this is where the keyword arguments are processed and placed into the 
00101        rule option's data structure */
00102     ParseTtl(data, otn);
00103 
00104     /* NOTE: the AddOptFuncToList call is moved to the parsing function since
00105        the linking is best determined within that function */
00106 }
00107 
00108 
00109 
00110 /****************************************************************************
00111  * 
00112  * Function: ParseTtl(char *, OptTreeNode *)
00113  *
00114  * Purpose: Parse the TTL keyword's arguments
00115  *
00116  * Arguments: data => argument data
00117  *            otn => pointer to the current rule's OTN
00118  *
00119  * Returns: void function
00120  *
00121  ****************************************************************************/
00122 void ParseTtl(char *data, OptTreeNode *otn)
00123 {
00124     TtlCheckData *ds_ptr;  /* data struct pointer */
00125     char ttlrel;
00126 
00127     /* set the ds pointer to make it easier to reference the option's
00128        particular data struct */
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; /* leading dash flag */
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     /* skip digit */
00151     while(isdigit((int)*data)) data++;
00152     /* and spaces.. if any */ 
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             /* sanity check.. */
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             /* wtf? */
00189             /* we need at least one statement after "default" or else Visual C++ issues a warning */
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  * Function: CheckTtlEq(char *, OptTreeNode *)
00202  *
00203  * Purpose: Test if the packet TTL equals the rule option's ttl
00204  *
00205  * Arguments: data => argument data
00206  *            otn => pointer to the current rule's OTN
00207  *
00208  * Returns:  0 on failure, return value of next list function on success
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         /* call the next function in the function list recursively */
00217         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00218     }
00219 #ifdef DEBUG
00220     else
00221     {
00222         /* you can put debug comments here or not */
00223         DebugMessage(DEBUG_PLUGIN, "CheckTtlEq: Not equal to %d\n",
00224         ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl);
00225     }
00226 #endif
00227 
00228     /* if the test isn't successful, return 0 */
00229     return 0;
00230 }
00231 
00232 
00233 
00234 /****************************************************************************
00235  * 
00236  * Function: CheckTtlGT(char *, OptTreeNode *)
00237  *
00238  * Purpose: Test the packet's payload size against the rule payload size 
00239  *          value.  This test determines if the packet payload size is 
00240  *          greater than the rule ttl.
00241  *
00242  * Arguments: data => argument data
00243  *            otn => pointer to the current rule's OTN
00244  *
00245  * Returns:  0 on failure, return value of next list function on success
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         /* call the next function in the function list recursively */
00254         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00255     }
00256 #ifdef DEBUG
00257     else
00258     {
00259         /* you can put debug comments here or not */
00260         DebugMessage(DEBUG_PLUGIN, "CheckTtlGt: Not greater than %d\n",
00261         ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl);
00262     }
00263 #endif
00264 
00265     /* if the test isn't successful, return 0 */
00266     return 0;
00267 }
00268 
00269 
00270 
00271 
00272 /****************************************************************************
00273  * 
00274  * Function: CheckTtlLT(char *, OptTreeNode *)
00275  *
00276  * Purpose: Test the packet's payload size against the rule payload size 
00277  *          value.  This test determines if the packet payload size is 
00278  *          less than the rule ttl.
00279  *
00280  * Arguments: data => argument data
00281  *            otn => pointer to the current rule's OTN
00282  *
00283  * Returns:  0 on failure, return value of next list function on success
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         /* call the next function in the function list recursively */
00292         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00293     }
00294 #ifdef DEBUG
00295     else
00296     {
00297         /* you can put debug comments here or not */
00298         DebugMessage(DEBUG_PLUGIN, "CheckTtlLT: Not Less than %d\n",
00299         ((TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK])->ttl);
00300     }
00301 #endif
00302 
00303     /* if the test isn't successful, return 0 */
00304     return 0;
00305 }
00306 
00307 
00308 
00309 
00310 
00311 /****************************************************************************
00312  * 
00313  * Function: CheckTtlRG(char *, OptTreeNode *)
00314  *
00315  * Purpose: Test the packet's payload size against the rule payload size 
00316  *          value.  This test determines if the packet payload size is 
00317  *          within the rule ttl.
00318  *
00319  * Arguments: data => argument data
00320  *            otn => pointer to the current rule's OTN
00321  *
00322  * Returns:  0 on failure, return value of next list function on success
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         /* call the next function in the function list recursively */
00332         return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00333     }
00334 #ifdef DEBUG
00335     else
00336     {
00337         /* you can put debug comments here or not */
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     /* if the test isn't successful, return 0 */
00347     return 0;
00348 }

Generated on Sun May 14 14:51:13 2006 by  doxygen 1.4.2