"Fossies" - the Fresh Open Source Software Archive

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


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

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