1 /*
2  * Copyright 2004-2013, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10 
11 #ifndef __TAP_SCTP_ANALYSIS_H__
12 #define __TAP_SCTP_ANALYSIS_H__
13 
14 #include <epan/dissectors/packet-sctp.h>
15 #include <epan/address.h>
16 #ifdef _WIN32
17 #include <winsock2.h>
18 #else
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #endif
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif /* __cplusplus */
27 
28 #define CHUNK_TYPE_LENGTH	      1
29 #define CHUNK_FLAGS_LENGTH	      1
30 #define CHUNK_LENGTH_LENGTH	      2
31 
32 #define CHUNK_HEADER_OFFSET	      0
33 #define CHUNK_TYPE_OFFSET	      CHUNK_HEADER_OFFSET
34 #define CHUNK_FLAGS_OFFSET	      (CHUNK_TYPE_OFFSET + CHUNK_TYPE_LENGTH)
35 #define CHUNK_LENGTH_OFFSET	      (CHUNK_FLAGS_OFFSET + CHUNK_FLAGS_LENGTH)
36 #define CHUNK_VALUE_OFFSET	      (CHUNK_LENGTH_OFFSET + CHUNK_LENGTH_LENGTH)
37 
38 #define INIT_CHUNK_INITIATE_TAG_LENGTH		     4
39 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH	     4
40 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH 2
41 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH  2
42 
43 
44 #define INIT_CHUNK_INITIATE_TAG_OFFSET		     CHUNK_VALUE_OFFSET
45 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET	     (INIT_CHUNK_INITIATE_TAG_OFFSET + \
46 						      INIT_CHUNK_INITIATE_TAG_LENGTH )
47 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET (INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
48 						      INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH )
49 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET  (INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET + \
50 						      INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH )
51 #define INIT_CHUNK_INITIAL_TSN_OFFSET		     (INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET + \
52 						      INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH )
53 
54 #define DATA_CHUNK_TSN_LENGTH	      4
55 #define DATA_CHUNK_TSN_OFFSET	      (CHUNK_VALUE_OFFSET + 0)
56 #define DATA_CHUNK_STREAM_ID_OFFSET   (DATA_CHUNK_TSN_OFFSET + DATA_CHUNK_TSN_LENGTH)
57 #define DATA_CHUNK_STREAM_ID_LENGTH   2
58 #define DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH 2
59 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
60 #define I_DATA_CHUNK_RESERVED_LENGTH 2
61 #define I_DATA_CHUNK_MID_LENGTH 4
62 #define I_DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
63 #define I_DATA_CHUNK_FSN_LENGTH 4
64 #define I_DATA_CHUNK_RESERVED_OFFSET  (DATA_CHUNK_STREAM_ID_OFFSET + \
65                                        DATA_CHUNK_STREAM_ID_LENGTH)
66 #define I_DATA_CHUNK_MID_OFFSET       (I_DATA_CHUNK_RESERVED_OFFSET + \
67                                        I_DATA_CHUNK_RESERVED_LENGTH)
68 #define I_DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET (I_DATA_CHUNK_MID_OFFSET + \
69                                                  I_DATA_CHUNK_MID_LENGTH)
70 #define I_DATA_CHUNK_FSN_OFFSET       (I_DATA_CHUNK_MID_OFFSET + \
71                                        I_DATA_CHUNK_MID_LENGTH)
72 #define I_DATA_CHUNK_PAYLOAD_OFFSET   (I_DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET + \
73                                        I_DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
74 #define DATA_CHUNK_HEADER_LENGTH      (CHUNK_HEADER_LENGTH + \
75 				       DATA_CHUNK_TSN_LENGTH + \
76 				       DATA_CHUNK_STREAM_ID_LENGTH + \
77 				       DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH + \
78 				       DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
79 #define I_DATA_CHUNK_HEADER_LENGTH    (CHUNK_HEADER_LENGTH + \
80                                        DATA_CHUNK_TSN_LENGTH + \
81                                        DATA_CHUNK_STREAM_ID_LENGTH + \
82                                        I_DATA_CHUNK_RESERVED_LENGTH + \
83                                        I_DATA_CHUNK_MID_LENGTH +\
84                                        I_DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
85 #define MAX_ADDRESS_LEN		       47
86 
87 #define SCTP_ABORT_CHUNK_T_BIT	      0x01
88 
89 #define PARAMETER_TYPE_LENGTH		 2
90 #define PARAMETER_LENGTH_LENGTH		 2
91 #define PARAMETER_HEADER_LENGTH		 (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
92 
93 #define PARAMETER_HEADER_OFFSET		 0
94 #define PARAMETER_TYPE_OFFSET		 PARAMETER_HEADER_OFFSET
95 #define PARAMETER_LENGTH_OFFSET		 (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
96 #define PARAMETER_VALUE_OFFSET		 (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
97 
98 #define IPV6_ADDRESS_LENGTH 16
99 #define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
100 #define IPV4_ADDRESS_LENGTH 4
101 #define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
102 #define IPV4ADDRESS_PARAMETER_ID	     0x0005
103 #define IPV6ADDRESS_PARAMETER_ID	     0x0006
104 
105 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH	4
106 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
107 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
108 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
109 						 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
110 
111 #define INIT_CHUNK_INITIAL_TSN_LENGTH		     4
112 #define INIT_CHUNK_FIXED_PARAMETERS_LENGTH	     (INIT_CHUNK_INITIATE_TAG_LENGTH + \
113 						      INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH + \
114 						      INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH + \
115 						      INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH + \
116 						      INIT_CHUNK_INITIAL_TSN_LENGTH)
117 #define CHUNK_HEADER_LENGTH	      (CHUNK_TYPE_LENGTH + \
118 				       CHUNK_FLAGS_LENGTH + \
119 				       CHUNK_LENGTH_LENGTH)
120 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET  (INIT_CHUNK_INITIAL_TSN_OFFSET + \
121 						      INIT_CHUNK_INITIAL_TSN_LENGTH )
122 
123 /* The below value is 255 */
124 #define NUM_CHUNKS  0x100
125 
126 /* This variable is used as an index into arrays
127  * which store the cumulative information corresponding
128  * all chunks with Chunk Type greater > 16
129  * The value for the below variable is 17
130  */
131 #define OTHER_CHUNKS_INDEX	0xfe
132 
133 /* VNB */
134 /* This variable stores the maximum chunk type value
135  * that can be associated with a sctp chunk.
136  */
137 #define MAX_SCTP_CHUNK_TYPE 256
138 
139 typedef struct _tsn {
140 	guint32	 frame_number;
141 	guint32	 secs;		/* Absolute seconds */
142 	guint32	 usecs;
143 	address	 src;
144 	address	 dst;
145 	guint32	 first_tsn;
146 	GList	*tsns;
147 } tsn_t;
148 
149 typedef struct _sctp_tmp_info {
150 	guint16 assoc_id;
151 	guint16 direction;
152 	address src;
153 	address dst;
154 	guint16 port1;
155 	guint16 port2;
156 	guint32 verification_tag1;
157 	guint32 verification_tag2;
158 	guint32 initiate_tag;
159 	guint32 n_tvbs;
160 } sctp_tmp_info_t;
161 
162 typedef struct _sctp_init_collision {
163 	guint32 init_vtag;		/* initiate tag of the INIT chunk */
164 	guint32 initack_vtag;		/* initiate tag of the INIT-ACK chunk */
165 	guint32 init_min_tsn;		/* initial tsn of the INIT chunk */
166 	guint32 initack_min_tsn;	/* initial tsn of the INIT-ACK chunk */
167 	gboolean init:1;
168 	gboolean initack:1;
169 } sctp_init_collision_t;
170 
171 struct tsn_sort{
172 	guint32 tsnumber;
173 	guint32 secs;
174 	guint32 usecs;
175 	guint32 offset;
176 	guint32 length;
177 	guint32 framenumber;
178 };
179 
180 typedef struct _sctp_addr_chunk {
181 	guint32	 direction;
182 	address addr;
183 	/* The array is initialized to MAX_SCTP_CHUNK_TYPE
184 	 * so that there is no memory overwrite
185 	 * when accessed using sctp chunk type as index.
186 	 */
187 	guint32	 addr_count[MAX_SCTP_CHUNK_TYPE];
188 } sctp_addr_chunk;
189 
190 typedef struct _sctp_assoc_info {
191 	guint16	   assoc_id;
192 	address	   src;
193 	address	   dst;
194 	guint16	   port1;
195 	guint16	   port2;
196 	guint32	   verification_tag1;
197 	guint32	   verification_tag2;
198 	guint32	   initiate_tag;
199 	guint32	   n_tvbs;
200 	GList	  *addr1;
201 	GList	  *addr2;
202 	guint16	   instream1;
203 	guint16	   outstream1;
204 	guint16	   instream2;
205 	guint16	   outstream2;
206 	guint32	   n_adler32_calculated;
207 	guint32	   n_adler32_correct;
208 	guint32	   n_crc32c_calculated;
209 	guint32	   n_crc32c_correct;
210 	gchar	   checksum_type[8];
211 	guint32	   n_checksum_errors;
212 	guint32	   n_bundling_errors;
213 	guint32	   n_padding_errors;
214 	guint32	   n_length_errors;
215 	guint32	   n_value_errors;
216 	guint32	   n_data_chunks;
217 	guint32	   n_forward_chunks;
218 	guint32	   n_forward_chunks_ep1;
219 	guint32	   n_forward_chunks_ep2;
220 	guint32	   n_data_bytes;
221 	guint32	   n_packets;
222 	guint32	   n_data_chunks_ep1;
223 	guint32	   n_data_bytes_ep1;
224 	guint32	   n_data_chunks_ep2;
225 	guint32	   n_data_bytes_ep2;
226 	guint32	   n_sack_chunks_ep1;
227 	guint32	   n_sack_chunks_ep2;
228 	guint32	   n_array_tsn1;
229 	guint32	   n_array_tsn2;
230 	guint32	   max_window1;
231 	guint32	   max_window2;
232 	guint32	   arwnd1;
233 	guint32	   arwnd2;
234 	gboolean   init:1;
235 	gboolean   initack:1;
236 	gboolean   firstdata:1;
237 	gboolean   init_collision:1;
238 	guint16	   initack_dir;
239 	guint16	   direction;
240 	guint32	   min_secs;
241 	guint32	   min_usecs;
242 	guint32	   max_secs;
243 	guint32	   max_usecs;
244 	guint32	   min_tsn1;
245 	guint32	   min_tsn2;
246 	guint32	   max_tsn1;
247 	guint32	   max_tsn2;
248 	guint32	   max_bytes1;
249 	guint32	   max_bytes2;
250 	sctp_init_collision_t *dir1;
251 	sctp_init_collision_t *dir2;
252 	GSList	  *min_max;
253 	GList	  *frame_numbers;
254 	GList	  *tsn1;
255 	GPtrArray *sort_tsn1;
256 	GPtrArray *sort_sack1;
257 	GList	  *sack1;
258 	GList	  *tsn2;
259 	GPtrArray *sort_tsn2;
260 	GPtrArray *sort_sack2;
261 	GList	  *sack2;
262 	gboolean   check_address;
263 	GList*	   error_info_list;
264 	/* The array is initialized to MAX_SCTP_CHUNK_TYPE
265 	 * so that there is no memory overwrite
266 	 * when accessed using sctp chunk type as index.
267 	 */
268 	guint32	   chunk_count[MAX_SCTP_CHUNK_TYPE];
269 	guint32	   ep1_chunk_count[MAX_SCTP_CHUNK_TYPE];
270 	guint32	   ep2_chunk_count[MAX_SCTP_CHUNK_TYPE];
271 	GList *addr_chunk_count;
272 } sctp_assoc_info_t;
273 
274 typedef struct _sctp_error_info {
275 	guint32	     frame_number;
276 	gchar	     chunk_info[200];
277 	const gchar *info_text;
278 } sctp_error_info_t;
279 
280 
281 typedef struct _sctp_allassocs_info {
282 	guint32	  sum_tvbs;
283 	GList	 *assoc_info_list;
284 	gboolean  is_registered;
285 	GList	 *children;
286 } sctp_allassocs_info_t;
287 
288 
289 
290 void register_tap_listener_sctp_stat(void);
291 
292 const sctp_allassocs_info_t* sctp_stat_get_info(void);
293 
294 void sctp_stat_scan(void);
295 
296 void remove_tap_listener_sctp_stat(void);
297 
298 const sctp_assoc_info_t* get_sctp_assoc_info(guint16 assoc_id);
299 const sctp_assoc_info_t* get_selected_assoc(void);
300 
301 #ifdef __cplusplus
302 }
303 #endif /* __cplusplus */
304 
305 #endif /* __TAP_SCTP_ANALYSIS_H__ */
306