"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/dynamic-preprocessors/s7commplus/s7comm_paf.c" (16 Oct 2020, 4292 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 "s7comm_paf.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * This program is free software; you can redistribute it and/or modify
    3  * it under the terms of the GNU General Public License Version 2 as
    4  * published by the Free Software Foundation.  You may not use, modify or
    5  * distribute this program under any other version of the GNU General
    6  * Public License.
    7  *
    8  * This program is distributed in the hope that it will be useful,
    9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11  * GNU General Public License for more details.
   12  *
   13  * You should have received a copy of the GNU General Public License
   14  * along with this program; if not, write to the Free Software
   15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   16  *
   17  * Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
   18  *
   19  * Authors: Jeffrey Gu <jgu@cisco.com>, Pradeep Damodharan <prdamodh@cisco.com>
   20  *
   21  * Protocol-Aware Flushing (PAF) code for the S7commplus preprocessor.
   22  *
   23  */
   24 
   25 #include "spp_s7comm.h"
   26 #include "s7comm_decode.h"
   27 #include "s7comm_paf.h"
   28 #include "sf_dynamic_preprocessor.h"
   29 
   30 int S7commplusPafRegisterPort (struct _SnortConfig *sc, uint16_t port, tSfPolicyId policy_id)
   31 {
   32     if (!_dpd.isPafEnabled())
   33         return 0;
   34 
   35     _dpd.streamAPI->register_paf_port(sc, policy_id, port, 0, (PAF_Callback)S7commplusPaf, true);
   36     _dpd.streamAPI->register_paf_port(sc, policy_id, port, 1, (PAF_Callback)S7commplusPaf, true);
   37 
   38     return 0;
   39 }
   40 
   41 #ifdef TARGET_BASED
   42 int S7commplusAddServiceToPaf (struct _SnortConfig *sc, uint16_t service, tSfPolicyId policy_id)
   43 {
   44     if (!_dpd.isPafEnabled())
   45         return 0;
   46 
   47     _dpd.streamAPI->register_paf_service(sc, policy_id, service, 0, (PAF_Callback)S7commplusPaf, true);
   48     _dpd.streamAPI->register_paf_service(sc, policy_id, service, 1, (PAF_Callback)S7commplusPaf, true);
   49 
   50     return 0;
   51 }
   52 #endif
   53 
   54 /* Function: S7commplusPaf()
   55 
   56 Purpose: S7commplus/TCP PAF callback.
   57 Statefully inspects S7commplus traffic from the start of a session,
   58 Reads up until the length octet is found, then sets a flush point.
   59 
   60 Arguments:
   61 void * - stream5 session pointer
   62 void ** - S7commplus state tracking structure
   63 const uint8_t * - payload data to inspect
   64 uint32_t - length of payload data
   65 uint32_t - flags to check whether client or server
   66 uint32_t * - pointer to set flush point
   67 
   68 Returns:
   69 PAF_Status - PAF_FLUSH if flush point found, PAF_SEARCH otherwise
   70  */
   71 
   72 PAF_Status S7commplusPaf(void *ssn, void **user, const uint8_t *data,
   73         uint32_t len, uint32_t flags, uint32_t *fp, uint32_t *fp_eoh)
   74 {
   75     s7commplus_paf_data_t *pafdata = *(s7commplus_paf_data_t **)user;
   76     uint32_t bytes_processed = 0;
   77 
   78     /* Allocate state object if it doesn't exist yet. */
   79     if (pafdata == NULL)
   80     {
   81         pafdata = calloc(1, sizeof(s7commplus_paf_data_t));
   82         if (pafdata == NULL)
   83             return PAF_ABORT;
   84 
   85         *user = pafdata;
   86     }
   87 
   88     /* Process this packet 1 byte at a time */
   89     while (bytes_processed < len)
   90     {
   91         switch (pafdata->state)
   92         {
   93             /* Skip the Transaction & Protocol IDs */
   94             case S7COMMPLUS_PAF_STATE__TPKT_VER:
   95             case S7COMMPLUS_PAF_STATE__TPKT_RESERVED:
   96             case S7COMMPLUS_PAF_STATE__COPT_LEN:
   97             case S7COMMPLUS_PAF_STATE__COPT_PDU_TYPE:
   98                 pafdata->state++;
   99                 break;
  100 
  101             case S7COMMPLUS_PAF_STATE__TPKT_LEN_1:
  102                 pafdata->tpkt_length |= ( *(data + bytes_processed) << 8 );
  103                 pafdata->state++;
  104                 break;
  105 
  106             case S7COMMPLUS_PAF_STATE__TPKT_LEN_2:
  107                 pafdata->tpkt_length |= *(data + bytes_processed);
  108                 pafdata->state++;
  109                 break;
  110 
  111             case S7COMMPLUS_PAF_STATE__SET_FLUSH:
  112                 if ((pafdata->tpkt_length < TPKT_MIN_HDR_LEN))
  113                 {
  114                     _dpd.alertAdd(GENERATOR_SPP_S7COMMPLUS, S7COMMPLUS_BAD_LENGTH, 1, 0, 3,
  115                             S7COMMPLUS_BAD_LENGTH_STR, 0);
  116                 }
  117                 /* flush point at the end of payload */
  118                 *fp = pafdata->tpkt_length;
  119                 pafdata->state = S7COMMPLUS_PAF_STATE__TPKT_VER;
  120                 pafdata->tpkt_length = 0;
  121                 return PAF_FLUSH;
  122         }
  123 
  124         bytes_processed++;
  125     }
  126 
  127     return PAF_SEARCH;
  128 }
  129 
  130 /* Take a S7commplus config + Snort policy, iterate through ports, register PAF callback */
  131 void S7commplusAddPortsToPaf(struct _SnortConfig *sc, s7commplus_config_t *config, tSfPolicyId policy_id)
  132 {
  133     unsigned int i;
  134 
  135     for (i = 0; i < MAX_PORTS; i++)
  136     {
  137         if (config->ports[PORT_INDEX(i)] & CONV_PORT(i))
  138         {
  139             S7commplusPafRegisterPort(sc, (uint16_t) i, policy_id);
  140         }
  141     }
  142 }