"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/dynamic-preprocessors/dcerpc2/spp_dce2.c" (16 Oct 2020, 60115 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_dce2.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 /****************************************************************************
    2  * Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    3  * Copyright (C) 2008-2013 Sourcefire, Inc.
    4  *
    5  * This program is free software; you can redistribute it and/or modify
    6  * it under the terms of the GNU General Public License Version 2 as
    7  * published by the Free Software Foundation.  You may not use, modify or
    8  * distribute this program under any other version of the GNU General
    9  * Public License.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   19  *
   20  ****************************************************************************
   21  *
   22  ****************************************************************************/
   23 
   24 #ifdef HAVE_CONFIG_H
   25 #include "config.h"
   26 #endif
   27 
   28 #include <assert.h>
   29 #include <stddef.h>
   30 
   31 #include "sf_types.h"
   32 #include "spp_dce2.h"
   33 #include "sf_preproc_info.h"
   34 #include "dce2_memory.h"
   35 #include "dce2_list.h"
   36 #include "dce2_utils.h"
   37 #include "dce2_config.h"
   38 #include "dce2_roptions.h"
   39 #include "dce2_stats.h"
   40 #include "dce2_event.h"
   41 #include "dce2_paf.h"
   42 #include "dce2_smb.h"
   43 #include "dce2_smb2.h"
   44 #include "snort_dce2.h"
   45 #include "preprocids.h"
   46 #include "profiler.h"
   47 #include "sfrt.h"
   48 #include "sf_snort_packet.h"
   49 #include "sf_dynamic_preprocessor.h"
   50 #include "stream_api.h"
   51 #include "sfPolicy.h"
   52 #include "sfPolicyUserData.h"
   53 
   54 #ifdef SNORT_RELOAD
   55 #include "appdata_adjuster.h"
   56 #include "dce2_session.h"
   57 #ifdef REG_TEST
   58 #include "reg_test.h"
   59 #endif
   60 #endif
   61 
   62 #ifdef DCE2_LOG_EXTRA_DATA
   63 #include "Unified2_common.h"
   64 #endif
   65 
   66 #ifdef DUMP_BUFFER
   67 #include "dcerpc2_buffer_dump.h"
   68 #endif
   69 
   70 /********************************************************************
   71  * Global variables
   72  ********************************************************************/
   73 #ifdef PERF_PROFILING
   74 PreprocStats dce2_pstat_main;
   75 PreprocStats dce2_pstat_session;
   76 PreprocStats dce2_pstat_new_session;
   77 PreprocStats dce2_pstat_session_state;
   78 PreprocStats dce2_pstat_detect;
   79 PreprocStats dce2_pstat_log;
   80 PreprocStats dce2_pstat_smb_seg;
   81 PreprocStats dce2_pstat_smb_req;
   82 PreprocStats dce2_pstat_smb_uid;
   83 PreprocStats dce2_pstat_smb_tid;
   84 PreprocStats dce2_pstat_smb_fid;
   85 PreprocStats dce2_pstat_smb_file;
   86 PreprocStats dce2_pstat_smb_file_detect;
   87 PreprocStats dce2_pstat_smb_file_api;
   88 PreprocStats dce2_pstat_smb_fingerprint;
   89 PreprocStats dce2_pstat_smb_negotiate;
   90 PreprocStats dce2_pstat_co_seg;
   91 PreprocStats dce2_pstat_co_frag;
   92 PreprocStats dce2_pstat_co_reass;
   93 PreprocStats dce2_pstat_co_ctx;
   94 PreprocStats dce2_pstat_cl_acts;
   95 PreprocStats dce2_pstat_cl_frag;
   96 PreprocStats dce2_pstat_cl_reass;
   97 #endif
   98 
   99 const int MAJOR_VERSION = 1;
  100 const int MINOR_VERSION = 0;
  101 const int BUILD_VERSION = 3;
  102 const char *PREPROC_NAME = "SF_DCERPC2";
  103 
  104 #define DCE2_RegisterPreprocessor DYNAMIC_PREPROC_SETUP
  105 
  106 /********************************************************************
  107  * Macros
  108  ********************************************************************/
  109 #ifdef PERF_PROFILING
  110 #define DCE2_PSTAT__MAIN         "DceRpcMain"
  111 #define DCE2_PSTAT__SESSION      "DceRpcSession"
  112 #define DCE2_PSTAT__NEW_SESSION  "DceRpcNewSession"
  113 #define DCE2_PSTAT__SSN_STATE    "DceRpcSessionState"
  114 #define DCE2_PSTAT__DETECT       "DceRpcDetect"
  115 #define DCE2_PSTAT__LOG          "DceRpcLog"
  116 #define DCE2_PSTAT__SMB_SEG      "DceRpcSmbSeg"
  117 #define DCE2_PSTAT__SMB_REQ      "DceRpcSmbReq"
  118 #define DCE2_PSTAT__SMB_UID      "DceRpcSmbUid"
  119 #define DCE2_PSTAT__SMB_TID      "DceRpcSmbTid"
  120 #define DCE2_PSTAT__SMB_FID      "DceRpcSmbFid"
  121 #define DCE2_PSTAT__SMB_FILE     "DceRpcSmbFile"
  122 #define DCE2_PSTAT__SMB_FILE_DETECT "DceRpcSmbFileDetect"
  123 #define DCE2_PSTAT__SMB_FILE_API "DceRpcSmbFileAPI"
  124 #define DCE2_PSTAT__SMB_FP       "DceRpcSmbFingerprint"
  125 #define DCE2_PSTAT__SMB_NEG      "DceRpcSmbNegotiate"
  126 #define DCE2_PSTAT__CO_SEG       "DceRpcCoSeg"
  127 #define DCE2_PSTAT__CO_FRAG      "DceRpcCoFrag"
  128 #define DCE2_PSTAT__CO_REASS     "DceRpcCoReass"
  129 #define DCE2_PSTAT__CO_CTX       "DceRpcCoCtx"
  130 #define DCE2_PSTAT__CL_ACTS      "DceRpcClActs"
  131 #define DCE2_PSTAT__CL_FRAG      "DceRpcClFrag"
  132 #define DCE2_PSTAT__CL_REASS     "DceRpcClReass"
  133 #endif  /* PERF_PROFILING */
  134 
  135 /********************************************************************
  136  * Private function prototypes
  137  ********************************************************************/
  138 static void DCE2_InitGlobal(struct _SnortConfig *, char *);
  139 static void DCE2_InitServer(struct _SnortConfig *, char *);
  140 static int DCE2_CheckConfig(struct _SnortConfig *);
  141 static void DCE2_Main(void *, void *);
  142 static void DCE2_PrintStats(int);
  143 static void DCE2_Reset(int, void *);
  144 static void DCE2_ResetStats(int, void *);
  145 static void DCE2_CleanExit(int, void *);
  146 #ifdef DCE2_LOG_EXTRA_DATA
  147 static int DCE2_LogSmbFileName(void *, uint8_t **, uint32_t *, uint32_t *);
  148 #endif
  149 
  150 #ifdef SNORT_RELOAD
  151 static void DCE2_ReloadGlobal(struct _SnortConfig *, char *, void **);
  152 static void DCE2_ReloadServer(struct _SnortConfig *, char *, void **);
  153 static int DCE2_ReloadVerify(struct _SnortConfig *, void *);
  154 static bool DCE2_ReloadAdjust(bool, tSfPolicyId, void *);
  155 static void * DCE2_ReloadSwap(struct _SnortConfig *, void *);
  156 static void DCE2_ReloadSwapFree(void *);
  157 #endif
  158 
  159 static void DCE2_AddPortsToPaf(struct _SnortConfig *, DCE2_Config *, tSfPolicyId);
  160 static void DCE2_ScAddPortsToPaf(struct _SnortConfig *, void *);
  161 static uint32_t max(uint32_t a, uint32_t b);
  162 static uint32_t DCE2_GetReloadSafeMemcap();
  163 
  164 static bool dce2_file_cache_is_enabled = false;
  165 static bool dce2_file_cache_was_enabled = false;
  166 #ifdef SNORT_RELOAD
  167 static bool dce2_ada_was_enabled = false;
  168 static bool dce2_ada_is_enabled = false;
  169 #endif
  170 
  171 /********************************************************************
  172  * Function: DCE2_RegisterPreprocessor()
  173  *
  174  * Purpose: Registers the DCE/RPC preprocessor with Snort
  175  *
  176  * Arguments: None
  177  *
  178  * Returns: None
  179  *
  180  ********************************************************************/
  181 void DCE2_RegisterPreprocessor(void)
  182 {
  183 #ifndef SNORT_RELOAD
  184     _dpd.registerPreproc(DCE2_GNAME, DCE2_InitGlobal);
  185     _dpd.registerPreproc(DCE2_SNAME, DCE2_InitServer);
  186 #else
  187     _dpd.registerPreproc(DCE2_GNAME, DCE2_InitGlobal, DCE2_ReloadGlobal,
  188                          DCE2_ReloadVerify, DCE2_ReloadSwap,
  189                          DCE2_ReloadSwapFree);
  190     _dpd.registerPreproc(DCE2_SNAME, DCE2_InitServer,
  191                          DCE2_ReloadServer, NULL, NULL, NULL);
  192 #endif
  193 #ifdef DUMP_BUFFER
  194     _dpd.registerBufferTracer(getDCERPC2Buffers, DCERPC2_BUFFER_DUMP_FUNC);
  195 #endif
  196 
  197 }
  198 
  199 /*********************************************************************
  200  * Function: DCE2_InitGlobal()
  201  *
  202  * Purpose: Initializes the global DCE/RPC preprocessor config.
  203  *
  204  * Arguments: snort.conf argument line for the DCE/RPC preprocessor.
  205  *
  206  * Returns: None
  207  *
  208  *********************************************************************/
  209 static void DCE2_InitGlobal(struct _SnortConfig *sc, char *args)
  210 {
  211     tSfPolicyId policy_id = _dpd.getParserPolicy(sc);
  212     DCE2_Config *pDefaultPolicyConfig = NULL;
  213     DCE2_Config *pCurrentPolicyConfig = NULL;
  214 
  215     if ((_dpd.streamAPI == NULL) || (_dpd.streamAPI->version != STREAM_API_VERSION5))
  216     {
  217         DCE2_Die("%s(%d) \"%s\" configuration: "
  218             "Stream must be enabled with TCP and UDP tracking.",
  219             *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
  220     }
  221 
  222     if (dce2_config == NULL)
  223     {
  224         dce2_config = sfPolicyConfigCreate();
  225         dce2_file_cache_is_enabled = false;
  226         dce2_file_cache_was_enabled = false;
  227 #ifdef SNORT_RELOAD
  228         dce2_ada_was_enabled = false;
  229         dce2_ada_is_enabled = false;
  230 #endif
  231         if (dce2_config == NULL)
  232         {
  233             DCE2_Die("%s(%d) \"%s\" configuration: Could not allocate memory "
  234                      "configuration.\n",
  235                      *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
  236         }
  237 
  238         DCE2_MemInit();
  239         DCE2_StatsInit();
  240         DCE2_EventsInit();
  241         smb_file_name[0] = '\0';
  242 
  243         /* Initialize reassembly packet */
  244         DCE2_InitRpkts();
  245 
  246 #ifdef ACTIVE_RESPONSE
  247         DCE2_SmbInitDeletePdu();
  248 #endif
  249 
  250         DCE2_SmbInitGlobals();
  251 
  252         _dpd.addPreprocConfCheck(sc, DCE2_CheckConfig);
  253         _dpd.registerPreprocStats(DCE2_GNAME, DCE2_PrintStats);
  254         _dpd.addPreprocReset(DCE2_Reset, NULL, PRIORITY_LAST, PP_DCE2);
  255         _dpd.addPreprocResetStats(DCE2_ResetStats, NULL, PRIORITY_LAST, PP_DCE2);
  256         _dpd.addPreprocExit(DCE2_CleanExit, NULL, PRIORITY_LAST, PP_DCE2);
  257 
  258 #ifdef PERF_PROFILING
  259         _dpd.addPreprocProfileFunc(DCE2_PSTAT__MAIN, &dce2_pstat_main, 0, _dpd.totalPerfStats, NULL);
  260         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SESSION, &dce2_pstat_session, 1, &dce2_pstat_main, NULL);
  261         _dpd.addPreprocProfileFunc(DCE2_PSTAT__NEW_SESSION, &dce2_pstat_new_session, 2, &dce2_pstat_session, NULL);
  262         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SSN_STATE, &dce2_pstat_session_state, 2, &dce2_pstat_session, NULL);
  263         _dpd.addPreprocProfileFunc(DCE2_PSTAT__LOG, &dce2_pstat_log, 1, &dce2_pstat_main, NULL);
  264         _dpd.addPreprocProfileFunc(DCE2_PSTAT__DETECT, &dce2_pstat_detect, 1, &dce2_pstat_main, NULL);
  265         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_SEG, &dce2_pstat_smb_seg, 1, &dce2_pstat_main, NULL);
  266         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_REQ, &dce2_pstat_smb_req, 1, &dce2_pstat_main, NULL);
  267         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_UID, &dce2_pstat_smb_uid, 1, &dce2_pstat_main, NULL);
  268         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_TID, &dce2_pstat_smb_tid, 1, &dce2_pstat_main, NULL);
  269         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_FID, &dce2_pstat_smb_fid, 1, &dce2_pstat_main, NULL);
  270         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_FILE, &dce2_pstat_smb_file, 1, &dce2_pstat_main, NULL);
  271         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_FILE_DETECT, &dce2_pstat_smb_file_detect, 2, &dce2_pstat_smb_file, NULL);
  272         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_FILE_API, &dce2_pstat_smb_file_api, 2, &dce2_pstat_smb_file, NULL);
  273         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_FP, &dce2_pstat_smb_fingerprint, 1, &dce2_pstat_main, NULL);
  274         _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_NEG, &dce2_pstat_smb_negotiate, 1, &dce2_pstat_main, NULL);
  275         _dpd.addPreprocProfileFunc(DCE2_PSTAT__CO_SEG, &dce2_pstat_co_seg, 1, &dce2_pstat_main, NULL);
  276         _dpd.addPreprocProfileFunc(DCE2_PSTAT__CO_FRAG, &dce2_pstat_co_frag, 1, &dce2_pstat_main, NULL);
  277         _dpd.addPreprocProfileFunc(DCE2_PSTAT__CO_REASS, &dce2_pstat_co_reass, 1, &dce2_pstat_main, NULL);
  278         _dpd.addPreprocProfileFunc(DCE2_PSTAT__CO_CTX, &dce2_pstat_co_ctx, 1, &dce2_pstat_main, NULL);
  279         _dpd.addPreprocProfileFunc(DCE2_PSTAT__CL_ACTS, &dce2_pstat_cl_acts, 1, &dce2_pstat_main, NULL);
  280         _dpd.addPreprocProfileFunc(DCE2_PSTAT__CL_FRAG, &dce2_pstat_cl_frag, 1, &dce2_pstat_main, NULL);
  281         _dpd.addPreprocProfileFunc(DCE2_PSTAT__CL_REASS, &dce2_pstat_cl_reass, 1, &dce2_pstat_main, NULL);
  282 #endif
  283 
  284 #ifdef TARGET_BASED
  285         dce2_proto_ids.dcerpc = _dpd.findProtocolReference(DCE2_PROTO_REF_STR__DCERPC);
  286         if (dce2_proto_ids.dcerpc == SFTARGET_UNKNOWN_PROTOCOL)
  287             dce2_proto_ids.dcerpc = _dpd.addProtocolReference(DCE2_PROTO_REF_STR__DCERPC);
  288 
  289         /* smb and netbios-ssn refer to the same thing */
  290         dce2_proto_ids.nbss = _dpd.findProtocolReference(DCE2_PROTO_REF_STR__NBSS);
  291         if (dce2_proto_ids.nbss == SFTARGET_UNKNOWN_PROTOCOL)
  292             dce2_proto_ids.nbss = _dpd.addProtocolReference(DCE2_PROTO_REF_STR__NBSS);
  293 
  294         // register with session to handle service 
  295         _dpd.sessionAPI->register_service_handler( PP_DCE2, dce2_proto_ids.dcerpc );
  296         _dpd.sessionAPI->register_service_handler( PP_DCE2, dce2_proto_ids.nbss );
  297 #endif
  298     }
  299 
  300     sfPolicyUserPolicySet(dce2_config, policy_id);
  301     pDefaultPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetDefault(dce2_config);
  302     pCurrentPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetCurrent(dce2_config);
  303 
  304     if ((policy_id != 0) && (pDefaultPolicyConfig == NULL))
  305     {
  306         DCE2_Die("%s(%d) \"%s\" configuration: Must configure default policy "
  307                  "if other policies are to be configured.\n",
  308                  *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
  309     }
  310 
  311     /* Can only do one global configuration */
  312     if (pCurrentPolicyConfig != NULL)
  313     {
  314         DCE2_Die("%s(%d) \"%s\" configuration: Only one global configuration can be specified.",
  315                  *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
  316     }
  317 
  318     DCE2_RegRuleOptions(sc);
  319 
  320     pCurrentPolicyConfig = (DCE2_Config *)DCE2_Alloc(sizeof(DCE2_Config), DCE2_MEM_TYPE__CONFIG);
  321     sfPolicyUserDataSetCurrent(dce2_config, pCurrentPolicyConfig);
  322 
  323     /* Parse configuration args */
  324     DCE2_GlobalConfigure(pCurrentPolicyConfig, args);
  325 
  326     if (policy_id != 0)
  327         pCurrentPolicyConfig->gconfig->memcap = pDefaultPolicyConfig->gconfig->memcap;
  328 
  329     if ( pCurrentPolicyConfig->gconfig->disabled )
  330         return;
  331 
  332     /* Register callbacks */
  333     _dpd.addPreproc(sc, DCE2_Main, PRIORITY_APPLICATION, PP_DCE2, PROTO_BIT__TCP | PROTO_BIT__UDP);
  334 
  335 #ifdef TARGET_BASED
  336     _dpd.streamAPI->set_service_filter_status
  337         (sc, dce2_proto_ids.dcerpc, PORT_MONITOR_SESSION, policy_id, 1);
  338 
  339     _dpd.streamAPI->set_service_filter_status
  340         (sc, dce2_proto_ids.nbss, PORT_MONITOR_SESSION, policy_id, 1);
  341 #endif
  342 
  343 #ifdef SNORT_RELOAD
  344     if (!ada)
  345     {
  346         size_t memcap = DCE2_GetReloadSafeMemcap(dce2_config);
  347         ada = ada_init(DCE2_MemInUse, PP_DCE2, memcap);
  348         if (!ada)
  349             _dpd.fatalMsg("Failed to initialize DCE ADA session cache.\n");
  350     }
  351     dce2_ada_is_enabled = true;
  352 #endif
  353 }
  354 
  355 /*********************************************************************
  356  * Function: DCE2_InitServer()
  357  *
  358  * Purpose: Initializes a DCE/RPC server configuration
  359  *
  360  * Arguments: snort.conf argument line for the DCE/RPC preprocessor.
  361  *
  362  * Returns: None
  363  *
  364  *********************************************************************/
  365 static void DCE2_InitServer(struct _SnortConfig *sc, char *args)
  366 {
  367     tSfPolicyId policy_id = _dpd.getParserPolicy(sc);
  368     DCE2_Config *pPolicyConfig = NULL;
  369 
  370     if (dce2_config != NULL)
  371     {
  372         sfPolicyUserPolicySet (dce2_config, policy_id);
  373         pPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetCurrent(dce2_config);
  374     }
  375 
  376     if ((dce2_config == NULL) || (pPolicyConfig == NULL)
  377             || (pPolicyConfig->gconfig == NULL))
  378     {
  379         DCE2_Die("%s(%d) \"%s\" configuration: \"%s\" must be configured "
  380                  "before \"%s\".", *_dpd.config_file, *_dpd.config_line,
  381                  DCE2_SNAME, DCE2_GNAME, DCE2_SNAME);
  382     }
  383 
  384     /* Parse configuration args */
  385     DCE2_ServerConfigure(sc, pPolicyConfig, args);
  386 
  387     // enable preproc for ports of interest...
  388     // TBD-EDM - verify...
  389     DCE2_RegisterPortsWithSession( sc, pPolicyConfig->dconfig );
  390 }
  391 
  392 static int DCE2_CheckConfigPolicy(
  393         struct _SnortConfig *sc,
  394         tSfPolicyUserContextId config,
  395         tSfPolicyId policyId,
  396         void* pData
  397         )
  398 {
  399     int rval;
  400     DCE2_Config *pPolicyConfig = (DCE2_Config *)pData;
  401     DCE2_ServerConfig *dconfig;
  402 
  403     if ( pPolicyConfig->gconfig->disabled )
  404         return 0;
  405 
  406     _dpd.setParserPolicy(sc, policyId);
  407     // config_file/config_line are not set here
  408     if (!_dpd.isPreprocEnabled(sc, PP_STREAM))
  409     {
  410         DCE2_Log(DCE2_LOG_TYPE__WARN, "Stream must be enabled with TCP and UDP tracking.");
  411         return -1;
  412     }
  413 
  414     dconfig = pPolicyConfig->dconfig;
  415 
  416     if (dconfig == NULL)
  417     {
  418         if ((rval = DCE2_CreateDefaultServerConfig(sc, pPolicyConfig, policyId)))
  419             return rval;
  420     }
  421 
  422 #ifdef TARGET_BASED
  423     if (!_dpd.isAdaptiveConfiguredForSnortConfig(sc))
  424 #endif
  425     {
  426         if ((rval = DCE2_ScCheckTransports(pPolicyConfig)))
  427             return rval;
  428     }
  429 
  430     DCE2_AddPortsToPaf(sc, pPolicyConfig, policyId);
  431 #ifdef TARGET_BASED
  432     DCE2_PafRegisterService(sc, dce2_proto_ids.nbss, policyId, DCE2_TRANS_TYPE__SMB);
  433     DCE2_PafRegisterService(sc, dce2_proto_ids.dcerpc, policyId, DCE2_TRANS_TYPE__TCP);
  434 #endif
  435 
  436 #ifdef DCE2_LOG_EXTRA_DATA
  437     pPolicyConfig->xtra_logging_smb_file_name_id =
  438         _dpd.streamAPI->reg_xtra_data_cb(DCE2_LogSmbFileName);
  439 #endif
  440 
  441     /* Register routing table memory */
  442     if (pPolicyConfig->sconfigs != NULL)
  443         DCE2_RegMem(sfrt_usage(pPolicyConfig->sconfigs), DCE2_MEM_TYPE__RT);
  444 
  445     if (!pPolicyConfig->gconfig->legacy_mode)
  446     {
  447         DCE2_Smb2Init(pPolicyConfig->gconfig->memcap);
  448         dce2_file_cache_is_enabled = true;
  449     }
  450 
  451     return 0;
  452 }
  453 
  454 /*********************************************************************
  455  * Function: DCE2_CheckConfig()
  456  *
  457  * Purpose: Verifies the DCE/RPC preprocessor configuration
  458  *
  459  * Arguments: None
  460  *
  461  * Returns: None
  462  *
  463  *********************************************************************/
  464 static int DCE2_CheckConfig(struct _SnortConfig *sc)
  465 {
  466     int rval;
  467 
  468     if ((rval = sfPolicyUserDataIterate (sc, dce2_config, DCE2_CheckConfigPolicy)))
  469     {
  470         return rval;
  471     }
  472     return 0;
  473 }
  474 
  475 /*********************************************************************
  476  * Function: DCE2_Main()
  477  *
  478  * Purpose: Main entry point for DCE/RPC processing.
  479  *
  480  * Arguments:
  481  *  void * - pointer to packet structure
  482  *  void * - pointer to context
  483  *
  484  * Returns: None
  485  *
  486  *********************************************************************/
  487 static void DCE2_Main(void *pkt, void *context)
  488 {
  489     SFSnortPacket *p = (SFSnortPacket *)pkt;
  490     PROFILE_VARS;
  491 
  492     DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__START_MSG));
  493 
  494     sfPolicyUserPolicySet (dce2_config, _dpd.getNapRuntimePolicy());
  495 
  496 #ifdef DUMP_BUFFER
  497     dumpBufferInit();
  498 #endif
  499 
  500 #ifdef DEBUG_MSGS
  501     if (DCE2_SsnFromServer(p))
  502     {
  503         DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Packet from Server.\n"));
  504     }
  505     else
  506     {
  507         DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Packet from Client.\n"));
  508     }
  509 #endif
  510 
  511     // preconditions - what we registered for
  512     assert((IsUDP(p) || IsTCP(p)) && p->payload && p->payload_size);
  513 
  514     /* No inspection to do */
  515     if ( !_dpd.sessionAPI->is_session_verified( p->stream_session ) )
  516     {
  517         DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Session not established - not inspecting.\n"));
  518         DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG));
  519         return;
  520     }
  521 
  522     PREPROC_PROFILE_START(dce2_pstat_main);
  523 
  524     if (DCE2_Process(p) == DCE2_RET__INSPECTED)
  525         DCE2_DisableDetect(p);
  526 
  527     PREPROC_PROFILE_END(dce2_pstat_main);
  528 
  529     DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG));
  530 }
  531 
  532 #ifdef DCE2_LOG_EXTRA_DATA
  533 /******************************************************************
  534  * Function: DCE2_LogSmbFileName
  535  *
  536  * Purpose: Callback for unified2 logging of extra data, in this
  537  *  case the SMB file name.
  538  *
  539  * Arguments:
  540  *  void *      - stream session pointer
  541  *  uint8_t **  - pointer to buffer for extra data
  542  *  uint32_t *  - pointer to length of extra data
  543  *  uint32_t *  - pointer to type of extra data
  544  *
  545  * Returns:
  546  *  int - 1 for success
  547  *        0 for failure
  548  *
  549  ******************************************************************/
  550 static int DCE2_LogSmbFileName(void *ssn_ptr, uint8_t **buf, uint32_t *len, uint32_t *type)
  551 {
  552     if ((_dpd.streamAPI->get_application_data(ssn_ptr, PP_DCE2) == NULL)
  553             || (smb_file_name_len == 0))
  554         return 0;
  555 
  556     *buf = (uint8_t *)smb_file_name;
  557     *len = smb_file_name_len;
  558     *type = EVENT_INFO_SMB_FILENAME;
  559 
  560     return 1;
  561 }
  562 #endif
  563 
  564 /******************************************************************
  565  * Function: DCE2_PrintStats()
  566  *
  567  * Purpose: Print statistics being kept by the preprocessor.
  568  *
  569  * Arguments:
  570  *  int - whether Snort is exiting or not
  571  *
  572  * Returns: None
  573  *
  574  ******************************************************************/
  575 static void DCE2_PrintStats(int exiting)
  576 {
  577     int smb_com;
  578     int sub_com;
  579 
  580     _dpd.logMsg("dcerpc2 Preprocessor Statistics\n");
  581     _dpd.logMsg("  Total sessions: "STDu64"\n", dce2_stats.sessions);
  582     _dpd.logMsg(" Active sessions: "STDu64"\n", dce2_stats.sessions_active);
  583     if (dce2_stats.sessions > 0)
  584     {
  585         if (dce2_stats.sessions_autodetected > 0)
  586             _dpd.logMsg("  Total sessions autodetected: "STDu64"\n", dce2_stats.sessions_autodetected);
  587         if (dce2_stats.sessions_aborted > 0)
  588             _dpd.logMsg("  Total sessions aborted: "STDu64"\n", dce2_stats.sessions_aborted);
  589         if (dce2_stats.bad_autodetects > 0)
  590             _dpd.logMsg("  Bad autodetects: "STDu64"\n", dce2_stats.bad_autodetects);
  591         if (dce2_stats.events > 0)
  592             _dpd.logMsg("  Preprocessor events: "STDu64"\n", dce2_stats.events);
  593 #ifdef DEBUG
  594         {
  595             unsigned int port;
  596             int first = 1;
  597 
  598             for (port = 0; port < (sizeof(dce2_stats.autoports) / sizeof(dce2_stats.autoports[0])); port++)
  599             {
  600                 DCE2_TransType ttype;
  601 
  602                 for (ttype = DCE2_TRANS_TYPE__NONE; ttype < DCE2_TRANS_TYPE__MAX; ttype++)
  603                 {
  604                     if ((dce2_stats.autoports[port][ttype] > 0) && (dce2_trans_strs[ttype] != NULL))
  605                     {
  606                         if (first)
  607                         {
  608                             _dpd.logMsg("\n");
  609                             _dpd.logMsg("  Autodetected ports:\n");
  610                             _dpd.logMsg("  %7s%15s%15s\n", "Port", "Transport", "Total");
  611                             first = 0;
  612                         }
  613 
  614                         _dpd.logMsg("  %7u%15s"FMTu64("15")"\n",
  615                                     port, dce2_trans_strs[ttype], dce2_stats.autoports[port][ttype]);
  616                     }
  617                 }
  618             }
  619         }
  620 #endif
  621 
  622         _dpd.logMsg("\n");
  623         _dpd.logMsg("  Transports\n");
  624         if (dce2_stats.smb_sessions > 0)
  625         {
  626             _dpd.logMsg("    SMB\n");
  627             _dpd.logMsg("      Total sessions: "STDu64"\n", dce2_stats.smb_sessions);
  628             _dpd.logMsg("      Packet stats\n");
  629             _dpd.logMsg("        Packets: "STDu64"\n", dce2_stats.smb_pkts);
  630             if (dce2_stats.smb_ignored_bytes > 0)
  631                 _dpd.logMsg("        Ignored bytes: "STDu64"\n", dce2_stats.smb_ignored_bytes);
  632             if (dce2_stats.smb_files_processed > 0)
  633                 _dpd.logMsg("        Files processed: "STDu64"\n", dce2_stats.smb_files_processed);
  634             if (dce2_stats.smb_cli_seg_reassembled > 0)
  635                 _dpd.logMsg("        Client TCP reassembled: "STDu64"\n", dce2_stats.smb_cli_seg_reassembled);
  636             if (dce2_stats.smb_srv_seg_reassembled > 0)
  637                 _dpd.logMsg("        Server TCP reassembled: "STDu64"\n", dce2_stats.smb_srv_seg_reassembled);
  638 
  639             _dpd.logMsg("        Maximum outstanding requests: "STDu64"\n",
  640                     dce2_stats.smb_max_outstanding_requests);
  641 
  642             // SMB command stats
  643             _dpd.logMsg("        SMB command requests/responses processed\n");
  644             for (smb_com = 0; smb_com < SMB_MAX_NUM_COMS; smb_com++)
  645             {
  646                 SmbAndXCom andx = smb_chain_map[smb_com];
  647 
  648                 // Print out the stats for command requests
  649                 if ((dce2_stats.smb_com_stats[SMB_TYPE__REQUEST][smb_com] != 0)
  650                         || (dce2_stats.smb_com_stats[SMB_TYPE__RESPONSE][smb_com] != 0))
  651                 {
  652                     _dpd.logMsg("          %s (0x%02X) : "STDu64"/"STDu64"\n",
  653                             smb_com_strings[smb_com], smb_com,
  654                             dce2_stats.smb_com_stats[SMB_TYPE__REQUEST][smb_com],
  655                             dce2_stats.smb_com_stats[SMB_TYPE__RESPONSE][smb_com]);
  656 
  657                     switch (smb_com)
  658                     {
  659                         case SMB_COM_TRANSACTION:
  660                             for (sub_com = 0; sub_com < TRANS_SUBCOM_MAX+1; sub_com++)
  661                             {
  662                                 if ((dce2_stats.smb_trans_subcom_stats[SMB_TYPE__REQUEST][sub_com] != 0)
  663                                         || (dce2_stats.smb_trans_subcom_stats[SMB_TYPE__RESPONSE][sub_com] != 0))
  664                                 {
  665                                     _dpd.logMsg("            %s (0x%04X) : "STDu64"/"STDu64"\n",
  666                                             (sub_com < TRANS_SUBCOM_MAX)
  667                                             ? smb_transaction_sub_command_strings[sub_com] : "Unknown",
  668                                             sub_com,
  669                                             dce2_stats.smb_trans_subcom_stats[SMB_TYPE__REQUEST][sub_com],
  670                                             dce2_stats.smb_trans_subcom_stats[SMB_TYPE__RESPONSE][sub_com]);
  671                                 }
  672                             }
  673                             break;
  674                         case SMB_COM_TRANSACTION2:
  675                             for (sub_com = 0; sub_com < TRANS2_SUBCOM_MAX+1; sub_com++)
  676                             {
  677                                 if ((dce2_stats.smb_trans2_subcom_stats[SMB_TYPE__REQUEST][sub_com] != 0)
  678                                         || (dce2_stats.smb_trans2_subcom_stats[SMB_TYPE__RESPONSE][sub_com] != 0))
  679                                 {
  680                                     _dpd.logMsg("            %s (0x%04X) : "STDu64"/"STDu64"\n",
  681                                             (sub_com < TRANS2_SUBCOM_MAX)
  682                                             ? smb_transaction2_sub_command_strings[sub_com] : "Unknown",
  683                                             sub_com,
  684                                             dce2_stats.smb_trans2_subcom_stats[SMB_TYPE__REQUEST][sub_com],
  685                                             dce2_stats.smb_trans2_subcom_stats[SMB_TYPE__RESPONSE][sub_com]);
  686                                 }
  687                             }
  688                             break;
  689                         case SMB_COM_NT_TRANSACT:
  690                             for (sub_com = 0; sub_com < NT_TRANSACT_SUBCOM_MAX+1; sub_com++)
  691                             {
  692                                 if ((dce2_stats.smb_nt_transact_subcom_stats[SMB_TYPE__REQUEST][sub_com] != 0)
  693                                         || (dce2_stats.smb_nt_transact_subcom_stats[SMB_TYPE__RESPONSE][sub_com] != 0))
  694                                 {
  695                                     _dpd.logMsg("            %s (0x%04X) : "STDu64"/"STDu64"\n",
  696                                             (sub_com < NT_TRANSACT_SUBCOM_MAX)
  697                                             ? smb_nt_transact_sub_command_strings[sub_com] : "Unknown",
  698                                             sub_com,
  699                                             dce2_stats.smb_nt_transact_subcom_stats[SMB_TYPE__REQUEST][sub_com],
  700                                             dce2_stats.smb_nt_transact_subcom_stats[SMB_TYPE__RESPONSE][sub_com]);
  701                                 }
  702                             }
  703                             break;
  704                         default:
  705                             break;
  706                     }
  707                 }
  708 
  709                 // Print out chaining stats for AndX command requests
  710                 if (andx != SMB_ANDX_COM__NONE)
  711                 {
  712                     int chained_com;
  713 
  714                     for (chained_com = 0; chained_com < SMB_MAX_NUM_COMS; chained_com++)
  715                     {
  716                         if ((dce2_stats.smb_chained_stats[SMB_TYPE__REQUEST][andx][chained_com] != 0)
  717                                 || (dce2_stats.smb_chained_stats[SMB_TYPE__RESPONSE][andx][chained_com] != 0))
  718                         {
  719                             _dpd.logMsg("            => %s (0x%02X) : "STDu64"/"STDu64"\n",
  720                                     smb_com_strings[chained_com], chained_com,
  721                                     dce2_stats.smb_chained_stats[SMB_TYPE__REQUEST][andx][chained_com],
  722                                     dce2_stats.smb_chained_stats[SMB_TYPE__RESPONSE][andx][chained_com]);
  723                         }
  724                     }
  725                 }
  726             }
  727 
  728             _dpd.logMsg("      Memory stats (bytes)\n");
  729             _dpd.logMsg("        Current total: %u\n", dce2_memory.smb_total);
  730             _dpd.logMsg("        Maximum total: %u\n", dce2_memory.smb_total_max);
  731             _dpd.logMsg("        Current session data: %u\n", dce2_memory.smb_ssn);
  732             _dpd.logMsg("        Maximum session data: %u\n", dce2_memory.smb_ssn_max);
  733             _dpd.logMsg("        Current segmentation buffering: %u\n", dce2_memory.smb_seg);
  734             _dpd.logMsg("        Maximum segmentation buffering: %u\n", dce2_memory.smb_seg_max);
  735             _dpd.logMsg("        Current uid tracking: %u\n", dce2_memory.smb_uid);
  736             _dpd.logMsg("        Maximum uid tracking: %u\n", dce2_memory.smb_uid_max);
  737             _dpd.logMsg("        Current tid tracking: %u\n", dce2_memory.smb_tid);
  738             _dpd.logMsg("        Maximum tid tracking: %u\n", dce2_memory.smb_tid_max);
  739             _dpd.logMsg("        Current fid tracking: %u\n", dce2_memory.smb_fid);
  740             _dpd.logMsg("        Maximum fid tracking: %u\n", dce2_memory.smb_fid_max);
  741             _dpd.logMsg("        Current file tracking: %u\n", dce2_memory.smb_file);
  742             _dpd.logMsg("        Maximum file tracking: %u\n", dce2_memory.smb_file_max);
  743             _dpd.logMsg("        Current request tracking: %u\n", dce2_memory.smb_req);
  744             _dpd.logMsg("        Maximum request tracking: %u\n", dce2_memory.smb_req_max);
  745             /* SMB2 stats */
  746             if (!exiting)
  747             {
  748                 DCE2_Smb2UpdateStats();
  749             }
  750             _dpd.logMsg("    SMB2\n");
  751             _dpd.logMsg("      Smb2 prunes: "STDu64"\n", dce2_stats.smb2_prunes);
  752             _dpd.logMsg("      Memory used for smb2 processing: "STDu64"\n", dce2_stats.smb2_memory_in_use);
  753             _dpd.logMsg("      Maximum memory used for smb2 processing: "STDu64"\n", dce2_stats.smb2_memory_in_use_max);
  754             _dpd.logMsg("      SMB2 command requests/responses processed\n");
  755             _dpd.logMsg("        smb2 create         : "STDu64"\n", dce2_stats.smb2_create);
  756             _dpd.logMsg("        smb2 write          : "STDu64"\n", dce2_stats.smb2_write);
  757             _dpd.logMsg("        smb2 read           : "STDu64"\n", dce2_stats.smb2_read);
  758             _dpd.logMsg("        smb2 set info       : "STDu64"\n", dce2_stats.smb2_set_info);
  759             _dpd.logMsg("        smb2 tree connect   : "STDu64"\n", dce2_stats.smb2_tree_connect);
  760             _dpd.logMsg("        smb2 tree disconnect: "STDu64"\n", dce2_stats.smb2_tree_disconnect);
  761             _dpd.logMsg("        smb2 close          : "STDu64"\n", dce2_stats.smb2_close);
  762         }
  763 
  764         if (dce2_stats.tcp_sessions > 0)
  765         {
  766             _dpd.logMsg("    TCP\n");
  767             _dpd.logMsg("      Total sessions: "STDu64"\n", dce2_stats.tcp_sessions);
  768             _dpd.logMsg("      Packet stats\n");
  769             _dpd.logMsg("        Packets: "STDu64"\n", dce2_stats.tcp_pkts);
  770             _dpd.logMsg("      Memory stats (bytes)\n");
  771             _dpd.logMsg("        Current total: %u\n", dce2_memory.tcp_total);
  772             _dpd.logMsg("        Maximum total: %u\n", dce2_memory.tcp_total_max);
  773             _dpd.logMsg("        Current session data: %u\n", dce2_memory.tcp_ssn);
  774             _dpd.logMsg("        Maximum session data: %u\n", dce2_memory.tcp_ssn_max);
  775         }
  776 
  777         if (dce2_stats.udp_sessions > 0)
  778         {
  779             _dpd.logMsg("    UDP\n");
  780             _dpd.logMsg("      Total sessions: "STDu64"\n", dce2_stats.udp_sessions);
  781             _dpd.logMsg("      Packet stats\n");
  782             _dpd.logMsg("        Packets: "STDu64"\n", dce2_stats.udp_pkts);
  783             _dpd.logMsg("      Memory stats (bytes)\n");
  784             _dpd.logMsg("        Current total: %u\n", dce2_memory.udp_total);
  785             _dpd.logMsg("        Maximum total: %u\n", dce2_memory.udp_total_max);
  786             _dpd.logMsg("        Current session data: %u\n", dce2_memory.udp_ssn);
  787             _dpd.logMsg("        Maximum session data: %u\n", dce2_memory.udp_ssn_max);
  788         }
  789 
  790         if ((dce2_stats.http_server_sessions > 0) || (dce2_stats.http_proxy_sessions > 0))
  791         {
  792             _dpd.logMsg("    RPC over HTTP\n");
  793             if (dce2_stats.http_server_sessions > 0)
  794                 _dpd.logMsg("      Total server sessions: "STDu64"\n", dce2_stats.http_server_sessions);
  795             if (dce2_stats.http_proxy_sessions > 0)
  796                 _dpd.logMsg("      Total proxy sessions: "STDu64"\n", dce2_stats.http_proxy_sessions);
  797             _dpd.logMsg("      Packet stats\n");
  798             if (dce2_stats.http_server_sessions > 0)
  799                 _dpd.logMsg("        Server packets: "STDu64"\n", dce2_stats.http_server_pkts);
  800             if (dce2_stats.http_proxy_sessions > 0)
  801                 _dpd.logMsg("        Proxy packets: "STDu64"\n", dce2_stats.http_proxy_pkts);
  802             _dpd.logMsg("      Memory stats (bytes)\n");
  803             _dpd.logMsg("        Current total: %u\n", dce2_memory.http_total);
  804             _dpd.logMsg("        Maximum total: %u\n", dce2_memory.http_total_max);
  805             _dpd.logMsg("        Current session data: %u\n", dce2_memory.http_ssn);
  806             _dpd.logMsg("        Maximum session data: %u\n", dce2_memory.http_ssn_max);
  807         }
  808 
  809         if ((dce2_stats.co_pdus > 0) || (dce2_stats.cl_pkts > 0))
  810         {
  811             _dpd.logMsg("\n");
  812             _dpd.logMsg("  DCE/RPC\n");
  813             if (dce2_stats.co_pdus > 0)
  814             {
  815                 _dpd.logMsg("    Connection oriented\n");
  816                 _dpd.logMsg("      Packet stats\n");
  817                 _dpd.logMsg("        PDUs: "STDu64"\n", dce2_stats.co_pdus);
  818                 if ((dce2_stats.co_bind > 0) || (dce2_stats.co_bind_ack > 0))
  819                 {
  820                     _dpd.logMsg("          Bind: "STDu64"\n", dce2_stats.co_bind);
  821                     _dpd.logMsg("          Bind Ack: "STDu64"\n", dce2_stats.co_bind_ack);
  822                 }
  823                 if ((dce2_stats.co_alter_ctx > 0) || (dce2_stats.co_alter_ctx_resp > 0))
  824                 {
  825                     _dpd.logMsg("          Alter context: "STDu64"\n", dce2_stats.co_alter_ctx);
  826                     _dpd.logMsg("          Alter context response: "STDu64"\n", dce2_stats.co_alter_ctx_resp);
  827                 }
  828                 if (dce2_stats.co_bind_nack > 0)
  829                     _dpd.logMsg("          Bind Nack: "STDu64"\n", dce2_stats.co_bind_nack);
  830                 if ((dce2_stats.co_request > 0) || (dce2_stats.co_response > 0))
  831                 {
  832                     _dpd.logMsg("          Request: "STDu64"\n", dce2_stats.co_request);
  833                     _dpd.logMsg("          Response: "STDu64"\n", dce2_stats.co_response);
  834                 }
  835                 if (dce2_stats.co_fault > 0)
  836                     _dpd.logMsg("          Fault: "STDu64"\n", dce2_stats.co_fault);
  837                 if (dce2_stats.co_reject > 0)
  838                     _dpd.logMsg("          Reject: "STDu64"\n", dce2_stats.co_reject);
  839                 if (dce2_stats.co_auth3 > 0)
  840                     _dpd.logMsg("          Auth3: "STDu64"\n", dce2_stats.co_auth3);
  841                 if (dce2_stats.co_shutdown > 0)
  842                     _dpd.logMsg("          Shutdown: "STDu64"\n", dce2_stats.co_shutdown);
  843                 if (dce2_stats.co_cancel > 0)
  844                     _dpd.logMsg("          Cancel: "STDu64"\n", dce2_stats.co_cancel);
  845                 if (dce2_stats.co_orphaned > 0)
  846                     _dpd.logMsg("          Orphaned: "STDu64"\n", dce2_stats.co_orphaned);
  847                 if (dce2_stats.co_ms_pdu > 0)
  848                     _dpd.logMsg("          Microsoft Request To Send RPC over HTTP: "STDu64"\n", dce2_stats.co_ms_pdu);
  849                 if (dce2_stats.co_other_req > 0)
  850                     _dpd.logMsg("          Other request type: "STDu64"\n", dce2_stats.co_other_req);
  851                 if (dce2_stats.co_other_resp > 0)
  852                     _dpd.logMsg("          Other response type: "STDu64"\n", dce2_stats.co_other_resp);
  853                 _dpd.logMsg("        Request fragments: "STDu64"\n", dce2_stats.co_req_fragments);
  854                 if (dce2_stats.co_req_fragments > 0)
  855                 {
  856                     _dpd.logMsg("          Min fragment size: "STDu64"\n", dce2_stats.co_cli_min_frag_size);
  857                     _dpd.logMsg("          Max fragment size: "STDu64"\n", dce2_stats.co_cli_max_frag_size);
  858                     _dpd.logMsg("          Frag reassembled: "STDu64"\n", dce2_stats.co_cli_frag_reassembled);
  859                 }
  860                 _dpd.logMsg("        Response fragments: "STDu64"\n", dce2_stats.co_resp_fragments);
  861                 if (dce2_stats.co_resp_fragments > 0)
  862                 {
  863                     _dpd.logMsg("          Min fragment size: "STDu64"\n", dce2_stats.co_srv_min_frag_size);
  864                     _dpd.logMsg("          Max fragment size: "STDu64"\n", dce2_stats.co_srv_max_frag_size);
  865                     _dpd.logMsg("          Frag reassembled: "STDu64"\n", dce2_stats.co_srv_frag_reassembled);
  866                 }
  867                 _dpd.logMsg("        Client PDU segmented reassembled: "STDu64"\n",
  868                         dce2_stats.co_cli_seg_reassembled);
  869                 _dpd.logMsg("        Server PDU segmented reassembled: "STDu64"\n",
  870                         dce2_stats.co_srv_seg_reassembled);
  871                 _dpd.logMsg("      Memory stats (bytes)\n");
  872                 _dpd.logMsg("        Current segmentation buffering: %u\n", dce2_memory.co_seg);
  873                 _dpd.logMsg("        Maximum segmentation buffering: %u\n", dce2_memory.co_seg_max);
  874                 _dpd.logMsg("        Current fragment tracker: %u\n", dce2_memory.co_frag);
  875                 _dpd.logMsg("        Maximum fragment tracker: %u\n", dce2_memory.co_frag_max);
  876                 _dpd.logMsg("        Current context tracking: %u\n", dce2_memory.co_ctx);
  877                 _dpd.logMsg("        Maximum context tracking: %u\n", dce2_memory.co_ctx_max);
  878             }
  879 
  880             if (dce2_stats.cl_pkts > 0)
  881             {
  882                 _dpd.logMsg("    Connectionless\n");
  883                 _dpd.logMsg("      Packet stats\n");
  884                 _dpd.logMsg("        Packets: "STDu64"\n", dce2_stats.cl_pkts);
  885                 if ((dce2_stats.cl_request > 0) || (dce2_stats.cl_response > 0))
  886                 {
  887                     _dpd.logMsg("        Request: "STDu64"\n", dce2_stats.cl_request);
  888                     _dpd.logMsg("        Response: "STDu64"\n", dce2_stats.cl_response);
  889                 }
  890                 if (dce2_stats.cl_ack > 0)
  891                     _dpd.logMsg("        Ack: "STDu64"\n", dce2_stats.cl_ack);
  892                 if (dce2_stats.cl_cancel > 0)
  893                     _dpd.logMsg("        Cancel: "STDu64"\n", dce2_stats.cl_cancel);
  894                 if (dce2_stats.cl_cli_fack > 0)
  895                     _dpd.logMsg("        Client Fack: "STDu64"\n", dce2_stats.cl_cli_fack);
  896                 if (dce2_stats.cl_ping > 0)
  897                     _dpd.logMsg("        Ping: "STDu64"\n", dce2_stats.cl_ping);
  898                 if (dce2_stats.cl_reject > 0)
  899                     _dpd.logMsg("        Reject: "STDu64"\n", dce2_stats.cl_reject);
  900                 if (dce2_stats.cl_cancel_ack > 0)
  901                     _dpd.logMsg("        Cancel Ack: "STDu64"\n", dce2_stats.cl_cancel_ack);
  902                 if (dce2_stats.cl_srv_fack > 0)
  903                     _dpd.logMsg("        Server Fack: "STDu64"\n", dce2_stats.cl_srv_fack);
  904                 if (dce2_stats.cl_fault > 0)
  905                     _dpd.logMsg("        Fault: "STDu64"\n", dce2_stats.cl_fault);
  906                 if (dce2_stats.cl_nocall > 0)
  907                     _dpd.logMsg("        NoCall: "STDu64"\n", dce2_stats.cl_nocall);
  908                 if (dce2_stats.cl_working > 0)
  909                     _dpd.logMsg("        Working: "STDu64"\n", dce2_stats.cl_working);
  910                 if (dce2_stats.cl_other_req > 0)
  911                     _dpd.logMsg("        Other request type: "STDu64"\n", dce2_stats.cl_other_req);
  912                 if (dce2_stats.cl_other_resp > 0)
  913                     _dpd.logMsg("        Other response type: "STDu64"\n", dce2_stats.cl_other_resp);
  914                 _dpd.logMsg("        Fragments: "STDu64"\n", dce2_stats.cl_fragments);
  915                 _dpd.logMsg("        Max fragment size: "STDu64"\n", dce2_stats.cl_max_frag_size);
  916                 _dpd.logMsg("        Reassembled: "STDu64"\n", dce2_stats.cl_frag_reassembled);
  917                 if (dce2_stats.cl_max_seqnum > 0)
  918                     _dpd.logMsg("        Max seq num: "STDu64"\n", dce2_stats.cl_max_seqnum);
  919                 _dpd.logMsg("      Memory stats (bytes)\n");
  920                 _dpd.logMsg("        Current activity tracker: %u\n", dce2_memory.cl_act);
  921                 _dpd.logMsg("        Maximum activity tracker: %u\n", dce2_memory.cl_act_max);
  922                 _dpd.logMsg("        Current fragment tracker: %u\n", dce2_memory.cl_frag);
  923                 _dpd.logMsg("        Maximum fragment tracker: %u\n", dce2_memory.cl_frag_max);
  924             }
  925         }
  926     }
  927 
  928     /* Have to free it here because CleanExit is called before stats functions
  929      * (so anything flushed by stream can go through and count towards stats) */
  930     if (exiting)
  931         DCE2_StatsFree();
  932 
  933     _dpd.logMsg("\n");
  934     _dpd.logMsg("  Memory stats (bytes)\n");
  935     _dpd.logMsg("    Current total: %u\n", dce2_memory.total);
  936     _dpd.logMsg("    Maximum total: %u\n", dce2_memory.total_max);
  937     _dpd.logMsg("    Current runtime total: %u\n", dce2_memory.rtotal);
  938     _dpd.logMsg("    Maximum runtime total: %u\n", dce2_memory.rtotal_max);
  939     _dpd.logMsg("    Current config total: %u\n", dce2_memory.config);
  940     _dpd.logMsg("    Maximum config total: %u\n", dce2_memory.config_max);
  941     _dpd.logMsg("    Current rule options total: %u\n", dce2_memory.roptions);
  942     _dpd.logMsg("    Maximum rule options total: %u\n", dce2_memory.roptions_max);
  943     _dpd.logMsg("    Current routing table total: %u\n", dce2_memory.rt);
  944     _dpd.logMsg("    Maximum routing table total: %u\n", dce2_memory.rt_max);
  945     _dpd.logMsg("    Current initialization total: %u\n", dce2_memory.init);
  946     _dpd.logMsg("    Maximum initialization total: %u\n", dce2_memory.init_max);
  947 }
  948 
  949 /******************************************************************
  950  * Function: DCE2_Reset()
  951  *
  952  * Purpose: Reset the preprocessor to a post configuration state.
  953  *
  954  * Arguments:
  955  *  int - signal that caused the reset
  956  *  void * - pointer to data
  957  *
  958  * Returns: None
  959  *
  960  ******************************************************************/
  961 static void DCE2_Reset(int signal, void *data)
  962 {
  963     if (!DCE2_CStackIsEmpty(dce2_pkt_stack))
  964     {
  965         DCE2_Log(DCE2_LOG_TYPE__ERROR,
  966                  "%s(%d) Packet stack is not empty when it should be.",
  967                  __FILE__, __LINE__);
  968 
  969         DCE2_CStackEmpty(dce2_pkt_stack);
  970     }
  971 }
  972 
  973 /******************************************************************
  974  * Function: DCE2_ResetStats()
  975  *
  976  * Purpose: Reset any statistics being kept by the preprocessor.
  977  *
  978  * Arguments:
  979  *  int - signal that caused function to be called
  980  *  void * - pointer to data
  981  *
  982  * Returns: None
  983  *
  984  ******************************************************************/
  985 static void DCE2_ResetStats(int signal, void *data)
  986 {
  987     DCE2_StatsInit();
  988 }
  989 
  990 /******************************************************************
  991  * Function: DCE2_CleanExit()
  992  *
  993  * Purpose: Do any cleanup necessary when Snort exits.
  994  *
  995  * Arguments:
  996  *  int - signal that caused Snort to exit
  997  *  void * - pointer to data
  998  *
  999  * Returns: None
 1000  *
 1001  ******************************************************************/
 1002 static void DCE2_CleanExit(int signal, void *data)
 1003 {
 1004     DCE2_FreeConfigs(dce2_config);
 1005     dce2_config = NULL;
 1006 #ifdef SNORT_RELOAD
 1007     ada_delete( ada );
 1008     ada = NULL;
 1009 #endif
 1010 
 1011     DCE2_FreeGlobals();
 1012     DCE2_Smb2Close();
 1013 }
 1014 
 1015 #ifdef SNORT_RELOAD
 1016 /*********************************************************************
 1017  * Function: DCE2_ReloadGlobal()
 1018  *
 1019  * Purpose: Creates a new global DCE/RPC preprocessor config.
 1020  *
 1021  * Arguments: snort.conf argument line for the DCE/RPC preprocessor.
 1022  *
 1023  * Returns: None
 1024  *
 1025  *********************************************************************/
 1026 static void DCE2_ReloadGlobal(struct _SnortConfig *sc, char *args, void **new_config)
 1027 {
 1028     tSfPolicyUserContextId dce2_swap_config = (tSfPolicyUserContextId)*new_config;
 1029     tSfPolicyId policy_id = _dpd.getParserPolicy(sc);
 1030     DCE2_Config *pDefaultPolicyConfig = NULL;
 1031     DCE2_Config *pCurrentPolicyConfig = NULL;
 1032 
 1033     if ((_dpd.streamAPI == NULL) || (_dpd.streamAPI->version != STREAM_API_VERSION5))
 1034     {
 1035         DCE2_Die("%s(%d) \"%s\" configuration: "
 1036             "Stream must be enabled with TCP and UDP tracking.",
 1037             *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
 1038     }
 1039 
 1040     if (dce2_swap_config == NULL)
 1041     {
 1042         //create a context
 1043         dce2_swap_config = sfPolicyConfigCreate();
 1044         dce2_file_cache_was_enabled = !DCE2_IsFileCache(NULL);
 1045         dce2_file_cache_is_enabled = false;
 1046         dce2_ada_is_enabled = false;
 1047         dce2_ada_was_enabled = ada != NULL;
 1048         if (dce2_swap_config == NULL)
 1049         {
 1050             DCE2_Die("%s(%d) \"%s\" configuration: Could not allocate memory "
 1051                      "configuration.\n",
 1052                      *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
 1053         }
 1054         *new_config = (void *)dce2_swap_config;
 1055     }
 1056 
 1057     sfPolicyUserPolicySet(dce2_swap_config, policy_id);
 1058     pDefaultPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetDefault(dce2_swap_config);
 1059     pCurrentPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetCurrent(dce2_swap_config);
 1060 
 1061     if ((policy_id != 0) && (pDefaultPolicyConfig == NULL))
 1062     {
 1063         DCE2_Die("%s(%d) \"%s\" configuration: Must configure default policy "
 1064                  "if other policies are to be configured.\n",
 1065                  *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
 1066     }
 1067 
 1068     /* Can only do one global configuration */
 1069     if (pCurrentPolicyConfig != NULL)
 1070     {
 1071         DCE2_Die("%s(%d) \"%s\" configuration: Only one global configuration can be specified.",
 1072                  *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
 1073     }
 1074 
 1075     DCE2_RegRuleOptions(sc);
 1076 
 1077     pCurrentPolicyConfig = (DCE2_Config *)DCE2_Alloc(sizeof(DCE2_Config),
 1078         DCE2_MEM_TYPE__CONFIG);
 1079 
 1080     sfPolicyUserDataSetCurrent(dce2_swap_config, pCurrentPolicyConfig);
 1081 
 1082     /* Parse configuration args */
 1083     DCE2_GlobalConfigure(pCurrentPolicyConfig, args);
 1084 
 1085     if ( pCurrentPolicyConfig->gconfig->disabled )
 1086         return;
 1087 
 1088     _dpd.addPreproc(sc, DCE2_Main, PRIORITY_APPLICATION, PP_DCE2,
 1089         PROTO_BIT__TCP | PROTO_BIT__UDP);
 1090 
 1091 #ifdef TARGET_BASED
 1092     _dpd.streamAPI->set_service_filter_status
 1093         (sc, dce2_proto_ids.dcerpc, PORT_MONITOR_SESSION, policy_id, 1);
 1094 
 1095     _dpd.streamAPI->set_service_filter_status
 1096         (sc, dce2_proto_ids.nbss, PORT_MONITOR_SESSION, policy_id, 1);
 1097 #endif
 1098 
 1099     if (policy_id != 0)
 1100         pCurrentPolicyConfig->gconfig->memcap = pDefaultPolicyConfig->gconfig->memcap;
 1101 
 1102     if (!ada)
 1103     {
 1104         size_t memcap = DCE2_GetReloadSafeMemcap(dce2_swap_config);
 1105         ada = ada_init(DCE2_MemInUse, PP_DCE2, memcap);
 1106         if (!ada)
 1107             _dpd.fatalMsg("Failed to initialize DCE ADA session cache.\n");
 1108     }
 1109     dce2_ada_is_enabled = true;
 1110 }
 1111 
 1112 /*********************************************************************
 1113  * Function: DCE2_ReloadServer()
 1114  *
 1115  * Purpose: Creates a new DCE/RPC server configuration
 1116  *
 1117  * Arguments: snort.conf argument line for the DCE/RPC preprocessor.
 1118  *
 1119  * Returns: None
 1120  *
 1121  *********************************************************************/
 1122 static void DCE2_ReloadServer(struct _SnortConfig *sc, char *args, void **new_config)
 1123 {
 1124     tSfPolicyUserContextId dce2_swap_config;
 1125     tSfPolicyId policy_id = _dpd.getParserPolicy(sc);
 1126     DCE2_Config *pPolicyConfig = NULL;
 1127 
 1128     dce2_swap_config = (tSfPolicyUserContextId)_dpd.getRelatedReloadData(sc, DCE2_GNAME);
 1129 
 1130     if (dce2_swap_config != NULL)
 1131     {
 1132         sfPolicyUserPolicySet (dce2_swap_config, policy_id);
 1133         pPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetCurrent(dce2_swap_config);
 1134     }
 1135 
 1136     if ((dce2_swap_config == NULL) || (pPolicyConfig == NULL)
 1137             || (pPolicyConfig->gconfig == NULL))
 1138     {
 1139         DCE2_Die("%s(%d) \"%s\" configuration: \"%s\" must be configured "
 1140                  "before \"%s\".", *_dpd.config_file, *_dpd.config_line,
 1141                  DCE2_SNAME, DCE2_GNAME, DCE2_SNAME);
 1142     }
 1143 
 1144     /* Parse configuration args */
 1145     DCE2_ServerConfigure(sc, pPolicyConfig, args);
 1146 }
 1147 
 1148 static int DCE2_ReloadVerifyPolicy(
 1149         struct _SnortConfig *sc,
 1150         tSfPolicyUserContextId config,
 1151         tSfPolicyId policyId,
 1152         void* pData
 1153         )
 1154 {
 1155     int rval;
 1156     DCE2_Config *swap_config = (DCE2_Config *)pData;
 1157     DCE2_Config *current_config = (DCE2_Config *)sfPolicyUserDataGet(dce2_config, policyId);
 1158     DCE2_ServerConfig *dconfig;
 1159 
 1160     //do any housekeeping before freeing DCE2_Config
 1161 
 1162     if ( swap_config == NULL || swap_config->gconfig->disabled )
 1163         return 0;
 1164 
 1165     if (!_dpd.isPreprocEnabled(sc, PP_STREAM))
 1166     {
 1167         DCE2_Log(DCE2_LOG_TYPE__WARN, "%s(%d) \"%s\" configuration: "
 1168             "Stream must be enabled with TCP and UDP tracking.",
 1169             *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
 1170         return -1;
 1171     }
 1172 
 1173     dconfig = swap_config->dconfig;
 1174 
 1175     if (dconfig == NULL)
 1176     {
 1177         if ((rval = DCE2_CreateDefaultServerConfig(sc, swap_config, policyId)))
 1178             return rval;
 1179     }
 1180 
 1181 #ifdef TARGET_BASED
 1182     if (!_dpd.isAdaptiveConfiguredForSnortConfig(sc))
 1183 #endif
 1184     {
 1185         if ((rval = DCE2_ScCheckTransports(swap_config)))
 1186             return rval;
 1187     }
 1188 
 1189     DCE2_AddPortsToPaf(sc, swap_config, policyId);
 1190 #ifdef TARGET_BASED
 1191     DCE2_PafRegisterService(sc, dce2_proto_ids.nbss, policyId, DCE2_TRANS_TYPE__SMB);
 1192     DCE2_PafRegisterService(sc, dce2_proto_ids.dcerpc, policyId, DCE2_TRANS_TYPE__TCP);
 1193 #endif
 1194 
 1195 #ifdef DCE2_LOG_EXTRA_DATA
 1196     swap_config->xtra_logging_smb_file_name_id =
 1197         _dpd.streamAPI->reg_xtra_data_cb(DCE2_LogSmbFileName);
 1198 #endif
 1199 
 1200     /* Register routing table memory */
 1201     if (swap_config->sconfigs != NULL)
 1202         DCE2_RegMem(sfrt_usage(swap_config->sconfigs), DCE2_MEM_TYPE__RT);
 1203 
 1204     if (!swap_config->gconfig->legacy_mode)
 1205     {
 1206         DCE2_Smb2Init(swap_config->gconfig->memcap);
 1207         dce2_file_cache_is_enabled = true;
 1208     }
 1209 
 1210     if (current_config == NULL)
 1211         return 0;
 1212 
 1213     return 0;
 1214 }
 1215 
 1216 /*********************************************************************
 1217  * Function: DCE2_ReloadVerify()
 1218  * WARNING This runs in a thread that is Asynchronous with the
 1219  * packet loop thread
 1220  *
 1221  * Purpose: Verifies a reloaded DCE/RPC preprocessor configuration
 1222  *
 1223  * Arguments: None
 1224  *
 1225  * Returns:
 1226  *  int
 1227  *      -1 if changed configuration value requires a restart
 1228  *       0 if configuration is ok
 1229  *
 1230  *********************************************************************/
 1231 static int DCE2_ReloadVerify(struct _SnortConfig *sc, void *swap_config)
 1232 {
 1233     tSfPolicyUserContextId dce2_swap_config = (tSfPolicyUserContextId)swap_config;
 1234 
 1235     if ((dce2_swap_config == NULL) || (dce2_config == NULL))
 1236         return 0;
 1237 
 1238     if (sfPolicyUserDataIterate(sc, dce2_swap_config, DCE2_ReloadVerifyPolicy) != 0)
 1239     {
 1240         return -1;
 1241     }
 1242 
 1243     tSfPolicyId policy_id = _dpd.getParserPolicy(sc);
 1244     /* Look in DCE2_InitGlobal and DCE2_ReloadGlobal to find that DefaultPolicy can't be NULL
 1245     *  You'll also find that all memcaps are synched to DefaultPolicy as the memcap is global
 1246     *  to all policies
 1247     *  Here we are setting up the work that needs to be done to adjust to the new configuration
 1248     */
 1249     uint32_t current_memcap     = DCE2_GetReloadSafeMemcap(dce2_config);
 1250     uint32_t new_memcap         = DCE2_GetReloadSafeMemcap(dce2_swap_config);
 1251 
 1252     if (dce2_ada_was_enabled && !dce2_ada_is_enabled)
 1253     {
 1254         ada_set_new_cap(ada, 0);
 1255         _dpd.reloadAdjustRegister(sc, "dce2-mem-reloader", policy_id, DCE2_ReloadAdjust, NULL, NULL);
 1256     }
 1257     else if (new_memcap != current_memcap ||
 1258         (dce2_file_cache_was_enabled && !dce2_file_cache_is_enabled))
 1259     {
 1260         ada_set_new_cap(ada, (size_t)(new_memcap));
 1261         _dpd.reloadAdjustRegister(sc, "dce2-mem-reloader", policy_id, DCE2_ReloadAdjust, NULL, NULL);
 1262     }
 1263 
 1264     return 0;
 1265 }
 1266 
 1267 /*********************************************************************
 1268  * Function: DCE2_ReloadAdjust
 1269  *
 1270  * Purpose: After reloading with a different configuration that
 1271  * that requres work to adapt, this function will perform the
 1272  * work in small bursts.
 1273  *
 1274  * Arguments:   idle - if snort is idling (low packets) do more work
 1275  *              raPolicyId - identifies which policy the config is for
 1276  *              userData - data needed by this function
 1277  *
 1278  * Returns:
 1279  *  bool
 1280  *      return false if it needs to work more
 1281  *      return true if there is no work left
 1282  *
 1283  *********************************************************************/
 1284 static bool DCE2_ReloadAdjust(bool idle, tSfPolicyId raPolicyId, void *userData)
 1285 {
 1286     /* delete files until the file cache memcaps are met
 1287      * delete file cache if not needed
 1288      * delete dce session data from sessions until dce global memcap is met
 1289      * delete ada cache if not needed
 1290      * return true when completed successfully, else false
 1291     */
 1292     int maxWork = idle ? 512 : 32;
 1293     bool memcaps_satisfied =    DCE2_Smb2AdjustFileCache(maxWork, dce2_file_cache_is_enabled) &&
 1294                                 ada_reload_adjust_func(idle, raPolicyId, (void *) ada);
 1295     if (memcaps_satisfied && dce2_ada_was_enabled && !dce2_ada_is_enabled)
 1296     {
 1297         ada_delete(ada);
 1298         ada = NULL;
 1299     }
 1300 #ifdef REG_TEST
 1301     if (memcaps_satisfied && REG_TEST_FLAG_RELOAD & getRegTestFlags())
 1302         printf("dcerpc2-reload reload-adjust %d %d \n", ada != NULL, !DCE2_IsFileCache(NULL));
 1303 #endif
 1304     return memcaps_satisfied;
 1305 }
 1306 
 1307 static int DCE2_ReloadSwapPolicy(
 1308         tSfPolicyUserContextId config,
 1309         tSfPolicyId policyId,
 1310         void* pData
 1311         )
 1312 {
 1313     DCE2_Config *pPolicyConfig = (DCE2_Config *)pData;
 1314 
 1315     //do any housekeeping before freeing config
 1316     if (pPolicyConfig->ref_count == 0)
 1317     {
 1318         sfPolicyUserDataClear (config, policyId);
 1319         DCE2_FreeConfig(pPolicyConfig);
 1320     }
 1321     return 0;
 1322 }
 1323 
 1324 /*********************************************************************
 1325  * Function: DCE2_ReloadSwap()
 1326  *
 1327  * Purpose: Swaps a new config for the old one.
 1328  *
 1329  * Arguments: None
 1330  *
 1331  * Returns: None
 1332  *
 1333  *********************************************************************/
 1334 static void * DCE2_ReloadSwap(struct _SnortConfig *sc, void *swap_config)
 1335 {
 1336     tSfPolicyUserContextId dce2_swap_config = (tSfPolicyUserContextId)  swap_config;
 1337     tSfPolicyUserContextId old_config       =                           dce2_config;
 1338 
 1339     if (dce2_swap_config == NULL)
 1340         return NULL;
 1341 
 1342     /* Set file cache's new memcaps so it doesn't misbehave
 1343     *  Ensure that the correct amount of memory is registered
 1344     *  See DCE2_Smb2Init for inspiration
 1345     */
 1346     uint32_t current_memcap = 0;
 1347     if (dce2_file_cache_was_enabled)
 1348         current_memcap = DCE2_GetReloadSafeMemcap(dce2_config);
 1349     uint32_t swap_memcap = 0;
 1350     if (dce2_file_cache_is_enabled)
 1351         swap_memcap    = DCE2_GetReloadSafeMemcap(dce2_swap_config);
 1352 
 1353     DCE2_SetSmbMemcap((uint64_t) swap_memcap >> 1);
 1354 
 1355     if (dce2_file_cache_was_enabled)
 1356     {
 1357         DCE2_UnRegMem(current_memcap >> 1, DCE2_MEM_TYPE__SMB_SSN);
 1358         if (dce2_file_cache_is_enabled)
 1359             DCE2_RegMem(swap_memcap >> 1, DCE2_MEM_TYPE__SMB_SSN);
 1360     }
 1361 
 1362     dce2_config = dce2_swap_config;
 1363     sfPolicyUserDataFreeIterate (old_config, DCE2_ReloadSwapPolicy);
 1364     if (sfPolicyUserPolicyGetActive(old_config) == 0)
 1365         return (void *)old_config;
 1366 
 1367     return NULL;
 1368 }
 1369 
 1370 static void DCE2_ReloadSwapFree(void *data)
 1371 {
 1372     if (data == NULL)
 1373         return;
 1374 
 1375     DCE2_FreeConfigs((tSfPolicyUserContextId)data);
 1376 }
 1377 #endif
 1378 
 1379 // Used for iterate function below since we can't pass it
 1380 static tSfPolicyId dce2_paf_tmp_policy_id = 0;
 1381 
 1382 /*********************************************************************
 1383  * Function: DCE2_AddPortsToPaf()
 1384  *
 1385  * Add detect and autodetect ports to stream5 paf
 1386  *
 1387  * Arguments:
 1388  *  DCE2_Config *
 1389  *      Pointer to configuration structure.
 1390  *
 1391  * Returns: None
 1392  *
 1393  *********************************************************************/
 1394 static void DCE2_AddPortsToPaf(struct _SnortConfig *sc, DCE2_Config *config, tSfPolicyId policy_id)
 1395 {
 1396     if (config == NULL)
 1397         return;
 1398 
 1399     dce2_paf_tmp_policy_id = policy_id;
 1400 
 1401     DCE2_ScAddPortsToPaf(sc, config->dconfig);
 1402 
 1403     if (config->sconfigs != NULL)
 1404         sfrt_iterate_with_snort_config(sc, config->sconfigs, DCE2_ScAddPortsToPaf);
 1405 
 1406     dce2_paf_tmp_policy_id = 0;
 1407 }
 1408 
 1409 static void DCE2_ScAddPortsToPaf(struct _SnortConfig *snortConf, void *data)
 1410 {
 1411     DCE2_ServerConfig *sc = (DCE2_ServerConfig *)data;
 1412     unsigned int port;
 1413     tSfPolicyId policy_id = dce2_paf_tmp_policy_id;
 1414 
 1415     if (data == NULL)
 1416         return;
 1417 
 1418     for (port = 0; port < DCE2_PORTS__MAX; port++)
 1419     {
 1420         if (DCE2_IsPortSet(sc->smb_ports, (uint16_t)port))
 1421         {
 1422             DCE2_PafRegisterPort(snortConf, (uint16_t)port, policy_id, DCE2_TRANS_TYPE__SMB);
 1423         }
 1424 
 1425         if (DCE2_IsPortSet(sc->auto_smb_ports, (uint16_t)port))
 1426         {
 1427             DCE2_PafRegisterPort(snortConf, (uint16_t)port, policy_id, DCE2_TRANS_TYPE__SMB);
 1428         }
 1429 
 1430         if (DCE2_IsPortSet(sc->tcp_ports, (uint16_t)port))
 1431         {
 1432             DCE2_PafRegisterPort(snortConf, (uint16_t)port, policy_id, DCE2_TRANS_TYPE__TCP);
 1433         }
 1434 
 1435         if (DCE2_IsPortSet(sc->auto_tcp_ports, (uint16_t)port))
 1436         {
 1437             DCE2_PafRegisterPort(snortConf, (uint16_t)port, policy_id, DCE2_TRANS_TYPE__TCP);
 1438         }
 1439 
 1440 #if 0
 1441         if (DCE2_IsPortSet(sc->http_proxy_ports, (uint16_t)port))
 1442         {
 1443             /* TODO Implement PAF registration and callback. */
 1444         }
 1445 
 1446         if (DCE2_IsPortSet(sc->http_server_ports, (uint16_t)port))
 1447         {
 1448             /* TODO Implement PAF registration and callback. */
 1449         }
 1450 #endif
 1451     }
 1452 }
 1453 
 1454 static uint32_t max(uint32_t a, uint32_t b)
 1455 {
 1456     if (a >= b)
 1457         return a;
 1458     return b;
 1459 }
 1460 
 1461 /*********************************************************************
 1462  * Function: DCE2_GetReloadSafeMemcap
 1463  *
 1464  * Purpose: Provide a safe memcap that can be used durring
 1465  * packet processing.
 1466  * This is based on how the memcaps are set in InitGlobal and
 1467  * ReloadGlobal
 1468  *
 1469  * The memcap in the config for the policyId currently running is
 1470  * what is used as a memcap, according to DCE2_Process calling 
 1471  * DCE2_GcMemcap.
 1472  *
 1473  * Based on InitGlobal and ReloadGlobal all memcaps are equal to
 1474  * the memcap in the default policy except for policy_id 0
 1475  *
 1476  * So to be safe we'll just return the max of the two.
 1477  *
 1478  * This function also helps to prevent segmentation faults caused
 1479  * by accessing null pointers.
 1480  *
 1481  * Arguments: pConfig - mapping between policyIDs and configs
 1482  *
 1483  * Returns: A safe memcap
 1484  *
 1485  *********************************************************************/
 1486 static uint32_t DCE2_GetReloadSafeMemcap(tSfPolicyUserContextId pConfig)
 1487 {
 1488   DCE2_Config *pDefaultPolicyConfig = sfPolicyUserDataGetDefault(pConfig);
 1489   DCE2_Config *pPolicyConfig        = sfPolicyUserDataGet(pConfig, 0);
 1490   uint32_t defaultMem = pDefaultPolicyConfig == NULL ?
 1491                         0 : pDefaultPolicyConfig->gconfig->memcap;
 1492   uint32_t policyMem  = pPolicyConfig == NULL ?
 1493                         0 : pPolicyConfig->gconfig->memcap;
 1494 
 1495   return max(defaultMem,policyMem);
 1496 }