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