"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 }