Azinix

rlpL7.c

Go to the documentation of this file.
00001 /** \file rlpL7.c
00002 
00003   \brief Routines for building a content check structure from an L7 formula.
00004 
00005 The idea is to simplify having to walk through a list of checks, 
00006 have a content struct with the case check, offset, etc. all in place.
00007 
00008 */
00009 
00010 #include "rlp.h"
00011 
00012 
00013 /*AutomaticStart*************************************************************/
00014 
00015 static Rlp_Formula_t *computeContentCheck (Rlp_Formula_t * walkFormula,
00016                        Rlp_ContentCheck_t * contentCheck);
00017 static Rlp_ContentCheck_t *mallocContentCheckStruct ();
00018 
00019 /*AutomaticEnd***************************************************************/
00020 
00021 
00022 /** \brief  Walk an L7 formula, build the list of checks.  */
00023 
00024 array_t *
00025 Rlp_BuildContentCheckArrayFromL7Formula (Rlp_Formula_t * aL7Formula)
00026 {
00027   Rlp_Formula_t *walkFormula = aL7Formula;
00028   Rlp_Formula_t *componentFormula;
00029 
00030   array_t *result = array_alloc (Rlp_L7Check_t *, 0);
00031 
00032   Rlp_L7Check_t *l7Check;
00033   Rlp_ContentCheck_t *contentCheck;
00034 
00035   while (walkFormula != NIL (Rlp_Formula_t))
00036     {
00037       componentFormula = car (walkFormula);
00038       switch (componentFormula->type)
00039     {
00040 
00041     case Rlp_Content_c:
00042     case Rlp_Uricontent_c:
00043       l7Check = (Rlp_L7Check_t *) malloc (sizeof (Rlp_L7Check_t));
00044       contentCheck = mallocContentCheckStruct ();
00045       if (componentFormula->type == Rlp_Content_c)
00046         {
00047           l7Check->type = Rlp_L7ContentCheck_c;
00048           l7Check->entryData.contentCheck = contentCheck;
00049         }
00050       else
00051         {
00052           l7Check->type = Rlp_L7UriContentCheck_c;
00053           l7Check->entryData.contentCheck = contentCheck;
00054         }
00055       walkFormula = computeContentCheck (walkFormula, contentCheck);
00056       array_insert_last (Rlp_L7Check_t *, result, l7Check);
00057       break;
00058 
00059     case Rlp_Byte_Test_c:
00060     case Rlp_Byte_Jump_c:
00061       l7Check = (Rlp_L7Check_t *) malloc (sizeof (Rlp_L7Check_t));
00062       if (componentFormula->type == Rlp_Byte_Test_c)
00063         {
00064           l7Check->type = Rlp_L7ByteTestCheck_c;
00065           l7Check->entryData.byteTestCheck =
00066         (Rlp_ByteTestAttribute_t *) (componentFormula->rchild);
00067         }
00068       else
00069         {
00070           l7Check->type = Rlp_L7ByteJumpCheck_c;
00071           l7Check->entryData.byteJumpCheck =
00072         (Rlp_ByteJumpAttribute_t *) (componentFormula->rchild);
00073         }
00074       array_insert_last (Rlp_L7Check_t *, result, l7Check);
00075       walkFormula = cdr (walkFormula);
00076       break;
00077 
00078     case Rlp_Pcre_c:
00079       l7Check = (Rlp_L7Check_t *) malloc (sizeof (Rlp_L7Check_t));
00080       l7Check->type = Rlp_L7PcreCheck_c;
00081       l7Check->entryData.pcreCheck =
00082         (Rlp_PcreAttribute_t *) (componentFormula->rchild);
00083       array_insert_last (Rlp_L7Check_t *, result, l7Check);
00084       walkFormula = cdr (walkFormula);
00085       break;
00086     default:
00087       walkFormula = cdr (walkFormula);
00088       break;        // all the non content/byte checks are ignored
00089     }
00090     }
00091 
00092   return result;
00093 }
00094 
00095 
00096 /** \brief  Free an array containing content check structs */
00097 
00098 int
00099 Rlp_FreeL7CheckArray (array_t * L7CheckArray)
00100 {
00101   int i;
00102   for (i = 0; i < array_n (L7CheckArray); i++)
00103     {
00104       Rlp_L7Check_t *l7Check = array_fetch (Rlp_L7Check_t *, L7CheckArray, i);
00105       if ((l7Check->type == Rlp_L7ContentCheck_c) ||
00106       (l7Check->type == Rlp_L7UriContentCheck_c))
00107     {
00108       free (l7Check->entryData.contentCheck);
00109     }
00110       free (l7Check);
00111     }
00112   array_free (L7CheckArray);
00113   return 0;
00114 }
00115 
00116 
00117 /** \brief  Extract the content fields from an Rlp_ContentAttribute_t struct */
00118 
00119 static Rlp_Formula_t *
00120 computeContentCheck (Rlp_Formula_t * walkFormula,
00121              Rlp_ContentCheck_t * contentCheck)
00122 {
00123   Rlp_Formula_t *result = walkFormula;
00124   bool processedContent = false;
00125   bool processedUriContent = false;
00126 
00127   while (result != NIL (Rlp_Formula_t))
00128     {
00129       Rlp_Formula_t *componentFormula = car (result);
00130       switch (componentFormula->type)
00131     {
00132     case Rlp_Content_c:
00133       if ((processedContent == true) || (processedUriContent == true))
00134         {
00135           // we've finished the content or uricontent field we were working on
00136           return result;
00137         }
00138       processedContent = true;
00139 
00140       contentCheck->negated = ((Rlp_ContentAttribute_t *)
00141                    componentFormula->rchild)->negated;
00142       contentCheck->content = ((Rlp_ContentAttribute_t *)
00143                    componentFormula->rchild)->byteArray;
00144       result = cdr (result);
00145       break;
00146     case Rlp_Uricontent_c:
00147       if ((processedContent == true) || (processedUriContent == true))
00148         {
00149           // we've finished the content or uricontent field we were working on
00150           return result;
00151         }
00152       processedUriContent = true;
00153       contentCheck->negated = ((Rlp_ContentAttribute_t *)
00154                    componentFormula->rchild)->negated;
00155       contentCheck->content = ((Rlp_ContentAttribute_t *)
00156                    componentFormula->rchild)->byteArray;
00157       result = cdr (result);
00158       break;
00159     case Rlp_Depth_c:
00160       contentCheck->depth = ((Rlp_IntAttribute_t *)
00161                  (componentFormula->rchild))->intEntry;
00162       result = cdr (result);
00163       break;
00164     case Rlp_Offset_c:
00165       contentCheck->offset = ((Rlp_IntAttribute_t *)
00166                   (componentFormula->rchild))->intEntry;
00167       result = cdr (result);
00168       break;
00169     case Rlp_Within_c:
00170       contentCheck->within = ((Rlp_IntAttribute_t *)
00171                   (componentFormula->rchild))->intEntry;
00172       result = cdr (result);
00173       break;
00174     case Rlp_Distance_c:
00175       contentCheck->distance = ((Rlp_IntAttribute_t *)
00176                     (componentFormula->rchild))->intEntry;
00177       result = cdr (result);
00178       break;
00179     case Rlp_Nocase_c:
00180       contentCheck->nocase = true;
00181       result = cdr (result);
00182       break;
00183     default:
00184       assert (contentCheck->content != NIL (util_byte_array_t));
00185       return result;
00186     }
00187     }
00188   return result;
00189 }
00190 
00191 
00192 /** \brief  Return an allocated contentCheck struct - initialize 
00193 all integer entries to -1, pointers to NIL.
00194 */
00195 
00196 static Rlp_ContentCheck_t *
00197 mallocContentCheckStruct ()
00198 {
00199   Rlp_ContentCheck_t *result =
00200     (Rlp_ContentCheck_t *) malloc (sizeof (Rlp_ContentCheck_t));
00201 
00202   result->nocase = false;
00203   result->depth = -1;
00204   result->offset = -1;
00205   result->distance = -1;
00206   result->within = -1;
00207   result->content = NIL (util_byte_array_t);
00208 
00209   return result;
00210 }