2 * Routines for Stream Control Transmission Protocol dissection
3 * It should be compilant to
6 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpimpguide-07.txt
7 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-addip-sctp-06.txt for the add-IP extension
8 * - http://www.ietf.org/internet-drafts/draft-stewart-tsvwg-prsctp-01.txt for the 'Partial Reliability' extension
9 * Copyright 2000, 2001, 2002, Michael Tuexen <Michael.Tuexen [AT] siemens.com>
10 * Still to do (so stay tuned)
11 * - support for reassembly
14 * $Id: packet-sctp.c,v 1.51 2003/01/31 03:17:46 guy Exp $
16 * Ethereal - Network traffic analyzer
17 * By Gerald Combs <gerald@ethereal.com>
18 * Copyright 1998 Gerald Combs
20 * Copied from README.developer
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
42 #include <epan/packet.h>
44 #include "sctpppids.h"
46 /* Initialize the protocol and registered fields */
47 static int proto_sctp = -1;
48 static int hf_sctp_port = -1;
49 static int hf_sctp_source_port = -1;
50 static int hf_sctp_destination_port = -1;
51 static int hf_sctp_verification_tag = -1;
52 static int hf_sctp_checksum = -1;
53 static int hf_sctp_checksum_bad = -1;
55 static int hf_sctp_chunk_type = -1;
56 static int hf_sctp_chunk_flags = -1;
57 static int hf_sctp_chunk_length = -1;
59 static int hf_sctp_init_chunk_initiate_tag = -1;
60 static int hf_sctp_init_chunk_adv_rec_window_credit = -1;
61 static int hf_sctp_init_chunk_number_of_outbound_streams = -1;
62 static int hf_sctp_init_chunk_number_of_inbound_streams = -1;
63 static int hf_sctp_init_chunk_initial_tsn = -1;
65 static int hf_sctp_cumulative_tsn_ack = -1;
67 static int hf_sctp_data_chunk_tsn = -1;
68 static int hf_sctp_data_chunk_stream_id = -1;
69 static int hf_sctp_data_chunk_stream_seq_number = -1;
70 static int hf_sctp_data_chunk_payload_proto_id = -1;
72 static int hf_sctp_data_chunk_e_bit = -1;
73 static int hf_sctp_data_chunk_b_bit = -1;
74 static int hf_sctp_data_chunk_u_bit = -1;
76 static int hf_sctp_sack_chunk_cumulative_tsn_ack = -1;
77 static int hf_sctp_sack_chunk_adv_rec_window_credit = -1;
78 static int hf_sctp_sack_chunk_number_of_gap_blocks = -1;
79 static int hf_sctp_sack_chunk_number_of_dup_tsns = -1;
80 static int hf_sctp_sack_chunk_gap_block_start = -1;
81 static int hf_sctp_sack_chunk_gap_block_end = -1;
82 static int hf_sctp_sack_chunk_duplicate_tsn = -1;
84 static int hf_sctp_shutdown_chunk_cumulative_tsn_ack = -1;
86 static int hf_sctp_cwr_chunk_lowest_tsn = -1;
88 static int hf_sctp_ecne_chunk_lowest_tsn = -1;
90 static int hf_sctp_shutdown_complete_chunk_t_bit = -1;
92 static int hf_sctp_chunk_parameter_type = -1;
93 static int hf_sctp_chunk_parameter_length = -1;
94 static int hf_sctp_parameter_ipv4_address = -1;
95 static int hf_sctp_parameter_ipv6_address = -1;
96 static int hf_sctp_parameter_cookie_preservative_increment = -1;
97 static int hf_sctp_parameter_hostname_hostname = -1;
98 static int hf_sctp_supported_address_types_parameter = -1;
100 static int hf_sctp_cause_code = -1;
101 static int hf_sctp_cause_length = -1;
102 static int hf_sctp_cause_stream_identifier = -1;
104 static int hf_sctp_cause_number_of_missing_parameters = -1;
105 static int hf_sctp_cause_missing_parameter_type = -1;
107 static int hf_sctp_cause_measure_of_staleness = -1;
109 static int hf_sctp_cause_tsn = -1;
111 static int hf_sctp_forward_tsn_chunk_tsn = -1;
112 static int hf_sctp_forward_tsn_chunk_sid = -1;
113 static int hf_sctp_forward_tsn_chunk_ssn = -1;
115 static int hf_sctp_asconf_ack_serial = -1;
116 static int hf_sctp_asconf_serial = -1;
117 static int hf_sctp_correlation_id = -1;
119 static int hf_sctp_adap_indication = -1;
120 static int hf_sctp_abort_chunk_t_bit = -1;
121 static dissector_table_t sctp_port_dissector_table;
122 static dissector_table_t sctp_ppi_dissector_table;
124 static module_t *sctp_module;
126 /* Initialize the subtree pointers */
127 static gint ett_sctp = -1;
128 static gint ett_sctp_chunk = -1;
129 static gint ett_sctp_chunk_parameter = -1;
130 static gint ett_sctp_chunk_cause = -1;
131 static gint ett_sctp_data_chunk_flags = -1;
132 static gint ett_sctp_shutdown_complete_chunk_flags = -1;
133 static gint ett_sctp_abort_chunk_flags = -1;
134 static gint ett_sctp_sack_chunk_gap_block = -1;
135 static gint ett_sctp_supported_address_types_parameter = -1;
136 static gint ett_sctp_unrecognized_parameter_parameter = -1;
138 static dissector_handle_t data_handle;
140 #define SCTP_DATA_CHUNK_ID 0
141 #define SCTP_INIT_CHUNK_ID 1
142 #define SCTP_INIT_ACK_CHUNK_ID 2
143 #define SCTP_SACK_CHUNK_ID 3
144 #define SCTP_HEARTBEAT_CHUNK_ID 4
145 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
146 #define SCTP_ABORT_CHUNK_ID 6
147 #define SCTP_SHUTDOWN_CHUNK_ID 7
148 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
149 #define SCTP_ERROR_CHUNK_ID 9
150 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
151 #define SCTP_COOKIE_ACK_CHUNK_ID 11
152 #define SCTP_ECNE_CHUNK_ID 12
153 #define SCTP_CWR_CHUNK_ID 13
154 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
155 #define SCTP_FORWARD_TSN_CHUNK_ID 192
156 #define SCTP_ASCONF_ACK_CHUNK_ID 0x80
157 #define SCTP_ASCONF_CHUNK_ID 0XC1
159 #define SCTP_IETF_EXT 255
161 static const value_string sctp_chunk_type_values[] = {
162 { SCTP_DATA_CHUNK_ID, "DATA" },
163 { SCTP_INIT_CHUNK_ID, "INIT" },
164 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
165 { SCTP_SACK_CHUNK_ID, "SACK" },
166 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
167 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
168 { SCTP_ABORT_CHUNK_ID, "ABORT" },
169 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
170 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
171 { SCTP_ERROR_CHUNK_ID, "ERROR" },
172 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
173 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
174 { SCTP_ECNE_CHUNK_ID, "ECNE" },
175 { SCTP_CWR_CHUNK_ID, "CWR" },
176 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
177 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
178 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
179 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
180 { SCTP_IETF_EXT, "IETF_EXTENSION" },
183 #define HEARTBEAT_INFO_PARAMETER_ID 0x0001
184 #define IPV4ADDRESS_PARAMETER_ID 0x0005
185 #define IPV6ADDRESS_PARAMETER_ID 0x0006
186 #define STATE_COOKIE_PARAMETER_ID 0x0007
187 #define UNREC_PARA_PARAMETER_ID 0x0008
188 #define COOKIE_PRESERVATIVE_PARAMETER_ID 0x0009
189 #define HOSTNAME_ADDRESS_PARAMETER_ID 0x000b
190 #define SUPPORTED_ADDRESS_TYPES_PARAMETER_ID 0x000c
191 #define ECN_PARAMETER_ID 0x8000
192 #define FORWARD_TSN_SUPPORTED_PARAMETER_ID 0xC000
193 #define ADD_IP_ADDRESS_PARAMETER_ID 0xC001
194 #define DEL_IP_ADDRESS_PARAMETER_ID 0xC002
195 #define ERROR_CAUSE_INDICATION_PARAMETER_ID 0xC003
196 #define SET_PRIMARY_ADDRESS_PARAMETER_ID 0xC004
197 #define SUCCESS_REPORT_PARAMETER_ID 0xC005
198 #define ADAP_LAYER_INDICATION_PARAMETER_ID 0xC006
200 static const value_string sctp_parameter_identifier_values[] = {
201 { HEARTBEAT_INFO_PARAMETER_ID, "Heartbeat info" },
202 { IPV4ADDRESS_PARAMETER_ID, "IPv4 address" },
203 { IPV6ADDRESS_PARAMETER_ID, "IPv6 address" },
204 { STATE_COOKIE_PARAMETER_ID, "State cookie" },
205 { UNREC_PARA_PARAMETER_ID, "Unrecognized parameters" },
206 { COOKIE_PRESERVATIVE_PARAMETER_ID, "Cookie preservative" },
207 { HOSTNAME_ADDRESS_PARAMETER_ID, "Hostname address" },
208 { SUPPORTED_ADDRESS_TYPES_PARAMETER_ID, "Supported address types" },
209 { ECN_PARAMETER_ID, "ECN" },
210 { FORWARD_TSN_SUPPORTED_PARAMETER_ID, "Forward TSN supported" },
211 { ADD_IP_ADDRESS_PARAMETER_ID, "Add IP address" },
212 { DEL_IP_ADDRESS_PARAMETER_ID, "Delete IP address" },
213 { ERROR_CAUSE_INDICATION_PARAMETER_ID, "Error cause indication" },
214 { SET_PRIMARY_ADDRESS_PARAMETER_ID, "Set primary address" },
215 { SUCCESS_REPORT_PARAMETER_ID, "Success report" },
216 { ADAP_LAYER_INDICATION_PARAMETER_ID, "Adaptation Layer Indication" },
219 #define PARAMETER_TYPE_LENGTH 2
220 #define PARAMETER_LENGTH_LENGTH 2
221 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
223 #define PARAMETER_HEADER_OFFSET 0
224 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
225 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
226 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
228 #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET
229 #define HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
231 #define IPV4_ADDRESS_LENGTH 4
232 #define IPV6_ADDRESS_LENGTH 16
234 #define STATE_COOKIE_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
235 #define STATE_COOKIE_PARAMETER_COOKIE_OFFSET PARAMETER_VALUE_OFFSET
237 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET PARAMETER_VALUE_OFFSET
238 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH 4
239 #define SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH 2
241 #define CAUSE_CODE_LENGTH 2
242 #define CAUSE_LENGTH_LENGTH 2
243 #define CAUSE_HEADER_LENGTH (CAUSE_CODE_LENGTH + CAUSE_LENGTH_LENGTH)
245 #define CAUSE_HEADER_OFFSET 0
246 #define CAUSE_CODE_OFFSET CAUSE_HEADER_OFFSET
247 #define CAUSE_LENGTH_OFFSET (CAUSE_CODE_OFFSET + CAUSE_CODE_LENGTH)
248 #define CAUSE_INFO_OFFSET (CAUSE_LENGTH_OFFSET + CAUSE_LENGTH_LENGTH)
250 #define CAUSE_STREAM_IDENTIFIER_LENGTH 2
251 #define CAUSE_RESERVED_LENGTH 2
252 #define CAUSE_STREAM_IDENTIFIER_OFFSET CAUSE_INFO_OFFSET
253 #define CAUSE_RESERVED_OFFSET (CAUSE_STREAM_IDENTIFIER_OFFSET + CAUSE_STREAM_IDENTIFIER_LENGTH)
255 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH 4
256 #define CAUSE_MISSING_PARAMETER_TYPE_LENGTH 2
258 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET CAUSE_INFO_OFFSET
259 #define CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET (CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET + \
260 CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH )
262 #define CAUSE_MEASURE_OF_STALENESS_LENGTH 4
263 #define CAUSE_MEASURE_OF_STALENESS_OFFSET CAUSE_INFO_OFFSET
265 #define CAUSE_TSN_LENGTH 4
266 #define CAUSE_TSN_OFFSET CAUSE_INFO_OFFSET
268 #define INVALID_STREAM_IDENTIFIER 0x01
269 #define MISSING_MANDATORY_PARAMETERS 0x02
270 #define STALE_COOKIE_ERROR 0x03
271 #define OUT_OF_RESOURCE 0x04
272 #define UNRESOLVABLE_ADDRESS 0x05
273 #define UNRECOGNIZED_CHUNK_TYPE 0x06
274 #define INVALID_MANDATORY_PARAMETER 0x07
275 #define UNRECOGNIZED_PARAMETERS 0x08
276 #define NO_USER_DATA 0x09
277 #define COOKIE_RECEIVED_WHILE_SHUTTING_DOWN 0x0a
278 #define RESTART_WITH_NEW_ADDRESSES 0x0b
279 #define USER_INITIATED_ABORT 0x0c
280 #define PROTOCOL_VIOLATION 0x0d
281 #define REQUEST_TO_DELETE_LAST_ADDRESS 0x0100
282 #define OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE 0X0101
283 #define REQUEST_TO_DELETE_SOURCE_ADDRESS 0x0102
284 #define ABORT_DUE_TO_ILLEGAL_ASCONF 0x0103
286 static const value_string sctp_cause_code_values[] = {
287 { INVALID_STREAM_IDENTIFIER, "Invalid stream identifier" },
288 { MISSING_MANDATORY_PARAMETERS, "Missing mandator parameter" },
289 { STALE_COOKIE_ERROR, "Stale cookie error" },
290 { OUT_OF_RESOURCE, "Out of resource" },
291 { UNRESOLVABLE_ADDRESS, "Unresolvable address" },
292 { UNRECOGNIZED_CHUNK_TYPE, "Unrecognized chunk type " },
293 { INVALID_MANDATORY_PARAMETER, "Invalid mandatory parameter" },
294 { UNRECOGNIZED_PARAMETERS, "Unrecognized parameters" },
295 { NO_USER_DATA, "No user data" },
296 { COOKIE_RECEIVED_WHILE_SHUTTING_DOWN, "Cookie received while shutting down" },
297 { RESTART_WITH_NEW_ADDRESSES, "Restart of an association with new addresses" },
298 { USER_INITIATED_ABORT, "User initiated ABORT" },
299 { PROTOCOL_VIOLATION, "Protocol violation" },
300 { REQUEST_TO_DELETE_LAST_ADDRESS, "Request to delete last address" },
301 { OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE, "Operation refused due to resource shortage" },
302 { REQUEST_TO_DELETE_SOURCE_ADDRESS, "Request to delete source address" },
303 { ABORT_DUE_TO_ILLEGAL_ASCONF, "Association Aborted due to illegal ASCONF-ACK" },
306 static const value_string sctp_payload_proto_id_values[] = {
307 { NOT_SPECIFIED_PROTOCOL_ID, "not specified" },
308 { IUA_PAYLOAD_PROTOCOL_ID, "IUA" },
309 { M2UA_PAYLOAD_PROTOCOL_ID, "M2UA" },
310 { M3UA_PAYLOAD_PROTOCOL_ID, "M3UA" },
311 { SUA_PAYLOAD_PROTOCOL_ID, "SUA" },
312 { M2PA_PAYLOAD_PROTOCOL_ID, "M2PA" },
313 { V5UA_PAYLOAD_PROTOCOL_ID, "V5UA" },
314 { H248_PAYLOAD_PROTOCOL_ID, "H.248/MEGACO" },
315 { BICC_PAYLOAD_PROTOCOL_ID, "BICC/Q.2150.3" },
316 { TALI_PAYLOAD_PROTOCOL_ID, "TALI" },
317 { DUA_PAYLOAD_PROTOCOL_ID, "DUA" },
318 { ASAP_PAYLOAD_PROTOCOL_ID, "ASAP" },
319 { ENRP_PAYLOAD_PROTOCOL_ID, "ENRP" },
320 { H323_PAYLOAD_PROTOCOL_ID, "H.323" },
323 /* The structure of the common header is described by the following constants */
324 #define SOURCE_PORT_LENGTH 2
325 #define DESTINATION_PORT_LENGTH 2
326 #define VERIFICATION_TAG_LENGTH 4
327 #define CHECKSUM_LENGTH 4
328 #define COMMON_HEADER_LENGTH (SOURCE_PORT_LENGTH + \
329 DESTINATION_PORT_LENGTH + \
330 VERIFICATION_TAG_LENGTH + \
332 #define SOURCE_PORT_OFFSET 0
333 #define DESTINATION_PORT_OFFSET (SOURCE_PORT_OFFSET + SOURCE_PORT_LENGTH)
334 #define VERIFICATION_TAG_OFFSET (DESTINATION_PORT_OFFSET + DESTINATION_PORT_LENGTH)
335 #define CHECKSUM_OFFSET (VERIFICATION_TAG_OFFSET + VERIFICATION_TAG_LENGTH)
337 /* The structure of the chunk header is described by the following constants */
338 #define CHUNK_TYPE_LENGTH 1
339 #define CHUNK_FLAGS_LENGTH 1
340 #define CHUNK_LENGTH_LENGTH 2
341 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
342 CHUNK_FLAGS_LENGTH + \
344 #define CHUNK_HEADER_OFFSET 0
345 #define CHUNK_TYPE_OFFSET CHUNK_HEADER_OFFSET
346 #define CHUNK_FLAGS_OFFSET (CHUNK_TYPE_OFFSET + CHUNK_TYPE_LENGTH)
347 #define CHUNK_LENGTH_OFFSET (CHUNK_FLAGS_OFFSET + CHUNK_FLAGS_LENGTH)
348 #define CHUNK_VALUE_OFFSET (CHUNK_LENGTH_OFFSET + CHUNK_LENGTH_LENGTH)
350 /* The following constants describe the structure of DATA chunks */
351 #define DATA_CHUNK_TSN_LENGTH 4
352 #define DATA_CHUNK_STREAM_ID_LENGTH 2
353 #define DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH 2
354 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
356 #define DATA_CHUNK_TSN_OFFSET (CHUNK_VALUE_OFFSET + 0)
357 #define DATA_CHUNK_STREAM_ID_OFFSET (DATA_CHUNK_TSN_OFFSET + DATA_CHUNK_TSN_LENGTH)
358 #define DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET (DATA_CHUNK_STREAM_ID_OFFSET + \
359 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
360 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET (DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET + \
361 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
362 #define DATA_CHUNK_PAYLOAD_OFFSET (DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET + \
363 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
365 #define DATA_CHUNK_HEADER_LENGTH (CHUNK_HEADER_LENGTH + \
366 DATA_CHUNK_TSN_LENGTH + \
367 DATA_CHUNK_STREAM_ID_LENGTH + \
368 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH + \
369 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
371 #define SCTP_DATA_CHUNK_E_BIT 0x01
372 #define SCTP_DATA_CHUNK_B_BIT 0x02
373 #define SCTP_DATA_CHUNK_U_BIT 0x04
375 #define INIT_CHUNK_INITIATE_TAG_LENGTH 4
376 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
377 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH 2
378 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH 2
379 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
381 #define INIT_CHUNK_INITIATE_TAG_OFFSET CHUNK_VALUE_OFFSET
382 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (INIT_CHUNK_INITIATE_TAG_OFFSET + \
383 INIT_CHUNK_INITIATE_TAG_LENGTH )
384 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET (INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
385 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH )
386 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET (INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET + \
387 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH )
388 #define INIT_CHUNK_INITIAL_TSN_OFFSET (INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET + \
389 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH )
390 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
391 INIT_CHUNK_INITIAL_TSN_LENGTH )
394 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
395 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
396 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH 2
397 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH 2
398 #define SACK_CHUNK_GAP_BLOCK_LENGTH 4
399 #define SACK_CHUNK_GAP_BLOCK_START_LENGTH 2
400 #define SACK_CHUNK_GAP_BLOCK_END_LENGTH 2
401 #define SACK_CHUNK_DUP_TSN_LENGTH 4
403 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
404 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
405 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
406 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET (SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
407 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH)
408 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET (SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET + \
409 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH)
410 #define SACK_CHUNK_GAP_BLOCK_OFFSET (SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET + \
411 SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH)
413 #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET
415 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET CHUNK_VALUE_OFFSET
416 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
418 #define ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
419 #define ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
421 #define COOKIE_ECHO_CHUNK_COOKIE_OFFSET CHUNK_VALUE_OFFSET
423 #define ECNE_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
424 #define ECNE_CHUNK_LOWEST_TSN_LENGTH 4
426 #define CWR_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
427 #define CWR_CHUNK_LOWEST_TSN_LENGTH 4
429 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT 0x01
431 static const true_false_string sctp_data_chunk_e_bit_value = {
433 "Not the last segment"
436 static const true_false_string sctp_data_chunk_b_bit_value = {
441 static const true_false_string sctp_data_chunk_u_bit_value = {
442 "Unordered delivery",
446 static const true_false_string sctp_shutdown_complete_chunk_t_bit_value = {
451 #define SCTP_CHECKSUM_NONE 0
452 #define SCTP_CHECKSUM_ADLER32 1
453 #define SCTP_CHECKSUM_CRC32C 2
454 #define SCTP_CHECKSUM_AUTOMATIC 3
456 static gint sctp_checksum = SCTP_CHECKSUM_ADLER32;
458 /* adler32.c -- compute the Adler-32 checksum of a data stream
459 * Copyright (C) 1995-1996 Mark Adler
460 * For conditions of distribution and use, see copyright notice in zlib.h
461 * available, e.g. from http://www.cdrom.com/pub/infozip/zlib/
463 * It was modified for the use in this dissector.
466 #define BASE 65521L /* largest prime smaller than 65536 */
467 #define NMAX 5540 /* NMAX is the largest n - 12 such that */
468 /* 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
470 #define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
471 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
472 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
473 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
474 #define DO16(buf) DO8(buf,0); DO8(buf,8);
477 sctp_adler32(const unsigned char* buf, unsigned int len)
479 unsigned int s1 = 1L;
480 unsigned int s2 = 0L;
483 /* handle the first 8 bytes of the datagram */
485 buf += SOURCE_PORT_LENGTH +
486 DESTINATION_PORT_LENGTH +
487 VERIFICATION_TAG_LENGTH;
489 /* handle four 0 bytes as checksum */
490 s2 += CHECKSUM_LENGTH * s1;
491 buf += CHECKSUM_LENGTH;
493 /* now we have 12 bytes handled */
494 len -= COMMON_HEADER_LENGTH;
496 /* handle the rest of the datagram */
498 k = len < NMAX ? len : NMAX;
512 return (s2 << 16) | s1;
515 /* The CRC32C code is taken from draft-ietf-tsvwg-sctpcsum-01.txt.
516 * That code is copyrighted by D. Otis and has been modified.
519 #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
520 static guint32 crc_c[256] =
522 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
523 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
524 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
525 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
526 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
527 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
528 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
529 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
530 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
531 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
532 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
533 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
534 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
535 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
536 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
537 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
538 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
539 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
540 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
541 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
542 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
543 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
544 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
545 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
546 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
547 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
548 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
549 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
550 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
551 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
552 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
553 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
554 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
555 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
556 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
557 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
558 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
559 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
560 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
561 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
562 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
563 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
564 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
565 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
566 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
567 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
568 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
569 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
570 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
571 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
572 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
573 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
574 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
575 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
576 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
577 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
578 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
579 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
580 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
581 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
582 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
583 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
584 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
585 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
589 sctp_crc32c(const unsigned char* buf, unsigned int len)
594 unsigned char byte0,byte1,byte2,byte3;
596 for (i = 0; i < SOURCE_PORT_LENGTH + DESTINATION_PORT_LENGTH + VERIFICATION_TAG_LENGTH; i++)
598 CRC32C(crc32, buf[i]);
604 for (i = COMMON_HEADER_LENGTH; i < len; i++)
606 CRC32C(crc32, buf[i]);
610 byte0 = result & 0xff;
611 byte1 = (result>>8) & 0xff;
612 byte2 = (result>>16) & 0xff;
613 byte3 = (result>>24) & 0xff;
614 crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
619 nr_of_padding_bytes (guint length)
623 remainder = length % 4;
628 return 4 - remainder;
632 * TLV parameter stuff for INIT and INIT-ACK chunks
636 dissect_parameter(tvbuff_t *, packet_info *, proto_tree *);
639 dissect_error_cause(tvbuff_t *, packet_info *, proto_tree *);
642 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
645 dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, packet_info *pinfo, proto_tree *tree)
647 guint offset, length, padding_length, total_length;
648 tvbuff_t *parameter_tvb;
651 while(tvb_reported_length_remaining(parameter_list_tvb, offset)) {
652 length = tvb_get_ntohs(parameter_list_tvb, offset + PARAMETER_LENGTH_OFFSET);
653 padding_length = nr_of_padding_bytes(length);
654 total_length = length + padding_length;
655 /* create a tvb for the chunk including the padding bytes */
656 parameter_tvb = tvb_new_subset(parameter_list_tvb, offset, total_length, total_length);
657 dissect_parameter(parameter_tvb, pinfo, tree);
658 /* get rid of the handled parameter */
659 offset += total_length;
664 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
666 guint16 length, heartbeat_info_length;
668 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
670 heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
672 proto_tree_add_text(parameter_tree, parameter_tvb, HEARTBEAT_INFO_PARAMETER_INFO_OFFSET, heartbeat_info_length,
673 "Heartbeat info (%u byte%s)",
674 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
676 proto_item_set_text(parameter_item, "Heartbeat info parameter with %u byte%s of info",
677 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
681 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
683 guint32 ipv4_address;
685 tvb_memcpy(parameter_tvb, (guint8 *)&ipv4_address, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH);
686 proto_tree_add_ipv4(parameter_tree, hf_sctp_parameter_ipv4_address,
687 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH,
689 proto_item_set_text(parameter_item, "IPV4 address parameter");
693 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
695 proto_tree_add_ipv6(parameter_tree, hf_sctp_parameter_ipv6_address,
696 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH,
697 tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH));
699 proto_item_set_text(parameter_item, "IPV6 address parameter");
703 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
705 guint16 length, state_cookie_length;
707 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
709 state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
711 proto_tree_add_text(parameter_tree, parameter_tvb, STATE_COOKIE_PARAMETER_COOKIE_OFFSET, state_cookie_length,
712 "State cookie (%u byte%s)",
713 state_cookie_length, plurality(state_cookie_length, "", "s"));
715 proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
716 state_cookie_length, plurality(state_cookie_length, "", "s"));
720 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
722 guint16 length, padding_length, parameter_value_length, unrecognized_parameter_type;
723 tvbuff_t *unrecognized_parameters_tvb;
725 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
726 padding_length = nr_of_padding_bytes(length);
728 parameter_value_length = length - PARAMETER_HEADER_LENGTH + padding_length;
730 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
731 parameter_value_length, parameter_value_length);
732 unrecognized_parameter_type = tvb_get_ntohs(unrecognized_parameters_tvb, PARAMETER_TYPE_OFFSET);
733 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, parameter_tree);
735 proto_item_set_text(parameter_item, "Unrecognized parameter of type %s (0x%x)",
736 val_to_str(unrecognized_parameter_type, sctp_parameter_identifier_values, "unknown"), unrecognized_parameter_type);
740 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
744 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
746 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
747 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
748 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
751 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
756 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
758 guint16 length, hostname_length;
759 const char *hostname;
761 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
763 hostname_length = length - PARAMETER_HEADER_LENGTH;
764 hostname = (const char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
765 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
766 PARAMETER_VALUE_OFFSET, hostname_length,
769 proto_item_set_text(parameter_item, "Hostname parameter");
773 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
775 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
777 proto_item *address_list_item;
778 proto_tree *address_list_tree;
780 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
781 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
782 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
784 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
785 "Supported Address Types (%u address type%s)",
786 number_of_address_types, plurality(number_of_address_types, "", "s"));
787 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
789 offset = PARAMETER_VALUE_OFFSET;
790 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
791 address_type = tvb_get_ntohs(parameter_tvb, offset);
792 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
793 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
794 address_type, "Supported address type: 0x%04x (%s)",
795 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
796 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
799 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
800 number_of_address_types, plurality(number_of_address_types, "", "s"));
804 dissect_ecn_parameter(proto_item *parameter_item)
806 proto_item_set_text(parameter_item, "ECN parameter");
810 dissect_forward_tsn_supported_parameter(proto_item *parameter_item)
812 proto_item_set_text(parameter_item, "Forward TSN supported parameter");
815 #define CORRELATION_ID_LENGTH 4
816 #define CORRELATION_ID_OFFSET PARAMETER_VALUE_OFFSET
817 #define ADDRESS_PARAMETER_OFFSET (CORRELATION_ID_OFFSET + CORRELATION_ID_LENGTH)
820 dissect_add_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
822 guint32 correlation_id;
823 guint16 length, parameter_value_length;
824 tvbuff_t *address_tvb;
826 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
827 parameter_value_length = length - PARAMETER_HEADER_LENGTH - CORRELATION_ID_LENGTH;
828 correlation_id = tvb_get_ntohl(parameter_tvb, CORRELATION_ID_OFFSET);
829 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
830 address_tvb = tvb_new_subset(parameter_tvb, ADDRESS_PARAMETER_OFFSET, parameter_value_length, parameter_value_length);
831 dissect_parameter(address_tvb, pinfo, parameter_tree);
833 proto_item_set_text(parameter_item, "Add IP address parameter");
837 dissect_del_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
839 guint32 correlation_id;
840 guint16 length, parameter_value_length;
841 tvbuff_t *address_tvb;
843 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
844 parameter_value_length = length - PARAMETER_HEADER_LENGTH - CORRELATION_ID_LENGTH;
845 correlation_id = tvb_get_ntohl(parameter_tvb, CORRELATION_ID_OFFSET);
846 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
847 address_tvb = tvb_new_subset(parameter_tvb, ADDRESS_PARAMETER_OFFSET, parameter_value_length, parameter_value_length);
848 dissect_parameter(address_tvb, pinfo, parameter_tree);
850 proto_item_set_text(parameter_item, "Delete IP address parameter");
854 dissect_error_cause_indication_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
856 guint32 correlation_id;
857 guint16 length, padding_length, total_length;
859 tvbuff_t *error_cause_tvb;
861 correlation_id = tvb_get_ntohl(parameter_tvb, CORRELATION_ID_OFFSET);
862 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
864 offset = PARAMETER_VALUE_OFFSET + CORRELATION_ID_LENGTH;
865 while(tvb_reported_length_remaining(parameter_tvb, offset)) {
866 length = tvb_get_ntohs(parameter_tvb, offset + CAUSE_LENGTH_OFFSET);
867 padding_length = nr_of_padding_bytes(length);
868 total_length = length + padding_length;
869 /* create a tvb for the chunk including the padding bytes */
870 error_cause_tvb = tvb_new_subset(parameter_tvb, offset , total_length, total_length);
871 dissect_error_cause(error_cause_tvb, pinfo, parameter_tree);
872 /* get rid of the handled parameter */
873 offset += total_length;
875 proto_item_set_text(parameter_item, "Error cause indication");
879 dissect_set_primary_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
881 guint32 correlation_id;
882 guint16 length, parameter_value_length;
883 tvbuff_t *address_tvb;
885 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
886 parameter_value_length = length - PARAMETER_HEADER_LENGTH - CORRELATION_ID_LENGTH;
888 correlation_id = tvb_get_ntohl(parameter_tvb, CORRELATION_ID_OFFSET);
889 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
890 address_tvb = tvb_new_subset(parameter_tvb, ADDRESS_PARAMETER_OFFSET, parameter_value_length, parameter_value_length);
891 dissect_parameter(address_tvb, pinfo, parameter_tree);
893 proto_item_set_text(parameter_item, "Set primary address parameter");
897 dissect_success_report_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
899 guint32 correlation_id;
901 correlation_id = tvb_get_ntohl(parameter_tvb, CORRELATION_ID_OFFSET);
902 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
904 proto_item_set_text(parameter_item, "Success report parameter");
907 #define ADAP_INDICATION_LENGTH 4
908 #define ADAP_INDICATION_OFFSET PARAMETER_VALUE_OFFSET
911 dissect_adap_indication_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
915 indication = tvb_get_ntohl(parameter_tvb, ADAP_INDICATION_OFFSET);
916 proto_tree_add_uint(parameter_tree, hf_sctp_adap_indication, parameter_tvb, ADAP_INDICATION_OFFSET, ADAP_INDICATION_LENGTH, indication);
917 proto_item_set_text(parameter_item, "Adaptation layer indication");
921 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
923 guint16 type, length, parameter_value_length;
925 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
926 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
928 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
930 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
931 "Parameter value (%u byte%s)",
932 parameter_value_length, plurality(parameter_value_length, "", "s"));
934 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
935 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
939 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *chunk_tree)
941 guint16 type, length, padding_length, total_length;
942 proto_item *parameter_item;
943 proto_tree *parameter_tree;
945 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
946 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
947 padding_length = nr_of_padding_bytes(length);
948 total_length = length + padding_length;
950 parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb,
951 PARAMETER_HEADER_OFFSET, total_length, "%s parameter",
952 val_to_str(type, sctp_parameter_identifier_values, "Unknown"));
953 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
955 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_type,
956 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
958 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
959 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
963 case HEARTBEAT_INFO_PARAMETER_ID:
964 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
966 case IPV4ADDRESS_PARAMETER_ID:
967 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
969 case IPV6ADDRESS_PARAMETER_ID:
970 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
972 case STATE_COOKIE_PARAMETER_ID:
973 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
975 case UNREC_PARA_PARAMETER_ID:
976 dissect_unrecognized_parameters_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
978 case COOKIE_PRESERVATIVE_PARAMETER_ID:
979 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
981 case HOSTNAME_ADDRESS_PARAMETER_ID:
982 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
984 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
985 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
987 case ECN_PARAMETER_ID:
988 dissect_ecn_parameter(parameter_item);
990 case FORWARD_TSN_SUPPORTED_PARAMETER_ID:
991 dissect_forward_tsn_supported_parameter(parameter_item);
993 case ADD_IP_ADDRESS_PARAMETER_ID:
994 dissect_add_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
996 case DEL_IP_ADDRESS_PARAMETER_ID:
997 dissect_del_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
999 case ERROR_CAUSE_INDICATION_PARAMETER_ID:
1000 dissect_error_cause_indication_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1002 case SET_PRIMARY_ADDRESS_PARAMETER_ID:
1003 dissect_set_primary_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1005 case SUCCESS_REPORT_PARAMETER_ID:
1006 dissect_success_report_parameter(parameter_tvb, parameter_tree, parameter_item);
1008 case ADAP_LAYER_INDICATION_PARAMETER_ID:
1009 dissect_adap_indication_parameter(parameter_tvb, parameter_tree, parameter_item);
1012 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1015 if ((padding_length > 0) && (type != UNREC_PARA_PARAMETER_ID))
1016 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
1017 "Padding: %u byte%s",
1018 padding_length, plurality(padding_length, "", "s"));
1022 * Code to handle error causes for ABORT and ERROR chunks
1025 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1027 guint16 stream_identifier;
1029 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
1030 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
1031 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
1033 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
1034 "Reserved (2 bytes)");
1036 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
1041 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1043 guint32 number_of_missing_parameters, missing_parameter_number;
1044 guint16 parameter_type;
1047 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
1048 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
1049 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
1050 number_of_missing_parameters);
1051 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
1052 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
1053 parameter_type = tvb_get_ntohs(cause_tvb, offset);
1054 proto_tree_add_uint(cause_tree, hf_sctp_cause_missing_parameter_type,
1055 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
1057 offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
1060 proto_item_set_text(cause_item, "Error cause reporting %u missing mandatory parameter%s",
1061 number_of_missing_parameters, plurality(number_of_missing_parameters, "", "s") );
1065 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1067 guint32 measure_of_staleness;
1069 measure_of_staleness = tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
1071 proto_tree_add_uint(cause_tree, hf_sctp_cause_measure_of_staleness, cause_tvb,
1072 CAUSE_MEASURE_OF_STALENESS_OFFSET,
1073 CAUSE_MEASURE_OF_STALENESS_LENGTH,
1074 measure_of_staleness);
1076 proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
1077 measure_of_staleness);
1081 dissect_out_of_resource_cause(proto_item *cause_item)
1083 proto_item_set_text(cause_item, "Error cause reporting lack of resources");
1087 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1089 guint16 code, length, parameter_length, parameter_type;
1090 tvbuff_t *parameter_tvb;
1092 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1093 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1095 parameter_length = length - CAUSE_HEADER_LENGTH;
1096 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
1097 parameter_length, parameter_length);
1099 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1100 parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
1102 proto_item_set_text(cause_item, "Error cause reporting unresolvable address of type 0x%04x (%s)",
1103 parameter_type, val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown") );
1107 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo,
1108 proto_tree *cause_tree, proto_item *cause_item)
1110 guint16 length, chunk_length;
1111 guint8 unrecognized_type;
1112 tvbuff_t *unrecognized_chunk_tvb;
1114 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1116 chunk_length = length - CAUSE_HEADER_LENGTH;
1118 unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, chunk_length, chunk_length);
1119 dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree);
1121 unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
1123 proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
1125 val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
1129 dissect_invalid_mandatory_parameter_cause(proto_item *cause_item)
1131 proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
1135 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1137 guint16 length, padding_length, cause_info_length;
1138 tvbuff_t *unrecognized_parameters_tvb;
1140 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1141 padding_length = nr_of_padding_bytes(length);
1142 cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
1144 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1145 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, cause_tree);
1147 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
1151 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1155 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
1156 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
1161 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
1166 dissect_cookie_received_while_shutting_down_cause(proto_item *cause_item)
1168 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
1172 dissect_restart_with_new_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree* cause_tree, proto_item *cause_item)
1174 guint16 length, padding_length, cause_info_length;
1175 tvbuff_t *unrecognized_parameters_tvb;
1177 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1178 padding_length = nr_of_padding_bytes(length);
1179 cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
1181 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1182 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, cause_tree);
1184 proto_item_set_text(cause_item, "Error cause reporting new addresses during restart");
1188 dissect_user_initiated_abort_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1190 guint16 code, length, cause_info_length;
1192 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1193 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1195 cause_info_length = length - CAUSE_HEADER_LENGTH;
1197 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
1198 "Upper layer abort reason (%u byte%s)",
1199 cause_info_length, plurality(cause_info_length, "", "s"));
1201 proto_item_set_text(cause_item, "User initiated abort (%u byte%s information)",
1202 cause_info_length, plurality(cause_info_length, "", "s"));
1206 dissect_protocol_violation_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1208 guint16 code, length, cause_info_length;
1210 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1211 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1213 cause_info_length = length - CAUSE_HEADER_LENGTH;
1215 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
1216 "Additional information (%u byte%s)",
1217 cause_info_length, plurality(cause_info_length, "", "s"));
1219 proto_item_set_text(cause_item, "Protocol violation (%u byte%s information)",
1220 cause_info_length, plurality(cause_info_length, "", "s"));
1224 dissect_delete_last_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1226 guint16 length, cause_info_length;
1227 tvbuff_t *parameter_tvb;
1229 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1230 cause_info_length = length - CAUSE_HEADER_LENGTH;
1231 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1232 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1233 proto_item_set_text(cause_item, "Delete last address cause");
1237 dissect_resource_outage_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1239 guint16 length, cause_info_length;
1240 tvbuff_t *parameter_tvb;
1242 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1243 cause_info_length = length - CAUSE_HEADER_LENGTH;
1244 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1245 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1246 proto_item_set_text(cause_item, "Operation refused due to resource shortage");
1250 dissect_delete_source_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1252 guint16 length, cause_info_length;
1253 tvbuff_t *parameter_tvb;
1255 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1256 cause_info_length = length - CAUSE_HEADER_LENGTH;
1257 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1258 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1259 proto_item_set_text(cause_item, "Delete source address cause");
1263 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1265 guint16 code, length, cause_info_length;
1267 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1268 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1270 cause_info_length = length - CAUSE_HEADER_LENGTH;
1272 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
1273 "Cause specific information (%u byte%s)",
1274 cause_info_length, plurality(cause_info_length, "", "s"));
1276 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
1277 code, cause_info_length, plurality(cause_info_length, "", "s"));
1281 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
1283 guint16 code, length, padding_length, total_length;
1284 proto_item *cause_item;
1285 proto_tree *cause_tree;
1287 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1288 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1289 padding_length = nr_of_padding_bytes(length);
1290 total_length = length + padding_length;
1292 cause_item = proto_tree_add_text(chunk_tree, cause_tvb,
1293 CAUSE_HEADER_OFFSET, total_length,
1295 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
1297 proto_tree_add_uint(cause_tree, hf_sctp_cause_code,
1298 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
1300 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
1301 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
1305 case INVALID_STREAM_IDENTIFIER:
1306 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
1308 case MISSING_MANDATORY_PARAMETERS:
1309 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
1311 case STALE_COOKIE_ERROR:
1312 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
1314 case OUT_OF_RESOURCE:
1315 dissect_out_of_resource_cause(cause_item);
1317 case UNRESOLVABLE_ADDRESS:
1318 dissect_unresolvable_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1320 case UNRECOGNIZED_CHUNK_TYPE:
1321 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
1323 case INVALID_MANDATORY_PARAMETER:
1324 dissect_invalid_mandatory_parameter_cause(cause_item);
1326 case UNRECOGNIZED_PARAMETERS:
1327 dissect_unrecognized_parameters_cause(cause_tvb, pinfo, cause_tree, cause_item);
1330 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
1332 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
1333 dissect_cookie_received_while_shutting_down_cause(cause_item);
1335 case RESTART_WITH_NEW_ADDRESSES:
1336 dissect_restart_with_new_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1338 case USER_INITIATED_ABORT:
1339 dissect_user_initiated_abort_cause(cause_tvb, cause_tree, cause_item);
1341 case PROTOCOL_VIOLATION:
1342 dissect_protocol_violation_cause(cause_tvb, cause_tree, cause_item);
1344 case REQUEST_TO_DELETE_LAST_ADDRESS:
1345 dissect_delete_last_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1347 case OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE:
1348 dissect_resource_outage_cause(cause_tvb, pinfo, cause_tree, cause_item);
1350 case REQUEST_TO_DELETE_SOURCE_ADDRESS:
1351 dissect_delete_source_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1354 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
1357 if ((padding_length > 0) && (code != UNRECOGNIZED_PARAMETERS))
1358 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
1359 "Padding: %u byte%s",
1360 padding_length, plurality(padding_length, "", "s"));
1364 * Code to actually dissect the packets
1368 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree, guint32 ppi)
1370 guint32 low_port, high_port;
1372 /* Do lookups with the subdissector table.
1374 When trying port numbers, we try the port number with the lower value
1375 first, followed by the port number with the higher value. This means
1376 that, for packets where a dissector is registered for *both* port
1377 numbers, and where there's no match on the PPI:
1379 1) we pick the same dissector for traffic going in both directions;
1381 2) we prefer the port number that's more likely to be the right
1382 one (as that prefers well-known ports to reserved ports);
1384 although there is, of course, no guarantee that any such strategy
1385 will always pick the right port number.
1387 XXX - we ignore port numbers of 0, as some dissectors use a port
1388 number of 0 to disable the port. */
1389 if (dissector_try_port(sctp_ppi_dissector_table, ppi, payload_tvb, pinfo, tree))
1391 if (pinfo->srcport > pinfo->destport) {
1392 low_port = pinfo->destport;
1393 high_port = pinfo->srcport;
1395 low_port = pinfo->srcport;
1396 high_port = pinfo->destport;
1398 if (low_port != 0 &&
1399 dissector_try_port(sctp_port_dissector_table, low_port, payload_tvb, pinfo, tree))
1401 if (high_port != 0 &&
1402 dissector_try_port(sctp_port_dissector_table, high_port, payload_tvb, pinfo, tree))
1405 if (check_col(pinfo->cinfo, COL_INFO))
1406 col_append_str(pinfo->cinfo, COL_INFO, "DATA ");
1407 call_dissector(data_handle, payload_tvb, pinfo, tree);
1412 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1413 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1416 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
1417 guint32 tsn, payload_proto_id;
1418 proto_tree *flag_tree;
1419 tvbuff_t *payload_tvb;
1421 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1422 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1423 padding_length = nr_of_padding_bytes(length);
1424 total_payload_length = payload_length + padding_length;
1425 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1426 payload_length, payload_length);
1427 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1430 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1432 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1433 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
1434 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1435 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1436 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1437 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1438 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1440 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1441 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1442 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1444 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1446 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1448 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1450 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1452 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1454 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1456 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1457 chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1459 if (padding_length > 0)
1460 proto_tree_add_text(chunk_tree, chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET + payload_length, padding_length,
1461 "Padding: %u byte%s",
1462 padding_length, plurality(padding_length, "", "s"));
1464 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1465 tsn, stream_id, stream_seq_number,
1466 payload_length, plurality(payload_length, "", "s"));
1467 proto_item_set_len(chunk_item, DATA_CHUNK_HEADER_LENGTH);
1470 return dissect_payload(payload_tvb, pinfo, tree, payload_proto_id);
1474 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1475 proto_tree *chunk_tree, proto_item *chunk_item)
1477 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1478 guint16 number_of_inbound_streams, number_of_outbound_streams;
1480 tvbuff_t *parameter_list_tvb;
1482 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1484 if (check_col(pinfo->cinfo, COL_INFO)) {
1485 if (type == SCTP_INIT_CHUNK_ID) {
1486 col_append_str(pinfo->cinfo, COL_INFO, "INIT ");
1488 col_append_str(pinfo->cinfo, COL_INFO, "INIT_ACK ");
1493 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1494 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1495 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1496 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1497 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1499 /* handle fixed parameters */
1500 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1502 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1504 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1506 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1507 adv_rec_window_credit);
1508 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1510 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1511 number_of_outbound_streams);
1512 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1514 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1515 number_of_inbound_streams);
1516 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1518 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1521 /* handle variable paramters */
1522 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1523 dissect_tlv_parameter_list(parameter_list_tvb, pinfo, chunk_tree);
1525 proto_item_set_text(chunk_item,
1526 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1527 val_to_str(type, sctp_chunk_type_values, "unknown"),
1528 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1529 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1534 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1535 proto_tree *chunk_tree, proto_item *chunk_item)
1537 dissect_init_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1541 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1542 proto_tree *chunk_tree, proto_item *chunk_item)
1544 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1545 guint16 number_of_gap_blocks, number_of_dup_tsns;
1546 guint16 gap_block_number, dup_tsn_number, start, end;
1547 gint gap_block_offset, dup_tsn_offset;
1548 proto_item *block_item;
1549 proto_tree *block_tree;
1551 if (check_col(pinfo->cinfo, COL_INFO))
1552 col_append_str(pinfo->cinfo, COL_INFO, "SACK ");
1555 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1556 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1557 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1558 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1560 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1562 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1563 cumulative_tsn_ack);
1564 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1566 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1567 adv_rec_window_credit);
1568 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1570 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1571 number_of_gap_blocks);
1572 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1574 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1575 number_of_dup_tsns);
1577 /* handle the gap acknowledgement blocks */
1578 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1579 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1580 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1581 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1582 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1583 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1584 "Gap Acknowledgement for %u TSN%s",
1585 1 + end - start, plurality(1 + end - start, "", "s"));
1586 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1587 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1589 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1591 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1593 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1594 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1596 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1599 /* handle the duplicate TSNs */
1600 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1601 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1602 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1603 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1605 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1607 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1610 proto_item_set_text(chunk_item,
1611 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1613 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1614 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1619 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1620 proto_tree *chunk_tree, proto_item *chunk_item)
1622 tvbuff_t *parameter_tvb;
1623 guint chunk_length, info_length, padding_length, total_length;
1625 if (check_col(pinfo->cinfo, COL_INFO))
1626 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT ");
1629 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1630 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1631 padding_length = nr_of_padding_bytes(info_length);
1632 total_length = info_length + padding_length;
1633 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1635 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1637 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1642 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1643 proto_tree *chunk_tree, proto_item *chunk_item)
1645 tvbuff_t *parameter_tvb;
1646 guint chunk_length, info_length, padding_length, total_length;
1648 if (check_col(pinfo->cinfo, COL_INFO))
1649 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT_ACK ");
1652 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1653 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1654 padding_length = nr_of_padding_bytes(info_length);
1655 total_length = info_length + padding_length;
1657 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1659 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1661 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1666 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1669 guint offset, number_of_causes;
1670 guint16 length, padding_length, total_length;
1671 tvbuff_t *cause_tvb;
1672 proto_tree *flag_tree;
1673 if (check_col(pinfo->cinfo, COL_INFO))
1674 col_append_str(pinfo->cinfo, COL_INFO, "ABORT ");
1677 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1678 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_abort_chunk_flags);
1679 proto_tree_add_boolean(flag_tree, hf_sctp_abort_chunk_t_bit, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1681 number_of_causes = 0;
1682 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1683 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1684 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1685 padding_length = nr_of_padding_bytes(length);
1686 total_length = length + padding_length;
1687 /* create a tvb for the chunk including the padding bytes */
1688 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1689 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1690 /* get rid of the handled parameter */
1691 offset += total_length;
1695 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s", number_of_causes, plurality(number_of_causes, "", "s"));
1700 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1701 proto_tree *chunk_tree, proto_item *chunk_item)
1703 guint32 cumulative_tsn_ack;
1705 if (check_col(pinfo->cinfo, COL_INFO))
1706 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN ");
1709 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1710 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1712 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1713 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1714 cumulative_tsn_ack);
1716 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1717 cumulative_tsn_ack);
1722 dissect_shutdown_ack_chunk(packet_info *pinfo,
1723 proto_tree *chunk_tree, proto_item *chunk_item)
1725 if (check_col(pinfo->cinfo, COL_INFO))
1726 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_ACK ");
1729 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1734 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1735 proto_tree *chunk_tree, proto_item *chunk_item)
1737 guint offset, number_of_causes;
1738 guint16 length, padding_length, total_length;
1739 tvbuff_t *cause_tvb;
1741 if (check_col(pinfo->cinfo, COL_INFO))
1742 col_append_str(pinfo->cinfo, COL_INFO, "ERROR ");
1745 number_of_causes = 0;
1746 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1748 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1749 padding_length = nr_of_padding_bytes(length);
1750 total_length = length + padding_length;
1751 /* create a tvb for the chunk including the padding bytes */
1752 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1753 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1754 /* get rid of the handled parameter */
1755 offset += total_length;
1757 } while(tvb_reported_length_remaining(chunk_tvb, offset));
1759 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1760 number_of_causes, plurality(number_of_causes, "", "s"));
1765 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1766 proto_tree *chunk_tree, proto_item *chunk_item)
1768 guint length, cookie_length, padding_length;
1770 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1771 padding_length = nr_of_padding_bytes(length);
1772 cookie_length = length - CHUNK_HEADER_LENGTH;
1774 if (check_col(pinfo->cinfo, COL_INFO))
1775 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ECHO ");
1778 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1779 "Cookie (%u byte%s)",
1780 cookie_length, plurality(cookie_length, "", "s"));
1781 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1782 cookie_length, plurality(cookie_length, "", "s"));
1784 if (padding_length > 0)
1785 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1786 "Padding: %u byte%s",
1787 padding_length, plurality(padding_length, "", "s"));
1792 dissect_cookie_ack_chunk(packet_info *pinfo,
1793 proto_tree *chunk_tree, proto_item *chunk_item)
1795 if (check_col(pinfo->cinfo, COL_INFO))
1796 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ACK ");
1799 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1804 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1805 proto_tree *chunk_tree, proto_item *chunk_item)
1809 if (check_col(pinfo->cinfo, COL_INFO))
1810 col_append_str(pinfo->cinfo, COL_INFO, "ECNE ");
1813 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1814 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1816 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1819 proto_item_set_text(chunk_item, "ECNE chunk");
1824 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1825 proto_tree *chunk_tree, proto_item *chunk_item)
1829 if (check_col(pinfo->cinfo, COL_INFO))
1830 col_append_str(pinfo->cinfo, COL_INFO, "CWR ");
1833 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1834 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1836 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1839 proto_item_set_text(chunk_item, "CWR chunk");
1844 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1845 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1849 proto_tree *flag_tree;
1851 if (check_col(pinfo->cinfo, COL_INFO))
1852 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_COMPLETE ");
1855 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1856 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1858 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_shutdown_complete_chunk_flags);
1859 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1860 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1862 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1866 #define FORWARD_TSN_CHUNK_TSN_LENGTH 4
1867 #define FORWARD_TSN_CHUNK_SID_LENGTH 2
1868 #define FORWARD_TSN_CHUNK_SSN_LENGTH 2
1869 #define FORWARD_TSN_CHUNK_TSN_OFFSET CHUNK_VALUE_OFFSET
1870 #define FORWARD_TSN_CHUNK_SID_OFFSET 0
1871 #define FORWARD_TSN_CHUNK_SSN_OFFSET (FORWARD_TSN_CHUNK_SID_OFFSET + FORWARD_TSN_CHUNK_SID_LENGTH)
1874 dissect_forward_tsn_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1878 guint16 number_of_affected_streams, affected_stream, length, sid, ssn;
1880 if (check_col(pinfo->cinfo, COL_INFO))
1881 col_append_str(pinfo->cinfo, COL_INFO, "FORWARD TSN ");
1884 tsn = tvb_get_ntohl(chunk_tvb, FORWARD_TSN_CHUNK_TSN_OFFSET);
1885 proto_tree_add_uint(chunk_tree, hf_sctp_forward_tsn_chunk_tsn, chunk_tvb, FORWARD_TSN_CHUNK_TSN_OFFSET, FORWARD_TSN_CHUNK_TSN_LENGTH, tsn);
1886 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1887 number_of_affected_streams = (length - CHUNK_HEADER_LENGTH - FORWARD_TSN_CHUNK_TSN_LENGTH) /
1888 (FORWARD_TSN_CHUNK_SID_LENGTH + FORWARD_TSN_CHUNK_SSN_LENGTH);
1889 offset = CHUNK_VALUE_OFFSET + FORWARD_TSN_CHUNK_TSN_LENGTH;
1891 for(affected_stream = 0; affected_stream < number_of_affected_streams; affected_stream++) {
1892 sid = tvb_get_ntohs(chunk_tvb, offset + FORWARD_TSN_CHUNK_SID_OFFSET);
1893 ssn = tvb_get_ntohs(chunk_tvb, offset + FORWARD_TSN_CHUNK_SSN_OFFSET);
1894 proto_tree_add_uint(chunk_tree, hf_sctp_forward_tsn_chunk_sid,
1895 chunk_tvb, offset + FORWARD_TSN_CHUNK_SID_OFFSET, FORWARD_TSN_CHUNK_SID_LENGTH, sid);
1896 proto_tree_add_uint(chunk_tree, hf_sctp_forward_tsn_chunk_ssn,
1897 chunk_tvb, offset + FORWARD_TSN_CHUNK_SSN_OFFSET, FORWARD_TSN_CHUNK_SSN_LENGTH, ssn);
1898 offset = offset + (FORWARD_TSN_CHUNK_SID_LENGTH + FORWARD_TSN_CHUNK_SSN_LENGTH);
1900 proto_item_set_text(chunk_item, "FORWARD TSN chunk (new cumulative TSN %u)", tsn);
1904 #define SERIAL_NUMBER_LENGTH 4
1905 #define SERIAL_NUMBER_OFFSET PARAMETER_VALUE_OFFSET
1908 dissect_asconf_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1910 guint32 serial_number;
1911 guint offset, length, padding_length, total_length;
1912 tvbuff_t *parameter_tvb;
1914 if (check_col(pinfo->cinfo, COL_INFO))
1915 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF ");
1918 offset = SERIAL_NUMBER_OFFSET;
1919 serial_number = tvb_get_ntohl(chunk_tvb, offset);
1920 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_serial, chunk_tvb, offset, SERIAL_NUMBER_LENGTH, serial_number);
1921 offset += SERIAL_NUMBER_LENGTH;
1922 proto_item_set_text(chunk_item, "ASCONF chunk");
1924 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1925 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1926 padding_length = nr_of_padding_bytes(length);
1927 total_length = length + padding_length;
1928 /* create a tvb for the chunk including the padding bytes */
1929 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1930 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1931 /* get rid of the handled parameter */
1932 offset += total_length;
1938 dissect_asconf_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1940 guint32 serial_number;
1941 guint offset, length, padding_length, total_length;
1942 tvbuff_t *parameter_tvb;
1944 if (check_col(pinfo->cinfo, COL_INFO))
1945 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF-ACK ");
1948 serial_number = tvb_get_ntohl(chunk_tvb, SERIAL_NUMBER_OFFSET);
1949 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_serial, chunk_tvb, SERIAL_NUMBER_OFFSET, SERIAL_NUMBER_LENGTH, serial_number);
1950 proto_item_set_text(chunk_item, "ASCONF-ACK chunk");
1952 offset = SERIAL_NUMBER_OFFSET + SERIAL_NUMBER_LENGTH;
1953 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1954 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1955 padding_length = nr_of_padding_bytes(length);
1956 total_length = length + padding_length;
1957 /* create a tvb for the chunk including the padding bytes */
1958 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1959 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1960 /* get rid of the handled parameter */
1961 offset += total_length;
1967 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1968 proto_tree *chunk_tree, proto_item *chunk_item)
1970 guint length, chunk_value_length, padding_length;
1973 if (check_col(pinfo->cinfo, COL_INFO))
1974 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN ");
1977 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1978 padding_length = nr_of_padding_bytes(length);
1979 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1981 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1983 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1984 "Chunk value (%u byte%s)",
1985 chunk_value_length, plurality(chunk_value_length, "", "s"));
1987 if (padding_length > 0)
1988 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1989 "Padding: %u byte%s",
1990 padding_length, plurality(padding_length, "", "s"));
1992 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1993 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1999 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
2004 proto_item *flags_item;
2005 proto_item *chunk_item;
2006 proto_tree *chunk_tree;
2010 /* first extract the chunk header */
2011 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
2012 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
2013 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
2016 /* create proto_tree stuff */
2017 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb, CHUNK_HEADER_OFFSET, -1, "Incomplete chunk");
2018 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
2020 /* then insert the chunk header components into the protocol tree */
2021 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_type, chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH, type);
2022 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
2023 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length, chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH, length);
2030 /* now dissect the chunk value */
2033 case SCTP_DATA_CHUNK_ID:
2034 result = dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2036 case SCTP_INIT_CHUNK_ID:
2037 dissect_init_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2039 case SCTP_INIT_ACK_CHUNK_ID:
2040 dissect_init_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2042 case SCTP_SACK_CHUNK_ID:
2043 dissect_sack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2045 case SCTP_HEARTBEAT_CHUNK_ID:
2046 dissect_heartbeat_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2048 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
2049 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2051 case SCTP_ABORT_CHUNK_ID:
2052 dissect_abort_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item, flags_item);
2054 case SCTP_SHUTDOWN_CHUNK_ID:
2055 dissect_shutdown_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2057 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
2058 dissect_shutdown_ack_chunk(pinfo, chunk_tree, chunk_item);
2060 case SCTP_ERROR_CHUNK_ID:
2061 dissect_error_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2063 case SCTP_COOKIE_ECHO_CHUNK_ID:
2064 dissect_cookie_echo_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2066 case SCTP_COOKIE_ACK_CHUNK_ID:
2067 dissect_cookie_ack_chunk(pinfo, chunk_tree, chunk_item);
2069 case SCTP_ECNE_CHUNK_ID:
2070 dissect_ecne_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2072 case SCTP_CWR_CHUNK_ID:
2073 dissect_cwr_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2075 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
2076 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item, flags_item);
2078 case SCTP_FORWARD_TSN_CHUNK_ID:
2079 dissect_forward_tsn_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2081 case SCTP_ASCONF_ACK_CHUNK_ID:
2082 dissect_asconf_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2084 case SCTP_ASCONF_CHUNK_ID:
2085 dissect_asconf_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2088 dissect_unknown_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2095 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *sctp_item, proto_tree *sctp_tree)
2097 tvbuff_t *chunk_tvb;
2098 guint16 length, padding_length, total_length;
2099 gint last_offset, offset;
2100 gboolean sctp_item_length_set;
2102 /* the common header of the datagram is already handled */
2104 offset = COMMON_HEADER_LENGTH;
2105 sctp_item_length_set = FALSE;
2107 while(tvb_reported_length_remaining(tvb, offset) > 0) {
2108 /* extract the chunk length and compute number of padding bytes */
2109 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
2110 padding_length = nr_of_padding_bytes(length);
2111 total_length = length + padding_length;
2112 /* create a tvb for the chunk including the padding bytes */
2113 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
2114 /* call dissect_sctp_chunk for a actual work */
2115 if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree) && (tree)) {
2116 proto_item_set_len(sctp_item, offset - last_offset + DATA_CHUNK_HEADER_LENGTH);
2117 sctp_item_length_set = TRUE;
2118 offset += total_length;
2119 last_offset = offset;
2120 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2121 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, offset, -1, FALSE);
2122 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2123 sctp_item_length_set = FALSE;
2126 /* get rid of the dissected chunk */
2127 offset += total_length;
2130 if (!sctp_item_length_set && (tree)) {
2131 proto_item_set_len(sctp_item, offset - last_offset);
2135 /* dissect_sctp handles the common header of a SCTP datagram.
2136 * For the handling of the chunks dissect_sctp_chunks is called.
2140 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2142 guint16 source_port, destination_port;
2143 guint32 verification_tag, checksum, calculated_crc32c, calculated_adler32;
2145 gboolean crc32c_correct, adler32_correct;
2146 proto_item *sctp_item;
2147 proto_tree *sctp_tree;
2149 /* Extract the common header */
2150 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
2151 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
2152 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
2153 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
2155 /* update pi structure */
2156 pinfo->ptype = PT_SCTP;
2157 pinfo->srcport = source_port;
2158 pinfo->destport = destination_port;
2160 /* make entry in the Protocol column on summary display */
2161 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2162 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCTP");
2164 /* Clear entries in Info column on summary display */
2165 if (check_col(pinfo->cinfo, COL_INFO))
2166 col_add_str(pinfo->cinfo, COL_INFO, "");
2168 /* In the interest of speed, if "tree" is NULL, don't do any work not
2169 necessary to generate protocol tree items. */
2171 /* create the sctp protocol tree */
2172 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, 0, -1, FALSE);
2173 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2175 /* add the components of the common header to the protocol tree */
2176 proto_tree_add_uint(sctp_tree, hf_sctp_source_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2177 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2178 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag, tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH, verification_tag);
2179 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2180 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2182 length = tvb_length(tvb);
2183 switch(sctp_checksum) {
2184 case SCTP_CHECKSUM_NONE:
2185 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum, "Checksum: 0x%08x (not verified)", checksum);
2187 case SCTP_CHECKSUM_ADLER32:
2188 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2189 adler32_correct = (checksum == calculated_adler32);
2190 if (adler32_correct)
2191 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2192 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2194 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2195 checksum, "Checksum: 0x%08x (incorrect Adler32, should be 0x%08x)", checksum, calculated_adler32);
2196 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(adler32_correct));
2198 case SCTP_CHECKSUM_CRC32C:
2199 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2200 crc32c_correct = (checksum == calculated_crc32c);
2202 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2203 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2205 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2206 checksum, "Checksum: 0x%08x (incorrect CRC32C, should be 0x%08x)", checksum, calculated_crc32c);
2207 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct));
2209 case SCTP_CHECKSUM_AUTOMATIC:
2210 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2211 adler32_correct = (checksum == calculated_adler32);
2212 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2213 crc32c_correct = (checksum == calculated_crc32c);
2214 if ((adler32_correct) && !(crc32c_correct))
2215 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2216 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2217 else if (!(adler32_correct) && (crc32c_correct))
2218 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2219 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2220 else if ((adler32_correct) && (crc32c_correct))
2221 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2222 checksum, "Checksum: 0x%08x (correct Adler32 and CRC32C)", checksum);
2224 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2225 checksum, "Checksum: 0x%08x (incorrect, should be 0x%08x (Adler32) or 0x%08x (CRC32C))",
2226 checksum, calculated_adler32, calculated_crc32c);
2227 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct || adler32_correct));
2234 /* add all chunks of the sctp datagram to the protocol tree */
2235 dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree);
2238 /* Register the protocol with Ethereal */
2240 proto_register_sctp(void)
2243 /* Setup list of header fields */
2244 static hf_register_info hf[] = {
2245 { &hf_sctp_source_port,
2246 { "Source port", "sctp.srcport",
2247 FT_UINT16, BASE_DEC, NULL, 0x0,
2250 { &hf_sctp_destination_port,
2251 { "Destination port", "sctp.dstport",
2252 FT_UINT16, BASE_DEC, NULL, 0x0,
2256 { "Port", "sctp.port",
2257 FT_UINT16, BASE_DEC, NULL, 0x0,
2260 { &hf_sctp_verification_tag,
2261 { "Verification tag", "sctp.verfication_tag",
2262 FT_UINT32, BASE_HEX, NULL, 0x0,
2265 { &hf_sctp_checksum,
2266 { "Checksum", "sctp.checksum",
2267 FT_UINT32, BASE_HEX, NULL, 0x0,
2270 { &hf_sctp_checksum_bad,
2271 { "Bad checksum", "sctp.checksum_bad",
2272 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2275 { &hf_sctp_chunk_type,
2276 { "Identifier", "sctp.chunk_type",
2277 FT_UINT8, BASE_DEC, VALS(sctp_chunk_type_values), 0x0,
2280 { &hf_sctp_chunk_flags,
2281 { "Flags", "sctp.chunk_flags",
2282 FT_UINT8, BASE_HEX, NULL, 0x0,
2285 { &hf_sctp_chunk_length,
2286 { "Length", "sctp.chunk_length",
2287 FT_UINT16, BASE_DEC, NULL, 0x0,
2290 { &hf_sctp_init_chunk_initiate_tag,
2291 { "Initiate tag", "sctp.init.chunk.initiate.tag",
2292 FT_UINT32, BASE_HEX, NULL, 0x0,
2295 { &hf_sctp_init_chunk_adv_rec_window_credit,
2296 { "Advertised receiver window credit (a_rwnd)", "sctp.init.chunk.credit",
2297 FT_UINT32, BASE_DEC, NULL, 0x0,
2300 { &hf_sctp_init_chunk_number_of_outbound_streams,
2301 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
2302 FT_UINT16, BASE_DEC, NULL, 0x0,
2305 { &hf_sctp_init_chunk_number_of_inbound_streams,
2306 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
2307 FT_UINT16, BASE_DEC, NULL, 0x0,
2310 {&hf_sctp_init_chunk_initial_tsn,
2311 { "Initial TSN", "sctp.init.chunk.initial.tsn",
2312 FT_UINT32, BASE_DEC, NULL, 0x0,
2315 {&hf_sctp_cumulative_tsn_ack,
2316 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
2317 FT_UINT32, BASE_DEC, NULL, 0x0,
2320 {&hf_sctp_data_chunk_tsn,
2321 { "TSN", "sctp.tsn",
2322 FT_UINT32, BASE_DEC, NULL, 0x0,
2325 {&hf_sctp_data_chunk_stream_id,
2326 { "Stream Identifier", "sctp.stream_id",
2327 FT_UINT16, BASE_HEX, NULL, 0x0,
2330 {&hf_sctp_data_chunk_stream_seq_number,
2331 { "Stream sequence number", "sctp.stream_seq_number",
2332 FT_UINT16, BASE_DEC, NULL, 0x0,
2335 {&hf_sctp_data_chunk_payload_proto_id,
2336 { "Payload protocol identifier", "sctp.payload_proto_id",
2337 FT_UINT32, BASE_DEC, VALS(sctp_payload_proto_id_values), 0x0,
2340 {&hf_sctp_data_chunk_e_bit,
2341 { "E-Bit", "sctp.data.e_bit",
2342 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
2345 {&hf_sctp_data_chunk_b_bit,
2346 { "B-Bit", "sctp.data.b_bit",
2347 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
2350 {&hf_sctp_data_chunk_u_bit,
2351 { "U-Bit", "sctp.data.u.bit",
2352 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
2355 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
2356 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
2357 FT_UINT32, BASE_DEC, NULL, 0x0,
2360 {&hf_sctp_sack_chunk_adv_rec_window_credit,
2361 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
2362 FT_UINT32, BASE_DEC, NULL, 0x0,
2365 {&hf_sctp_sack_chunk_number_of_gap_blocks,
2366 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
2367 FT_UINT16, BASE_DEC, NULL, 0x0,
2370 {&hf_sctp_sack_chunk_number_of_dup_tsns,
2371 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
2372 FT_UINT16, BASE_DEC, NULL, 0x0,
2375 {&hf_sctp_sack_chunk_gap_block_start,
2376 { "Start", "sctp.sack.gap_block_start",
2377 FT_UINT16, BASE_DEC, NULL, 0x0,
2380 {&hf_sctp_sack_chunk_gap_block_end,
2381 { "End", "sctp.sack.gap_block_end",
2382 FT_UINT16, BASE_DEC, NULL, 0x0,
2385 {&hf_sctp_sack_chunk_duplicate_tsn,
2386 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
2387 FT_UINT16, BASE_DEC, NULL, 0x0,
2390 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
2391 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
2392 FT_UINT32, BASE_DEC, NULL, 0x0,
2395 {&hf_sctp_ecne_chunk_lowest_tsn,
2396 { "Lowest TSN", "sctp.ecne.lowest_tsn",
2397 FT_UINT32, BASE_DEC, NULL, 0x0,
2400 {&hf_sctp_cwr_chunk_lowest_tsn,
2401 { "Lowest TSN", "sctp.cwr.lowest_tsn",
2402 FT_UINT32, BASE_DEC, NULL, 0x0,
2405 {&hf_sctp_shutdown_complete_chunk_t_bit,
2406 { "T-Bit", "sctp.shutdown_complete.t_bit",
2407 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2410 {&hf_sctp_abort_chunk_t_bit,
2411 { "T-Bit", "sctp.abort.t_bit",
2412 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2415 {&hf_sctp_forward_tsn_chunk_tsn,
2416 { "New cumulative TSN", "sctp.forward_tsn.tsn",
2417 FT_UINT32, BASE_DEC, NULL, 0x0,
2420 {&hf_sctp_forward_tsn_chunk_sid,
2421 { "Stream identifier", "sctp.forward_tsn.sid",
2422 FT_UINT16, BASE_DEC, NULL, 0x0,
2425 {&hf_sctp_forward_tsn_chunk_ssn,
2426 { "Stream sequence number", "sctp.forward_tsn.ssn",
2427 FT_UINT16, BASE_DEC, NULL, 0x0,
2430 {&hf_sctp_chunk_parameter_type,
2431 { "Parameter type", "sctp.parameter.type",
2432 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2435 {&hf_sctp_chunk_parameter_length,
2436 { "Parameter length", "sctp.parameter.length",
2437 FT_UINT16, BASE_DEC, NULL, 0x0,
2440 {&hf_sctp_parameter_ipv4_address,
2441 { "IP Version 4 address", "sctp.parameter.ipv4_address",
2442 FT_IPv4, BASE_NONE, NULL, 0x0,
2445 {&hf_sctp_parameter_ipv6_address,
2446 { "IP Version 6 address", "sctp.parameter.ipv6_address",
2447 FT_IPv6, BASE_NONE, NULL, 0x0,
2450 {&hf_sctp_parameter_cookie_preservative_increment,
2451 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
2452 FT_UINT32, BASE_DEC, NULL, 0x0,
2455 {&hf_sctp_parameter_hostname_hostname,
2456 { "Hostname", "sctp.parameter.hostname.hostname",
2457 FT_STRING, BASE_NONE, NULL, 0x0,
2460 {&hf_sctp_supported_address_types_parameter,
2461 { "Supported address type", "sctp.parameter.supported_addres_type",
2462 FT_UINT16, BASE_DEC, NULL, 0x0,
2465 {&hf_sctp_asconf_serial,
2466 { "Serial Number", "sctp.asconf.serial_number",
2467 FT_UINT32, BASE_HEX, NULL, 0x0,
2470 {&hf_sctp_asconf_ack_serial,
2471 { "Serial Number", "sctp.asconf_ack.serial_number",
2472 FT_UINT32, BASE_HEX, NULL, 0x0,
2475 {&hf_sctp_correlation_id,
2476 { "Correlation_id", "sctp.correlation_id",
2477 FT_UINT32, BASE_HEX, NULL, 0x0,
2480 {&hf_sctp_adap_indication,
2481 { "Indication", "sctp.adapation_layer_indication.indication",
2482 FT_UINT32, BASE_HEX, NULL, 0x0,
2485 {&hf_sctp_cause_code,
2486 { "Cause code", "sctp.cause.code",
2487 FT_UINT16, BASE_HEX, VALS(sctp_cause_code_values), 0x0,
2490 {&hf_sctp_cause_length,
2491 { "Cause length", "sctp.cause.length",
2492 FT_UINT16, BASE_DEC, NULL, 0x0,
2495 {&hf_sctp_cause_stream_identifier,
2496 { "Stream identifier", "sctp.cause.stream_identifier",
2497 FT_UINT16, BASE_DEC, NULL, 0x0,
2500 {&hf_sctp_cause_number_of_missing_parameters,
2501 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
2502 FT_UINT32, BASE_DEC, NULL, 0x0,
2505 {&hf_sctp_cause_missing_parameter_type,
2506 { "Missing parameter type", "sctp.cause.missing_parameter_type",
2507 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2510 {&hf_sctp_cause_measure_of_staleness,
2511 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
2512 FT_UINT32, BASE_DEC, NULL, 0x0,
2515 {&hf_sctp_cause_tsn,
2516 { "TSN", "sctp.cause.tsn",
2517 FT_UINT32, BASE_DEC, NULL, 0x0,
2522 /* Setup protocol subtree array */
2523 static gint *ett[] = {
2526 &ett_sctp_chunk_parameter,
2527 &ett_sctp_chunk_cause,
2528 &ett_sctp_data_chunk_flags,
2529 &ett_sctp_shutdown_complete_chunk_flags,
2530 &ett_sctp_abort_chunk_flags,
2531 &ett_sctp_sack_chunk_gap_block,
2532 &ett_sctp_supported_address_types_parameter,
2533 &ett_sctp_unrecognized_parameter_parameter,
2536 static enum_val_t sctp_checksum_options[] = {
2537 { "None", SCTP_CHECKSUM_NONE },
2538 { "Adler 32", SCTP_CHECKSUM_ADLER32 },
2539 { "CRC 32c", SCTP_CHECKSUM_CRC32C },
2540 { "Automatic", SCTP_CHECKSUM_AUTOMATIC},
2544 /* Register the protocol name and description */
2545 proto_sctp = proto_register_protocol("Stream Control Transmission Protocol", "SCTP", "sctp");
2546 sctp_module = prefs_register_protocol(proto_sctp, NULL);
2547 prefs_register_enum_preference(sctp_module, "checksum",
2549 "The type of checksum used in SCTP packets",
2550 &sctp_checksum, sctp_checksum_options, FALSE);
2552 /* Required function calls to register the header fields and subtrees used */
2553 proto_register_field_array(proto_sctp, hf, array_length(hf));
2554 proto_register_subtree_array(ett, array_length(ett));
2556 /* subdissector code */
2557 sctp_port_dissector_table = register_dissector_table("sctp.port", "SCTP port", FT_UINT16, BASE_DEC);
2558 sctp_ppi_dissector_table = register_dissector_table("sctp.ppi", "SCTP payload protocol identifier", FT_UINT32, BASE_HEX);
2563 proto_reg_handoff_sctp(void)
2565 dissector_handle_t sctp_handle;
2567 data_handle = find_dissector("data");
2568 sctp_handle = create_dissector_handle(dissect_sctp, proto_sctp);
2569 dissector_add("ip.proto", IP_PROTO_SCTP, sctp_handle);