Branch data Line data Source code
1 : : // $Id:$
2 : : //
3 : : // An analyzer for application-layer protocol-detection.
4 : :
5 : : #ifndef PIA_H
6 : : #define PIA_H
7 : :
8 : : #include "Analyzer.h"
9 : : #include "TCP.h"
10 : :
11 : : class RuleEndpointState;
12 : :
13 : : // Abstract PIA class providing common functionality for both TCP and UDP.
14 : : // Accepts only packet input.
15 : : //
16 : : // Note that the PIA provides our main interface to the signature engine and
17 : : // also keeps the matching state. This is because (i) it needs to match
18 : : // itself, and (ii) in case of tunnel-decapsulation we may have multiple
19 : : // PIAs and then each needs its own matching-state.
20 : : class PIA : public RuleMatcherState {
21 : : public:
22 : : PIA(Analyzer* as_analyzer);
23 : : virtual ~PIA();
24 : :
25 : : // Called when PIA wants to put an Analyzer in charge. rule is the
26 : : // signature that triggered the activitation, if any.
27 : : virtual void ActivateAnalyzer(AnalyzerTag::Tag tag,
28 : : const Rule* rule = 0) = 0;
29 : :
30 : : // Called when PIA wants to remove an Analyzer.
31 : : virtual void DeactivateAnalyzer(AnalyzerTag::Tag tag) = 0;
32 : :
33 : : void Match(Rule::PatternType type, const u_char* data, int len,
34 : : bool is_orig, bool bol, bool eol, bool clear_state);
35 : :
36 : : void ReplayPacketBuffer(Analyzer* analyzer);
37 : :
38 : : // Children are also derived from Analyzer. Return this object
39 : : // as pointer to an Analyzer.
40 : 28386 : Analyzer* AsAnalyzer() { return as_analyzer; }
41 : :
42 : 2 : static bool Available() { return true; }
43 : :
44 : : protected:
45 : : void PIA_Done();
46 : : void PIA_DeliverPacket(int len, const u_char* data, bool is_orig,
47 : : int seq, const IP_Hdr* ip, int caplen);
48 : :
49 : : enum State { INIT, BUFFERING, MATCHING_ONLY, SKIPPING } state;
50 : :
51 : : // Buffers one chunk of data. Used both for packet payload (incl.
52 : : // sequence numbers for TCP) and chunks of a reassembled stream.
53 : : struct DataBlock {
54 : : const u_char* data;
55 : : bool is_orig;
56 : : int len;
57 : : int seq;
58 : : DataBlock* next;
59 : : };
60 : :
61 : : struct Buffer {
62 : 2560 : Buffer() { head = tail = 0; size = 0; state = INIT; }
63 : :
64 : : DataBlock* head;
65 : : DataBlock* tail;
66 : : int size;
67 : : State state;
68 : : };
69 : :
70 : : void AddToBuffer(Buffer* buffer, int seq, int len,
71 : : const u_char* data, bool is_orig);
72 : : void AddToBuffer(Buffer* buffer, int len,
73 : : const u_char* data, bool is_orig);
74 : : void ClearBuffer(Buffer* buffer);
75 : :
76 : 0 : DataBlock* CurrentPacket() { return ¤t_packet; }
77 : :
78 : : void DoMatch(const u_char* data, int len, bool is_orig, bool bol,
79 : : bool eol, bool clear_state, const IP_Hdr* ip = 0);
80 : :
81 : 1622 : void SetConn(Connection* c) { conn = c; }
82 : :
83 : : Buffer pkt_buffer;
84 : :
85 : : private:
86 : : Analyzer* as_analyzer;
87 : : Connection* conn;
88 : : DataBlock current_packet;
89 : : };
90 : :
91 : : // PIA for UDP.
92 : : class PIA_UDP : public PIA, public Analyzer {
93 : : public:
94 : 684 : PIA_UDP(Connection* conn)
95 : 684 : : PIA(this), Analyzer(AnalyzerTag::PIA_UDP, conn)
96 : 684 : { SetConn(conn); }
97 [ + - ][ # # ]: 684 : virtual ~PIA_UDP() { }
98 : :
99 : 0 : static Analyzer* InstantiateAnalyzer(Connection* conn)
100 [ # # ]: 0 : { return new PIA_UDP(conn); }
101 : :
102 : : protected:
103 : 684 : virtual void Done()
104 : : {
105 : 684 : Analyzer::Done();
106 : 684 : PIA_Done();
107 : 684 : }
108 : :
109 : : virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
110 : 1683 : int seq, const IP_Hdr* ip, int caplen)
111 : : {
112 : 1683 : Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
113 : 1683 : PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen);
114 : 1683 : }
115 : :
116 : : virtual void ActivateAnalyzer(AnalyzerTag::Tag tag, const Rule* rule);
117 : : virtual void DeactivateAnalyzer(AnalyzerTag::Tag tag);
118 : : };
119 : :
120 : : // PIA for TCP. Accepts both packet and stream input (and reassembles
121 : : // packets before passing payload on to children).
122 : : class PIA_TCP : public PIA, public TCP_ApplicationAnalyzer {
123 : : public:
124 : 938 : PIA_TCP(Connection* conn)
125 : 938 : : PIA(this), TCP_ApplicationAnalyzer(AnalyzerTag::PIA_TCP, conn)
126 : 938 : { stream_mode = false; SetConn(conn); }
127 : :
128 : : virtual ~PIA_TCP();
129 : :
130 : : virtual void Init();
131 : :
132 : : // The first packet for each direction of a connection is passed
133 : : // in here.
134 : : //
135 : : // (This is a bit crude as it doesn't really fit nicely into the
136 : : // analyzer interface. Yet we need it for initializing the packet
137 : : // matcher in the case that we already get reassembled input,
138 : : // and making it part of the general analyzer interface seems
139 : : // to be unnecessary overhead.)
140 : : void FirstPacket(bool is_orig, const IP_Hdr* ip);
141 : :
142 : : void ReplayStreamBuffer(Analyzer* analyzer);
143 : :
144 : 0 : static Analyzer* InstantiateAnalyzer(Connection* conn)
145 [ # # ]: 0 : { return new PIA_TCP(conn); }
146 : :
147 : : protected:
148 : 938 : virtual void Done()
149 : : {
150 : 938 : Analyzer::Done();
151 : 938 : PIA_Done();
152 : 938 : }
153 : :
154 : : virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
155 : 0 : int seq, const IP_Hdr* ip, int caplen)
156 : : {
157 : 0 : Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
158 : 0 : PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen);
159 : 0 : }
160 : :
161 : : virtual void DeliverStream(int len, const u_char* data, bool is_orig);
162 : : virtual void Undelivered(int seq, int len, bool is_orig);
163 : :
164 : : virtual void ActivateAnalyzer(AnalyzerTag::Tag tag,
165 : : const Rule* rule = 0);
166 : : virtual void DeactivateAnalyzer(AnalyzerTag::Tag tag);
167 : :
168 : : private:
169 : : // FIXME: Not sure yet whether we need both pkt_buffer and stream_buffer.
170 : : // In any case, it's easier this way...
171 : : Buffer stream_buffer;
172 : :
173 : : bool stream_mode;
174 : : };
175 : :
176 : : #endif
|