00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #ifndef LOG_FILTER_H
00026 #define LOG_FILTER_H
00027 
00028 #include "libts.h"
00029 #include "IpMap.h"
00030 #include "LogAccess.h"
00031 #include "LogField.h"
00032 #include "LogFormat.h"
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 class LogFilter
00043 {
00044 public:
00045   enum Type
00046   {
00047     INT_FILTER = 0,
00048     STRING_FILTER,
00049     IP_FILTER,
00050     N_TYPES
00051   };
00052 
00053   enum Action
00054   {
00055     REJECT = 0,
00056     ACCEPT,
00057     WIPE_FIELD_VALUE,
00058     N_ACTIONS
00059   };
00060   static const char *ACTION_NAME[];
00061 
00062   
00063   
00064   
00065   
00066   enum Operator
00067   {
00068     MATCH = 0,
00069     CASE_INSENSITIVE_MATCH,
00070     CONTAIN,
00071     CASE_INSENSITIVE_CONTAIN,
00072     N_OPERATORS
00073   };
00074   static const char *OPERATOR_NAME[];
00075 
00076   LogFilter(const char *name, LogField * field, Action action, Operator oper);
00077   virtual ~LogFilter();
00078 
00079   char *name() const { return m_name; }
00080   Type type() const { return m_type; }
00081   size_t get_num_values() const { return m_num_values; };
00082 
00083   virtual bool toss_this_entry(LogAccess * lad) = 0;
00084   virtual bool wipe_this_entry(LogAccess * lad) = 0;
00085   virtual void display(FILE * fd = stdout) = 0;
00086   virtual void display_as_XML(FILE * fd = stdout) = 0;
00087 
00088   void reverse() { m_action = (m_action == REJECT ? ACCEPT : REJECT); }
00089 
00090 protected:
00091   char *m_name;
00092   LogField *m_field;
00093   Action m_action;              
00094   Operator m_operator;
00095   Type m_type;
00096   size_t m_num_values;          
00097 
00098 public:
00099   LINK(LogFilter, link);      
00100 
00101 private:
00102   
00103   LogFilter();
00104   LogFilter(const LogFilter & rhs);
00105   LogFilter & operator=(LogFilter & rhs);
00106 };
00107 
00108 
00109 
00110 
00111 
00112 
00113 class LogFilterString:public LogFilter
00114 {
00115 public:
00116   LogFilterString(const char *name, LogField * field, Action a, Operator o, char *value);
00117   LogFilterString(const char *name, LogField * field, Action a, Operator o, size_t num_values, char **value);
00118   LogFilterString(const LogFilterString & rhs);
00119   ~LogFilterString();
00120   bool operator==(LogFilterString & rhs);
00121 
00122   bool toss_this_entry(LogAccess * lad);
00123   bool wipe_this_entry(LogAccess * lad);
00124   void display(FILE * fd = stdout);
00125   void display_as_XML(FILE * fd = stdout);
00126 
00127 private:
00128   char **m_value;               
00129 
00130   
00131   
00132   char **m_value_uppercase;     
00133   size_t *m_length;             
00134 
00135   void _setValues(size_t n, char **value);
00136 
00137   
00138   
00139   typedef int (*OperatorFunction) (const char *, const char *);
00140 
00141   static int _isSubstring(const char *s0, const char *s1)
00142   {
00143     
00144     
00145     
00146     return (strstr(s0, s1) == NULL ? 1 : 0);
00147   };
00148 
00149   enum LengthCondition
00150   {
00151     DATA_LENGTH_EQUAL = 0,
00152     DATA_LENGTH_LARGER
00153   };
00154 
00155   inline bool _checkCondition(OperatorFunction f,
00156                               const char *field_value, size_t field_value_length, char **val, LengthCondition lc);
00157 
00158   inline bool _checkConditionAndWipe(OperatorFunction f, char **field_value, size_t field_value_length, char **val,
00159                                      LengthCondition lc);
00160 
00161   
00162   LogFilterString();
00163   LogFilterString & operator=(LogFilterString & rhs);
00164 };
00165 
00166 
00167 
00168 
00169 
00170 
00171 class LogFilterInt:public LogFilter
00172 {
00173 public:
00174   LogFilterInt(const char *name, LogField * field, Action a, Operator o, int64_t value);
00175     LogFilterInt(const char *name, LogField * field, Action a, Operator o, size_t num_values, int64_t *value);
00176     LogFilterInt(const char *name, LogField * field, Action a, Operator o, char *values);
00177     LogFilterInt(const LogFilterInt & rhs);
00178    ~LogFilterInt();
00179   bool operator==(LogFilterInt & rhs);
00180 
00181   bool toss_this_entry(LogAccess * lad);
00182   bool wipe_this_entry(LogAccess * lad);
00183   void display(FILE * fd = stdout);
00184   void display_as_XML(FILE * fd = stdout);
00185 
00186 private:
00187   int64_t *m_value;            
00188 
00189   void _setValues(size_t n, int64_t *value);
00190   int _convertStringToInt(char *val, int64_t *ival, LogFieldAliasMap * map);
00191 
00192   
00193   LogFilterInt();
00194   LogFilterInt & operator=(LogFilterInt & rhs);
00195 };
00196 
00197 
00198 
00199 
00200 
00201 
00202 class LogFilterIP:public LogFilter
00203 {
00204 public:
00205   LogFilterIP(const char *name, LogField * field, Action a, Operator o, IpAddr value);
00206   LogFilterIP(const char *name, LogField * field, Action a, Operator o, size_t num_values,  IpAddr* value);
00207   LogFilterIP(const char *name, LogField * field, Action a, Operator o, char *values);
00208   LogFilterIP(const LogFilterIP & rhs);
00209   ~LogFilterIP();
00210 
00211   bool operator==(LogFilterIP & rhs);
00212 
00213   virtual bool toss_this_entry(LogAccess * lad);
00214   virtual bool wipe_this_entry(LogAccess * lad);
00215   void display(FILE * fd = stdout);
00216   void display_as_XML(FILE * fd = stdout);
00217 
00218 private:
00219   IpMap m_map;
00220 
00221 
00222   void init();
00223 
00224   void displayRanges(FILE* fd);
00225   void displayRange(FILE* fd, IpMap::iterator const& iter);
00226 
00227   
00228   bool is_match(LogAccess* lad);
00229   
00230   
00231   LogFilterIP();
00232   LogFilterIP & operator=(LogFilterIP & rhs);
00233 };
00234 
00235 bool filters_are_equal(LogFilter * filt1, LogFilter * filt2);
00236 
00237 
00238 
00239 
00240 
00241 class LogFilterList
00242 {
00243 public:
00244   LogFilterList();
00245   ~LogFilterList();
00246   bool operator==(LogFilterList &);
00247 
00248   void add(LogFilter * filter, bool copy = true);
00249   bool toss_this_entry(LogAccess * lad);
00250   bool wipe_this_entry(LogAccess * lad);
00251   LogFilter *find_by_name(char *name);
00252   void clear();
00253 
00254   LogFilter *first() const { return m_filter_list.head; }
00255   LogFilter *next(LogFilter * here) const { return (here->link).next; }
00256 
00257   unsigned count();
00258   void display(FILE * fd = stdout);
00259   void display_as_XML(FILE * fd = stdout);
00260 
00261   bool does_conjunction() const { return m_does_conjunction;  };
00262   void set_conjunction(bool c) { m_does_conjunction = c;  };
00263 
00264 private:
00265   Queue<LogFilter> m_filter_list;
00266 
00267   bool m_does_conjunction;
00268   
00269   
00270   
00271   
00272   
00273   
00274 
00275   
00276   LogFilterList(const LogFilterList & rhs);
00277   LogFilterList & operator=(const LogFilterList & rhs);
00278 };
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 inline bool
00305 LogFilterString::_checkCondition(OperatorFunction f,
00306                                  const char *field_value, size_t field_value_length, char **val, LengthCondition lc)
00307 {
00308   bool retVal = false;
00309 
00310   
00311   
00312   if (m_num_values == 1) {
00313     switch (lc) {
00314     case DATA_LENGTH_EQUAL:
00315       retVal = (field_value_length == *m_length ? ((*f) (field_value, *val) == 0 ? true : false) : false);
00316       break;
00317     case DATA_LENGTH_LARGER:
00318       retVal = (field_value_length > *m_length ? ((*f) (field_value, *val) == 0 ? true : false) : false);
00319       break;
00320     default:
00321       ink_assert(!"LogFilterString::checkCondition " "unknown LengthCondition");
00322     }
00323   } else {
00324     size_t i;
00325     switch (lc) {
00326     case DATA_LENGTH_EQUAL:
00327       for (i = 0; i < m_num_values; ++i) {
00328         
00329         if (field_value_length == m_length[i] && (*f) (field_value, val[i]) == 0) {
00330           retVal = true;
00331           break;
00332         }
00333       }
00334       break;
00335     case DATA_LENGTH_LARGER:
00336       for (i = 0; i < m_num_values; ++i) {
00337         
00338         if (field_value_length > m_length[i] && (*f) (field_value, val[i]) == 0) {
00339           retVal = true;
00340           break;
00341         }
00342       }
00343       break;
00344     default:
00345       ink_assert(!"LogFilterString::checkCondition " "unknown LengthCondition");
00346     }
00347   }
00348   return retVal;
00349 }
00350 
00351 
00352 
00353 
00354 
00355 
00356 static void
00357 wipeField(char** dest, char* field)
00358 {
00359 
00360   char* buf_dest  = *dest;
00361 
00362   if (buf_dest) {
00363 
00364     char* query_param = strstr(buf_dest, "?");
00365 
00366     if (!query_param) return;
00367 
00368     char* p1 = strstr(query_param, field);
00369 
00370     if (p1) {
00371       char tmp_text[strlen(buf_dest) + 10];
00372       char *temp_text = tmp_text;
00373       memcpy(temp_text, buf_dest, (p1 - buf_dest));
00374       temp_text += (p1 - buf_dest);
00375       char* p2 = strstr(p1, "=");
00376       if (p2) {
00377         p2++;
00378         memcpy(temp_text, p1, (p2 - p1));
00379         temp_text += (p2 - p1);
00380         char* p3 = strstr(p2, "&");
00381         if (p3) {
00382           for (int i=0; i<(p3 - p2); i++)
00383             temp_text[i] = 'X';
00384           temp_text += (p3 - p2);
00385           memcpy(temp_text, p3, ((buf_dest+strlen(buf_dest)) - p3));
00386         } else {
00387           for (int i=0; i<((buf_dest+strlen(buf_dest)) - p2); i++)
00388             temp_text[i] = 'X';
00389         }
00390       } else {
00391         return;
00392       }
00393 
00394       tmp_text[strlen(buf_dest)] = '\0';
00395       strcpy(*dest, tmp_text);
00396     }
00397   }
00398 }
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 inline bool
00420 LogFilterString::_checkConditionAndWipe(OperatorFunction f, char **field_value, size_t field_value_length,
00421                                         char **val, LengthCondition lc)
00422 {
00423   bool retVal = false;
00424 
00425   if (m_action != WIPE_FIELD_VALUE) return false;
00426 
00427   
00428   
00429   if (m_num_values == 1) {
00430     switch (lc) {
00431     case DATA_LENGTH_EQUAL:
00432       retVal = (field_value_length == *m_length ? ((*f) (*field_value, *val) == 0 ? true : false) : false);
00433       if (retVal) {
00434         wipeField(field_value, *val);
00435       }
00436       break;
00437     case DATA_LENGTH_LARGER:
00438       retVal = (field_value_length > *m_length ? ((*f) (*field_value, *val) == 0 ? true : false) : false);
00439       if (retVal) {
00440         wipeField(field_value, *val);
00441       }
00442       break;
00443     default:
00444       ink_assert(!"LogFilterString::checkCondition " "unknown LengthCondition");
00445     }
00446   } else {
00447     size_t i;
00448     switch (lc) {
00449     case DATA_LENGTH_EQUAL:
00450       for (i = 0; i < m_num_values; ++i) {
00451         
00452         if (field_value_length == m_length[i] && (*f) (*field_value, val[i]) == 0) {
00453           retVal = true;
00454           wipeField(field_value, val[i]);
00455         }
00456       }
00457       break;
00458     case DATA_LENGTH_LARGER:
00459       for (i = 0; i < m_num_values; ++i) {
00460         
00461         if (field_value_length > m_length[i] && (*f) (*field_value, val[i]) == 0) {
00462           retVal = true;
00463           wipeField(field_value, val[i]);
00464         }
00465       }
00466       break;
00467     default:
00468       ink_assert(!"LogFilterString::checkConditionAndWipe " "unknown LengthConditionAndWipe");
00469     }
00470   }
00471   return retVal;
00472 }
00473 
00474 #endif