Branch data Line data Source code
1 : : // $Id: NCP.cc 6916 2009-09-24 20:48:36Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #include "config.h"
6 : :
7 : : #include <stdlib.h>
8 : : #include <string>
9 : : #include <map>
10 : :
11 : : using namespace std;
12 : :
13 : : #include "NCP.h"
14 : : #include "Sessions.h"
15 : :
16 : : #define xbyte(b, n) (((const u_char*) (b))[n])
17 : : #define extract_uint16(little_endian, bytes) \
18 : : ((little_endian) ? \
19 : : uint16(xbyte(bytes, 0)) | ((uint16(xbyte(bytes, 1))) << 8) : \
20 : : uint16(xbyte(bytes, 1)) | ((uint16(xbyte(bytes, 0))) << 8))
21 : :
22 : 0 : NCP_Session::NCP_Session(Analyzer* a)
23 : 0 : : analyzer(a)
24 : : {
25 : 0 : req_frame_type = 0;
26 : 0 : req_func = 0;
27 : 0 : }
28 : :
29 : 0 : void NCP_Session::Deliver(int is_orig, int len, const u_char* data)
30 : : {
31 : : try
32 : : {
33 : 0 : binpac::NCP::ncp_over_tcpip_frame frame(is_orig);
34 : 0 : frame.Parse(data, data + len);
35 : :
36 : 0 : DeliverFrame(frame.ncp());
37 : : }
38 : 0 : catch ( const binpac::Exception& e )
39 : : {
40 : 0 : analyzer->Weird(e.msg().c_str());
41 : : }
42 : 0 : }
43 : :
44 : 0 : void NCP_Session::DeliverFrame(const binpac::NCP::ncp_frame* frame)
45 : : {
46 [ # # ]: 0 : if ( frame->is_orig() )
47 : : {
48 : 0 : req_frame_type = frame->frame_type();
49 : 0 : req_func = frame->request()->function();
50 [ # # ]: 0 : if ( req_func == 0x57 ) // enhanced FILE_DIR services
51 : : {
52 : : req_func = (req_func << 8) |
53 : 0 : frame->request()->subfunction();
54 : : }
55 : : }
56 : :
57 [ # # ]: 0 : EventHandlerPtr f = frame->is_orig() ? ncp_request : ncp_reply;
58 [ # # ]: 0 : if ( f )
59 : : {
60 : 0 : val_list* vl = new val_list;
61 : 0 : vl->append(analyzer->BuildConnVal());
62 : 0 : vl->append(new Val(frame->frame_type(), TYPE_COUNT));
63 : 0 : vl->append(new Val(frame->body_length(), TYPE_COUNT));
64 : :
65 [ # # ]: 0 : if ( frame->is_orig() )
66 : 0 : vl->append(new Val(req_func, TYPE_COUNT));
67 : : else
68 : : {
69 : 0 : vl->append(new Val(req_frame_type, TYPE_COUNT));
70 : 0 : vl->append(new Val(req_func, TYPE_COUNT));
71 : : vl->append(new Val(frame->reply()->completion_code(),
72 : 0 : TYPE_COUNT));
73 : : }
74 : :
75 : 0 : analyzer->ConnectionEvent(f, vl);
76 : : }
77 : 0 : }
78 : :
79 : 0 : FrameBuffer::FrameBuffer(int header_length)
80 : : {
81 : 0 : hdr_len = header_length;
82 : 0 : msg_buf = 0;
83 : 0 : buf_len = 0;
84 : 0 : Reset();
85 : 0 : }
86 : :
87 : 0 : FrameBuffer::~FrameBuffer()
88 : : {
89 [ # # ][ # # ]: 0 : delete [] msg_buf;
[ # # ]
90 [ # # ][ # # ]: 0 : }
[ # # ]
91 : :
92 : 0 : void FrameBuffer::Reset()
93 : : {
94 : : // Allocate space for header.
95 [ # # ]: 0 : if ( ! msg_buf )
96 : : {
97 : 0 : buf_len = hdr_len;
98 : 0 : msg_buf = new u_char[buf_len];
99 : : }
100 : :
101 : 0 : buf_n = 0;
102 : 0 : msg_len = 0;
103 : 0 : }
104 : :
105 : : // Returns true if we have a complete frame
106 : 0 : bool FrameBuffer::Deliver(int &len, const u_char* &data)
107 : : {
108 [ # # ]: 0 : ASSERT(buf_len >= hdr_len);
109 : :
110 [ # # ]: 0 : if ( len == 0 )
111 : 0 : return false;
112 : :
113 [ # # ]: 0 : if ( buf_n < hdr_len )
114 : : {
115 [ # # ][ # # ]: 0 : while ( buf_n < hdr_len && len > 0 )
116 : : {
117 [ # # ]: 0 : ASSERT(buf_n < buf_len);
118 : 0 : msg_buf[buf_n] = *data;
119 : 0 : ++buf_n; ++data; --len;
120 : : }
121 : :
122 [ # # ]: 0 : if ( buf_n < hdr_len )
123 : 0 : return false;
124 : :
125 : 0 : compute_msg_length();
126 : :
127 [ # # ]: 0 : if ( msg_len > buf_len )
128 : : {
129 : 0 : buf_len = msg_len * 2;
130 : 0 : u_char* new_buf = new u_char[buf_len];
131 : 0 : memcpy(new_buf, msg_buf, buf_n);
132 [ # # ]: 0 : delete [] msg_buf;
133 : 0 : msg_buf = new_buf;
134 : : }
135 : : }
136 : :
137 [ # # ][ # # ]: 0 : while ( buf_n < msg_len && len > 0 )
138 : : {
139 : 0 : msg_buf[buf_n] = *data;
140 : 0 : ++buf_n; ++data; --len;
141 : : }
142 : :
143 : 0 : return buf_n >= msg_len;
144 : : }
145 : :
146 : 0 : void NCP_FrameBuffer::compute_msg_length()
147 : : {
148 : 0 : const u_char* data = Data();
149 : 0 : msg_len = 0;
150 [ # # ]: 0 : for ( int i = 0; i < 4; ++i )
151 : 0 : msg_len = (msg_len << 8) | data[4+i];
152 : 0 : }
153 : :
154 : 0 : Contents_NCP_Analyzer::Contents_NCP_Analyzer(Connection* conn, bool orig, NCP_Session* arg_session)
155 : 0 : : TCP_SupportAnalyzer(AnalyzerTag::Contents_NCP, conn, orig)
156 : : {
157 : 0 : session = arg_session;
158 : 0 : resync = true;
159 : :
160 : 0 : TCP_Analyzer* tcp = static_cast<TCP_ApplicationAnalyzer*>(Parent())->TCP();
161 [ # # # # ]: 0 : if ( tcp )
162 : : resync = (orig ? tcp->OrigState() : tcp->RespState()) !=
163 [ # # ][ # # ]: 0 : TCP_ENDPOINT_ESTABLISHED;
164 : 0 : }
165 : :
166 : 0 : Contents_NCP_Analyzer::~Contents_NCP_Analyzer()
167 : : {
168 [ # # ][ # # ]: 0 : }
[ # # ]
169 : :
170 : 0 : void Contents_NCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
171 : : {
172 : 0 : TCP_SupportAnalyzer::DeliverStream(len, data, orig);
173 : :
174 : 0 : TCP_Analyzer* tcp = static_cast<TCP_ApplicationAnalyzer*>(Parent())->TCP();
175 : :
176 [ # # # # ]: 0 : if ( tcp && tcp->HadGap(orig) )
[ # # ]
177 : 0 : return;
178 : :
179 : 0 : DEBUG_MSG("NCP deliver: len = %d resync = %d buffer.empty = %d\n",
180 : : len, resync, buffer.empty());
181 : :
182 [ # # # # ]: 0 : if ( buffer.empty() && resync )
[ # # ]
183 : : {
184 : : // Assume NCP frames align with packet boundary.
185 [ # # ][ # # ]: 0 : if ( (IsOrig() && len < 22) || (! IsOrig() && len < 16) )
[ # # ][ # # ]
[ # # ]
186 : : { // ignore small fragmeents
187 : 0 : DEBUG_MSG("NCP discard small pieces: %d\n", len);
188 : 0 : return;
189 : : }
190 : :
191 [ # # ]: 0 : int frame_type_index = IsOrig() ? 16 : 8;
192 : : int frame_type = ((int) data[frame_type_index]) << 8 |
193 : 0 : data[frame_type_index + 1];
194 : :
195 [ # # ][ # # ]: 0 : if ( frame_type != 0x1111 && frame_type != 0x2222 &&
[ # # ][ # # ]
[ # # ][ # # ]
196 : : frame_type != 0x3333 && frame_type != 0x5555 &&
197 : : frame_type != 0x7777 && frame_type != 0x9999 )
198 : : // Skip this packet
199 : 0 : return;
200 : :
201 : 0 : resync = false;
202 : : }
203 : :
204 [ # # ]: 0 : while ( buffer.Deliver(len, data) )
205 : : {
206 : 0 : session->Deliver(IsOrig(), buffer.Len(), buffer.Data());
207 : 0 : buffer.Reset();
208 : : }
209 : : }
210 : :
211 : 0 : void Contents_NCP_Analyzer::Undelivered(int seq, int len, bool orig)
212 : : {
213 : 0 : TCP_SupportAnalyzer::Undelivered(seq, len, orig);
214 : :
215 : 0 : buffer.Reset();
216 : 0 : resync = true;
217 : 0 : }
218 : :
219 : 0 : NCP_Analyzer::NCP_Analyzer(Connection* conn)
220 : 0 : : TCP_ApplicationAnalyzer(AnalyzerTag::NCP, conn)
221 : : {
222 : 0 : session = new NCP_Session(this);
223 : 0 : o_ncp = new Contents_NCP_Analyzer(conn, true, session);
224 : 0 : r_ncp = new Contents_NCP_Analyzer(conn, false, session);
225 : 0 : }
226 : :
227 : 0 : NCP_Analyzer::~NCP_Analyzer()
228 : : {
229 [ # # ][ # # ]: 0 : delete session;
[ # # ]
230 [ + - ][ + - ]: 6 : }
[ # # ][ # # ]
[ # # ]
231 : 3 :
|