"Fossies" - the Fresh Open Source Software Archive 
Member "snort-2.9.17/src/dynamic-preprocessors/dcerpc2/snort_dce2.c" (16 Oct 2020, 42570 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "snort_dce2.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.9.16.1_vs_2.9.17.
1 /****************************************************************************
2 * Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
3 * Copyright (C) 2008-2013 Sourcefire, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License Version 2 as
7 * published by the Free Software Foundation. You may not use, modify or
8 * distribute this program under any other version of the GNU General
9 * Public License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 ****************************************************************************
21 *
22 ****************************************************************************/
23
24 #include <daq.h>
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "sf_types.h"
30 #include "snort_dce2.h"
31 #include "spp_dce2.h"
32 #include "dce2_config.h"
33 #include "dce2_utils.h"
34 #include "dce2_list.h"
35 #include "dce2_stats.h"
36 #include "dce2_session.h"
37 #include "dce2_event.h"
38 #include "dce2_smb.h"
39 #include "dce2_udp.h"
40 #include "dce2_tcp.h"
41 #include "dce2_http.h"
42 #include "dce2_co.h"
43 #include "dce2_cl.h"
44 #include "dce2_memory.h"
45 #include "sf_dynamic_preprocessor.h"
46 #include "stream_api.h"
47 #include "sfrt.h"
48 #include "profiler.h"
49 #include "sfPolicy.h"
50 #include "sf_seqnums.h"
51
52 /********************************************************************
53 * Global variables
54 ********************************************************************/
55 DCE2_CStack *dce2_pkt_stack = NULL;
56 DCE2_ProtoIds dce2_proto_ids;
57
58 static SFSnortPacket* dce2_rpkt[DCE2_RPKT_TYPE__MAX] = {
59 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
60 };
61
62 #ifdef SNORT_RELOAD
63 APPDATA_ADJUSTER *ada;
64 #endif
65
66 static int dce2_detected = 0;
67
68 // Used to indicate that a session is no longer being looked at
69 // It will be the session data that is returned so a pointer check
70 // is sufficient to tell if the preprocessor shouldn't look at the session.
71 uint8_t dce2_no_inspect;
72
73 /********************************************************************
74 * Macros
75 ********************************************************************/
76 #define DCE2_PKT_STACK__SIZE 10
77
78 /********************************************************************
79 * Private function prototypes
80 ********************************************************************/
81 static DCE2_SsnData * DCE2_NewSession(SFSnortPacket *, tSfPolicyId);
82 static DCE2_TransType DCE2_GetTransport(SFSnortPacket *, const DCE2_ServerConfig *, int *);
83 static DCE2_TransType DCE2_GetDetectTransport(SFSnortPacket *, const DCE2_ServerConfig *);
84 static DCE2_TransType DCE2_GetAutodetectTransport(SFSnortPacket *, const DCE2_ServerConfig *);
85 static DCE2_Ret DCE2_SetSsnState(DCE2_SsnData *, SFSnortPacket *);
86 static void DCE2_SsnFree(void *);
87
88 /*********************************************************************
89 * Function:
90 *
91 * Purpose:
92 *
93 * Arguments:
94 *
95 * Returns:
96 *
97 *********************************************************************/
98 static DCE2_SsnData * DCE2_NewSession(SFSnortPacket *p, tSfPolicyId policy_id)
99 {
100 DCE2_SsnData *sd = NULL;
101 DCE2_TransType trans;
102 const DCE2_ServerConfig *sc = DCE2_ScGetConfig(p);
103 int autodetected = 0;
104 PROFILE_VARS;
105
106 PREPROC_PROFILE_START(dce2_pstat_new_session);
107
108 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Creating new session: "));
109 trans = DCE2_GetTransport(p, sc, &autodetected);
110 switch (trans)
111 {
112 case DCE2_TRANS_TYPE__SMB:
113 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "SMB transport ... "));
114 sd = (DCE2_SsnData *)DCE2_SmbSsnInit(p);
115 break;
116
117 case DCE2_TRANS_TYPE__TCP:
118 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "TCP transport ... "));
119 sd = (DCE2_SsnData *)DCE2_TcpSsnInit();
120 break;
121
122 case DCE2_TRANS_TYPE__UDP:
123 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "UDP transport ... "));
124 sd = (DCE2_SsnData *)DCE2_UdpSsnInit();
125 break;
126
127 case DCE2_TRANS_TYPE__HTTP_PROXY:
128 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "RPC over HTTP proxy transport ... "));
129 sd = (DCE2_SsnData *)DCE2_HttpProxySsnInit();
130 break;
131
132 case DCE2_TRANS_TYPE__HTTP_SERVER:
133 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "RPC over HTTP server transport ... "));
134 sd = (DCE2_SsnData *)DCE2_HttpServerSsnInit();
135 break;
136
137 case DCE2_TRANS_TYPE__NONE:
138 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Not configured to "
139 "look at this traffic or unable to autodetect - not inspecting.\n"));
140 PREPROC_PROFILE_END(dce2_pstat_new_session);
141 return NULL;
142
143 default:
144 DCE2_Log(DCE2_LOG_TYPE__ERROR,
145 "%s(%d) Invalid transport type: %d",
146 __FILE__, __LINE__, trans);
147 PREPROC_PROFILE_END(dce2_pstat_new_session);
148 return NULL;
149 }
150
151 if (sd == NULL)
152 {
153 PREPROC_PROFILE_END(dce2_pstat_new_session);
154 return NULL;
155 }
156
157 DCE2_SsnSetAppData(p, (void *)sd, DCE2_SsnFree);
158 #ifdef SNORT_RELOAD
159 ada_add( ada, (void *) sd, p->stream_session );
160 #endif
161
162 dce2_stats.sessions++;
163 dce2_stats.sessions_active++;
164 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Created (%p)\n", (void *)sd));
165
166 sd->trans = trans;
167 sd->server_policy = DCE2_ScPolicy(sc);
168 sd->client_policy = DCE2_POLICY__WINXP; // Default to Windows XP
169 sd->sconfig = sc;
170 sd->wire_pkt = p;
171
172 sd->policy_id = policy_id;
173 sd->config = dce2_config;
174 ((DCE2_Config *)sfPolicyUserDataGet(sd->config, policy_id))->ref_count++;
175
176 if (autodetected)
177 {
178 dce2_stats.sessions_autodetected++;
179
180 #ifdef DEBUG
181 if (DCE2_SsnFromServer(p))
182 dce2_stats.autoports[p->src_port][trans]++;
183 else
184 dce2_stats.autoports[p->dst_port][trans]++;
185 #endif
186
187 DCE2_SsnSetAutodetected(sd, p);
188 }
189
190 /* If we've determined a transport, make sure we're doing
191 * reassembly on the session */
192 if (IsTCP(p))
193 {
194 int rs_dir = DCE2_SsnGetReassembly(p);
195
196 if (!_dpd.isPafEnabled() && (rs_dir != SSN_DIR_BOTH))
197 {
198 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN,
199 "Setting client/server reassembly to FOOTPRINT for this session.\n"));
200 DCE2_SsnSetReassembly(p);
201 }
202
203 if (!DCE2_SsnIsRebuilt(p))
204 {
205 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-rebuilt packet\n"));
206
207 if (DCE2_SsnIsStreamInsert(p))
208 {
209 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Stream inserted - not inspecting.\n"));
210 PREPROC_PROFILE_END(dce2_pstat_new_session);
211 return NULL;
212 }
213 else if ((DCE2_SsnFromClient(p) && (rs_dir == SSN_DIR_FROM_SERVER))
214 || (DCE2_SsnFromServer(p) && (rs_dir == SSN_DIR_FROM_CLIENT))
215 || (rs_dir == SSN_DIR_BOTH))
216 {
217 /* Reassembly was already set for this session, but stream
218 * decided not to use the packet so it's probably not good */
219 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-stream inserted packet - not inspecting\n"));
220 PREPROC_PROFILE_END(dce2_pstat_new_session);
221 return NULL;
222 }
223 }
224 }
225
226 PREPROC_PROFILE_END(dce2_pstat_new_session);
227 return sd;
228 }
229
230 /*********************************************************************
231 * Function: DCE2_Process()
232 *
233 * Purpose: Main entry point for DCE/RPC processing.
234 *
235 * Arguments:
236 * SFSnortPacket * - pointer to packet structure
237 *
238 * Returns:
239 * DCE2_Ret - status
240 *
241 *********************************************************************/
242 DCE2_Ret DCE2_Process(SFSnortPacket *p)
243 {
244 tSfPolicyId policy_id = _dpd.getNapRuntimePolicy();
245 DCE2_SsnData *sd = (DCE2_SsnData *)DCE2_SsnGetAppData(p);
246 PROFILE_VARS;
247
248 PREPROC_PROFILE_START(dce2_pstat_session);
249
250 if ((sd != NULL) && DCE2_SsnNoInspect(sd))
251 {
252 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Session set to "
253 "not inspect. Returning\n"));
254 PREPROC_PROFILE_END(dce2_pstat_session);
255 return DCE2_RET__NOT_INSPECTED;
256 }
257
258 dce2_eval_config = (DCE2_Config *)sfPolicyUserDataGet(dce2_config, policy_id);
259 if (sd != NULL)
260 dce2_eval_config = (DCE2_Config *)sfPolicyUserDataGet(sd->config, sd->policy_id);
261
262 if (dce2_eval_config == NULL)
263 {
264 PREPROC_PROFILE_END(dce2_pstat_session);
265 return DCE2_RET__NOT_INSPECTED;
266 }
267
268 if (sd == NULL)
269 {
270 sd = DCE2_NewSession(p, policy_id);
271 if (sd == NULL)
272 {
273 PREPROC_PROFILE_END(dce2_pstat_session);
274 return DCE2_RET__NOT_INSPECTED;
275 }
276 }
277 else
278 {
279 sd->wire_pkt = p;
280
281 if (_dpd.isPafEnabled() && !DCE2_SsnIsPafActive(p))
282 {
283 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "PAF was aborted on "
284 "one or both sides - aborting session inspection\n"));
285 DCE2_SetNoInspect(sd);
286 PREPROC_PROFILE_END(dce2_pstat_session);
287 return DCE2_RET__NOT_INSPECTED;
288 }
289
290 if (IsTCP(p) && !DCE2_SsnIsRebuilt(p))
291 {
292 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-rebuilt packet "
293 "on session (%p)\n", (void *)sd));
294
295 if (DCE2_SsnIsStreamInsert(p))
296 {
297 if (!_dpd.isPafEnabled())
298 {
299 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Flushing opposite direction.\n"));
300 DCE2_SsnFlush(p);
301 }
302
303 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Stream inserted - not inspecting.\n"));
304 }
305 else
306 {
307 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-stream inserted packet "
308 "- not inspecting\n"));
309 }
310
311 PREPROC_PROFILE_END(dce2_pstat_session);
312 return DCE2_RET__NOT_INSPECTED;
313 }
314 else if (DCE2_SsnAutodetected(sd) && !(p->flags & sd->autodetect_dir))
315 {
316 /* Try to autodetect in opposite direction */
317 if ((sd->trans != DCE2_TRANS_TYPE__HTTP_PROXY) &&
318 (sd->trans != DCE2_TRANS_TYPE__HTTP_SERVER) &&
319 (DCE2_GetAutodetectTransport(p, sd->sconfig) != sd->trans))
320 {
321 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Bad autodetect.\n"));
322
323 DCE2_SetNoInspect(sd);
324 dce2_stats.bad_autodetects++;
325
326 PREPROC_PROFILE_END(dce2_pstat_session);
327 return DCE2_RET__NOT_INSPECTED;
328 }
329
330 DCE2_SsnClearAutodetected(sd);
331 }
332 }
333
334 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Session pointer: %p\n", (void *)sd));
335
336 if (IsTCP(p) && (DCE2_SetSsnState(sd, p) != DCE2_RET__SUCCESS))
337 {
338 PREPROC_PROFILE_END(dce2_pstat_session);
339 return DCE2_RET__NOT_INSPECTED;
340 }
341
342 if (DCE2_PushPkt((void *)p) != DCE2_RET__SUCCESS)
343 {
344 DCE2_Log(DCE2_LOG_TYPE__ERROR,
345 "%s(%d) Failed to push packet onto packet stack.",
346 __FILE__, __LINE__);
347 PREPROC_PROFILE_END(dce2_pstat_session);
348 return DCE2_RET__NOT_INSPECTED;
349 }
350
351 p->flags |= FLAG_ALLOW_MULTIPLE_DETECT;
352 dce2_detected = 0;
353
354 PREPROC_PROFILE_END(dce2_pstat_session);
355
356 switch (sd->trans)
357 {
358 case DCE2_TRANS_TYPE__SMB:
359 DCE2_SmbProcess((DCE2_SmbSsnData *)sd);
360 break;
361 case DCE2_TRANS_TYPE__TCP:
362 DCE2_TcpProcess((DCE2_TcpSsnData *)sd);
363 break;
364 case DCE2_TRANS_TYPE__UDP:
365 DCE2_UdpProcess((DCE2_UdpSsnData *)sd);
366 break;
367 case DCE2_TRANS_TYPE__HTTP_PROXY:
368 DCE2_HttpProcessProxy((DCE2_HttpSsnData *)sd);
369 break;
370 case DCE2_TRANS_TYPE__HTTP_SERVER:
371 DCE2_HttpProcessServer((DCE2_HttpSsnData *)sd);
372 break;
373 default:
374 DCE2_Log(DCE2_LOG_TYPE__ERROR,
375 "%s(%d) Invalid transport type: %d",
376 __FILE__, __LINE__, sd->trans);
377 return DCE2_RET__NOT_INSPECTED;
378 }
379
380 if (sd->flags & DCE2_SSN_FLAG__NO_INSPECT)
381 {
382 DCE2_SetNoInspect(sd);
383 DCE2_PopPkt();
384 PREPROC_PROFILE_END(dce2_pstat_session);
385 return DCE2_RET__NOT_INSPECTED;
386 }
387
388 if (!dce2_detected)
389 DCE2_Detect(sd);
390
391 DCE2_ResetRopts(&sd->ropts);
392 DCE2_PopPkt();
393
394 if (dce2_mem_state == DCE2_MEM_STATE__MEMCAP)
395 {
396 DCE2_SetNoInspect(sd);
397 dce2_mem_state = DCE2_MEM_STATE__OKAY;
398 return DCE2_RET__NOT_INSPECTED;
399 }
400
401 if (DCE2_SsnAutodetected(sd))
402 return DCE2_RET__NOT_INSPECTED;
403
404 return DCE2_RET__INSPECTED;
405 }
406
407 /********************************************************************
408 * Function:
409 *
410 * Purpose:
411 *
412 * Arguments:
413 *
414 * Returns:
415 *
416 ********************************************************************/
417 void DCE2_SetNoInspect(DCE2_SsnData *sd)
418 {
419 if (sd == NULL)
420 return;
421
422 dce2_stats.sessions_aborted++;
423 DCE2_SsnSetNoInspect(sd->wire_pkt);
424 }
425
426 /********************************************************************
427 * Function: DCE2_SetSsnState()
428 *
429 * Purpose:
430 * Checks for missing packets and overlapping data on session
431 *
432 * Arguments:
433 * DCE2_SsnData * - session data pointer
434 * SFSnortPacket * - packet structure
435 *
436 * Returns:
437 * DCE2_RET__SUCCESS
438 * DCE2_RET__ERROR
439 *
440 ********************************************************************/
441 static DCE2_Ret DCE2_SetSsnState(DCE2_SsnData *sd, SFSnortPacket *p)
442 {
443 uint32_t pkt_seq = ntohl(p->tcp_header->sequence);
444 PROFILE_VARS;
445
446 PREPROC_PROFILE_START(dce2_pstat_session_state);
447
448 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Payload size: %u\n", p->payload_size));
449
450 if (DCE2_SsnFromClient(p) && !DCE2_SsnSeenClient(sd))
451 {
452 uint32_t pkt_ack = ntohl(p->tcp_header->acknowledgement);
453
454 if (DCE2_SsnSeenServer(sd) && SEQ_LT(sd->cli_seq, pkt_seq)
455 && (sd->trans != DCE2_TRANS_TYPE__HTTP_SERVER))
456 {
457 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN,
458 "Missing packets on session - aborting session inspection\n"));
459 DCE2_SetNoInspect(sd);
460 PREPROC_PROFILE_END(dce2_pstat_session_state);
461 return DCE2_RET__ERROR;
462 }
463
464 DCE2_SsnSetSeenClient(sd);
465 sd->cli_seq = pkt_seq;
466 sd->cli_nseq = pkt_seq + p->payload_size;
467
468 if (!DCE2_SsnSeenServer(sd))
469 sd->srv_seq = sd->srv_nseq = pkt_ack;
470
471 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Initial client => seq: %u, "
472 "next seq: %u\n", sd->cli_seq, sd->cli_nseq));
473 }
474 else if (DCE2_SsnFromServer(p) && !DCE2_SsnSeenServer(sd))
475 {
476 uint32_t pkt_ack = ntohl(p->tcp_header->acknowledgement);
477
478 if ((DCE2_SsnSeenClient(sd) && SEQ_LT(sd->srv_seq, pkt_seq))
479 || (!DCE2_SsnSeenClient(sd) && (sd->trans != DCE2_TRANS_TYPE__HTTP_SERVER)))
480 {
481 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN,
482 "Missing packets on session - aborting session inspection\n"));
483 PREPROC_PROFILE_END(dce2_pstat_session_state);
484 DCE2_SetNoInspect(sd);
485 return DCE2_RET__ERROR;
486 }
487
488 DCE2_SsnSetSeenServer(sd);
489 sd->srv_seq = pkt_seq;
490 sd->srv_nseq = pkt_seq + p->payload_size;
491
492 if (!DCE2_SsnSeenClient(sd))
493 sd->cli_seq = sd->cli_nseq = pkt_ack;
494
495 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Initial server => seq: %u, "
496 "next seq: %u\n", sd->srv_seq, sd->srv_nseq));
497 }
498 else
499 {
500 uint32_t *ssn_seq;
501 uint32_t *ssn_nseq;
502
503 if (DCE2_SsnFromClient(p))
504 {
505 ssn_seq = &sd->cli_seq;
506 ssn_nseq = &sd->cli_nseq;
507
508 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Client last => seq: %u, "
509 "next seq: %u\n", sd->cli_seq, sd->cli_nseq));
510 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "This packet => seq: %u, "
511 "next seq: %u\n", pkt_seq, pkt_seq + p->payload_size));
512 }
513 else
514 {
515 ssn_seq = &sd->srv_seq;
516 ssn_nseq = &sd->srv_nseq;
517
518 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Server last => seq: %u, "
519 "next seq: %u\n", sd->srv_seq, sd->srv_nseq));
520 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "This packet => seq: %u, "
521 "next seq: %u\n", pkt_seq, pkt_seq + p->payload_size));
522 }
523
524 if (*ssn_nseq != pkt_seq)
525 {
526 if (SEQ_LT(*ssn_nseq, pkt_seq))
527 {
528 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Next expected sequence number (%u) is less than "
529 "this sequence number (%u).\n", *ssn_nseq, pkt_seq));
530 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN,
531 "Missing packets on session - aborting session inspection\n"));
532
533 DCE2_SetNoInspect(sd);
534 PREPROC_PROFILE_END(dce2_pstat_session_state);
535 return DCE2_RET__ERROR;
536 }
537 else
538 {
539 /* Got some kind of overlap. This shouldn't happen since we're doing
540 * reassembly on both sides and not looking at non-reassembled packets
541 * Actually this can happen if the stream seg list is empty */
542 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Overlap => seq: %u, "
543 "next seq: %u - aborting session inspection\n",
544 pkt_seq, pkt_seq + p->payload_size));
545
546 DCE2_SetNoInspect(sd);
547 PREPROC_PROFILE_END(dce2_pstat_session_state);
548 return DCE2_RET__ERROR;
549 }
550 }
551
552 *ssn_seq = pkt_seq;
553 *ssn_nseq = pkt_seq + p->payload_size;
554 }
555
556 PREPROC_PROFILE_END(dce2_pstat_session_state);
557 return DCE2_RET__SUCCESS;
558 }
559
560 /*********************************************************************
561 * Function: DCE2_GetTransport()
562 *
563 * Determines whether or not we should look at this traffic and if
564 * so, what transport it should be classified as.
565 *
566 * Arguments:
567 * SFSnortPacket *
568 * Pointer to packet structure.
569 * const DCE2_ServerConfig *
570 * The server configuration associated with the packet's IP.
571 * int *
572 * Pointer to a value that will be filled in with whether
573 * or not the packet was autodetected.
574 * Non-zero if autodetected
575 * Zero if not autodetected
576 *
577 * Returns:
578 * DCE2_TransType
579 * DCE2_TRANS_TYPE__NONE if a transport could not be
580 * determined or target based labeled the session as
581 * traffic we are not interested in.
582 * DCE2_TRANS_TYPE__SMB if the traffic is determined to be
583 * DCE/RPC over SMB.
584 * DCE2_TRANS_TYPE__TCP if the traffic is determined to be
585 * DCE/RPC over TCP.
586 * DCE2_TRANS_TYPE__UDP if the traffic is determined to be
587 * DCE/RPC over UDP.
588 * DCE2_TRANS_TYPE__HTTP_PROXY if the traffic is determined
589 * to be DCE/RPC over HTTP proxy.
590 * DCE2_TRANS_TYPE__HTTP_SERVER if the traffic is determined
591 * to be DCE/RPC over HTTP server.
592 *
593 *********************************************************************/
594 static DCE2_TransType DCE2_GetTransport(SFSnortPacket *p, const DCE2_ServerConfig *sc, int *autodetected)
595 {
596 DCE2_TransType trans = DCE2_TRANS_TYPE__NONE;
597 #ifdef TARGET_BASED
598 int16_t proto_id = 0;
599 #endif
600
601 *autodetected = 0;
602
603 #ifdef TARGET_BASED
604 if (_dpd.isAdaptiveConfigured())
605 {
606 proto_id = _dpd.sessionAPI->get_application_protocol_id(p->stream_session);
607
608 if (proto_id == SFTARGET_UNKNOWN_PROTOCOL)
609 return DCE2_TRANS_TYPE__NONE;
610 }
611
612 if (proto_id != 0)
613 {
614 if (proto_id == dce2_proto_ids.dcerpc)
615 {
616 if (IsTCP(p))
617 {
618 return DCE2_TRANS_TYPE__TCP;
619 }
620 else
621 {
622 return DCE2_TRANS_TYPE__UDP;
623 }
624 }
625 else if (proto_id == dce2_proto_ids.nbss)
626 {
627 return DCE2_TRANS_TYPE__SMB;
628 }
629 }
630 else
631 #endif
632 {
633 trans = DCE2_GetDetectTransport(p, sc);
634 if (trans == DCE2_TRANS_TYPE__NONE)
635 {
636 trans = DCE2_GetAutodetectTransport(p, sc);
637 *autodetected = 1;
638 }
639 else if ((trans == DCE2_TRANS_TYPE__HTTP_PROXY) &&
640 (DCE2_ScAutodetectHttpProxyPorts(sc) == DCE2_CS__ENABLED))
641 {
642 trans = DCE2_HttpAutodetectProxy(p);
643 *autodetected = 1;
644 }
645 }
646
647 return trans;
648 }
649
650 /*********************************************************************
651 * Function:
652 *
653 * Purpose:
654 *
655 * Arguments:
656 *
657 * Returns:
658 *
659 *********************************************************************/
660 static DCE2_TransType DCE2_GetDetectTransport(SFSnortPacket *p, const DCE2_ServerConfig *sc)
661 {
662 DCE2_TransType trans = DCE2_TRANS_TYPE__NONE;
663 uint16_t port;
664
665 if (DCE2_SsnFromServer(p))
666 port = p->src_port;
667 else
668 port = p->dst_port;
669
670 /* Check our configured ports to see if we should continue processing */
671 if (IsTCP(p))
672 {
673 if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__SMB))
674 trans = DCE2_TRANS_TYPE__SMB;
675 else if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__TCP))
676 trans = DCE2_TRANS_TYPE__TCP;
677 else if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__HTTP_PROXY))
678 trans = DCE2_TRANS_TYPE__HTTP_PROXY;
679 else if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__HTTP_SERVER))
680 trans = DCE2_TRANS_TYPE__HTTP_SERVER;
681 }
682 else /* it's UDP */
683 {
684 if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__UDP))
685 trans = DCE2_TRANS_TYPE__UDP;
686 }
687
688 return trans;
689 }
690
691 /*********************************************************************
692 * Function: DCE2_GetAutodetectTransport()
693 *
694 *
695 * Arguments:
696 *
697 * Returns:
698 *
699 *********************************************************************/
700 static DCE2_TransType DCE2_GetAutodetectTransport(SFSnortPacket *p, const DCE2_ServerConfig *sc)
701 {
702 DCE2_TransType trans = DCE2_TRANS_TYPE__NONE;
703 uint16_t port;
704
705 if (DCE2_SsnFromServer(p))
706 port = p->src_port;
707 else
708 port = p->dst_port;
709
710 if (IsTCP(p))
711 {
712 /* Look for raw DCE/RCP over TCP first, since it's
713 * more likely not to have configured a port for this. */
714 if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__TCP))
715 {
716 trans = DCE2_TcpAutodetect(p);
717 if (trans != DCE2_TRANS_TYPE__NONE)
718 return trans;
719 }
720
721 if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__HTTP_SERVER))
722 {
723 trans = DCE2_HttpAutodetectServer(p);
724 if (trans != DCE2_TRANS_TYPE__NONE)
725 return trans;
726 }
727
728 if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__HTTP_PROXY))
729 {
730 trans = DCE2_HttpAutodetectProxy(p);
731 if (trans != DCE2_TRANS_TYPE__NONE)
732 return trans;
733 }
734
735 if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__SMB))
736 {
737 trans = DCE2_SmbAutodetect(p);
738 if (trans != DCE2_TRANS_TYPE__NONE)
739 return trans;
740 }
741 }
742 else /* it's UDP */
743 {
744 if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__UDP))
745 {
746 trans = DCE2_UdpAutodetect(p);
747 if (trans != DCE2_TRANS_TYPE__NONE)
748 return trans;
749 }
750 }
751
752 return DCE2_TRANS_TYPE__NONE;
753 }
754
755 /*********************************************************************
756 * Function: DCE2_InitRpkts()
757 *
758 * Purpose: Allocate and initialize reassembly packets.
759 *
760 * Arguments: None
761 *
762 * Returns: None
763 *
764 *********************************************************************/
765 void DCE2_InitRpkts(void)
766 {
767 int i;
768 dce2_pkt_stack = DCE2_CStackNew(DCE2_PKT_STACK__SIZE, NULL, DCE2_MEM_TYPE__INIT);
769
770 if (dce2_pkt_stack == NULL)
771 {
772 DCE2_Die("%s(%d) Failed to allocate memory for packet stack.",
773 __FILE__, __LINE__);
774 }
775 for ( i = 0; i < DCE2_RPKT_TYPE__MAX; i++ )
776 dce2_rpkt[i] = _dpd.encodeNew();
777 }
778
779 /*********************************************************************
780 * Function: DCE2_GetRpkt()
781 *
782 * Purpose:
783 *
784 * Arguments:
785 * SFSnortPacket * - pointer to packet off wire
786 * const uint8_t * - pointer to data to attach to reassembly packet
787 * uint16_t - length of data
788 *
789 * Returns:
790 * SFSnortPacket * - pointer to reassembly packet
791 *
792 *********************************************************************/
793 SFSnortPacket * DCE2_GetRpkt(const SFSnortPacket *wire_pkt, DCE2_RpktType rpkt_type,
794 const uint8_t *data, uint32_t data_len)
795 {
796 DCE2_Ret status;
797 SFSnortPacket *rpkt;
798 uint16_t payload_len = 0;
799 uint16_t data_overhead = 0;
800
801 rpkt = dce2_rpkt[rpkt_type];
802
803 switch (rpkt_type)
804 {
805 case DCE2_RPKT_TYPE__SMB_SEG:
806 _dpd.encodeFormat(ENC_DYN_FWD, wire_pkt, rpkt, PSEUDO_PKT_SMB_SEG);
807 break;
808
809 case DCE2_RPKT_TYPE__SMB_TRANS:
810 // TBD these memset()s could be encapsulated by the various
811 // init functions which should also return the data_overhead.
812 // Better still pass in rpkt and let the init function update
813 // payload, etc. Also, some memsets could probably be avoided
814 // by explicitly setting the unitialized header fields.
815 _dpd.encodeFormat(ENC_DYN_FWD, wire_pkt, rpkt, PSEUDO_PKT_SMB_TRANS);
816
817 if (DCE2_SsnFromClient(wire_pkt))
818 {
819 data_overhead = DCE2_MOCK_HDR_LEN__SMB_CLI;
820 memset((void*)rpkt->payload, 0, data_overhead);
821 DCE2_SmbInitRdata((uint8_t *)rpkt->payload, FLAG_FROM_CLIENT);
822 }
823 else
824 {
825 data_overhead = DCE2_MOCK_HDR_LEN__SMB_SRV;
826 memset((void*)rpkt->payload, 0, data_overhead);
827 DCE2_SmbInitRdata((uint8_t *)rpkt->payload, FLAG_FROM_SERVER);
828 }
829 break;
830
831 case DCE2_RPKT_TYPE__SMB_CO_SEG:
832 _dpd.encodeFormat(ENC_DYN_FWD, wire_pkt, rpkt, PSEUDO_PKT_DCE_SEG);
833
834 if (DCE2_SsnFromClient(wire_pkt))
835 {
836 data_overhead = DCE2_MOCK_HDR_LEN__SMB_CLI;
837 memset((void*)rpkt->payload, 0, data_overhead);
838 DCE2_SmbInitRdata((uint8_t *)rpkt->payload, FLAG_FROM_CLIENT);
839 }
840 else
841 {
842 data_overhead = DCE2_MOCK_HDR_LEN__SMB_SRV;
843 memset((void*)rpkt->payload, 0, data_overhead);
844 DCE2_SmbInitRdata((uint8_t *)rpkt->payload, FLAG_FROM_SERVER);
845 }
846 break;
847
848 case DCE2_RPKT_TYPE__SMB_CO_FRAG:
849 _dpd.encodeFormat(ENC_DYN_FWD, wire_pkt, rpkt, PSEUDO_PKT_DCE_FRAG);
850
851 if (DCE2_SsnFromClient(wire_pkt))
852 {
853 data_overhead = DCE2_MOCK_HDR_LEN__SMB_CLI + DCE2_MOCK_HDR_LEN__CO_CLI;
854 memset((void*)rpkt->payload, 0, data_overhead);
855 DCE2_SmbInitRdata((uint8_t *)rpkt->payload, FLAG_FROM_CLIENT);
856 DCE2_CoInitRdata((uint8_t *)rpkt->payload +
857 DCE2_MOCK_HDR_LEN__SMB_CLI, FLAG_FROM_CLIENT);
858 }
859 else
860 {
861 data_overhead = DCE2_MOCK_HDR_LEN__SMB_SRV + DCE2_MOCK_HDR_LEN__CO_SRV;
862 memset((void*)rpkt->payload, 0, data_overhead);
863 DCE2_SmbInitRdata((uint8_t *)rpkt->payload, FLAG_FROM_SERVER);
864 DCE2_CoInitRdata((uint8_t *)rpkt->payload +
865 DCE2_MOCK_HDR_LEN__SMB_SRV, FLAG_FROM_SERVER);
866 }
867 break;
868
869 case DCE2_RPKT_TYPE__TCP_CO_SEG:
870 _dpd.encodeFormat(ENC_DYN_FWD, wire_pkt, rpkt, PSEUDO_PKT_DCE_SEG);
871 break;
872
873 case DCE2_RPKT_TYPE__TCP_CO_FRAG:
874 _dpd.encodeFormat(ENC_DYN_FWD, wire_pkt, rpkt, PSEUDO_PKT_DCE_FRAG);
875
876 if (DCE2_SsnFromClient(wire_pkt))
877 {
878 data_overhead = DCE2_MOCK_HDR_LEN__CO_CLI;
879 memset((void*)rpkt->payload, 0, data_overhead);
880 DCE2_CoInitRdata((uint8_t *)rpkt->payload, FLAG_FROM_CLIENT);
881 }
882 else
883 {
884 data_overhead = DCE2_MOCK_HDR_LEN__CO_SRV;
885 memset((void*)rpkt->payload, 0, data_overhead);
886 DCE2_CoInitRdata((uint8_t *)rpkt->payload, FLAG_FROM_SERVER);
887 }
888 break;
889
890 case DCE2_RPKT_TYPE__UDP_CL_FRAG:
891 _dpd.encodeFormat(ENC_DYN_FWD, wire_pkt, rpkt, PSEUDO_PKT_DCE_FRAG);
892 data_overhead = DCE2_MOCK_HDR_LEN__CL;
893 memset((void*)rpkt->payload, 0, data_overhead);
894 DCE2_ClInitRdata((uint8_t *)rpkt->payload);
895 break;
896
897 default:
898 DCE2_Log(DCE2_LOG_TYPE__ERROR,
899 "%s(%d) Invalid reassembly packet type: %d",
900 __FILE__, __LINE__, rpkt_type);
901 return NULL;
902 }
903
904 payload_len = rpkt->max_payload;
905
906 if ((data_overhead + data_len) > payload_len)
907 data_len -= (data_overhead + data_len) - payload_len;
908
909 status = DCE2_Memcpy(
910 (void *)(rpkt->payload + data_overhead),
911 (void *)data, (size_t)data_len, (void *)rpkt->payload,
912 (void *)((uint8_t *)rpkt->payload + payload_len));
913
914 if (status != DCE2_RET__SUCCESS)
915 {
916 DCE2_Log(DCE2_LOG_TYPE__ERROR,
917 "%s(%d) Failed to copy data into reassembly packet.",
918 __FILE__, __LINE__);
919 return NULL;
920 }
921
922 rpkt->payload_size = (uint16_t)(data_overhead + data_len);
923 _dpd.encodeUpdate(rpkt);
924
925 if (wire_pkt->family == AF_INET)
926 {
927 rpkt->ip4h->ip_len = rpkt->ip4_header->data_length;
928 }
929 else
930 {
931 IP6RawHdr* ip6h = (IP6RawHdr*)rpkt->raw_ip6_header;
932 if ( ip6h ) rpkt->ip6h->len = ip6h->ip6_payload_len;
933 }
934
935 rpkt->flags |= FLAG_STREAM_EST;
936 if (DCE2_SsnFromClient(wire_pkt))
937 rpkt->flags |= FLAG_FROM_CLIENT;
938 else
939 rpkt->flags |= FLAG_FROM_SERVER;
940 rpkt->stream_session = wire_pkt->stream_session;
941
942 return rpkt;
943 }
944
945 /*********************************************************************
946 * Function:
947 *
948 * Purpose:
949 *
950 * Arguments:
951 *
952 * Returns:
953 *
954 *********************************************************************/
955 DCE2_Ret DCE2_AddDataToRpkt(SFSnortPacket *rpkt, DCE2_RpktType rtype,
956 const uint8_t *data, uint32_t data_len)
957 {
958 int hdr_overhead = 0;
959 const uint8_t *pkt_data_end;
960 const uint8_t *payload_end;
961 DCE2_Ret status;
962
963 if ((rpkt == NULL) || (data == NULL) || (data_len == 0))
964 return DCE2_RET__ERROR;
965
966 if (rpkt->payload == NULL)
967 return DCE2_RET__ERROR;
968
969 /* This is a check to make sure we don't overwrite header data */
970 switch (rtype)
971 {
972 case DCE2_RPKT_TYPE__SMB_CO_SEG:
973 if (DCE2_SsnFromClient(rpkt))
974 hdr_overhead = DCE2_MOCK_HDR_LEN__SMB_CLI;
975 else
976 hdr_overhead = DCE2_MOCK_HDR_LEN__SMB_SRV;
977 break;
978
979 case DCE2_RPKT_TYPE__SMB_CO_FRAG:
980 if (DCE2_SsnFromClient(rpkt))
981 hdr_overhead = DCE2_MOCK_HDR_LEN__SMB_CLI + DCE2_MOCK_HDR_LEN__CO_CLI;
982 else
983 hdr_overhead = DCE2_MOCK_HDR_LEN__SMB_SRV + DCE2_MOCK_HDR_LEN__CO_SRV;
984 break;
985
986 case DCE2_RPKT_TYPE__TCP_CO_FRAG:
987 if (DCE2_SsnFromClient(rpkt))
988 hdr_overhead = DCE2_MOCK_HDR_LEN__CO_CLI;
989 else
990 hdr_overhead = DCE2_MOCK_HDR_LEN__CO_SRV;
991 break;
992
993 case DCE2_RPKT_TYPE__UDP_CL_FRAG:
994 hdr_overhead = DCE2_MOCK_HDR_LEN__CL;
995 break;
996
997 default:
998 break;
999 }
1000
1001 if (rpkt->payload_size < hdr_overhead)
1002 return DCE2_RET__ERROR;
1003
1004 pkt_data_end = rpkt->pkt_data + rpkt->max_payload;
1005 payload_end = rpkt->payload + rpkt->payload_size;
1006
1007 if ((payload_end + data_len) > pkt_data_end)
1008 data_len = pkt_data_end - payload_end;
1009
1010 status = DCE2_Memcpy((void *)payload_end, (void *)data, (size_t)data_len,
1011 (void *)payload_end, (void *)pkt_data_end);
1012
1013 if (status != DCE2_RET__SUCCESS)
1014 {
1015 DCE2_Log(DCE2_LOG_TYPE__ERROR,
1016 "%s(%d) Failed to copy data into reassembly packet.",
1017 __FILE__, __LINE__);
1018 return DCE2_RET__ERROR;
1019 }
1020
1021 rpkt->payload_size += (uint16_t)data_len;
1022 // there is room for optimization here since the update was done
1023 // earlier - that my be eliminated, but only in this case one
1024 // approach is to move the updates to push pkt - but don't want
1025 // to update non-dce2 pseudo pkts; perhaps a flag check there
1026 // will suffice.
1027 _dpd.encodeUpdate(rpkt);
1028
1029 if (rpkt->family == AF_INET)
1030 {
1031 rpkt->ip4h->ip_len = rpkt->ip4_header->data_length;
1032 }
1033 else
1034 {
1035 IP6RawHdr* ip6h = (IP6RawHdr*)rpkt->raw_ip6_header;
1036 if ( ip6h ) rpkt->ip6h->len = ip6h->ip6_payload_len;
1037 }
1038 return DCE2_RET__SUCCESS;
1039 }
1040
1041 /*********************************************************************
1042 * Function:
1043 *
1044 * Purpose:
1045 *
1046 * Arguments:
1047 *
1048 * Returns:
1049 *
1050 *********************************************************************/
1051 DCE2_Ret DCE2_PushPkt(SFSnortPacket *p)
1052 {
1053 SFSnortPacket *top_pkt = (SFSnortPacket *)DCE2_CStackTop(dce2_pkt_stack);
1054
1055 if (top_pkt != NULL)
1056 {
1057 PROFILE_VARS;
1058
1059 PREPROC_PROFILE_START(dce2_pstat_log);
1060
1061 _dpd.pushAlerts();
1062 _dpd.logAlerts((void *)top_pkt);
1063 _dpd.resetAlerts();
1064 _dpd.popAlerts();
1065
1066 PREPROC_PROFILE_END(dce2_pstat_log);
1067 }
1068
1069 if (DCE2_CStackPush(dce2_pkt_stack, (void *)p) != DCE2_RET__SUCCESS)
1070 return DCE2_RET__ERROR;
1071
1072 return DCE2_RET__SUCCESS;
1073 }
1074
1075 /*********************************************************************
1076 * Function:
1077 *
1078 * Purpose:
1079 *
1080 * Arguments:
1081 *
1082 * Returns:
1083 *
1084 *********************************************************************/
1085 void DCE2_PopPkt(void)
1086 {
1087 SFSnortPacket *pop_pkt = (SFSnortPacket *)DCE2_CStackPop(dce2_pkt_stack);
1088 PROFILE_VARS;
1089
1090 PREPROC_PROFILE_START(dce2_pstat_log);
1091
1092 if (pop_pkt == NULL)
1093 {
1094 DCE2_Log(DCE2_LOG_TYPE__ERROR,
1095 "%s(%d) No packet to pop off stack.",
1096 __FILE__, __LINE__);
1097 PREPROC_PROFILE_END(dce2_pstat_log);
1098 return;
1099 }
1100
1101 _dpd.pushAlerts();
1102 _dpd.logAlerts((void *)pop_pkt);
1103 _dpd.resetAlerts();
1104 _dpd.popAlerts();
1105
1106 PREPROC_PROFILE_END(dce2_pstat_log);
1107 }
1108
1109 /*********************************************************************
1110 * Function:
1111 *
1112 * Purpose:
1113 *
1114 * Arguments:
1115 *
1116 * Returns:
1117 *
1118 *********************************************************************/
1119 void DCE2_Detect(DCE2_SsnData *sd)
1120 {
1121 SFSnortPacket *top_pkt = (SFSnortPacket *)DCE2_CStackTop(dce2_pkt_stack);
1122 PROFILE_VARS;
1123
1124 if (top_pkt == NULL)
1125 {
1126 DCE2_Log(DCE2_LOG_TYPE__ERROR,
1127 "%s(%d) No packet on top of stack.",
1128 __FILE__, __LINE__);
1129 return;
1130 }
1131
1132 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Detecting ------------------------------------------------\n"));
1133 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ROPTIONS, " Rule options:\n"));
1134 DCE2_DEBUG_CODE(DCE2_DEBUG__ROPTIONS, DCE2_PrintRoptions(&sd->ropts););
1135 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Payload:\n"));
1136 DCE2_DEBUG_CODE(DCE2_DEBUG__MAIN, DCE2_PrintPktData(top_pkt->payload, top_pkt->payload_size););
1137 DCE2_DEBUG_CODE(DCE2_DEBUG__ROPTIONS,
1138 if (sd->ropts.stub_data != NULL) {
1139 printf("\nStub data:\n");
1140 DCE2_PrintPktData(sd->ropts.stub_data,
1141 top_pkt->payload_size - (sd->ropts.stub_data - top_pkt->payload)); });
1142
1143 PREPROC_PROFILE_START(dce2_pstat_detect);
1144
1145 _dpd.pushAlerts();
1146 _dpd.detect(top_pkt);
1147 _dpd.popAlerts();
1148
1149 PREPROC_PROFILE_END(dce2_pstat_detect);
1150
1151 /* Always reset rule option data after detecting */
1152 DCE2_ResetRopts(&sd->ropts);
1153 dce2_detected = 1;
1154 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "----------------------------------------------------------\n"));
1155 }
1156
1157 void DCE2_FileDetect(DCE2_SsnData *sd)
1158 {
1159 SFSnortPacket *top_pkt = (SFSnortPacket *)DCE2_CStackTop(dce2_pkt_stack);
1160 PROFILE_VARS;
1161
1162 if (top_pkt == NULL)
1163 {
1164 DCE2_Log(DCE2_LOG_TYPE__ERROR,
1165 "%s(%d) No packet on top of stack.",
1166 __FILE__, __LINE__);
1167 return;
1168 }
1169
1170 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Detecting ------------------------------------------------\n"));
1171 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Payload:\n"));
1172 DCE2_DEBUG_CODE(DCE2_DEBUG__MAIN, DCE2_PrintPktData(top_pkt->payload, top_pkt->payload_size););
1173
1174 PREPROC_PROFILE_START(dce2_pstat_smb_file_detect);
1175
1176 _dpd.pushAlerts();
1177 _dpd.detect(top_pkt);
1178 _dpd.popAlerts();
1179
1180 PREPROC_PROFILE_END(dce2_pstat_smb_file_detect);
1181
1182 // Reset file data pointer after detecting
1183 _dpd.setFileDataPtr(NULL, 0);
1184 dce2_detected = 1;
1185 DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "----------------------------------------------------------\n"));
1186 }
1187
1188 /*********************************************************************
1189 * Function:
1190 *
1191 * Purpose:
1192 *
1193 * Arguments:
1194 *
1195 * Returns:
1196 *
1197 *********************************************************************/
1198 // TBD this function could be called on the actual rpkt
1199 // to very easily get the exact available payload space and
1200 // then truncate the data as needed. That avoids the calculations
1201 // here which inevitably include tacit assumptions about the
1202 // rpkt which may not be true (nor future proof).
1203 uint16_t DCE2_GetRpktMaxData(DCE2_SsnData *sd, DCE2_RpktType rtype)
1204 {
1205 const SFSnortPacket *p = sd->wire_pkt;
1206 uint16_t overhead;
1207
1208 uint8_t* base, *last;
1209 int n = p->next_layer_index - 1;
1210 if ( n < 2 ) return 0;
1211
1212 base = p->proto_layers[1].proto_start;
1213 last = p->proto_layers[n].proto_start + p->proto_layers[n].proto_length;
1214
1215 overhead = last - base;
1216
1217 switch (rtype)
1218 {
1219 case DCE2_RPKT_TYPE__SMB_SEG:
1220 case DCE2_RPKT_TYPE__SMB_TRANS:
1221 break;
1222
1223 case DCE2_RPKT_TYPE__SMB_CO_SEG:
1224 if (DCE2_SsnFromClient(p))
1225 overhead += DCE2_MOCK_HDR_LEN__SMB_CLI;
1226 else
1227 overhead += DCE2_MOCK_HDR_LEN__SMB_SRV;
1228 break;
1229
1230 case DCE2_RPKT_TYPE__SMB_CO_FRAG:
1231 if (DCE2_SsnFromClient(p))
1232 overhead += DCE2_MOCK_HDR_LEN__SMB_CLI + DCE2_MOCK_HDR_LEN__CO_CLI;
1233 else
1234 overhead += DCE2_MOCK_HDR_LEN__SMB_SRV + DCE2_MOCK_HDR_LEN__CO_SRV;
1235 break;
1236
1237 case DCE2_RPKT_TYPE__TCP_CO_SEG:
1238 break;
1239
1240 case DCE2_RPKT_TYPE__TCP_CO_FRAG:
1241 if (DCE2_SsnFromClient(p))
1242 overhead += DCE2_MOCK_HDR_LEN__CO_CLI;
1243 else
1244 overhead += DCE2_MOCK_HDR_LEN__CO_SRV;
1245 break;
1246
1247 case DCE2_RPKT_TYPE__UDP_CL_FRAG:
1248 overhead += DCE2_MOCK_HDR_LEN__CL;
1249 break;
1250
1251 default:
1252 DCE2_Log(DCE2_LOG_TYPE__ERROR,
1253 "%s(%d) Invalid reassembly packet type: %d",
1254 __FILE__, __LINE__, rtype);
1255 return 0;
1256 }
1257 return (IP_MAXPKT - overhead);
1258 }
1259
1260 /******************************************************************
1261 * Function:
1262 *
1263 * Purpose:
1264 *
1265 * Arguments:
1266 *
1267 * Returns:
1268 *
1269 ******************************************************************/
1270 void DCE2_FreeGlobals(void)
1271 {
1272 int i;
1273
1274 if (dce2_pkt_stack != NULL)
1275 {
1276 DCE2_CStackDestroy(dce2_pkt_stack);
1277 dce2_pkt_stack = NULL;
1278 }
1279
1280 for ( i = 0; i < DCE2_RPKT_TYPE__MAX; i++ )
1281 {
1282 if ( dce2_rpkt[i] != NULL )
1283 {
1284 _dpd.encodeDelete(dce2_rpkt[i]);
1285 dce2_rpkt[i] = NULL;
1286 }
1287 }
1288
1289 DCE2_EventsFree();
1290 }
1291
1292 static void DCE2_SsnFree(void *data)
1293 {
1294 DCE2_SsnData *sd = (DCE2_SsnData *)data;
1295 #ifdef SNORT_RELOAD
1296 DCE2_Config *pPolicyConfig;
1297 tSfPolicyUserContextId config;
1298 tSfPolicyId policy_id;
1299 #endif
1300
1301 if (sd == NULL)
1302 return;
1303
1304 #ifdef SNORT_RELOAD
1305 ada_appdata_freed( ada, data );
1306 config = sd->config;
1307 policy_id = sd->policy_id;
1308 #endif
1309
1310 switch (sd->trans)
1311 {
1312 case DCE2_TRANS_TYPE__SMB:
1313 DCE2_SmbSsnFree((DCE2_SmbSsnData *)sd);
1314 break;
1315
1316 case DCE2_TRANS_TYPE__TCP:
1317 DCE2_TcpSsnFree((DCE2_TcpSsnData *)sd);
1318 break;
1319
1320 case DCE2_TRANS_TYPE__UDP:
1321 DCE2_UdpSsnFree((DCE2_UdpSsnData *)sd);
1322 break;
1323
1324 case DCE2_TRANS_TYPE__HTTP_SERVER:
1325 case DCE2_TRANS_TYPE__HTTP_PROXY:
1326 DCE2_HttpSsnFree((DCE2_HttpSsnData *)sd);
1327 break;
1328
1329 default:
1330 DCE2_Log(DCE2_LOG_TYPE__ERROR,
1331 "%s(%d) Invalid transport type: %d",
1332 __FILE__, __LINE__, sd->trans);
1333 return;
1334 }
1335
1336 #ifdef SNORT_RELOAD
1337 pPolicyConfig = (DCE2_Config *)sfPolicyUserDataGet(config, policy_id);
1338
1339 if (pPolicyConfig != NULL)
1340 {
1341 pPolicyConfig->ref_count--;
1342 if ((pPolicyConfig->ref_count == 0) &&
1343 (config != dce2_config))
1344 {
1345 sfPolicyUserDataClear (config, policy_id);
1346 DCE2_FreeConfig(pPolicyConfig);
1347
1348 /* No more outstanding policies for this config */
1349 if (sfPolicyUserPolicyGetActive(config) == 0)
1350 DCE2_FreeConfigs(config);
1351 }
1352 }
1353 #endif
1354 dce2_stats.sessions_active--;
1355 }
1356