LCOV - code coverage report
Current view: top level - src - Analyzer.h (source / functions) Hit Total Coverage
Test: app.info Lines: 30 50 60.0 %
Date: 2010-12-13 Functions: 22 39 56.4 %
Branches: 1 10 10.0 %

           Branch data     Line data    Source code
       1                 :            : // $Id:$
       2                 :            : //
       3                 :            : // Main analyzer interface.
       4                 :            : 
       5                 :            : #ifndef ANALYZER_H
       6                 :            : #define ANALYZER_H
       7                 :            : 
       8                 :            : #include <list>
       9                 :            : 
      10                 :            : #include "AnalyzerTags.h"
      11                 :            : #include "Conn.h"
      12                 :            : #include "Obj.h"
      13                 :            : 
      14                 :            : class DPM;
      15                 :            : class PIA;
      16                 :            : class Analyzer;
      17                 :            : typedef list<Analyzer*> analyzer_list;
      18                 :            : 
      19                 :            : typedef void (Analyzer::*analyzer_timer_func)(double t);
      20                 :            : 
      21                 :            : // FIXME: This is a copy of ConnectionTimer, which we may eventually be
      22                 :            : // able to get rid of.
      23                 :            : class AnalyzerTimer : public Timer {
      24                 :            : public:
      25                 :            :         AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
      26                 :      18043 :                         double arg_t, int arg_do_expire, TimerType arg_type)
      27                 :      18043 :                 : Timer(arg_t, arg_type)
      28                 :      18043 :                 { Init(arg_analyzer, arg_timer, arg_do_expire); }
      29                 :            :         virtual ~AnalyzerTimer();
      30                 :            : 
      31                 :            :         void Dispatch(double t, int is_expire);
      32                 :            : 
      33                 :            : protected:
      34                 :            :         AnalyzerTimer() {}
      35                 :            : 
      36                 :            :         void Init(Analyzer* analyzer, analyzer_timer_func timer, int do_expire);
      37                 :            : 
      38                 :            :         Analyzer* analyzer;
      39                 :            :         analyzer_timer_func timer;
      40                 :            :         int do_expire;
      41                 :            : };
      42                 :            : 
      43                 :            : 
      44                 :            : // Main analyzer interface.
      45                 :            : //
      46                 :            : // Each analyzer is part of a tree, having a parent analyzer and an
      47                 :            : // arbitrary number of child analyzers.  Each analyzer also has a list of
      48                 :            : // *suppport analyzers*.  All its input first passes through this list of
      49                 :            : // support analyzers, which can perform arbitrary preprocessing.  Support
      50                 :            : // analyzers share the same interface as regular analyzers, except that
      51                 :            : // they are unidirectional, i.e., they see only one side of a connection.
      52                 :            : //
      53                 :            : // When overiding any of these methods, always make sure to call the
      54                 :            : // base-class version first.
      55                 :            : 
      56                 :            : class SupportAnalyzer;
      57                 :            : class OutputHandler;
      58                 :            : 
      59                 :            : class Analyzer {
      60                 :            : public:
      61                 :            :         Analyzer(AnalyzerTag::Tag tag, Connection* conn);
      62                 :            :         virtual ~Analyzer();
      63                 :            : 
      64                 :            :         virtual void Init();
      65                 :            :         virtual void Done();
      66                 :            : 
      67                 :            :         // Pass data to the analyzer (it's automatically passed through its
      68                 :            :         // support analyzers first).  We have packet-wise and stream-wise
      69                 :            :         // interfaces.  For the packet-interface, some analyzers may require
      70                 :            :         // more information than others, so IP/caplen and seq may or may
      71                 :            :         // not be set.
      72                 :            :         void NextPacket(int len, const u_char* data, bool orig,
      73                 :            :                         int seq = -1, const IP_Hdr* ip = 0, int caplen = 0);
      74                 :            :         void NextStream(int len, const u_char* data, bool is_orig);
      75                 :            : 
      76                 :            :         // Used for data that can't be delivered (e.g., due to a previous
      77                 :            :         // sequence hole/gap).
      78                 :            :         void NextUndelivered(int seq, int len, bool is_orig);
      79                 :            : 
      80                 :            :         // Report message boundary. (See EndOfData() below.)
      81                 :            :         void NextEndOfData(bool orig);
      82                 :            : 
      83                 :            :         // Pass data on to all child analyzer(s).  For SupportAnalyzers (see
      84                 :            :         // below), this is overridden to pass it on to the next sibling (or
      85                 :            :         // finally to the parent, if it's the last support analyzer).
      86                 :            :         //
      87                 :            :         // If we have an associated OutputHandler (see below), the data is
      88                 :            :         // additionally passed to that, too. For SupportAnalyzers, it is *only*
      89                 :            :         // delivered to the OutputHandler.
      90                 :            :         virtual void ForwardPacket(int len, const u_char* data,
      91                 :            :                                         bool orig, int seq,
      92                 :            :                                         const IP_Hdr* ip, int caplen);
      93                 :            :         virtual void ForwardStream(int len, const u_char* data, bool orig);
      94                 :            :         virtual void ForwardUndelivered(int seq, int len, bool orig);
      95                 :            : 
      96                 :            :         // Report a message boundary to all child analyzers
      97                 :            :         virtual void ForwardEndOfData(bool orig);
      98                 :            : 
      99                 :      84747 :         AnalyzerID GetID() const        { return id; }
     100                 :     246031 :         Connection* Conn() const        { return conn; }
     101                 :            : 
     102                 :            :         // An OutputHandler can be used to get access to data extracted by this
     103                 :            :         // analyzer (i.e., all data which is passed to
     104                 :            :         // Forward{Packet,Stream,Undelivered}).  We take the ownership of
     105                 :            :         // the handler.
     106                 :        111 :         class OutputHandler {
     107                 :            :         public:
     108 [ #  # ][ #  # ]:          0 :                 virtual ~OutputHandler() { }
     109                 :            : 
     110                 :            :                 virtual void DeliverPacket(int len, const u_char* data,
     111                 :            :                                                 bool orig, int seq,
     112                 :          0 :                                                 const IP_Hdr* ip, int caplen)
     113                 :          0 :                         { }
     114                 :            :                 virtual void DeliverStream(int len, const u_char* data,
     115                 :          0 :                                                 bool orig)      { }
     116                 :          0 :                 virtual void Undelivered(int seq, int len, bool orig)   { }
     117                 :            :         };
     118                 :            : 
     119                 :      16568 :         OutputHandler* GetOutputHandler() const { return output_handler; }
     120                 :        111 :         void SetOutputHandler(OutputHandler* handler)
     121                 :        111 :                 { output_handler = handler; }
     122                 :            : 
     123                 :            :         // If an analyzer was triggered by a signature match, this returns the
     124                 :            :         // name of the signature; nil if not.
     125                 :            :         const Rule* Signature() const           { return signature; }
     126                 :          0 :         void SetSignature(const Rule* sig)      { signature = sig; }
     127                 :            : 
     128                 :          0 :         void SetSkip(bool do_skip)              { skip = do_skip; }
     129                 :      15720 :         bool Skipping() const                   { return skip; }
     130                 :            : 
     131                 :       2311 :         bool IsFinished() const                 { return finished; }
     132                 :            : 
     133                 :       7208 :         AnalyzerTag::Tag GetTag() const         { return tag; }
     134                 :            :         const char* GetTagName() const;
     135                 :            :         static AnalyzerTag::Tag GetTag(const char* tag);
     136                 :            :         static const char* GetTagName(AnalyzerTag::Tag tag);
     137                 :          0 :         static bool IsAvailable(AnalyzerTag::Tag tag)
     138                 :          0 :                 { return analyzer_configs[tag].available(); }
     139                 :            : 
     140                 :            :         // Management of the tree.
     141                 :            :         //
     142                 :            :         // We immediately discard an added analyzer if there's already a child
     143                 :            :         // of the same type.
     144                 :          0 :         void AddChildAnalyzer(Analyzer* analyzer)
     145                 :          0 :                 { AddChildAnalyzer(analyzer, true); }
     146                 :            :         Analyzer* AddChildAnalyzer(AnalyzerTag::Tag tag);
     147                 :            : 
     148                 :            :         void RemoveChildAnalyzer(Analyzer* analyzer);
     149                 :            :         void RemoveChildAnalyzer(AnalyzerID id);
     150                 :            : 
     151                 :            :         bool HasChildAnalyzer(AnalyzerTag::Tag tag);
     152                 :            : 
     153                 :            :         // Recursive; returns nil if not found.
     154                 :            :         Analyzer* FindChild(AnalyzerID id);
     155                 :            : 
     156                 :            :         // Recursive; returns first found, or nil.
     157                 :            :         Analyzer* FindChild(AnalyzerTag::Tag tag);
     158                 :            : 
     159                 :       6304 :         const analyzer_list& GetChildren()  { return children; }
     160                 :            : 
     161                 :      23310 :         Analyzer* Parent() const        { return parent; }
     162                 :          0 :         void SetParent(Analyzer* p)     { parent = p; }
     163                 :            : 
     164                 :            :         // Remove this child analyzer from the parent's list.
     165         [ #  # ]:          0 :         void Remove()   { assert(parent); parent->RemoveChildAnalyzer(this); }
     166                 :            : 
     167                 :            :         // Management of support analyzers.  Support analyzers are associated
     168                 :            :         // with a direction, and will only see data in the corresponding flow.
     169                 :            :         //
     170                 :            :         // We immediately discard an added analyzer if there's already a child
     171                 :            :         // of the same type for the same direction.
     172                 :            : 
     173                 :            :         // Adds to tail of list.
     174                 :            :         void AddSupportAnalyzer(SupportAnalyzer* analyzer);
     175                 :            : 
     176                 :            :         void RemoveSupportAnalyzer(SupportAnalyzer* analyzer);
     177                 :            : 
     178                 :            :         // These are the methods where the analyzer actually gets its input.
     179                 :            :         // Each analyzer has only to implement the schemes it supports.
     180                 :            : 
     181                 :            :         // Packet-wise (or more generally chunk-wise) input.  "data" points
     182                 :            :         // to the payload that the analyzer is supposed to examine.  If it's
     183                 :            :         // part of a full packet, "ip" points to its IP header.  An analyzer
     184                 :            :         // may or may not require to be given the full packet (and its caplen)
     185                 :            :         // as well.
     186                 :            :         virtual void DeliverPacket(int len, const u_char* data, bool orig,
     187                 :            :                                         int seq, const IP_Hdr* ip, int caplen);
     188                 :            : 
     189                 :            :         // Stream-wise payload input.
     190                 :            :         virtual void DeliverStream(int len, const u_char* data, bool orig);
     191                 :            : 
     192                 :            :         // If a parent analyzer can't turn a sequence of packets into a stream
     193                 :            :         // (e.g., due to holes), it can pass the remaining data through this
     194                 :            :         // method to the child.
     195                 :            :         virtual void Undelivered(int seq, int len, bool orig);
     196                 :            : 
     197                 :            :         // Report a message boundary.  This is a generic method that can be used
     198                 :            :         // by specific Analyzers if all data of a message has been delivered,
     199                 :            :         // e.g., to report that HTTP body has been delivered completely by the
     200                 :            :         // HTTP analyzer before it starts with the next body. EndOfData() is
     201                 :            :         // automatically generated by the analyzer's Done() method.
     202                 :            :         virtual void EndOfData(bool is_orig);
     203                 :            : 
     204                 :            :         // Occasionally we may find during analysis that we got the direction
     205                 :            :         // of the connection wrong.  In these cases, this method is called
     206                 :            :         // to swap state if necessary.  This will not happen after payload
     207                 :            :         // has already been passed on, so most analyzers don't need to care.
     208                 :            :         virtual void FlipRoles();
     209                 :            : 
     210                 :            :         // Feedback about protocol conformance, to be called by the
     211                 :            :         // analyzer's processing.  The methods raise the correspondiong
     212                 :            :         // protocol_confirmation and protocol_violation events.
     213                 :            : 
     214                 :            :         // Report that we believe we're parsing the right protocol.  This
     215                 :            :         // should be called as early as possible during a connection's
     216                 :            :         // life-time. The protocol_confirmed event is only raised once per
     217                 :            :         // analyzer, even if the method is called multiple times.
     218                 :            :         virtual void ProtocolConfirmation();
     219                 :            : 
     220                 :            :         // Report that we found a significant protocol violation which might
     221                 :            :         // indicate that the analyzed data is in fact not the expected
     222                 :            :         // protocol.  The protocol_violation event is raised once per call to
     223                 :            :         // this method so that the script-level may build up some notion of
     224                 :            :         // how "severely" protocol semantics are violated.
     225                 :            :         virtual void ProtocolViolation(const char* reason,
     226                 :            :                                         const char* data = 0, int len = 0);
     227                 :            : 
     228                 :            :         // Returns true if the analyzer or one of its children is rewriting
     229                 :            :         // the trace.
     230                 :            :         virtual int RewritingTrace();
     231                 :            : 
     232                 :            :         virtual unsigned int MemoryAllocation() const;
     233                 :            : 
     234                 :            :         // The following methods are proxies: calls are directly forwarded
     235                 :            :         // to the connection instance.  These are for convenience only,
     236                 :            :         // allowing us to reuse more of the old analyzer code unchanged.
     237                 :      12038 :         RecordVal* BuildConnVal()
     238                 :      12038 :                 { return conn->BuildConnVal(); }
     239                 :       3960 :         void Event(EventHandlerPtr f, const char* name = 0)
     240                 :       3960 :                 { conn->Event(f, this, name); }
     241                 :          0 :         void Event(EventHandlerPtr f, Val* v1, Val* v2 = 0)
     242                 :          0 :                 { conn->Event(f, this, v1, v2); }
     243                 :      11764 :         void ConnectionEvent(EventHandlerPtr f, val_list* vl)
     244                 :      11764 :                 { conn->ConnectionEvent(f, this, vl); }
     245                 :        433 :         void Weird(const char* name)    { conn->Weird(name); }
     246                 :          0 :         void Weird(const char* name, const char* addl)
     247                 :          0 :                 { conn->Weird(name, addl); }
     248                 :          0 :         void Weird(const char* name, int addl_len, const char* addl)
     249                 :          0 :                 { conn->Weird(name, addl_len, addl); };
     250                 :            : 
     251                 :            :         // Factory function to instantiate new analyzers.
     252                 :            :         static Analyzer* InstantiateAnalyzer(AnalyzerTag::Tag tag, Connection* c);
     253                 :            : 
     254                 :            : protected:
     255                 :            :         friend class DPM;
     256                 :            :         friend class Connection;
     257                 :            :         friend class AnalyzerTimer;
     258                 :            :         friend class TCP_ApplicationAnalyzer;
     259                 :            : 
     260                 :            :         Analyzer()      { }
     261                 :            : 
     262                 :            :         // Associates a connection with this analyzer.  Must be called if
     263                 :            :         // we're using the default ctor.
     264                 :            :         void SetConnection(Connection* c)       { conn = c; }
     265                 :            : 
     266                 :            :         // Creates the given timer to expire at time t.  If do_expire
     267                 :            :         // is true, then the timer is also evaluated when Bro terminates,
     268                 :            :         // otherwise not.
     269                 :            :         void AddTimer(analyzer_timer_func timer, double t, int do_expire,
     270                 :            :                         TimerType type);
     271                 :            : 
     272                 :            :         void RemoveTimer(Timer* t);
     273                 :            :         void CancelTimers();
     274                 :            : 
     275                 :            :         bool HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig);
     276                 :            : 
     277                 :            :         void AddChildAnalyzer(Analyzer* analyzer, bool init);
     278                 :            :         void InitChildren();
     279                 :            :         void AppendNewChildren();
     280                 :            : 
     281                 :            : private:
     282                 :            :         AnalyzerTag::Tag tag;
     283                 :            :         AnalyzerID id;
     284                 :            : 
     285                 :            :         Connection* conn;
     286                 :            :         Analyzer* parent;
     287                 :            :         const Rule* signature;
     288                 :            :         OutputHandler* output_handler;
     289                 :            : 
     290                 :            :         analyzer_list children;
     291                 :            :         SupportAnalyzer* orig_supporters;
     292                 :            :         SupportAnalyzer* resp_supporters;
     293                 :            : 
     294                 :            :         analyzer_list new_children;
     295                 :            : 
     296                 :            :         bool protocol_confirmed;
     297                 :            : 
     298                 :            :         timer_list timers;
     299                 :            :         bool timers_canceled;
     300                 :            :         bool skip;
     301                 :            :         bool finished;
     302                 :            : 
     303                 :            :         static AnalyzerID id_counter;
     304                 :            : 
     305                 :            :         typedef bool (*available_callback)();
     306                 :            :         typedef Analyzer* (*factory_callback)(Connection* conn);
     307                 :            :         typedef bool (*match_callback)(Connection*);
     308                 :            : 
     309                 :            :         struct Config {
     310                 :            :                 AnalyzerTag::Tag tag;
     311                 :            :                 const char* name;
     312                 :            :                 factory_callback factory;
     313                 :            :                 available_callback available;
     314                 :            :                 match_callback match;
     315                 :            :                 bool partial;
     316                 :            :         };
     317                 :            : 
     318                 :            :         // Table of analyzers.
     319                 :            :         static const Config analyzer_configs[];
     320                 :            : 
     321                 :            : };
     322                 :            : 
     323                 :            : #define ADD_ANALYZER_TIMER(timer, t, do_expire, type) \
     324                 :            :         AddTimer(analyzer_timer_func(timer), (t), (do_expire), (type))
     325                 :            : 
     326                 :            : #define LOOP_OVER_CHILDREN(var) \
     327                 :            :         for ( analyzer_list::iterator var = children.begin(); \
     328                 :            :               var != children.end(); var++ )
     329                 :            : 
     330                 :            : #define LOOP_OVER_CONST_CHILDREN(var) \
     331                 :            :         for ( analyzer_list::const_iterator var = children.begin(); \
     332                 :            :               var != children.end(); var++ )
     333                 :            : 
     334                 :            : #define LOOP_OVER_GIVEN_CHILDREN(var, the_kids) \
     335                 :            :         for ( analyzer_list::iterator var = the_kids.begin(); \
     336                 :            :               var != the_kids.end(); var++ )
     337                 :            : 
     338                 :            : class SupportAnalyzer : public Analyzer {
     339                 :            : public:
     340                 :       1497 :         SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig)
     341                 :       1497 :                 : Analyzer(tag, conn)   { orig = arg_orig; sibling = 0; }
     342                 :            : 
     343 [ -  + ][ #  # ]:       1497 :         virtual ~SupportAnalyzer() {}
     344                 :            : 
     345                 :      19500 :         bool IsOrig() const     { return orig; }
     346                 :            : 
     347                 :            :         virtual void ForwardPacket(int len, const u_char* data, bool orig,
     348                 :            :                                         int seq, const IP_Hdr* ip, int caplen);
     349                 :            :         virtual void ForwardStream(int len, const u_char* data, bool orig);
     350                 :            :         virtual void ForwardUndelivered(int seq, int len, bool orig);
     351                 :            : 
     352                 :       3065 :         SupportAnalyzer* Sibling() const        { return sibling; }
     353                 :            : 
     354                 :            : protected:
     355                 :            :         friend class Analyzer;
     356                 :            : 
     357                 :            :         SupportAnalyzer()       { }
     358                 :            : private:
     359                 :            :         bool orig;
     360                 :            : 
     361                 :            :         // Points to next support analyzer in chain.  The list is managed by
     362                 :            :         // parent analyzer.
     363                 :            :         SupportAnalyzer* sibling;
     364                 :            : };
     365                 :            : 
     366                 :            : 
     367                 :            : class TransportLayerAnalyzer : public Analyzer {
     368                 :            : public:
     369                 :       1627 :         TransportLayerAnalyzer(AnalyzerTag::Tag tag, Connection* conn)
     370                 :       1627 :                 : Analyzer(tag, conn)   { pia = 0; rewriter = 0; }
     371                 :            : 
     372                 :            :         virtual ~TransportLayerAnalyzer();
     373                 :            : 
     374                 :            :         virtual void Done();
     375                 :            :         virtual void UpdateEndpointVal(RecordVal* endp, int is_orig) = 0;
     376                 :            :         virtual bool IsReuse(double t, const u_char* pkt) = 0;
     377                 :            : 
     378                 :            :         virtual void SetContentsFile(unsigned int direction, BroFile* f);
     379                 :            :         virtual BroFile* GetContentsFile(unsigned int direction) const;
     380                 :            : 
     381                 :        938 :         void SetPIA(PIA* arg_PIA)       { pia = arg_PIA; }
     382                 :          0 :         PIA* GetPIA() const             { return pia; }
     383                 :            : 
     384                 :      21236 :         Rewriter* TraceRewriter()       { return rewriter; }
     385                 :            : 
     386                 :            :         // Takes ownership.
     387                 :            :         void SetTraceRewriter(Rewriter* r);
     388                 :            : 
     389                 :            :         // Raises packet_contents event.
     390                 :            :         void PacketContents(const u_char* data, int len);
     391                 :            : 
     392                 :            : protected:
     393                 :            :         TransportLayerAnalyzer()        { }
     394                 :            : 
     395                 :            : private:
     396                 :            :         PIA* pia;
     397                 :            :         Rewriter* rewriter;
     398                 :            : };
     399                 :            : 
     400                 :            : #endif

Generated by: LCOV version 1.8