"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/preprocessors/spp_stream6.c" (16 Oct 2020, 72563 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "spp_stream6.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

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