"Fossies" - the Fresh Open Source Software Archive 
Member "snort-2.9.17/src/preprocessors/spp_stream6.c" (16 Oct 2020, 72563 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 "spp_stream6.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 /* $Id$ */
2 /****************************************************************************
3 *
4 * Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
5 * Copyright (C) 2005-2013 Sourcefire, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License Version 2 as
9 * published by the Free Software Foundation. You may not use, modify or
10 * distribute this program under any other version of the GNU General
11 * Public License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 *
22 ****************************************************************************/
23
24 /**
25 * @file spp_stream6.c
26 * @author Martin Roesch <roesch@sourcefire.com>
27 * Steven Sturges <ssturges@sourcefire.com>
28 * davis mcpherson <dmcpherson@sourcefire.com>
29 * @date 19 Apr 2005
30 *
31 * @brief You can never have too many stream reassemblers...
32 */
33
34 /* I N C L U D E S ************************************************/
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38
39 #include <assert.h>
40 #include <stdio.h>
41
42 #ifndef WIN32
43 #include <sys/time.h> /* struct timeval */
44 #endif
45 #include <sys/types.h> /* u_int*_t */
46
47 #include "snort.h"
48 #include "snort_bounds.h"
49 #include "util.h"
50 #include "snort_debug.h"
51 #include "plugbase.h"
52 #include "session_api.h"
53 #include "spp_stream6.h"
54 #include "stream_api.h"
55 #include "stream_paf.h"
56 #include "stream_common.h"
57 #include "session_common.h"
58 #include "snort_stream_tcp.h"
59 #include "snort_stream_udp.h"
60 #include "snort_stream_icmp.h"
61 #include "snort_stream_ip.h"
62 #include "checksum.h"
63 #include "mstring.h"
64 #include "parser/IpAddrSet.h"
65 #include "decode.h"
66 #include "detect.h"
67 #include "generators.h"
68 #include "event_queue.h"
69 #include "session_expect.h"
70 #include "perf.h"
71 #include "active.h"
72 #include "sfdaq.h"
73 #include "ipv6_port.h"
74 #include "sfPolicy.h"
75 #include "sp_flowbits.h"
76 #include "stream5_ha.h"
77 #include "control/sfcontrol_funcs.h"
78
79 #ifdef TARGET_BASED
80 #include "sftarget_protocol_reference.h"
81 #include "sftarget_hostentry.h"
82 #endif
83
84 #include "profiler.h"
85 #ifdef PERF_PROFILING
86 PreprocStats s5PerfStats;
87 extern PreprocStats s5TcpPerfStats;
88 extern PreprocStats s5UdpPerfStats;
89 extern PreprocStats s5IcmpPerfStats;
90 extern PreprocStats s5IpPerfStats;
91 #endif
92
93 extern OptTreeNode *otn_tmp;
94
95 extern FlushConfig ignore_flush_policy[MAX_PORTS];
96 #ifdef TARGET_BASED
97 extern FlushConfig ignore_flush_policy_protocol[MAX_PROTOCOL_ORDINAL];
98 #endif
99
100
101 /* M A C R O S **************************************************/
102 #define PP_STREAM6_PRIORITY PRIORITY_CORE + PP_CORE_ORDER_STREAM
103
104 /* G L O B A L S **************************************************/
105 tSfPolicyUserContextId stream_parsing_config = NULL;
106 tSfPolicyUserContextId stream_online_config = NULL;
107
108 SessionConfiguration *stream_session_config = NULL;
109
110 StreamStats s5stats;
111
112 uint32_t xtradata_func_count = 0;
113 LogFunction xtradata_map[LOG_FUNC_MAX];
114 LogExtraData extra_data_log = NULL;
115 void *extra_data_config = NULL;
116
117 static bool old_config_freed = false;
118
119 /* P R O T O T Y P E S ********************************************/
120 #ifdef MPLS
121 static void updateMplsHeaders(Packet *, SessionControlBlock *);
122 #endif
123
124 static void StreamPolicyInitTcp(struct _SnortConfig *, char *);
125 static void StreamPolicyInitUdp(struct _SnortConfig *, char *);
126 static void StreamPolicyInitIcmp(struct _SnortConfig *, char *);
127 static void StreamPolicyInitIp(struct _SnortConfig *, char *);
128 static void StreamCleanExit(int, void *);
129 static void StreamReset(int, void *);
130 static void StreamResetStats(int, void *);
131 static int StreamVerifyConfig(struct _SnortConfig *);
132 static void StreamPrintSessionConfig(SessionConfiguration *);
133 static void StreamPrintStats(int);
134 static void DisplayStreamStatistics (uint16_t type, void *old_context, struct _THREAD_ELEMENT *te, ControlDataSendFunc f);
135 static void StreamProcess(Packet *p, void *context);
136 static inline int IsEligible(Packet *p);
137 #ifdef TARGET_BASED
138 static void initServiceFilterStatus(struct _SnortConfig *sc);
139 #endif
140
141 #ifdef SNORT_RELOAD
142 static void StreamTcpReload(struct _SnortConfig *, char *, void **);
143 static void StreamUdpReload(struct _SnortConfig *, char *, void **);
144 static void StreamIcmpReload(struct _SnortConfig *, char *, void **);
145 static void StreamIpReload(struct _SnortConfig *, char *, void **);
146 static int StreamReloadVerify(struct _SnortConfig *, void *);
147 static void * StreamReloadSwap(struct _SnortConfig *, void *);
148 static void StreamReloadSwapFree(void *);
149 #endif
150
151 /* S T R E A M A P I **********************************************/
152 static int StreamMidStreamDropAlert(void);
153 static int StreamAlertFlushStream(Packet *p);
154 static int StreamRequestFlushStream(Packet *p);
155 static int StreamResponseFlushStream(Packet *p);
156 static int StreamAddSessionAlert(void *ssnptr, Packet *p, uint32_t gid, uint32_t sid);
157 static int StreamCheckSessionAlert(void *ssnptr, Packet *p, uint32_t gid, uint32_t sid);
158 static int StreamUpdateSessionAlert(void *ssnptr, Packet *p, uint32_t gid, uint32_t sid,
159 uint32_t event_id, uint32_t event_second);
160 static char StreamSetReassembly(void *ssnptr, uint8_t flush_policy, char dir, char flags);
161 static void StreamUpdateDirection( void * scbptr, char dir, sfaddr_t* ip, uint16_t port );
162 static char StreamGetReassemblyDirection(void *ssnptr);
163 static char StreamGetReassemblyFlushPolicy(void *ssnptr, char dir);
164 static char StreamIsStreamSequenced(void *ssnptr, char dir);
165 static int StreamMissingInReassembled(void *ssnptr, char dir);
166 static char StreamPacketsMissing(void *ssnptr, char dir);
167 static void StreamDropPacket( Packet *p );
168 static int StreamGetRebuiltPackets( Packet *p, PacketIterator callback, void *userdata);
169 static int StreamGetStreamSegments( Packet *p, StreamSegmentIterator callback, void *userdata);
170 static uint32_t StreamGetFlushPoint(void *ssnptr, char dir);
171 static void StreamSetFlushPoint(void *ssnptr, char dir, uint32_t flush_point);
172 static uint8_t StreamRegisterPAFPort(
173 struct _SnortConfig *, tSfPolicyId,
174 uint16_t server_port, bool toServer,
175 PAF_Callback, bool autoEnable);
176 static uint8_t StreamRegisterPAFService(
177 struct _SnortConfig *, tSfPolicyId,
178 uint16_t service, bool toServer,
179 PAF_Callback, bool autoEnable);
180 static void** StreamGetPAFUserData(void* ssnptr, bool to_server, uint8_t id);
181 static bool StreamIsPafActive(void* ssnptr, bool to_server);
182 static bool StreamActivatePaf(void* ssnptr, int dir, int16_t service, uint8_t type);
183
184 static uint32_t StreamRegisterXtraData(LogFunction );
185 static uint32_t StreamGetXtraDataMap(LogFunction **);
186 static void StreamRegisterXtraDataLog(LogExtraData, void * );
187 static void StreamSetExtraData(void* ssn, Packet*, uint32_t);
188 static void StreamClearExtraData(void* ssn, Packet*, uint32_t);
189 static void s5SetPortFilterStatus( struct _SnortConfig *, IpProto protocol, uint16_t port, uint16_t status,
190 tSfPolicyId policyId, int parsing );
191 static void s5UnsetPortFilterStatus( struct _SnortConfig *, IpProto protocol, uint16_t port, uint16_t status,
192 tSfPolicyId policyId, int parsing );
193 #ifdef TARGET_BASED
194 static void setServiceFilterStatus( struct _SnortConfig *sc, int service, int status, tSfPolicyId policyId, int parsing );
195 #endif
196 static void StreamForceSessionExpiration(void *ssnptr);
197 static void StreamForceDeleteSession(void *ssnptr );
198 static void registerReassemblyPort( char *network, uint16_t port, int reassembly_direction );
199 static void unregisterReassemblyPort( char *network, uint16_t port, int reassembly_direction );
200 static unsigned StreamRegisterHandler(Stream_Callback);
201 static bool StreamSetHandler(void* ssnptr, unsigned id, Stream_Event);
202 static uint32_t StreamGetPreprocFlags( void *ssnptr);
203 static void StreamResetPolicy(void* ssnptr, int dir, uint16_t policy, uint16_t mss);
204 static void StreamSetSessionDecrypted(void* ssnptr, bool enable);
205 static bool StreamIsSessionDecrypted(void* ssnptr);
206 struct _ExpectNode;
207 static int StreamSetApplicationProtocolIdExpectedPreassignCallbackId( const Packet *ctrlPkt, sfaddr_t* srcIP,
208 uint16_t srcPort, sfaddr_t* dstIP, uint16_t dstPort, uint8_t protocol, int16_t protoId,
209 uint32_t preprocId, void *protoData, void (*protoDataFreeFn)(void*), unsigned cbId, Stream_Event se,
210 struct _ExpectNode** packetExpectedNode);
211
212 #if defined(FEAT_OPEN_APPID)
213 static void SetApplicationId(void* ssnptr, int16_t serviceAppId, int16_t clientAppId,
214 int16_t payloadAppId, int16_t miscAppId);
215 static void GetApplicationId(void* ssnptr, int16_t *serviceAppId, int16_t *clientAppId,
216 int16_t *payloadAppId, int16_t *miscAppId);
217 static int RegisterHttpHeaderCallback (Http_Processor_Callback cb);
218 #endif /* defined(FEAT_OPEN_APPID) */
219
220 static bool serviceEventPublish(unsigned int preprocId, void *ssnptr, ServiceEventType eventType, void * eventData);
221 static bool serviceEventSubscribe(unsigned int preprocId, ServiceEventType eventType, ServiceEventNotifierFunc cb);
222 static void StreamRegisterPAFFree(uint8_t id, PAF_Free_Callback cb);
223 static Packet* getWirePacket();
224 static uint8_t getFlushPolicyDir();
225 static bool StreamIsSessionHttp2(void* ssnptr);
226 static void StreamSetSessionHttp2(void* ssnptr);
227 static bool StreamShowRebuiltPackets();
228 static bool StreamIsSessionHttp2Upg(void* ssnptr);
229 static void StreamSetSessionHttp2Upg(void* ssnptr);
230 static int RegisterFTPFlushCallback (FTP_Processor_Flush_Callback cb);
231 static void setFtpFilePosition (void *scbptr,bool flush);
232 #ifdef HAVE_DAQ_DECRYPTED_SSL
233 static int StreamSimulateTcpAck(void *ssnptr, uint8_t dir, uint32_t len);
234 #endif
235
236 StreamAPI s5api = {
237 /* .version = */ STREAM_API_VERSION5,
238 /* .alert_inline_midstream_drops = */ StreamMidStreamDropAlert,
239 /* .alert_flush_stream = */ StreamAlertFlushStream,
240 /* .request_flush_stream = */ StreamRequestFlushStream,
241 /* .response_flush_stream = */ StreamResponseFlushStream,
242 /* .traverse_reassembled = */ StreamGetRebuiltPackets,
243 /* .traverse_stream_segments = */ StreamGetStreamSegments,
244 /* .add_session_alert = */ StreamAddSessionAlert,
245 /* .check_session_alerted = */ StreamCheckSessionAlert,
246 /* .update_session_alert = */ StreamUpdateSessionAlert,
247 /* .set_reassembly = */ StreamSetReassembly,
248 /* .update_direction = */ StreamUpdateDirection,
249 /* .get_reassembly_direction = */ StreamGetReassemblyDirection,
250 /* .get_reassembly_flush_policy = */ StreamGetReassemblyFlushPolicy,
251 /* .is_stream_sequenced = */ StreamIsStreamSequenced,
252 /* .missing_in_reassembled = */ StreamMissingInReassembled,
253 /* .missed_packets = */ StreamPacketsMissing,
254 /* .drop_packet = */ StreamDropPacket,
255 /* .get_flush_point = */ StreamGetFlushPoint,
256 /* .set_flush_point = */ StreamSetFlushPoint,
257 /* .register_paf_port = */ StreamRegisterPAFPort,
258 /* .get_paf_user_data = */ StreamGetPAFUserData,
259 /* .is_paf_active = */ StreamIsPafActive,
260 /* .activate_paf = */ StreamActivatePaf,
261 /* .set_tcp_syn_session_status = */ s5TcpSetSynSessionStatus,
262 /* .unset_tcp_syn_session_status = */ s5TcpUnsetSynSessionStatus,
263 /* .reg_xtra_data_cb = */ StreamRegisterXtraData,
264 /* .reg_xtra_data_log = */ StreamRegisterXtraDataLog,
265 /* .get_xtra_data_map = */ StreamGetXtraDataMap,
266 /* .register_paf_service = */ StreamRegisterPAFService,
267 /* .set_extra_data = */ StreamSetExtraData,
268 /* .clear_extra_data = */ StreamClearExtraData,
269
270 // The methods below may move to Session
271 /* .set_port_filter_status = */ s5SetPortFilterStatus,
272 /* .unset_port_filter_status = */ s5UnsetPortFilterStatus,
273 #ifdef TARGET_BASED
274 /* .set_service_filter_status = */ setServiceFilterStatus,
275 #endif
276 /* .register_reassembly_port = */ registerReassemblyPort,
277 /* .register_reassembly_port = */ unregisterReassemblyPort,
278 /* .expire_session = */ StreamForceSessionExpiration,
279 /* .force_delete_session = */ StreamForceDeleteSession,
280 /* .register_event_handler = */ StreamRegisterHandler,
281 /* .set_event_handler = */ StreamSetHandler,
282 /* .set_reset_policy = */ StreamResetPolicy,
283 /* .set_session_decrypted = */ StreamSetSessionDecrypted,
284 /* .is_session_decrypted = */ StreamIsSessionDecrypted,
285 /* .set_application_protocol_id_expected_preassign_callback = */ StreamSetApplicationProtocolIdExpectedPreassignCallbackId,
286 /* .print_normalization_stats = */ Stream_PrintNormalizationStats,
287 /* .reset_normalization_stats = */ Stream_ResetNormalizationStats,
288 #if defined(FEAT_OPEN_APPID)
289 /* .set_application_id = */ SetApplicationId,
290 /* .get_application_id = */ GetApplicationId,
291 /* .register_http_header_callback = */ RegisterHttpHeaderCallback,
292 #endif /* defined(FEAT_OPEN_APPID) */
293 /* .service_event_publish */ serviceEventPublish,
294 /* .service_event_subscribe */ serviceEventSubscribe,
295 /* .register_paf_free */ StreamRegisterPAFFree,
296 /* .get_wire_packet */ getWirePacket,
297 /* .get_flush_policy_dir */ getFlushPolicyDir,
298 /* .is_session_http2 */ StreamIsSessionHttp2,
299 /* .set_session_http2 */ StreamSetSessionHttp2,
300 /* .is_show_rebuilt_packets_enabled */ StreamShowRebuiltPackets,
301 /* .is_session_http2_upg */ StreamIsSessionHttp2Upg,
302 /* .set_session_http2_upg */ StreamSetSessionHttp2Upg,
303 /* .get_preproc_flags */ StreamGetPreprocFlags,
304 /* .register_ftp_flush_cb */ RegisterFTPFlushCallback,
305 /* .set_ftp_file_position */ setFtpFilePosition
306 #ifdef HAVE_DAQ_DECRYPTED_SSL
307 ,
308 /* .simulate_tcp_ack_in_peer_stream_tracker = */ StreamSimulateTcpAck
309 #endif
310 };
311
312 void SetupStream6(void)
313 {
314 #ifndef SNORT_RELOAD
315 RegisterPreprocessor("stream5_tcp", StreamPolicyInitTcp);
316 RegisterPreprocessor("stream5_udp", StreamPolicyInitUdp);
317 RegisterPreprocessor("stream5_icmp", StreamPolicyInitIcmp);
318 RegisterPreprocessor("stream5_ip", StreamPolicyInitIp);
319 #else
320 RegisterPreprocessor("stream5_tcp", StreamPolicyInitTcp, StreamTcpReload,
321 StreamReloadVerify, StreamReloadSwap, StreamReloadSwapFree);
322 RegisterPreprocessor("stream5_udp", StreamPolicyInitUdp, StreamUdpReload,
323 StreamReloadVerify, StreamReloadSwap, StreamReloadSwapFree);
324 RegisterPreprocessor("stream5_icmp", StreamPolicyInitIcmp, StreamIcmpReload,
325 StreamReloadVerify, StreamReloadSwap, StreamReloadSwapFree);
326 RegisterPreprocessor("stream5_ip", StreamPolicyInitIp, StreamIpReload,
327 StreamReloadVerify, StreamReloadSwap, StreamReloadSwapFree);
328 #endif
329
330 // init pointer to stream api dispatch table...
331 stream_api = &s5api;
332
333 /* Registering for SFR CLI */
334 ControlSocketRegisterHandler(CS_TYPE_STREAM_STATS, NULL, NULL, &DisplayStreamStatistics);
335 DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Stream preprocessor setup complete.\n"););
336 }
337
338 // Initialize the configuration object for a stream preprocessor policy. If this is the first stream configuration
339 // being parsed for this NAP policy then allocate the config context object that holds the config settings for all
340 // the possible stream protocols. This function is called before each protocol specific configuration string is
341 // processed for each NAP policy defined.
342 static StreamConfig *initStreamPolicyConfig( struct _SnortConfig *sc, bool reload_config )
343 {
344 tSfPolicyId policy_id = getParserPolicy( sc );
345 StreamConfig *pCurrentPolicyConfig = NULL;
346
347 if( stream_parsing_config == NULL )
348 {
349 // we are parsing the first stream conf file, create a context and do all stream
350 // one time initialization functions.
351 //
352 stream_parsing_config = sfPolicyConfigCreate();
353
354 if( !reload_config )
355 {
356 #ifdef PERF_PROFILING
357 RegisterPreprocessorProfile( "s5", &s5PerfStats, 0, &totalPerfStats , NULL);
358 RegisterPreprocessorProfile( "s5tcp", &s5TcpPerfStats, 1, &s5PerfStats , NULL);
359 RegisterPreprocessorProfile( "s5udp", &s5UdpPerfStats, 1, &s5PerfStats , NULL);
360 RegisterPreprocessorProfile( "s5icmp", &s5IcmpPerfStats, 1, &s5PerfStats , NULL);
361 RegisterPreprocessorProfile( "s5ip", &s5IpPerfStats, 1, &s5PerfStats , NULL);
362 #endif
363
364 AddFuncToPreprocCleanExitList( StreamCleanExit, NULL, PP_STREAM6_PRIORITY, PP_STREAM );
365 AddFuncToPreprocResetList( StreamReset, NULL, PP_STREAM6_PRIORITY, PP_STREAM );
366 AddFuncToPreprocResetStatsList( StreamResetStats, NULL, PP_STREAM6_PRIORITY, PP_STREAM );
367 AddFuncToConfigCheckList( sc, StreamVerifyConfig );
368 RegisterPreprocStats( "stream5", StreamPrintStats );
369 }
370 else
371 old_config_freed = false;
372
373 }
374
375 // set this policy id as current and get pointer to the struct of pointers to the
376 // protocol specific configuration pointers for this policy...
377 // if this pointer is NULL then this is the first stream protocol conf file we are
378 // parsing for this policy, so allocate required memory
379 sfPolicyUserPolicySet( stream_parsing_config, policy_id );
380 pCurrentPolicyConfig = ( StreamConfig * ) sfPolicyUserDataGetCurrent( stream_parsing_config );
381 if( pCurrentPolicyConfig == NULL )
382 {
383 pCurrentPolicyConfig = ( StreamConfig * ) SnortAlloc( sizeof( StreamConfig ) );
384 sfPolicyUserDataSetCurrent( stream_parsing_config, pCurrentPolicyConfig );
385 // get pointer to the session configuration...if it's NULL bad news, session not
386 // configured so Fatal Error...
387 pCurrentPolicyConfig->session_config = getSessionConfiguration( reload_config );
388 if( pCurrentPolicyConfig->session_config == NULL )
389 {
390 FatalError( "%s(%d) - Session Must Be Configured Before Stream!\n", file_name, file_line );
391 }
392
393 // stream registers to run for all ports
394 session_api->enable_preproc_all_ports( sc, PP_STREAM, PROTO_BIT__ALL );
395 pCurrentPolicyConfig->verified = false;
396 pCurrentPolicyConfig->swapped = false;
397 pCurrentPolicyConfig->reload_config = reload_config;
398 StreamPrintSessionConfig( pCurrentPolicyConfig->session_config );
399 }
400
401 return pCurrentPolicyConfig;
402 }
403
404 // return pointer to configuration context object for all stream polices. If parsing is
405 // true return pointer to current parsing context object (NULL if parsing not in progress)
406 // otherwise pointer to the current active config context object
407 static inline tSfPolicyUserContextId getStreamConfigContext( bool parsing )
408 {
409 if( parsing )
410 return stream_parsing_config;
411 else
412 return stream_online_config;
413 }
414
415 // return pointer to Stream configuration for the specified policy. If parsing is
416 // true return pointer to config struct the policy is being parsed into, otherwise pointer
417 // to the currently active config
418 StreamConfig *getStreamPolicyConfig( tSfPolicyId policy_id, bool parsing )
419 {
420 tSfPolicyUserContextId ctx;
421
422 if( parsing )
423 ctx = ( stream_parsing_config != NULL ) ? stream_parsing_config : stream_online_config;
424 else
425 ctx = stream_online_config;
426
427 if( ctx != NULL )
428 return ( StreamConfig * ) sfPolicyUserDataGet( ctx, policy_id );
429 else
430 return NULL;
431 }
432
433
434 static void StreamPrintSessionConfig( SessionConfiguration *config )
435 {
436 LogMessage("Stream global config:\n");
437 LogMessage(" Track TCP sessions: %s\n", config->track_tcp_sessions == STREAM_TRACK_YES ?
438 "ACTIVE" : "INACTIVE");
439 if( config->track_tcp_sessions == STREAM_TRACK_YES )
440 {
441 LogMessage(" Max TCP sessions: %u\n", config->max_tcp_sessions);
442 LogMessage(" TCP cache pruning timeout: %u seconds\n", config->tcp_cache_pruning_timeout);
443 LogMessage(" TCP cache nominal timeout: %u seconds\n", config->tcp_cache_nominal_timeout);
444 }
445
446 LogMessage(" Memcap (for reassembly packet storage): %d\n", config->memcap);
447 LogMessage(" Track UDP sessions: %s\n", config->track_udp_sessions == STREAM_TRACK_YES ?
448 "ACTIVE" : "INACTIVE");
449 if( config->track_udp_sessions == STREAM_TRACK_YES )
450 {
451 LogMessage(" Max UDP sessions: %u\n", config->max_udp_sessions);
452 LogMessage(" UDP cache pruning timeout: %u seconds\n", config->udp_cache_pruning_timeout);
453 LogMessage(" UDP cache nominal timeout: %u seconds\n", config->udp_cache_nominal_timeout);
454 }
455
456 LogMessage(" Track ICMP sessions: %s\n", config->track_icmp_sessions == STREAM_TRACK_YES ?
457 "ACTIVE" : "INACTIVE");
458 if( config->track_icmp_sessions == STREAM_TRACK_YES )
459 LogMessage(" Max ICMP sessions: %u\n", config->max_icmp_sessions);
460
461 LogMessage(" Track IP sessions: %s\n", config->track_ip_sessions == STREAM_TRACK_YES ?
462 "ACTIVE" : "INACTIVE");
463 if( config->track_ip_sessions == STREAM_TRACK_YES )
464 LogMessage(" Max IP sessions: %u\n", config->max_ip_sessions);
465 if( config->prune_log_max )
466 LogMessage(" Log info if session memory consumption exceeds %d\n", config->prune_log_max);
467 #ifdef ACTIVE_RESPONSE
468 LogMessage(" Send up to %d active responses\n", config->max_active_responses);
469
470 if( config->max_active_responses > 1 )
471 {
472 LogMessage(" Wait at least %d seconds between responses\n",
473 config->min_response_seconds);
474 }
475 #endif
476 LogMessage(" Protocol Aware Flushing: %s\n", ScPafEnabled() ? "ACTIVE" : "INACTIVE");
477 LogMessage(" Maximum Flush Point: %u\n", ScPafMax());
478 #ifdef ENABLE_HA
479 LogMessage(" High Availability: %s\n", config->enable_ha ? "ENABLED" : "DISABLED");
480 #endif
481
482 #ifdef REG_TEST
483 LogMessage(" Session Control Block Size: %lu\n", (long unsigned int)sizeof(SessionControlBlock));
484 #endif
485
486 }
487
488 static void StreamPolicyInitTcp( struct _SnortConfig *sc, char *args )
489 {
490 StreamConfig *config = NULL;
491
492 config = initStreamPolicyConfig( sc, false );
493 if ( !config->session_config->track_tcp_sessions )
494 return;
495
496 if( config->tcp_config == NULL )
497 {
498 config->tcp_config = ( StreamTcpConfig * ) SnortAlloc( sizeof( StreamTcpConfig ) );
499 StreamInitTcp( );
500 StreamTcpInitFlushPoints( );
501 StreamTcpRegisterRuleOptions( sc );
502 AddFuncToPreprocPostConfigList( sc, StreamPostConfigTcp, config->tcp_config );
503 }
504
505 /* Call the protocol specific initializer */
506 StreamTcpPolicyInit( sc, config->tcp_config, args );
507 }
508
509 static void StreamPolicyInitUdp( struct _SnortConfig *sc, char *args )
510 {
511 StreamConfig *config;
512
513 config = initStreamPolicyConfig( sc, false );
514 if( !config->session_config->track_udp_sessions )
515 return;
516
517 if( config->udp_config == NULL )
518 {
519 config->udp_config = ( StreamUdpConfig * ) SnortAlloc( sizeof( StreamUdpConfig ) );
520 StreamInitUdp( );
521 }
522
523 /* Call the protocol specific initializer */
524 StreamUdpPolicyInit( config->udp_config, args );
525 }
526
527 static void StreamPolicyInitIcmp( struct _SnortConfig *sc, char *args )
528 {
529 StreamConfig *config;
530
531 config = initStreamPolicyConfig( sc, false );
532 if( !config->session_config->track_icmp_sessions )
533 return;
534
535 if( config->icmp_config == NULL )
536 {
537 config->icmp_config = ( StreamIcmpConfig * ) SnortAlloc( sizeof( StreamIcmpConfig ) );
538 StreamInitIcmp( );
539 }
540
541 /* Call the protocol specific initializer */
542 StreamIcmpPolicyInit( config->icmp_config, args );
543 }
544
545 static void StreamPolicyInitIp( struct _SnortConfig *sc, char *args )
546 {
547 StreamConfig *config;
548
549 config = initStreamPolicyConfig( sc, false );
550 if( !config->session_config->track_ip_sessions )
551 return;
552
553 if( config->ip_config == NULL )
554 {
555 config->ip_config = ( StreamIpConfig * ) SnortAlloc( sizeof( StreamIpConfig ) );
556 StreamInitIp( );
557 }
558
559 /* Call the protocol specific initializer */
560 StreamIpPolicyInit( config->ip_config, args );
561 }
562
563 int StreamVerifyProtocolConfigs( struct _SnortConfig *sc, StreamConfig *s5c,
564 tSfPolicyId policyId, int *proto_flags )
565 {
566 int tcpNotConfigured = 0;
567 int udpNotConfigured = 0;
568 int icmpNotConfigured = 0;
569 int ipNotConfigured = 0;
570
571 if( s5c->tcp_config )
572 {
573 tcpNotConfigured = StreamVerifyTcpConfig( sc, s5c->tcp_config, policyId );
574 if( tcpNotConfigured )
575 WarningMessage("WARNING: Stream TCP misconfigured.\n");
576 else
577 *proto_flags |= PROTO_BIT__TCP;
578 }
579
580 if( s5c->udp_config )
581 {
582 udpNotConfigured = StreamVerifyUdpConfig( sc, s5c->udp_config, policyId );
583 if( udpNotConfigured )
584 WarningMessage("WARNING: Stream UDP misconfigured.\n");
585 else
586 *proto_flags |= PROTO_BIT__UDP;
587 }
588
589 if( s5c->icmp_config )
590 {
591 icmpNotConfigured = StreamVerifyIcmpConfig( s5c->icmp_config, policyId );
592 if( icmpNotConfigured )
593 WarningMessage("WARNING: Stream ICMP misconfigured.\n");
594 else
595 *proto_flags |= PROTO_BIT__ICMP;
596 }
597
598 if( s5c->ip_config )
599 {
600 ipNotConfigured = StreamVerifyIpConfig( s5c->ip_config, policyId );
601 if( ipNotConfigured )
602 WarningMessage("WARNING: Stream IP misconfigured.\n");
603 else
604 *proto_flags |= PROTO_BIT__IP;
605 }
606
607 return( tcpNotConfigured || udpNotConfigured || icmpNotConfigured || ipNotConfigured );
608 }
609
610 static int StreamVerifyConfigPolicy( struct _SnortConfig *sc, tSfPolicyUserContextId config,
611 tSfPolicyId policyId, void* pData )
612 {
613 int configNotValid = 0;
614 int proto_flags = 0;
615 tSfPolicyId tmp_policy_id = getParserPolicy( sc );
616 StreamConfig *stream_conf = ( StreamConfig * ) pData;
617
618 if( stream_conf->verified )
619 return 0;
620
621 // verify that session is configured.
622 if ( stream_conf->session_config == NULL )
623 {
624 FatalError("%s(%d) No Stream session configuration...exiting.\n", __FILE__, __LINE__);
625 }
626
627 configNotValid = StreamVerifyProtocolConfigs( sc, stream_conf, policyId, &proto_flags );
628 if ( configNotValid )
629 {
630 FatalError("%s(%d) Stream not properly configured... exiting\n", __FILE__, __LINE__);
631 }
632
633 stream_conf->verified = true;
634 setParserPolicy( sc, policyId );
635 AddFuncToPreprocList( sc, StreamProcess, PP_STREAM6_PRIORITY, PP_STREAM, proto_flags );
636 setParserPolicy( sc, tmp_policy_id );
637
638 return 0;
639 }
640
641 static int StreamVerifyConfig(struct _SnortConfig *sc)
642 {
643 int rval = sfPolicyUserDataIterate( sc, stream_parsing_config, StreamVerifyConfigPolicy );
644 if( rval )
645 return rval;
646
647 stream_online_config = stream_parsing_config;
648 stream_parsing_config = NULL;
649
650 #ifdef TARGET_BASED
651 initServiceFilterStatus( sc );
652 #endif
653
654 return 0;
655 }
656
657 static void StreamReset(int signal, void *foo)
658 {
659 if (stream_online_config == NULL)
660 return;
661
662 StreamResetTcp();
663 StreamResetUdp();
664 StreamResetIcmp();
665 StreamResetIp();
666 }
667
668 static void StreamResetStats(int signal, void *foo)
669 {
670 memset(&s5stats, 0, sizeof(s5stats));
671 StreamResetTcpPrunes();
672 StreamResetUdpPrunes();
673 StreamResetIcmpPrunes();
674 StreamResetIpPrunes();
675 }
676
677 static void StreamCleanExit(int signal, void *foo)
678 {
679 #ifdef ENABLE_QUICK_EXIT
680 LogMessage("Snort quick exit enabled\n");
681 return;
682 #else
683 /* Protocol specific cleanup actions */
684 StreamCleanTcp();
685 StreamCleanUdp();
686 StreamCleanIcmp();
687 StreamCleanIp();
688
689 StreamFreeConfigs(stream_online_config);
690 stream_online_config = NULL;
691 #endif
692 }
693
694 static void DisplayStreamStatistics (uint16_t type, void *old_context, struct _THREAD_ELEMENT *te, ControlDataSendFunc f)
695 {
696 char buffer[CS_STATS_BUF_SIZE + 1];
697 int len = 0;
698 int total_sessions = s5stats.total_tcp_sessions + s5stats.total_udp_sessions +
699 s5stats.total_icmp_sessions + s5stats.total_ip_sessions;
700
701 if (total_sessions) {
702 len = snprintf(buffer, CS_STATS_BUF_SIZE, "Stream statistics:\n"
703 " Total sessions: %u\n"
704 " TCP sessions: %u\n"
705 " UDP sessions: %u\n"
706 " ICMP sessions: %u\n"
707 " IP sessions: %u\n"
708 " TCP Prunes: %u\n"
709 " UDP Prunes: %u\n"
710 " ICMP Prunes: %u\n"
711 " IP Prunes: %u\n"
712 "TCP StreamTrackers Created: %u\n"
713 "TCP StreamTrackers Deleted: %u\n"
714 " TCP Timeouts: %u\n"
715 " TCP Overlaps: %u\n"
716 " TCP Segments Queued: %u\n"
717 " TCP Segments Released: %u\n"
718 " TCP Rebuilt Packets: %u\n"
719 " TCP Segments Used: %u\n"
720 " TCP Discards: %u\n"
721 " TCP Gaps: %u\n"
722 " UDP Sessions Created: %u\n"
723 " UDP Sessions Deleted: %u\n"
724 " UDP Timeouts: %u\n"
725 " UDP Discards: %u\n"
726 " Events: %u\n"
727 " Internal Events: %u\n"
728 " TCP Port Filter\n"
729 " Filtered: %u\n"
730 " Inspected: %u\n"
731 " Tracked: %u\n"
732 " UDP Port Filter\n"
733 " Filtered: %u\n"
734 " Inspected: %u\n"
735 " Tracked: %u\n"
736 , total_sessions
737 , s5stats.total_tcp_sessions
738 , s5stats.total_udp_sessions
739 , s5stats.total_icmp_sessions
740 , s5stats.total_ip_sessions
741 , StreamGetTcpPrunes()
742 , StreamGetUdpPrunes()
743 , StreamGetIcmpPrunes()
744 , StreamGetIpPrunes()
745 , s5stats.tcp_streamtrackers_created
746 , s5stats.tcp_streamtrackers_released
747 , s5stats.tcp_timeouts
748 , s5stats.tcp_overlaps
749 , s5stats.tcp_streamsegs_created
750 , s5stats.tcp_streamsegs_released
751 , s5stats.tcp_rebuilt_packets
752 , s5stats.tcp_rebuilt_seqs_used
753 , s5stats.tcp_discards
754 , s5stats.tcp_gaps
755 , s5stats.udp_sessions_created
756 , s5stats.udp_sessions_released
757 , s5stats.udp_timeouts
758 , s5stats.udp_discards
759 , s5stats.events
760 , s5stats.internalEvents
761 , s5stats.tcp_port_filter.filtered
762 , s5stats.tcp_port_filter.inspected
763 , s5stats.tcp_port_filter.session_tracked
764 , s5stats.udp_port_filter.filtered
765 , s5stats.udp_port_filter.inspected
766 , s5stats.udp_port_filter.session_tracked);
767 } else {
768 len = snprintf(buffer, CS_STATS_BUF_SIZE, "Stream statistics not available\n Total sessions: %u", total_sessions);
769 }
770
771 if (-1 == f(te, (const uint8_t *)buffer, len)) {
772 LogMessage("Unable to send data to the frontend\n");
773 }
774 }
775
776 static void StreamPrintStats(int exiting)
777 {
778 LogMessage("Stream statistics:\n");
779 LogMessage(" Total sessions: %u\n", s5stats.total_tcp_sessions +
780 s5stats.total_udp_sessions +
781 s5stats.total_icmp_sessions +
782 s5stats.total_ip_sessions);
783
784 LogMessage(" TCP sessions: %u\n", s5stats.total_tcp_sessions);
785 LogMessage(" Active TCP sessions: %u\n", s5stats.active_tcp_sessions);
786 LogMessage(" Non mempool TCP sess mem: %u\n", session_mem_in_use);
787 LogMessage(" TCP mempool used: %"PRIu64"\n", get_tcp_used_mempool());
788 LogMessage(" UDP sessions: %u\n", s5stats.total_udp_sessions);
789 LogMessage(" Active UDP sessions: %u\n", s5stats.active_udp_sessions);
790 LogMessage(" UDP mempool used: %"PRIu64"\n", get_udp_used_mempool());
791 LogMessage(" ICMP sessions: %u\n", s5stats.total_icmp_sessions);
792 LogMessage(" Active ICMP sessions: %u\n", s5stats.active_icmp_sessions);
793 LogMessage(" ICMP mempool used: %"PRIu64"\n", get_icmp_used_mempool());
794 LogMessage(" IP sessions: %u\n", s5stats.total_ip_sessions);
795 LogMessage(" Active IP sessions: %u\n", s5stats.active_ip_sessions);
796 LogMessage(" IP mempool used: %"PRIu64"\n", get_ip_used_mempool());
797
798 LogMessage(" TCP Prunes: %u\n", StreamGetTcpPrunes());
799 LogMessage(" UDP Prunes: %u\n", StreamGetUdpPrunes());
800 LogMessage(" ICMP Prunes: %u\n", StreamGetIcmpPrunes());
801 LogMessage(" IP Prunes: %u\n", StreamGetIpPrunes());
802 LogMessage("TCP StreamTrackers Created: %u\n", s5stats.tcp_streamtrackers_created);
803 LogMessage("TCP StreamTrackers Deleted: %u\n", s5stats.tcp_streamtrackers_released);
804 LogMessage(" TCP Timeouts: %u\n", s5stats.tcp_timeouts);
805 LogMessage(" TCP Overlaps: %u\n", s5stats.tcp_overlaps);
806 LogMessage(" TCP Segments Queued: %u\n", s5stats.tcp_streamsegs_created);
807 LogMessage(" TCP Segments Released: %u\n", s5stats.tcp_streamsegs_released);
808 LogMessage(" TCP Rebuilt Packets: %u\n", s5stats.tcp_rebuilt_packets);
809 LogMessage(" TCP Segments Used: %u\n", s5stats.tcp_rebuilt_seqs_used);
810 LogMessage(" TCP Discards: %u\n", s5stats.tcp_discards);
811 LogMessage(" TCP Gaps: %u\n", s5stats.tcp_gaps);
812 LogMessage(" UDP Sessions Created: %u\n", s5stats.udp_sessions_created);
813 LogMessage(" UDP Sessions Deleted: %u\n", s5stats.udp_sessions_released);
814 LogMessage(" UDP Timeouts: %u\n", s5stats.udp_timeouts);
815 LogMessage(" UDP Discards: %u\n", s5stats.udp_discards);
816 LogMessage(" Events: %u\n", s5stats.events);
817 LogMessage(" Internal Events: %u\n", s5stats.internalEvents);
818 LogMessage(" TCP Port Filter\n");
819 LogMessage(" Filtered: %u\n", s5stats.tcp_port_filter.filtered);
820 LogMessage(" Inspected: %u\n", s5stats.tcp_port_filter.inspected);
821 LogMessage(" Tracked: %u\n", s5stats.tcp_port_filter.session_tracked);
822 LogMessage(" UDP Port Filter\n");
823 LogMessage(" Filtered: %u\n", s5stats.udp_port_filter.filtered);
824 LogMessage(" Inspected: %u\n", s5stats.udp_port_filter.inspected);
825 LogMessage(" Tracked: %u\n", s5stats.udp_port_filter.session_tracked);
826
827 // TBD-EDM move to session will need to fix reg tests?
828 #ifdef ENABLE_HA
829 SessionPrintHAStats();
830 #endif
831
832 }
833
834 static void checkOnewayStatus( uint32_t protocol, SessionControlBlock *scb )
835 {
836 if( scb->in_oneway_list && scb->session_established )
837 session_api->remove_session_from_oneway_list( protocol, scb );
838 }
839
840 static void updateMplsHeaders(Packet *p, SessionControlBlock *scb )
841 {
842 uint8_t layerIndex;
843 uint32_t direction = session_api->get_packet_direction(p);
844
845 if(direction == PKT_FROM_CLIENT && !(scb->clientMplsHeader->start))
846 {
847 for(layerIndex=0; layerIndex < p->next_layer; layerIndex++)
848 {
849 if( p->layers[layerIndex].proto == PROTO_MPLS && p->layers[layerIndex].start != NULL )
850 {
851 scb->clientMplsHeader->length = p->layers[layerIndex].length;
852 scb->clientMplsHeader->start = (uint8_t*)SnortMalloc(scb->clientMplsHeader->length);
853 memcpy(scb->clientMplsHeader->start,p->layers[layerIndex].start,scb->clientMplsHeader->length);
854 break;
855 }
856 }
857 }
858 else if ( direction == PKT_FROM_SERVER && !(scb->serverMplsHeader->start))
859 {
860 for(layerIndex=0; layerIndex < p->next_layer; layerIndex++)
861 {
862 if( p->layers[layerIndex].proto == PROTO_MPLS && p->layers[layerIndex].start != NULL )
863 {
864 scb->serverMplsHeader->length = p->layers[layerIndex].length;
865 scb->serverMplsHeader->start = (uint8_t*)SnortMalloc(scb->serverMplsHeader->length);
866 memcpy(scb->serverMplsHeader->start,p->layers[layerIndex].start, scb->serverMplsHeader->length);
867 break;
868 }
869 }
870 }
871 else
872 return;
873 }
874
875
876 /*
877 * MAIN ENTRY POINT
878 */
879 void StreamProcess(Packet *p, void *context)
880 {
881 SessionKey key;
882 SessionControlBlock *scb;
883 PROFILE_VARS;
884
885 if (!firstPacketTime)
886 firstPacketTime = p->pkth->ts.tv_sec;
887
888 DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
889 "++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"););
890 DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "In Stream!\n"););
891
892 // get the session and if NULL, bail we can't do anything with that...
893 scb = p->ssnptr;
894 if( scb == NULL )
895 {
896 DEBUG_WRAP( DebugMessage( DEBUG_STREAM_STATE,
897 "Stream Processing called with NULL pointer to session control block\n" ) );
898 return;
899 }
900
901 stream_session_config = scb->session_config;
902 if( scb->stream_config_stale || scb->stream_config == NULL )
903 {
904 scb->stream_config = sfPolicyUserDataGet( stream_online_config, getNapRuntimePolicy() );
905 if( scb->stream_config == NULL )
906 {
907 ErrorMessage("Stream Configuration is NULL, Stream Packet Processing Terminated.\n");
908 return;
909 }
910 else
911 {
912 scb->proto_policy = NULL;
913 scb->stream_config_stale = false;
914 }
915 }
916
917 if(!IsEligible(p))
918 {
919 DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Is not eligible!\n"););
920 return;
921 }
922
923 #ifdef MPLS
924 if(scb->clientMplsHeader != NULL && scb->serverMplsHeader != NULL )
925 {
926 if(!(scb->clientMplsHeader->start) || !(scb->serverMplsHeader->start))
927 updateMplsHeaders(p,scb);
928 }
929 #endif
930
931 PREPROC_PROFILE_START(s5PerfStats);
932 /* Call individual TCP/UDP/ICMP/IP processing, per GET_IPH_PROTO(p) */
933 switch( GET_IPH_PROTO( p ) )
934 {
935 case IPPROTO_TCP:
936 if( session_api->protocol_tracking_enabled( SESSION_PROTO_TCP ) )
937 {
938 StreamProcessTcp( p, scb, scb->proto_policy, &key );
939 checkOnewayStatus( SESSION_PROTO_TCP, scb );
940 }
941 break;
942
943 case IPPROTO_UDP:
944 if (session_api->protocol_tracking_enabled( SESSION_PROTO_UDP ) )
945 {
946 StreamProcessUdp(p, scb, scb->proto_policy, &key);
947 checkOnewayStatus( SESSION_PROTO_UDP, scb );
948 }
949 break;
950
951 case IPPROTO_ICMP:
952 if (session_api->protocol_tracking_enabled( SESSION_PROTO_ICMP ) )
953 {
954 StreamProcessIcmp(p);
955 checkOnewayStatus( SESSION_PROTO_ICMP, scb );
956 break;
957 }
958 // fall thru ...
959
960 default:
961 if (session_api->protocol_tracking_enabled( SESSION_PROTO_IP ) )
962 {
963 StreamProcessIp(p, scb, &key);
964 checkOnewayStatus( SESSION_PROTO_IP, scb );
965 }
966 break;
967 }
968
969 PREPROC_PROFILE_END(s5PerfStats);
970 }
971
972 static inline int IsEligible(Packet *p)
973 {
974 if ((p->frag_flag) || (p->error_flags & PKT_ERR_CKSUM_IP))
975 return 0;
976
977 if (p->packet_flags & PKT_REBUILT_STREAM)
978 return 0;
979
980 if (!IPH_IS_VALID(p))
981 return 0;
982
983 switch(GET_IPH_PROTO(p))
984 {
985 case IPPROTO_TCP:
986 {
987 if(p->tcph == NULL)
988 return 0;
989
990 if (p->error_flags & PKT_ERR_CKSUM_TCP)
991 return 0;
992 }
993 break;
994 case IPPROTO_UDP:
995 {
996 if(p->udph == NULL)
997 return 0;
998
999 if (p->error_flags & PKT_ERR_CKSUM_UDP)
1000 return 0;
1001 }
1002 break;
1003 case IPPROTO_ICMP:
1004 case IPPROTO_ICMPV6:
1005 {
1006 if(p->icmph == NULL)
1007 return 0;
1008
1009 if (p->error_flags & PKT_ERR_CKSUM_ICMP)
1010 return 0;
1011 }
1012 break;
1013 default:
1014 if(p->iph == NULL)
1015 return 0;
1016 break;
1017 }
1018
1019 return 1;
1020 }
1021
1022 /*************************** API Implementations *******************/
1023
1024 static int StreamMidStreamDropAlert(void)
1025 {
1026 StreamConfig *config = sfPolicyUserDataGet(stream_online_config, getNapRuntimePolicy());
1027
1028 if (config == NULL)
1029 return 1;
1030
1031 return (config->session_config->flags &
1032 STREAM_CONFIG_MIDSTREAM_DROP_NOALERT) ? 0 : 1;
1033 }
1034
1035 static inline bool StreamOkToFlush(Packet *p)
1036 {
1037 SessionControlBlock *ssn;
1038
1039 if ((p == NULL) || (p->ssnptr == NULL))
1040 {
1041 DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
1042 "Don't flush NULL packet or session\n"););
1043 return false;
1044 }
1045
1046 ssn = p->ssnptr;
1047
1048 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1049 return false;
1050
1051 if ((ssn->protocol != IPPROTO_TCP) ||
1052 (p->packet_flags & PKT_REBUILT_STREAM))
1053 {
1054 DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
1055 "Don't flush on rebuilt packets\n"););
1056 return false;
1057 }
1058 return true;
1059 }
1060
1061 static int StreamAlertFlushStream(Packet *p)
1062 {
1063
1064 if (!StreamOkToFlush(p))
1065 return 0;
1066
1067 if (!(stream_session_config->flags & STREAM_CONFIG_FLUSH_ON_ALERT))
1068 {
1069 DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
1070 "Don't flush on alert from individual packet\n"););
1071 return 0;
1072 }
1073
1074 /* Flush the listener queue -- this is the same side that
1075 * the packet gets inserted into */
1076 StreamFlushListener(p, p->ssnptr);
1077
1078 return 0;
1079 }
1080
1081 static int StreamRequestFlushStream(Packet *p)
1082 {
1083 if (!StreamOkToFlush(p))
1084 return 0;
1085
1086 /* Flush the talker queue -- this is the opposite side that
1087 * the packet gets inserted into */
1088 StreamFlushListener(p, p->ssnptr);
1089
1090 return 0;
1091 }
1092
1093 static int StreamResponseFlushStream(Packet *p)
1094 {
1095 if (!StreamOkToFlush(p))
1096 return 0;
1097
1098 /* Flush the talker queue -- this is the opposite side that
1099 * the packet gets inserted into */
1100 StreamFlushTalker(p, p->ssnptr);
1101
1102 return 0;
1103 }
1104
1105 static int StreamAddSessionAlert(
1106 void *ssnptr,
1107 Packet *p,
1108 uint32_t gid,
1109 uint32_t sid)
1110 {
1111 SessionControlBlock *ssn;
1112
1113 if ( !ssnptr )
1114 return 0;
1115
1116 ssn = (SessionControlBlock *)ssnptr;
1117 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1118 return 0;
1119
1120 /* Don't need to do this for other protos because they don't
1121 do any reassembly. */
1122 if ( GET_IPH_PROTO(p) != IPPROTO_TCP )
1123 return 0;
1124
1125 return StreamAddSessionAlertTcp(ssn, p, gid, sid);
1126 }
1127
1128 /* return non-zero if gid/sid have already been seen */
1129 static int StreamCheckSessionAlert(
1130 void *ssnptr,
1131 Packet *p,
1132 uint32_t gid,
1133 uint32_t sid)
1134 {
1135 SessionControlBlock *ssn;
1136
1137 if ( !ssnptr )
1138 return 0;
1139
1140 ssn = (SessionControlBlock *)ssnptr;
1141 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1142 return 0;
1143
1144 /* Don't need to do this for other protos because they don't
1145 do any reassembly. */
1146 if ( GET_IPH_PROTO(p) != IPPROTO_TCP )
1147 return 0;
1148
1149 return StreamCheckSessionAlertTcp(ssn, p, gid, sid);
1150 }
1151
1152 static int StreamUpdateSessionAlert(
1153 void *ssnptr,
1154 Packet *p,
1155 uint32_t gid,
1156 uint32_t sid,
1157 uint32_t event_id,
1158 uint32_t event_second)
1159 {
1160 SessionControlBlock *ssn;
1161
1162 if ( !ssnptr )
1163 return 0;
1164
1165 ssn = (SessionControlBlock *)ssnptr;
1166 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1167 return 0;
1168
1169 /* Don't need to do this for other protos because they don't
1170 do any reassembly. */
1171 if ( GET_IPH_PROTO(p) != IPPROTO_TCP )
1172 return 0;
1173
1174 return StreamUpdateSessionAlertTcp(ssn, p, gid, sid, event_id, event_second);
1175 }
1176
1177 static void StreamSetExtraData (void* pv, Packet* p, uint32_t flag)
1178 {
1179 SessionControlBlock* ssn = pv;
1180
1181 if ( !ssn )
1182 return;
1183
1184 StreamSetExtraDataTcp(ssn, p, flag);
1185 }
1186
1187 // FIXTHIS get pv/ssn from packet directly?
1188 static void StreamClearExtraData (void* pv, Packet* p, uint32_t flag)
1189 {
1190 SessionControlBlock* ssn = pv;
1191
1192 if ( !ssn )
1193 return;
1194
1195 StreamClearExtraDataTcp(ssn, p, flag);
1196 }
1197
1198 static int StreamGetRebuiltPackets(
1199 Packet *p,
1200 PacketIterator callback,
1201 void *userdata)
1202 {
1203 SessionControlBlock *ssn = (SessionControlBlock*)p->ssnptr;
1204
1205 if (!ssn || ssn->protocol != IPPROTO_TCP)
1206 return 0;
1207
1208 /* Only if this is a rebuilt packet */
1209 if (!(p->packet_flags & PKT_REBUILT_STREAM))
1210 return 0;
1211
1212 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1213 return 0;
1214
1215 return GetTcpRebuiltPackets(p, ssn, callback, userdata);
1216 }
1217
1218 static int StreamGetStreamSegments(
1219 Packet *p,
1220 StreamSegmentIterator callback,
1221 void *userdata)
1222 {
1223 SessionControlBlock *ssn = (SessionControlBlock*)p->ssnptr;
1224
1225 if ((ssn == NULL) || (ssn->protocol != IPPROTO_TCP))
1226 return -1;
1227
1228 /* Only if this is a rebuilt packet */
1229 if (!(p->packet_flags & PKT_REBUILT_STREAM))
1230 return -1;
1231
1232 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1233 return -1;
1234
1235 return GetTcpStreamSegments(p, ssn, callback, userdata);
1236 }
1237
1238 static void StreamUpdateDirection( void * scbptr, char dir, sfaddr_t* ip, uint16_t port )
1239 {
1240 SessionControlBlock *scb = (SessionControlBlock *)scbptr;
1241
1242 if (!scb)
1243 return;
1244
1245 if (StreamSetRuntimeConfiguration(scb, scb->protocol) == -1)
1246 return;
1247
1248 switch (scb->protocol)
1249 {
1250 case IPPROTO_TCP:
1251 TcpUpdateDirection(scb, dir, ip, port);
1252 break;
1253 case IPPROTO_UDP:
1254 UdpUpdateDirection(scb, dir, ip, port);
1255 break;
1256 case IPPROTO_ICMP:
1257 //IcmpUpdateDirection(scb, dir, ip, port);
1258 break;
1259 }
1260 }
1261
1262 static char StreamGetReassemblyDirection(void *ssnptr)
1263 {
1264 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1265
1266 if (!ssn || ssn->protocol != IPPROTO_TCP)
1267 return SSN_DIR_NONE;
1268
1269 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1270 return SSN_DIR_NONE;
1271
1272 return StreamGetReassemblyDirectionTcp(ssn);
1273 }
1274
1275 static uint32_t StreamGetFlushPoint(void *ssnptr, char dir)
1276 {
1277 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1278
1279 if ((ssn == NULL) || (ssn->protocol != IPPROTO_TCP))
1280 return 0;
1281
1282 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1283 return 0;
1284
1285 return StreamGetFlushPointTcp(ssn, dir);
1286 }
1287
1288 static void StreamSetFlushPoint(void *ssnptr, char dir, uint32_t flush_point)
1289 {
1290 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1291
1292 if ((ssn == NULL) || (ssn->protocol != IPPROTO_TCP))
1293 return;
1294
1295 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1296 return;
1297
1298 StreamSetFlushPointTcp(ssn, dir, flush_point);
1299 }
1300
1301 static char StreamSetReassembly(void *ssnptr,
1302 uint8_t flush_policy,
1303 char dir,
1304 char flags)
1305 {
1306 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1307
1308 if (!ssn || ssn->protocol != IPPROTO_TCP)
1309 return 0;
1310
1311 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1312 return 0;
1313
1314 return StreamSetReassemblyTcp(ssn, flush_policy, dir, flags);
1315 }
1316
1317 #ifdef HAVE_DAQ_DECRYPTED_SSL
1318 static int StreamSimulateTcpAck(void *ssnptr,
1319 uint8_t dir,
1320 uint32_t len)
1321 {
1322 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1323
1324 if (!ssn || ssn->protocol != IPPROTO_TCP)
1325 return -1;
1326
1327 stream_session_config = ssn->session_config;
1328
1329 return StreamSimulatePeerTcpAckp(ssn, dir, len);
1330 }
1331 #endif
1332
1333 static char StreamGetReassemblyFlushPolicy(void *ssnptr, char dir)
1334 {
1335 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1336
1337 if (!ssn || ssn->protocol != IPPROTO_TCP)
1338 return STREAM_FLPOLICY_NONE;
1339
1340 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1341 return STREAM_FLPOLICY_NONE;
1342
1343 return StreamGetReassemblyFlushPolicyTcp(ssn, dir);
1344 }
1345
1346 static char StreamIsStreamSequenced(void *ssnptr, char dir)
1347 {
1348 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1349
1350 if (!ssn || ssn->protocol != IPPROTO_TCP)
1351 return 1;
1352
1353 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1354 return 1;
1355
1356 return StreamIsStreamSequencedTcp(ssn, dir);
1357 }
1358
1359 static int StreamMissingInReassembled(void *ssnptr, char dir)
1360 {
1361 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1362
1363 if (!ssn || ssn->protocol != IPPROTO_TCP)
1364 return SSN_MISSING_NONE;
1365
1366 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1367 return SSN_MISSING_NONE;
1368
1369 return StreamMissingInReassembledTcp(ssn, dir);
1370 }
1371
1372 static void StreamDropPacket( Packet *p )
1373 {
1374 SessionControlBlock* scb = (SessionControlBlock*)p->ssnptr;
1375
1376 if ( !scb )
1377 return;
1378
1379 switch (scb->protocol)
1380 {
1381 case IPPROTO_TCP:
1382 StreamTcpSessionClear(p);
1383 break;
1384 case IPPROTO_UDP:
1385 UdpSessionCleanup(scb);
1386 break;
1387 case IPPROTO_IP:
1388 IpSessionCleanup(scb);
1389 break;
1390 case IPPROTO_ICMP:
1391 IcmpSessionCleanup(scb);
1392 break;
1393 default:
1394 break;
1395 }
1396
1397 if (!(p->packet_flags & PKT_STATELESS))
1398 session_api->drop_traffic(p, p->ssnptr, SSN_DIR_BOTH);
1399 }
1400
1401 static char StreamPacketsMissing(void *ssnptr, char dir)
1402 {
1403 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1404
1405 if (!ssn || ssn->protocol != IPPROTO_TCP)
1406 return 1;
1407
1408 if (StreamSetRuntimeConfiguration(ssn, ssn->protocol) == -1)
1409 return 1;
1410
1411 return StreamPacketsMissingTcp(ssn, dir);
1412 }
1413
1414 #ifdef TARGET_BASED
1415 static void initServiceFilterStatus( struct _SnortConfig *sc )
1416 {
1417 SFGHASH_NODE *hashNode;
1418 tSfPolicyId policyId = 0;
1419
1420 if( sc == NULL )
1421 {
1422 FatalError("%s(%d) Snort config for parsing is NULL.\n", __FILE__, __LINE__);
1423 }
1424
1425 for( hashNode = sfghash_findfirst( sc->otn_map );
1426 hashNode;
1427 hashNode = sfghash_findnext( sc->otn_map ) )
1428 {
1429 OptTreeNode *otn = ( OptTreeNode * ) hashNode->data;
1430
1431 for( policyId = 0; policyId < otn->proto_node_num; policyId++ )
1432 {
1433 RuleTreeNode *rtn = getRtnFromOtn( otn, policyId );
1434 if( rtn && ( rtn->proto == IPPROTO_TCP ) )
1435 {
1436 unsigned int svc_idx;
1437 for( svc_idx = 0; svc_idx < otn->sigInfo.num_services; svc_idx++ )
1438 if( otn->sigInfo.services[svc_idx].service_ordinal )
1439 setServiceFilterStatus( sc, otn->sigInfo.services[svc_idx].service_ordinal,
1440 PORT_MONITOR_SESSION, policyId, 1 );
1441 }
1442 }
1443 }
1444 }
1445
1446 static void setServiceFilterStatus( struct _SnortConfig *sc, int service, int status, tSfPolicyId policyId, int parsing )
1447 {
1448 StreamConfig *config;
1449
1450 config = getStreamPolicyConfig( policyId, parsing );
1451 if ( config != NULL )
1452 config->service_filter[ service ] = status;
1453 }
1454
1455 static int getServiceFilterStatus( struct _SnortConfig *sc, int service, tSfPolicyId policyId, int parsing )
1456 {
1457 StreamConfig *config;
1458
1459 config = getStreamPolicyConfig( policyId, parsing );
1460 if ( config != NULL )
1461 return config->service_filter[ service ];
1462 else
1463 return PORT_MONITOR_NONE;
1464 }
1465 #endif
1466
1467 int isPacketFilterDiscard( Packet *p, int ignore_any_rules )
1468 {
1469 uint8_t action = 0;
1470 tPortFilterStats *pPortFilterStats = NULL;
1471 tSfPolicyId policy_id = getNapRuntimePolicy();
1472 #ifdef TARGET_BASED
1473 int protocolId = GetProtocolReference(p);
1474 #endif
1475
1476 #ifdef TARGET_BASED
1477 if( ( protocolId > 0 ) && getServiceFilterStatus( NULL, protocolId, policy_id, 0 ) )
1478 {
1479 return PORT_MONITOR_PACKET_PROCESS;
1480 }
1481 #endif
1482
1483 switch( GET_IPH_PROTO( p ) )
1484 {
1485 case IPPROTO_TCP:
1486 if( session_api->protocol_tracking_enabled( SESSION_PROTO_TCP ) )
1487 {
1488 action = s5TcpGetPortFilterStatus( NULL, p->sp, policy_id, 0 )
1489 |
1490 s5TcpGetPortFilterStatus( NULL, p->dp, policy_id, 0 );
1491 }
1492
1493 pPortFilterStats = &s5stats.tcp_port_filter;
1494 break;
1495
1496 case IPPROTO_UDP:
1497 if( session_api->protocol_tracking_enabled( SESSION_PROTO_UDP ) )
1498 {
1499 action = s5UdpGetPortFilterStatus( NULL, p->sp, policy_id, 0 )
1500 |
1501 s5UdpGetPortFilterStatus( NULL, p->dp, policy_id, 0 );
1502 }
1503
1504 pPortFilterStats = &s5stats.udp_port_filter;
1505 break;
1506
1507 default:
1508 return PORT_MONITOR_PACKET_PROCESS;
1509 }
1510
1511 if( !( action & PORT_MONITOR_SESSION_BITS ) )
1512 {
1513 if( !( action & PORT_MONITOR_INSPECT ) && ignore_any_rules )
1514 {
1515 /* Ignore this TCP packet entirely */
1516 DisableDetect( p );
1517 //otn_tmp = NULL;
1518 pPortFilterStats->filtered++;
1519 }
1520 else
1521 {
1522 pPortFilterStats->inspected++;
1523 }
1524
1525 return PORT_MONITOR_PACKET_DISCARD;
1526 }
1527
1528 pPortFilterStats->session_tracked++;
1529 return PORT_MONITOR_PACKET_PROCESS;
1530 }
1531
1532 int isPacketFilterDiscardUdp ( Packet *p, int ignore_any_rules )
1533 {
1534 uint8_t action_ips = 0, action_nap = 0;
1535 tPortFilterStats *pPortFilterStats = NULL;
1536 SessionControlBlock *scb;
1537 tSfPolicyId policy_id_ips = getIpsRuntimePolicy();
1538 tSfPolicyId policy_id_nap = getNapRuntimePolicy();
1539 SnortPolicy *policy;
1540 PreprocEnableMask enabled_pps;
1541 bool nap_inspect = false;
1542
1543 scb = p->ssnptr;
1544 if ( !scb ) {
1545 DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Session control block of packet is NULL.\n"););
1546 return PORT_MONITOR_PACKET_DISCARD;
1547 }
1548
1549 if ( session_api->protocol_tracking_enabled( SESSION_PROTO_UDP ) &&
1550 ( snort_conf->udp_ips_port_filter_list ) ) {
1551 action_ips = s5UdpGetIPSPortFilterStatus (snort_conf, p->sp, p->dp, policy_id_ips);
1552 }
1553
1554 pPortFilterStats = &s5stats.udp_port_filter;
1555
1556 // Check if NAP has marked it as inspect/filter.
1557 action_nap = s5UdpGetPortFilterStatus (NULL, p->sp, policy_id_nap, 0) |
1558 s5UdpGetPortFilterStatus (NULL, p->dp, policy_id_nap, 0);
1559 if ( !( action_nap & PORT_MONITOR_SESSION_BITS ) && ( action_nap & PORT_MONITOR_INSPECT ) && ignore_any_rules ) {
1560 nap_inspect = true ;
1561 }
1562
1563 if ( !( action_ips & PORT_MONITOR_SESSION_BITS ) ) {
1564 if ( !( action_ips & PORT_MONITOR_INSPECT ) && ignore_any_rules ) {
1565 // Port not present in IPS port list too, disable detection.
1566 DisableDetect( p );
1567 } else {
1568 /*
1569 * If nap_inspect is true it implies NAP marked it for inspect, now IPS too marking for inspect,
1570 * so no change in counter.
1571 * If nap_inspect is false ie: NAP marked for filter, now IPS marks it to inspect undo the NAP counter.
1572 */
1573 if ( !nap_inspect ) {
1574 sfBase.total_udp_filtered_packets--;
1575 pPortFilterStats->filtered--;
1576 pPortFilterStats->inspected++;
1577 }
1578 }
1579 return PORT_MONITOR_PACKET_DISCARD;
1580 }
1581 // Undo NAPs increment and enable detection
1582 if ( nap_inspect )
1583 pPortFilterStats->inspected--;
1584 else
1585 pPortFilterStats->filtered--;
1586
1587 pPortFilterStats->session_tracked++;
1588 policy = snort_conf->targeted_policies[ getNapRuntimePolicy() ];
1589 enabled_pps = policy->pp_enabled[ p->dp ] | policy->pp_enabled[ p->sp ];
1590 EnableContentPreprocDetection (p,enabled_pps);
1591
1592 return PORT_MONITOR_PACKET_PROCESS;
1593 }
1594
1595 static uint8_t StreamRegisterPAFPort( struct _SnortConfig *sc, tSfPolicyId id, uint16_t server_port,
1596 bool to_server, PAF_Callback cb, bool autoEnable)
1597 {
1598 return s5_paf_register_port( sc, id, server_port, to_server, cb, autoEnable );
1599 }
1600
1601 static uint8_t StreamRegisterPAFService( struct _SnortConfig *sc, tSfPolicyId id, uint16_t service,
1602 bool to_server, PAF_Callback cb, bool autoEnable)
1603 {
1604 return s5_paf_register_service( sc, id, service, to_server, cb, autoEnable );
1605 }
1606
1607 static uint32_t StreamRegisterXtraData( LogFunction f )
1608 {
1609 uint32_t i = 0;
1610 while( i < xtradata_func_count )
1611 {
1612 if( xtradata_map[i++] == f )
1613 {
1614 return i;
1615 }
1616 }
1617 if( xtradata_func_count == LOG_FUNC_MAX )
1618 return 0;
1619 xtradata_map[xtradata_func_count++] = f;
1620 return xtradata_func_count;
1621 }
1622
1623 static uint32_t StreamGetXtraDataMap( LogFunction **f )
1624 {
1625 if( f )
1626 {
1627 *f = xtradata_map;
1628 return xtradata_func_count;
1629 }
1630 else
1631 return 0;
1632 }
1633
1634 static void StreamRegisterXtraDataLog( LogExtraData f, void *config )
1635 {
1636 extra_data_log = f;
1637 extra_data_config = config;
1638 }
1639
1640 void** StreamGetPAFUserData( void* ssnptr, bool to_server, uint8_t id )
1641 {
1642 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1643
1644 if (!ssn || ssn->protocol != IPPROTO_TCP)
1645 return NULL;
1646
1647 return StreamGetPAFUserDataTcp( ( SessionControlBlock * ) ssnptr, to_server, id );
1648 }
1649
1650 static bool StreamIsPafActive( void* ssnptr, bool to_server )
1651 {
1652 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1653
1654 if (!ssn || ssn->protocol != IPPROTO_TCP)
1655 return false;
1656
1657 return StreamIsPafActiveTcp( ( SessionControlBlock * ) ssnptr, to_server );
1658 }
1659
1660 static bool StreamActivatePaf( void* ssnptr, int dir, int16_t service, uint8_t type )
1661 {
1662 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1663
1664 if (!ssn || ssn->protocol != IPPROTO_TCP)
1665 return false;
1666
1667 return StreamActivatePafTcp( ( SessionControlBlock *) ssnptr, dir, service, type );
1668 }
1669
1670 static void StreamResetPolicy( void *ssnptr, int dir, uint16_t policy, uint16_t mss )
1671 {
1672 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1673
1674 if( ssn )
1675 {
1676 if (ssn->protocol != IPPROTO_TCP )
1677 return;
1678
1679 StreamResetPolicyTcp( ssnptr, dir, policy, mss );
1680 }
1681
1682 return;
1683 }
1684
1685 static void StreamSetSessionDecrypted( void *ssnptr, bool enable )
1686 {
1687 SessionControlBlock *ssn = (SessionControlBlock *)ssnptr;
1688
1689 if( ssn )
1690 {
1691 if (ssn->protocol != IPPROTO_TCP )
1692 return;
1693
1694 StreamSetSessionDecryptedTcp( ssnptr, enable );
1695 }
1696
1697 return;
1698 }
1699
1700 static bool StreamIsSessionDecrypted( void *ssnptr )
1701 {
1702 SessionControlBlock *ssn;
1703
1704 if(ssnptr)
1705 {
1706 ssn = (SessionControlBlock *)ssnptr;
1707 if (ssn->protocol == IPPROTO_TCP )
1708 return StreamIsSessionDecryptedTcp( ssnptr );
1709 else
1710 return false;
1711 }
1712 else
1713 return false;
1714 }
1715
1716 static void s5SetPortFilterStatus( struct _SnortConfig *sc, IpProto protocol, uint16_t port, uint16_t status,
1717 tSfPolicyId policyId, int parsing )
1718 {
1719 switch( protocol )
1720 {
1721 case IPPROTO_TCP:
1722 s5TcpSetPortFilterStatus( sc, port, status, policyId, parsing );
1723 break;
1724
1725 case IPPROTO_UDP:
1726 s5UdpSetPortFilterStatus( sc, port, status, policyId, parsing );
1727 break;
1728
1729 case IPPROTO_ICMP:
1730 break;
1731
1732 default:
1733 break;
1734 }
1735 }
1736
1737 static void s5UnsetPortFilterStatus( struct _SnortConfig *sc, IpProto protocol, uint16_t port, uint16_t status,
1738 tSfPolicyId policyId, int parsing )
1739 {
1740 if( status <= PORT_MONITOR_SESSION )
1741 return;
1742
1743 switch( protocol )
1744 {
1745 case IPPROTO_TCP:
1746 s5TcpUnsetPortFilterStatus( sc, port, status, policyId, parsing );
1747 break;
1748
1749 case IPPROTO_UDP:
1750 s5UdpUnsetPortFilterStatus( sc, port, status, policyId, parsing );
1751 break;
1752
1753 case IPPROTO_ICMP:
1754 break;
1755
1756 default:
1757 break;
1758 }
1759 }
1760
1761 static void StreamForceSessionExpiration( void *ssnptr )
1762 {
1763 SessionControlBlock *scb = ( SessionControlBlock * ) ssnptr;
1764
1765 if( StreamExpireSession( scb ) )
1766 {
1767 #ifdef ENABLE_HA
1768 SessionHANotifyDeletion( scb );
1769 #endif
1770 }
1771 }
1772
1773 static void StreamForceDeleteSession(void *ssnptr )
1774 {
1775 SessionControlBlock *scb = ( SessionControlBlock * ) ssnptr;
1776
1777 if(scb)
1778 StreamDeleteSession( scb );
1779 }
1780
1781 static void registerReassemblyPort( char *network, uint16_t port, int reassembly_direction )
1782 {
1783 registerPortForReassembly( network, port, reassembly_direction );
1784 }
1785
1786 static void unregisterReassemblyPort( char *network, uint16_t port, int reassembly_direction )
1787 {
1788 unregisterPortForReassembly( network, port, reassembly_direction );
1789 }
1790
1791 #define CB_MAX 32
1792 static Stream_Callback stream_cb[ CB_MAX ];
1793 static unsigned stream_cb_idx = 1;
1794
1795 static unsigned StreamRegisterHandler( Stream_Callback cb )
1796 {
1797 unsigned id;
1798
1799 for ( id = 1; id < stream_cb_idx; id++ )
1800 {
1801 if ( stream_cb[id] == cb )
1802 break;
1803 }
1804 if ( id == CB_MAX )
1805 return 0;
1806
1807 if ( id == stream_cb_idx )
1808 stream_cb[stream_cb_idx++] = cb;
1809
1810 return id;
1811 }
1812
1813 static bool StreamSetHandler( void* ssnptr, unsigned id, Stream_Event se )
1814 {
1815 SessionControlBlock *scb = ( SessionControlBlock * ) ssnptr;
1816
1817 if ( se >= SE_MAX || scb->handler[ se ] )
1818 return false;
1819
1820 scb->handler[ se ] = id;
1821 return true;
1822 }
1823
1824 static uint32_t StreamGetPreprocFlags( void *ssnptr)
1825 {
1826 SessionControlBlock *scb = ( SessionControlBlock * ) ssnptr;
1827 if( scb )
1828 return StreamGetPreprocFlagsTcp(ssnptr);
1829
1830 return 0;
1831
1832 }
1833
1834 #if defined(FEAT_OPEN_APPID)
1835 static void SetApplicationId(void* ssnptr, int16_t serviceAppId, int16_t clientAppId,
1836 int16_t payloadAppId, int16_t miscAppId)
1837 {
1838 SessionControlBlock *scb = (SessionControlBlock *)ssnptr;
1839
1840 scb->app_protocol_id[APP_PROTOID_SERVICE] = serviceAppId;
1841 scb->app_protocol_id[APP_PROTOID_CLIENT] = clientAppId;
1842 scb->app_protocol_id[APP_PROTOID_PAYLOAD] = payloadAppId;
1843 scb->app_protocol_id[APP_PROTOID_MISC] = miscAppId;
1844 }
1845
1846 static void GetApplicationId(void* ssnptr, int16_t *serviceAppId, int16_t *clientAppId,
1847 int16_t *payloadAppId, int16_t *miscAppId)
1848 {
1849 SessionControlBlock *scb = (SessionControlBlock *)ssnptr;
1850
1851 *serviceAppId = scb->app_protocol_id[APP_PROTOID_SERVICE];
1852 *clientAppId = scb->app_protocol_id[APP_PROTOID_CLIENT];
1853 *payloadAppId = scb->app_protocol_id[APP_PROTOID_PAYLOAD];
1854 *miscAppId = scb->app_protocol_id[APP_PROTOID_MISC];
1855 }
1856
1857 #define HTTP_HEADER_PROCESSOR_MAX 10
1858 static Http_Processor_Callback http_header_processor_cb[HTTP_HEADER_PROCESSOR_MAX];
1859 static unsigned http_header_processor_cb_idx = 1;
1860
1861 static int RegisterHttpHeaderCallback(Http_Processor_Callback cb)
1862 {
1863 unsigned id;
1864
1865 for ( id = 1; id < http_header_processor_cb_idx; id++ )
1866 {
1867 if ( http_header_processor_cb[id] == cb )
1868 break;
1869 }
1870 if ( id == HTTP_HEADER_PROCESSOR_MAX )
1871 return -1;
1872
1873 if ( id == http_header_processor_cb_idx )
1874 http_header_processor_cb[http_header_processor_cb_idx++] = cb;
1875
1876 return 0;
1877 }
1878
1879 void CallHttpHeaderProcessors(Packet* p, HttpParsedHeaders * const headers)
1880 {
1881 unsigned id;
1882
1883 for ( id = 1; id < http_header_processor_cb_idx; id++ )
1884 {
1885 http_header_processor_cb[id](p, headers);
1886 }
1887 }
1888
1889 bool IsAnybodyRegisteredForHttpHeader(void)
1890 {
1891 return ((http_header_processor_cb_idx - 1) > 0);
1892 }
1893 #endif /* defined(FEAT_OPEN_APPID) */
1894
1895 #define SERVICE_EVENT_SUBSCRIBER_MAX 10
1896 #define SERVICE_EVENT_TYPE_MAX 10
1897 static ServiceEventNotifierFunc serviceEventRegistry[PP_MAX][SERVICE_EVENT_TYPE_MAX][SERVICE_EVENT_SUBSCRIBER_MAX];
1898
1899 static bool serviceEventSubscribe(unsigned int preprocId, ServiceEventType eventType, ServiceEventNotifierFunc cb)
1900 {
1901 unsigned i;
1902 ServiceEventNotifierFunc *notifierPtr;
1903
1904 if (preprocId >= PP_MAX || eventType >= SERVICE_EVENT_TYPE_MAX)
1905 return false;
1906
1907 notifierPtr = serviceEventRegistry[preprocId][eventType];
1908
1909 for ( i = 0; i < SERVICE_EVENT_SUBSCRIBER_MAX; i++ , notifierPtr++)
1910 {
1911 if ( *notifierPtr == cb )
1912 return true;
1913 if (!(*notifierPtr))
1914 {
1915 *notifierPtr = cb;
1916 return true;
1917 }
1918 }
1919 return false;
1920 }
1921
1922 static bool serviceEventPublish(unsigned int preprocId, void *ssnptr, ServiceEventType eventType, void * eventData)
1923 {
1924 unsigned i;
1925 ServiceEventNotifierFunc *notifierPtr;
1926
1927 if (preprocId >= PP_MAX || eventType >= SERVICE_EVENT_TYPE_MAX)
1928 return false;
1929
1930 notifierPtr = serviceEventRegistry[preprocId][eventType];
1931
1932 for ( i = 0; i < SERVICE_EVENT_SUBSCRIBER_MAX; i++ , notifierPtr++)
1933 {
1934 if (*notifierPtr)
1935 (*notifierPtr)(ssnptr, eventType, eventData);
1936 else
1937 break;
1938 }
1939
1940 return true;
1941 }
1942
1943 void StreamCallHandler( Packet* p, unsigned id )
1944 {
1945 assert( id && id < stream_cb_idx && stream_cb[ id ] );
1946 stream_cb[ id ]( p );
1947 }
1948
1949 static void setFtpFilePosition (void *scbptr,bool flush)
1950 {
1951 SetFTPFileLocation(scbptr,flush);
1952 return;
1953 }
1954
1955
1956 static int StreamSetApplicationProtocolIdExpectedPreassignCallbackId( const Packet *ctrlPkt,
1957 sfaddr_t* srcIP, uint16_t srcPort, sfaddr_t* dstIP, uint16_t dstPort,
1958 uint8_t protocol, int16_t protoId, uint32_t preprocId, void *protoData,
1959 void ( *protoDataFreeFn )( void * ), unsigned cbId, Stream_Event se,
1960 struct _ExpectNode** packetExpectedNode)
1961 {
1962 return StreamExpectAddChannelPreassignCallback(ctrlPkt, srcIP, srcPort, dstIP, dstPort,
1963 SSN_DIR_BOTH, 0, protocol, STREAM_EXPECTED_CHANNEL_TIMEOUT,
1964 protoId, preprocId, protoData, protoDataFreeFn, cbId, se,
1965 packetExpectedNode);
1966 }
1967
1968 #define FTP_PROCESSOR_MAX 2
1969 static FTP_Processor_Flush_Callback ftp_processor_flush_cb[FTP_PROCESSOR_MAX];
1970 static unsigned ftp_processor_flush_cb_idx = 1;
1971
1972 static int RegisterFTPFlushCallback(FTP_Processor_Flush_Callback cb)
1973 {
1974 unsigned id;
1975
1976 for ( id = 1; id < ftp_processor_flush_cb_idx; id++ )
1977 {
1978 if ( ftp_processor_flush_cb[id] == cb )
1979 break;
1980 }
1981 if ( id == FTP_PROCESSOR_MAX)
1982 return -1;
1983
1984 if ( id == ftp_processor_flush_cb_idx)
1985 ftp_processor_flush_cb[ftp_processor_flush_cb_idx++] = cb;
1986
1987 return 0;
1988 }
1989
1990 void CallFTPFlushProcessor(Packet* p)
1991 {
1992 unsigned id;
1993
1994 for ( id = 1; id < ftp_processor_flush_cb_idx; id++ )
1995 {
1996 ftp_processor_flush_cb[id](p);
1997 }
1998 }
1999
2000 #ifdef SNORT_RELOAD
2001 static void StreamTcpReload( struct _SnortConfig *sc, char *args, void **new_config )
2002 {
2003 StreamConfig *config;
2004
2005 config = initStreamPolicyConfig( sc, true );
2006 if( !config->session_config->track_tcp_sessions )
2007 return;
2008
2009 if( config->tcp_config == NULL )
2010 {
2011 config->tcp_config = ( StreamTcpConfig * ) SnortAlloc( sizeof( StreamTcpConfig ) );
2012
2013 StreamTcpInitFlushPoints();
2014 StreamTcpRegisterRuleOptions( sc );
2015 AddFuncToPreprocPostConfigList( sc, StreamPostConfigTcp, config->tcp_config );
2016 }
2017
2018 /* Call the protocol specific initializer */
2019 StreamTcpPolicyInit( sc, config->tcp_config, args );
2020
2021 *new_config = getStreamConfigContext( true );
2022 }
2023
2024 static void StreamUdpReload(struct _SnortConfig *sc, char *args, void **new_config)
2025 {
2026 StreamConfig *config;
2027
2028 config = initStreamPolicyConfig( sc, true );
2029 if( !config->session_config->track_udp_sessions )
2030 return;
2031
2032 if( config->udp_config == NULL )
2033 config->udp_config = ( StreamUdpConfig * ) SnortAlloc( sizeof( StreamUdpConfig ) );
2034
2035 /* Call the protocol specific initializer */
2036 StreamUdpPolicyInit( config->udp_config, args );
2037
2038 *new_config = getStreamConfigContext( true );
2039 }
2040
2041 static void StreamIcmpReload(struct _SnortConfig *sc, char *args, void **new_config)
2042 {
2043 StreamConfig *config;
2044
2045 config = initStreamPolicyConfig( sc, true );
2046 if( !config->session_config->track_icmp_sessions )
2047 return;
2048
2049 if( config->icmp_config == NULL )
2050 config->icmp_config = ( StreamIcmpConfig * ) SnortAlloc( sizeof( StreamIcmpConfig ) );
2051
2052 /* Call the protocol specific initializer */
2053 StreamIcmpPolicyInit( config->icmp_config, args );
2054
2055 *new_config = getStreamConfigContext( true );
2056 }
2057
2058 static void StreamIpReload(struct _SnortConfig *sc, char *args, void **new_config)
2059 {
2060 StreamConfig *config;
2061
2062 config = initStreamPolicyConfig( sc, true );
2063 if( !config->session_config->track_ip_sessions )
2064 return;
2065
2066 if( config->ip_config == NULL )
2067 config->ip_config = ( StreamIpConfig * ) SnortAlloc( sizeof( *config->ip_config ) );
2068
2069 /* Call the protocol specific initializer */
2070 StreamIpPolicyInit( config->ip_config, args );
2071
2072 *new_config = getStreamConfigContext( true );
2073 }
2074
2075 static int StreamReloadVerify( struct _SnortConfig *sc, void *swap_config )
2076 {
2077 tSfPolicyUserContextId ssc = ( tSfPolicyUserContextId ) swap_config;
2078
2079 if( ( ssc == NULL ) || ( stream_online_config == NULL ) )
2080 return 0;
2081
2082 if( sfPolicyUserDataIterate( sc, ssc, StreamVerifyConfigPolicy ) != 0 )
2083 return -1;
2084
2085 #ifdef TARGET_BASED
2086 initServiceFilterStatus( sc );
2087 #endif
2088
2089 return 0;
2090 }
2091 static void StreamFreeOldConfig( void *data )
2092 {
2093 if( data == NULL )
2094 return;
2095
2096 StreamFreeConfigs( ( tSfPolicyUserContextId ) data );
2097 }
2098
2099 static int StreamReloadSwapPolicy( struct _SnortConfig *sc, tSfPolicyUserContextId config,
2100 tSfPolicyId policyId, void *pData )
2101 {
2102 StreamConfig *stream_config = ( StreamConfig * ) pData;
2103
2104 if( stream_config->session_config->policy_ref_count[ policyId ] == 0 )
2105 {
2106 sfPolicyUserDataClear( config, policyId );
2107 StreamFreeConfig( stream_config );
2108 }
2109 else
2110 register_no_ref_policy_callback(stream_config->session_config, StreamFreeOldConfig, (void *)config);
2111
2112 return 0;
2113 }
2114
2115 static void *StreamReloadSwap( struct _SnortConfig *sc, void *swap_config )
2116 {
2117 tSfPolicyUserContextId new_config = ( tSfPolicyUserContextId ) swap_config;
2118 tSfPolicyUserContextId old_config = stream_online_config;
2119
2120
2121 if( ( new_config == stream_online_config ) || new_config == NULL )
2122 return NULL;
2123
2124 stream_online_config = new_config;
2125 stream_parsing_config = NULL;
2126 // free memory for all configs with no refs
2127 sfPolicyUserDataIterate( sc, old_config, StreamReloadSwapPolicy );
2128 if( sfPolicyUserPolicyGetActive( old_config ) == 0 )
2129 return old_config;
2130
2131 // still some active sessions with ref to old config...
2132 return NULL;
2133 }
2134
2135 static void StreamReloadSwapFree( void *data )
2136 {
2137 if( data == NULL )
2138 return;
2139
2140 if( !old_config_freed )
2141 {
2142 StreamFreeConfigs( ( tSfPolicyUserContextId ) data );
2143 old_config_freed = true;
2144 }
2145 }
2146
2147 #endif
2148
2149 static void StreamRegisterPAFFree(uint8_t id, PAF_Free_Callback cb)
2150 {
2151 s5_paf_register_free(id, cb);
2152 }
2153
2154 static Packet* getWirePacket()
2155 {
2156 return getWirePacketTcp();
2157 }
2158
2159 static uint8_t getFlushPolicyDir()
2160 {
2161 return getFlushPolicyDirTcp();
2162 }
2163
2164 static bool StreamIsSessionHttp2( void *ssnptr )
2165 {
2166 SessionControlBlock *ssn;
2167
2168 if(ssnptr)
2169 {
2170 ssn = (SessionControlBlock *)ssnptr;
2171 if (ssn->protocol == IPPROTO_TCP )
2172 return StreamIsSessionHttp2Tcp( ssnptr );
2173 else
2174 return false;
2175 }
2176 else
2177 return false;
2178 }
2179 static void StreamSetSessionHttp2( void *ssnptr)
2180 {
2181 if( ssnptr )
2182 StreamSetSessionHttp2Tcp( ssnptr );
2183
2184 return;
2185 }
2186
2187 static bool StreamShowRebuiltPackets()
2188 {
2189 return (stream_session_config->flags & STREAM_CONFIG_SHOW_PACKETS);
2190 }
2191
2192 static bool StreamIsSessionHttp2Upg( void *ssnptr )
2193 {
2194 SessionControlBlock *ssn;
2195
2196 if(ssnptr)
2197 {
2198 ssn = (SessionControlBlock *)ssnptr;
2199 if (ssn->protocol == IPPROTO_TCP )
2200 return StreamIsSessionHttp2UpgTcp( ssnptr );
2201 else
2202 return false;
2203 }
2204 else
2205 return false;
2206 }
2207 static void StreamSetSessionHttp2Upg( void *ssnptr)
2208 {
2209 if( ssnptr )
2210 StreamSetSessionHttp2UpgTcp( ssnptr );
2211
2212 return;
2213 }
2214