2 * Routines for Stream Control Transmission Protocol dissection
3 * It should be compilant to
4 * - RFC 2960, for basic SCTP support
5 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-addip-sctp-06.txt for the add-IP extension
6 * - http://www.ietf.org/internet-drafts/draft-stewart-tsvwg-prsctp-01.txt for the 'Partial Reliability' extension
7 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpcsum-07.txt
8 * Copyright 2000, 2001, 2002, Michael Tuexen <Michael.Tuexen@icn.siemens.de>
9 * Still to do (so stay tuned)
10 * - support for reassembly
13 * $Id: packet-sctp.c,v 1.40 2002/07/10 21:01:57 guy Exp $
15 * Ethereal - Network traffic analyzer
16 * By Gerald Combs <gerald@ethereal.com>
17 * Copyright 1998 Gerald Combs
19 * Copied from README.developer
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License
23 * as published by the Free Software Foundation; either version 2
24 * of the License, or (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 #include <epan/packet.h>
44 /* Initialize the protocol and registered fields */
45 static int proto_sctp = -1;
46 static int hf_sctp_port = -1;
47 static int hf_sctp_source_port = -1;
48 static int hf_sctp_destination_port = -1;
49 static int hf_sctp_verification_tag = -1;
50 static int hf_sctp_checksum = -1;
51 static int hf_sctp_checksum_bad = -1;
53 static int hf_sctp_chunk_type = -1;
54 static int hf_sctp_chunk_flags = -1;
55 static int hf_sctp_chunk_length = -1;
57 static int hf_sctp_init_chunk_initiate_tag = -1;
58 static int hf_sctp_init_chunk_adv_rec_window_credit = -1;
59 static int hf_sctp_init_chunk_number_of_outbound_streams = -1;
60 static int hf_sctp_init_chunk_number_of_inbound_streams = -1;
61 static int hf_sctp_init_chunk_initial_tsn = -1;
63 static int hf_sctp_cumulative_tsn_ack = -1;
65 static int hf_sctp_data_chunk_tsn = -1;
66 static int hf_sctp_data_chunk_stream_id = -1;
67 static int hf_sctp_data_chunk_stream_seq_number = -1;
68 static int hf_sctp_data_chunk_payload_proto_id = -1;
70 static int hf_sctp_data_chunk_e_bit = -1;
71 static int hf_sctp_data_chunk_b_bit = -1;
72 static int hf_sctp_data_chunk_u_bit = -1;
74 static int hf_sctp_sack_chunk_cumulative_tsn_ack = -1;
75 static int hf_sctp_sack_chunk_adv_rec_window_credit = -1;
76 static int hf_sctp_sack_chunk_number_of_gap_blocks = -1;
77 static int hf_sctp_sack_chunk_number_of_dup_tsns = -1;
78 static int hf_sctp_sack_chunk_gap_block_start = -1;
79 static int hf_sctp_sack_chunk_gap_block_end = -1;
80 static int hf_sctp_sack_chunk_duplicate_tsn = -1;
82 static int hf_sctp_shutdown_chunk_cumulative_tsn_ack = -1;
84 static int hf_sctp_cwr_chunk_lowest_tsn = -1;
86 static int hf_sctp_ecne_chunk_lowest_tsn = -1;
88 static int hf_sctp_shutdown_complete_chunk_t_bit = -1;
90 static int hf_sctp_chunk_parameter_type = -1;
91 static int hf_sctp_chunk_parameter_length = -1;
92 static int hf_sctp_parameter_ipv4_address = -1;
93 static int hf_sctp_parameter_ipv6_address = -1;
94 static int hf_sctp_parameter_cookie_preservative_increment = -1;
95 static int hf_sctp_parameter_hostname_hostname = -1;
96 static int hf_sctp_supported_address_types_parameter = -1;
98 static int hf_sctp_cause_code = -1;
99 static int hf_sctp_cause_length = -1;
100 static int hf_sctp_cause_stream_identifier = -1;
102 static int hf_sctp_cause_number_of_missing_parameters = -1;
103 static int hf_sctp_cause_missing_parameter_type = -1;
105 static int hf_sctp_cause_measure_of_staleness = -1;
107 static int hf_sctp_cause_tsn = -1;
109 static int hf_sctp_forward_tsn_chunk_tsn = -1;
110 static int hf_sctp_forward_tsn_chunk_sid = -1;
111 static int hf_sctp_forward_tsn_chunk_ssn = -1;
113 static int hf_sctp_asconf_ack_serial = -1;
114 static int hf_sctp_asconf_serial = -1;
115 static int hf_sctp_correlation_id = -1;
117 static int hf_sctp_adap_indication = -1;
118 static int hf_sctp_abort_chunk_t_bit = -1;
119 static dissector_table_t sctp_port_dissector_table;
120 static dissector_table_t sctp_ppi_dissector_table;
122 static module_t *sctp_module;
124 /* Initialize the subtree pointers */
125 static gint ett_sctp = -1;
126 static gint ett_sctp_chunk = -1;
127 static gint ett_sctp_chunk_parameter = -1;
128 static gint ett_sctp_chunk_cause = -1;
129 static gint ett_sctp_data_chunk_flags = -1;
130 static gint ett_sctp_shutdown_complete_chunk_flags = -1;
131 static gint ett_sctp_abort_chunk_flags = -1;
132 static gint ett_sctp_sack_chunk_gap_block = -1;
133 static gint ett_sctp_supported_address_types_parameter = -1;
134 static gint ett_sctp_unrecognized_parameter_parameter = -1;
136 static dissector_handle_t data_handle;
138 #define SCTP_DATA_CHUNK_ID 0
139 #define SCTP_INIT_CHUNK_ID 1
140 #define SCTP_INIT_ACK_CHUNK_ID 2
141 #define SCTP_SACK_CHUNK_ID 3
142 #define SCTP_HEARTBEAT_CHUNK_ID 4
143 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
144 #define SCTP_ABORT_CHUNK_ID 6
145 #define SCTP_SHUTDOWN_CHUNK_ID 7
146 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
147 #define SCTP_ERROR_CHUNK_ID 9
148 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
149 #define SCTP_COOKIE_ACK_CHUNK_ID 11
150 #define SCTP_ECNE_CHUNK_ID 12
151 #define SCTP_CWR_CHUNK_ID 13
152 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
153 #define SCTP_FORWARD_TSN_CHUNK_ID 192
154 #define SCTP_ASCONF_ACK_CHUNK_ID 0x80
155 #define SCTP_ASCONF_CHUNK_ID 0XC1
157 #define SCTP_IETF_EXT 255
159 static const value_string sctp_chunk_type_values[] = {
160 { SCTP_DATA_CHUNK_ID, "DATA" },
161 { SCTP_INIT_CHUNK_ID, "INIT" },
162 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
163 { SCTP_SACK_CHUNK_ID, "SACK" },
164 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
165 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
166 { SCTP_ABORT_CHUNK_ID, "ABORT" },
167 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
168 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
169 { SCTP_ERROR_CHUNK_ID, "ERROR" },
170 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
171 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
172 { SCTP_ECNE_CHUNK_ID, "ECNE" },
173 { SCTP_CWR_CHUNK_ID, "CWR" },
174 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
175 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
176 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
177 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
178 { SCTP_IETF_EXT, "IETF_EXTENSION" },
181 #define HEARTBEAT_INFO_PARAMETER_ID 0x0001
182 #define IPV4ADDRESS_PARAMETER_ID 0x0005
183 #define IPV6ADDRESS_PARAMETER_ID 0x0006
184 #define STATE_COOKIE_PARAMETER_ID 0x0007
185 #define UNREC_PARA_PARAMETER_ID 0x0008
186 #define COOKIE_PRESERVATIVE_PARAMETER_ID 0x0009
187 #define HOSTNAME_ADDRESS_PARAMETER_ID 0x000b
188 #define SUPPORTED_ADDRESS_TYPES_PARAMETER_ID 0x000c
189 #define ECN_PARAMETER_ID 0x8000
190 #define FORWARD_TSN_SUPPORTED_PARAMETER_ID 0xC000
191 #define ADD_IP_ADDRESS_PARAMETER_ID 0xC001
192 #define DEL_IP_ADDRESS_PARAMETER_ID 0xC002
193 #define ERROR_CAUSE_INDICATION_PARAMETER_ID 0xC003
194 #define SET_PRIMARY_ADDRESS_PARAMETER_ID 0xC004
195 #define SUCCESS_REPORT_PARAMETER_ID 0xC005
196 #define ADAP_LAYER_INDICATION_PARAMETER_ID 0xC006
198 static const value_string sctp_parameter_identifier_values[] = {
199 { HEARTBEAT_INFO_PARAMETER_ID, "Heartbeat info" },
200 { IPV4ADDRESS_PARAMETER_ID, "IPv4 address" },
201 { IPV6ADDRESS_PARAMETER_ID, "IPv6 address" },
202 { STATE_COOKIE_PARAMETER_ID, "State cookie" },
203 { UNREC_PARA_PARAMETER_ID, "Unrecognized parameters" },
204 { COOKIE_PRESERVATIVE_PARAMETER_ID, "Cookie preservative" },
205 { HOSTNAME_ADDRESS_PARAMETER_ID, "Hostname address" },
206 { SUPPORTED_ADDRESS_TYPES_PARAMETER_ID, "Supported address types" },
207 { ECN_PARAMETER_ID, "ECN" },
208 { FORWARD_TSN_SUPPORTED_PARAMETER_ID, "Forward TSN supported" },
209 { ADD_IP_ADDRESS_PARAMETER_ID, "Add IP address" },
210 { DEL_IP_ADDRESS_PARAMETER_ID, "Delete IP address" },
211 { ERROR_CAUSE_INDICATION_PARAMETER_ID, "Error cause indication" },
212 { SET_PRIMARY_ADDRESS_PARAMETER_ID, "Set primary address" },
213 { SUCCESS_REPORT_PARAMETER_ID, "Success report" },
214 { ADAP_LAYER_INDICATION_PARAMETER_ID, "Adaptation Layer Indication" },
217 #define PARAMETER_TYPE_LENGTH 2
218 #define PARAMETER_LENGTH_LENGTH 2
219 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
221 #define PARAMETER_HEADER_OFFSET 0
222 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
223 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
224 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
226 #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET
227 #define HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
229 #define IPV4_ADDRESS_LENGTH 4
230 #define IPV6_ADDRESS_LENGTH 16
232 #define STATE_COOKIE_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
233 #define STATE_COOKIE_PARAMETER_COOKIE_OFFSET PARAMETER_VALUE_OFFSET
235 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET PARAMETER_VALUE_OFFSET
236 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH 4
237 #define SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH 2
239 #define CAUSE_CODE_LENGTH 2
240 #define CAUSE_LENGTH_LENGTH 2
241 #define CAUSE_HEADER_LENGTH (CAUSE_CODE_LENGTH + CAUSE_LENGTH_LENGTH)
243 #define CAUSE_HEADER_OFFSET 0
244 #define CAUSE_CODE_OFFSET CAUSE_HEADER_OFFSET
245 #define CAUSE_LENGTH_OFFSET (CAUSE_CODE_OFFSET + CAUSE_CODE_LENGTH)
246 #define CAUSE_INFO_OFFSET (CAUSE_LENGTH_OFFSET + CAUSE_LENGTH_LENGTH)
248 #define CAUSE_STREAM_IDENTIFIER_LENGTH 2
249 #define CAUSE_RESERVED_LENGTH 2
250 #define CAUSE_STREAM_IDENTIFIER_OFFSET CAUSE_INFO_OFFSET
251 #define CAUSE_RESERVED_OFFSET (CAUSE_STREAM_IDENTIFIER_OFFSET + CAUSE_STREAM_IDENTIFIER_LENGTH)
253 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH 4
254 #define CAUSE_MISSING_PARAMETER_TYPE_LENGTH 2
256 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET CAUSE_INFO_OFFSET
257 #define CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET (CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET + \
258 CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH )
260 #define CAUSE_MEASURE_OF_STALENESS_LENGTH 4
261 #define CAUSE_MEASURE_OF_STALENESS_OFFSET CAUSE_INFO_OFFSET
263 #define CAUSE_TSN_LENGTH 4
264 #define CAUSE_TSN_OFFSET CAUSE_INFO_OFFSET
266 #define INVALID_STREAM_IDENTIFIER 0x01
267 #define MISSING_MANDATORY_PARAMETERS 0x02
268 #define STALE_COOKIE_ERROR 0x03
269 #define OUT_OF_RESOURCE 0x04
270 #define UNRESOLVABLE_ADDRESS 0x05
271 #define UNRECOGNIZED_CHUNK_TYPE 0x06
272 #define INVALID_MANDATORY_PARAMETER 0x07
273 #define UNRECOGNIZED_PARAMETERS 0x08
274 #define NO_USER_DATA 0x09
275 #define COOKIE_RECEIVED_WHILE_SHUTTING_DOWN 0x0a
276 #define RESTART_WITH_NEW_ADDRESSES 0x0b
277 #define REQUEST_TO_DELETE_LAST_ADDRESS 0x0100
278 #define OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE 0X0101
279 #define REQUEST_TO_DELETE_SOURCE_ADDRESS 0x0102
280 #define ABORT_DUE_TO_ILLEGAL_ASCONF 0x0103
282 static const value_string sctp_cause_code_values[] = {
283 { INVALID_STREAM_IDENTIFIER, "Invalid stream identifier" },
284 { MISSING_MANDATORY_PARAMETERS, "Missing mandator parameter" },
285 { STALE_COOKIE_ERROR, "Stale cookie error" },
286 { OUT_OF_RESOURCE, "Out of resource" },
287 { UNRESOLVABLE_ADDRESS, "Unresolvable address" },
288 { UNRECOGNIZED_CHUNK_TYPE, "Unrecognized chunk type " },
289 { INVALID_MANDATORY_PARAMETER, "Invalid mandatory parameter" },
290 { UNRECOGNIZED_PARAMETERS, "Unrecognized parameters" },
291 { NO_USER_DATA, "No user data" },
292 { COOKIE_RECEIVED_WHILE_SHUTTING_DOWN, "Cookie received while shutting down" },
293 { RESTART_WITH_NEW_ADDRESSES, "Restart of an association with new addresses" },
294 { REQUEST_TO_DELETE_LAST_ADDRESS, "Request to delete last address" },
295 { OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE, "Operation refused due to resource shortage" },
296 { REQUEST_TO_DELETE_SOURCE_ADDRESS, "Request to delete source address" },
297 { ABORT_DUE_TO_ILLEGAL_ASCONF, "Association Aborted due to illegal ASCONF-ACK" },
300 #define NOT_SPECIFIED_PROTOCOL_ID 0
301 #define IUA_PAYLOAD_PROTOCOL_ID 1
302 #define M2UA_PAYLOAD_PROTOCOL_ID 2
303 #define M3UA_PAYLOAD_PROTOCOL_ID 3
304 #define SUA_PAYLOAD_PROTOCOL_ID 4
305 #define M2PA_PAYLOAD_PROTOCOL_ID 5
306 #define V5UA_PAYLOAD_PROTOCOL_ID 6
308 static const value_string sctp_payload_proto_id_values[] = {
309 { NOT_SPECIFIED_PROTOCOL_ID, "not specified" },
310 { IUA_PAYLOAD_PROTOCOL_ID, "IUA" },
311 { M2UA_PAYLOAD_PROTOCOL_ID, "M2UA" },
312 { M3UA_PAYLOAD_PROTOCOL_ID, "M3UA" },
313 { SUA_PAYLOAD_PROTOCOL_ID, "SUA" },
314 { M2PA_PAYLOAD_PROTOCOL_ID, "M2PA" },
315 { V5UA_PAYLOAD_PROTOCOL_ID, "V5UA" },
318 /* The structure of the common header is described by the following constants */
319 #define SOURCE_PORT_LENGTH 2
320 #define DESTINATION_PORT_LENGTH 2
321 #define VERIFICATION_TAG_LENGTH 4
322 #define CHECKSUM_LENGTH 4
323 #define COMMON_HEADER_LENGTH (SOURCE_PORT_LENGTH + \
324 DESTINATION_PORT_LENGTH + \
325 VERIFICATION_TAG_LENGTH + \
327 #define SOURCE_PORT_OFFSET 0
328 #define DESTINATION_PORT_OFFSET (SOURCE_PORT_OFFSET + SOURCE_PORT_LENGTH)
329 #define VERIFICATION_TAG_OFFSET (DESTINATION_PORT_OFFSET + DESTINATION_PORT_LENGTH)
330 #define CHECKSUM_OFFSET (VERIFICATION_TAG_OFFSET + VERIFICATION_TAG_LENGTH)
332 /* The structure of the chunk header is described by the following constants */
333 #define CHUNK_TYPE_LENGTH 1
334 #define CHUNK_FLAGS_LENGTH 1
335 #define CHUNK_LENGTH_LENGTH 2
336 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
337 CHUNK_FLAGS_LENGTH + \
339 #define CHUNK_HEADER_OFFSET 0
340 #define CHUNK_TYPE_OFFSET CHUNK_HEADER_OFFSET
341 #define CHUNK_FLAGS_OFFSET (CHUNK_TYPE_OFFSET + CHUNK_TYPE_LENGTH)
342 #define CHUNK_LENGTH_OFFSET (CHUNK_FLAGS_OFFSET + CHUNK_FLAGS_LENGTH)
343 #define CHUNK_VALUE_OFFSET (CHUNK_LENGTH_OFFSET + CHUNK_LENGTH_LENGTH)
345 /* The following constants describe the structure of DATA chunks */
346 #define DATA_CHUNK_TSN_LENGTH 4
347 #define DATA_CHUNK_STREAM_ID_LENGTH 2
348 #define DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH 2
349 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
351 #define DATA_CHUNK_TSN_OFFSET (CHUNK_VALUE_OFFSET + 0)
352 #define DATA_CHUNK_STREAM_ID_OFFSET (DATA_CHUNK_TSN_OFFSET + DATA_CHUNK_TSN_LENGTH)
353 #define DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET (DATA_CHUNK_STREAM_ID_OFFSET + \
354 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
355 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET (DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET + \
356 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
357 #define DATA_CHUNK_PAYLOAD_OFFSET (DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET + \
358 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
360 #define DATA_CHUNK_HEADER_LENGTH (CHUNK_HEADER_LENGTH + \
361 DATA_CHUNK_TSN_LENGTH + \
362 DATA_CHUNK_STREAM_ID_LENGTH + \
363 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH + \
364 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
366 #define SCTP_DATA_CHUNK_E_BIT 0x01
367 #define SCTP_DATA_CHUNK_B_BIT 0x02
368 #define SCTP_DATA_CHUNK_U_BIT 0x04
370 #define INIT_CHUNK_INITIATE_TAG_LENGTH 4
371 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
372 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH 2
373 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH 2
374 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
376 #define INIT_CHUNK_INITIATE_TAG_OFFSET CHUNK_VALUE_OFFSET
377 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (INIT_CHUNK_INITIATE_TAG_OFFSET + \
378 INIT_CHUNK_INITIATE_TAG_LENGTH )
379 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET (INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
380 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH )
381 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET (INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET + \
382 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH )
383 #define INIT_CHUNK_INITIAL_TSN_OFFSET (INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET + \
384 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH )
385 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
386 INIT_CHUNK_INITIAL_TSN_LENGTH )
389 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
390 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
391 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH 2
392 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH 2
393 #define SACK_CHUNK_GAP_BLOCK_LENGTH 4
394 #define SACK_CHUNK_GAP_BLOCK_START_LENGTH 2
395 #define SACK_CHUNK_GAP_BLOCK_END_LENGTH 2
396 #define SACK_CHUNK_DUP_TSN_LENGTH 4
398 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
399 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
400 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
401 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET (SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
402 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH)
403 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET (SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET + \
404 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH)
405 #define SACK_CHUNK_GAP_BLOCK_OFFSET (SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET + \
406 SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH)
408 #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET
410 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET CHUNK_VALUE_OFFSET
411 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
413 #define ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
414 #define ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
416 #define COOKIE_ECHO_CHUNK_COOKIE_OFFSET CHUNK_VALUE_OFFSET
418 #define ECNE_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
419 #define ECNE_CHUNK_LOWEST_TSN_LENGTH 4
421 #define CWR_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
422 #define CWR_CHUNK_LOWEST_TSN_LENGTH 4
424 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT 0x01
426 static const true_false_string sctp_data_chunk_e_bit_value = {
428 "Not the last segment"
431 static const true_false_string sctp_data_chunk_b_bit_value = {
436 static const true_false_string sctp_data_chunk_u_bit_value = {
437 "Unordered delivery",
441 static const true_false_string sctp_shutdown_complete_chunk_t_bit_value = {
446 #define SCTP_CHECKSUM_NONE 0
447 #define SCTP_CHECKSUM_ADLER32 1
448 #define SCTP_CHECKSUM_CRC32C 2
449 #define SCTP_CHECKSUM_AUTOMATIC 3
451 static gint sctp_checksum = SCTP_CHECKSUM_ADLER32;
453 /* adler32.c -- compute the Adler-32 checksum of a data stream
454 * Copyright (C) 1995-1996 Mark Adler
455 * For conditions of distribution and use, see copyright notice in zlib.h
456 * available, e.g. from http://www.cdrom.com/pub/infozip/zlib/
458 * It was modified for the use in this dissector.
461 #define BASE 65521L /* largest prime smaller than 65536 */
462 #define NMAX 5540 /* NMAX is the largest n - 12 such that */
463 /* 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
465 #define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
466 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
467 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
468 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
469 #define DO16(buf) DO8(buf,0); DO8(buf,8);
472 sctp_adler32(const unsigned char* buf, unsigned int len)
474 unsigned int s1 = 1L;
475 unsigned int s2 = 0L;
478 /* handle the first 8 bytes of the datagram */
480 buf += SOURCE_PORT_LENGTH +
481 DESTINATION_PORT_LENGTH +
482 VERIFICATION_TAG_LENGTH;
484 /* handle four 0 bytes as checksum */
485 s2 += CHECKSUM_LENGTH * s1;
486 buf += CHECKSUM_LENGTH;
488 /* now we have 12 bytes handled */
489 len -= COMMON_HEADER_LENGTH;
491 /* handle the rest of the datagram */
493 k = len < NMAX ? len : NMAX;
507 return (s2 << 16) | s1;
510 /* The CRC32C code is taken from draft-ietf-tsvwg-sctpcsum-01.txt.
511 * That code is copyrighted by D. Otis and has been modified.
514 #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
515 static unsigned long crc_c[256] =
517 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
518 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
519 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
520 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
521 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
522 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
523 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
524 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
525 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
526 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
527 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
528 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
529 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
530 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
531 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
532 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
533 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
534 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
535 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
536 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
537 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
538 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
539 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
540 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
541 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
542 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
543 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
544 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
545 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
546 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
547 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
548 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
549 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
550 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
551 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
552 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
553 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
554 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
555 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
556 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
557 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
558 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
559 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
560 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
561 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
562 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
563 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
564 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
565 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
566 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
567 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
568 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
569 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
570 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
571 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
572 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
573 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
574 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
575 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
576 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
577 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
578 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
579 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
580 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
584 sctp_crc32c(const unsigned char* buf, unsigned int len)
587 unsigned long crc32 = ~0L;
588 unsigned long result;
589 unsigned char byte0,byte1,byte2,byte3;
591 for (i = 0; i < SOURCE_PORT_LENGTH + DESTINATION_PORT_LENGTH + VERIFICATION_TAG_LENGTH; i++)
593 CRC32C(crc32, buf[i]);
599 for (i = COMMON_HEADER_LENGTH; i < len; i++)
601 CRC32C(crc32, buf[i]);
605 byte0 = result & 0xff;
606 byte1 = (result>>8) & 0xff;
607 byte2 = (result>>16) & 0xff;
608 byte3 = (result>>24) & 0xff;
609 crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
614 nr_of_padding_bytes (guint length)
618 remainder = length % 4;
623 return 4 - remainder;
627 * TLV parameter stuff for INIT and INIT-ACK chunks
631 dissect_parameter(tvbuff_t *, packet_info *, proto_tree *);
634 dissect_error_cause(tvbuff_t *, packet_info *, proto_tree *);
637 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
640 dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, packet_info *pinfo, proto_tree *tree)
642 guint offset, length, padding_length, total_length;
643 tvbuff_t *parameter_tvb;
646 while(tvb_reported_length_remaining(parameter_list_tvb, offset)) {
647 length = tvb_get_ntohs(parameter_list_tvb, offset + PARAMETER_LENGTH_OFFSET);
648 padding_length = nr_of_padding_bytes(length);
649 total_length = length + padding_length;
650 /* create a tvb for the chunk including the padding bytes */
651 parameter_tvb = tvb_new_subset(parameter_list_tvb, offset, total_length, total_length);
652 dissect_parameter(parameter_tvb, pinfo, tree);
653 /* get rid of the handled parameter */
654 offset += total_length;
659 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
661 guint16 length, heartbeat_info_length;
663 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
665 heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
667 proto_tree_add_text(parameter_tree, parameter_tvb, HEARTBEAT_INFO_PARAMETER_INFO_OFFSET, heartbeat_info_length,
668 "Heartbeat info (%u byte%s)",
669 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
671 proto_item_set_text(parameter_item, "Heartbeat info parameter with %u byte%s of info",
672 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
676 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
678 guint32 ipv4_address;
680 tvb_memcpy(parameter_tvb, (guint8 *)&ipv4_address, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH);
681 proto_tree_add_ipv4(parameter_tree, hf_sctp_parameter_ipv4_address,
682 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH,
684 proto_item_set_text(parameter_item, "IPV4 address parameter");
688 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
690 proto_tree_add_ipv6(parameter_tree, hf_sctp_parameter_ipv6_address,
691 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH,
692 tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH));
694 proto_item_set_text(parameter_item, "IPV6 address parameter");
698 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
700 guint16 length, state_cookie_length;
702 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
704 state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
706 proto_tree_add_text(parameter_tree, parameter_tvb, STATE_COOKIE_PARAMETER_COOKIE_OFFSET, state_cookie_length,
707 "State cookie (%u byte%s)",
708 state_cookie_length, plurality(state_cookie_length, "", "s"));
710 proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
711 state_cookie_length, plurality(state_cookie_length, "", "s"));
715 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
717 guint16 length, padding_length, parameter_value_length, unrecognized_parameter_type;
718 tvbuff_t *unrecognized_parameters_tvb;
720 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
721 padding_length = nr_of_padding_bytes(length);
723 parameter_value_length = length - PARAMETER_HEADER_LENGTH + padding_length;
725 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
726 parameter_value_length, parameter_value_length);
727 unrecognized_parameter_type = tvb_get_ntohs(unrecognized_parameters_tvb, PARAMETER_TYPE_OFFSET);
728 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, parameter_tree);
730 proto_item_set_text(parameter_item, "Unrecognized parameter of type %s (0x%x)",
731 val_to_str(unrecognized_parameter_type, sctp_parameter_identifier_values, "unknown"), unrecognized_parameter_type);
735 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
739 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
741 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
742 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
743 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
746 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
751 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
753 guint16 length, hostname_length;
756 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
758 hostname_length = length - PARAMETER_HEADER_LENGTH;
759 hostname = (char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
760 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
761 PARAMETER_VALUE_OFFSET, hostname_length,
764 proto_item_set_text(parameter_item, "Hostname parameter");
768 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
770 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
772 proto_item *address_list_item;
773 proto_tree *address_list_tree;
775 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
776 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
777 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
779 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
780 "Supported Address Types (%u address type%s)",
781 number_of_address_types, plurality(number_of_address_types, "", "s"));
782 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
784 offset = PARAMETER_VALUE_OFFSET;
785 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
786 address_type = tvb_get_ntohs(parameter_tvb, offset);
787 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
788 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
789 address_type, "Supported address type: 0x%04x (%s)",
790 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
791 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
794 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
795 number_of_address_types, plurality(number_of_address_types, "", "s"));
799 dissect_ecn_parameter(proto_item *parameter_item)
801 proto_item_set_text(parameter_item, "ECN parameter");
805 dissect_forward_tsn_supported_parameter(proto_item *parameter_item)
807 proto_item_set_text(parameter_item, "Forward TSN supported parameter");
810 #define CORRELATION_ID_LENGTH 4
811 #define CORRELATION_ID_OFFSET PARAMETER_VALUE_OFFSET
812 #define ADDRESS_PARAMETER_OFFSET (CORRELATION_ID_OFFSET + CORRELATION_ID_LENGTH)
815 dissect_add_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
817 guint32 correlation_id;
818 guint16 length, parameter_value_length;
819 tvbuff_t *address_tvb;
821 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
822 parameter_value_length = length - PARAMETER_HEADER_LENGTH - CORRELATION_ID_LENGTH;
823 correlation_id = tvb_get_ntohs(parameter_tvb, CORRELATION_ID_OFFSET);
824 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
825 address_tvb = tvb_new_subset(parameter_tvb, ADDRESS_PARAMETER_OFFSET, parameter_value_length, parameter_value_length);
826 dissect_parameter(address_tvb, pinfo, parameter_tree);
828 proto_item_set_text(parameter_item, "Add IP address parameter");
832 dissect_del_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
834 guint32 correlation_id;
835 guint16 length, parameter_value_length;
836 tvbuff_t *address_tvb;
838 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
839 parameter_value_length = length - PARAMETER_HEADER_LENGTH - CORRELATION_ID_LENGTH;
840 correlation_id = tvb_get_ntohs(parameter_tvb, CORRELATION_ID_OFFSET);
841 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
842 address_tvb = tvb_new_subset(parameter_tvb, ADDRESS_PARAMETER_OFFSET, parameter_value_length, parameter_value_length);
843 dissect_parameter(address_tvb, pinfo, parameter_tree);
845 proto_item_set_text(parameter_item, "Delete IP address parameter");
849 dissect_error_cause_indication_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
851 guint32 correlation_id;
852 guint16 length, padding_length, total_length;
854 tvbuff_t *error_cause_tvb;
856 correlation_id = tvb_get_ntohs(parameter_tvb, CORRELATION_ID_OFFSET);
857 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
859 offset = PARAMETER_VALUE_OFFSET + CORRELATION_ID_LENGTH;
860 while(tvb_reported_length_remaining(parameter_tvb, offset)) {
861 length = tvb_get_ntohs(parameter_tvb, offset + CAUSE_LENGTH_OFFSET);
862 padding_length = nr_of_padding_bytes(length);
863 total_length = length + padding_length;
864 /* create a tvb for the chunk including the padding bytes */
865 error_cause_tvb = tvb_new_subset(parameter_tvb, offset , total_length, total_length);
866 dissect_error_cause(error_cause_tvb, pinfo, parameter_tree);
867 /* get rid of the handled parameter */
868 offset += total_length;
870 proto_item_set_text(parameter_item, "Error cause indication");
874 dissect_set_primary_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
876 guint32 correlation_id;
877 guint16 length, parameter_value_length;
878 tvbuff_t *address_tvb;
880 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
881 parameter_value_length = length - PARAMETER_HEADER_LENGTH - CORRELATION_ID_LENGTH;
883 correlation_id = tvb_get_ntohs(parameter_tvb, CORRELATION_ID_OFFSET);
884 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
885 address_tvb = tvb_new_subset(parameter_tvb, ADDRESS_PARAMETER_OFFSET, parameter_value_length, parameter_value_length);
886 dissect_parameter(address_tvb, pinfo, parameter_tree);
888 proto_item_set_text(parameter_item, "Set primary address parameter");
892 dissect_success_report_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
894 guint32 correlation_id;
896 correlation_id = tvb_get_ntohs(parameter_tvb, CORRELATION_ID_OFFSET);
897 proto_tree_add_uint(parameter_tree, hf_sctp_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, correlation_id);
899 proto_item_set_text(parameter_item, "Success report parameter");
902 #define ADAP_INDICATION_LENGTH 4
903 #define ADAP_INDICATION_OFFSET PARAMETER_VALUE_OFFSET
906 dissect_adap_indication_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
910 indication = tvb_get_ntohl(parameter_tvb, ADAP_INDICATION_OFFSET);
911 proto_tree_add_uint(parameter_tree, hf_sctp_adap_indication, parameter_tvb, ADAP_INDICATION_OFFSET, ADAP_INDICATION_LENGTH, indication);
912 proto_item_set_text(parameter_item, "Adaptation layer indication");
916 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
918 guint16 type, length, parameter_value_length;
920 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
921 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
923 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
925 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
926 "Parameter value (%u byte%s)",
927 parameter_value_length, plurality(parameter_value_length, "", "s"));
929 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
930 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
934 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *chunk_tree)
936 guint16 type, length, padding_length, total_length;
937 proto_item *parameter_item;
938 proto_tree *parameter_tree;
940 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
941 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
942 padding_length = nr_of_padding_bytes(length);
943 total_length = length + padding_length;
945 parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb,
946 PARAMETER_HEADER_OFFSET, total_length, "%s parameter",
947 val_to_str(type, sctp_parameter_identifier_values, "Unknown"));
948 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
950 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_type,
951 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
953 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
954 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
958 case HEARTBEAT_INFO_PARAMETER_ID:
959 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
961 case IPV4ADDRESS_PARAMETER_ID:
962 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
964 case IPV6ADDRESS_PARAMETER_ID:
965 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
967 case STATE_COOKIE_PARAMETER_ID:
968 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
970 case UNREC_PARA_PARAMETER_ID:
971 dissect_unrecognized_parameters_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
973 case COOKIE_PRESERVATIVE_PARAMETER_ID:
974 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
976 case HOSTNAME_ADDRESS_PARAMETER_ID:
977 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
979 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
980 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
982 case ECN_PARAMETER_ID:
983 dissect_ecn_parameter(parameter_item);
985 case FORWARD_TSN_SUPPORTED_PARAMETER_ID:
986 dissect_forward_tsn_supported_parameter(parameter_item);
988 case ADD_IP_ADDRESS_PARAMETER_ID:
989 dissect_add_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
991 case DEL_IP_ADDRESS_PARAMETER_ID:
992 dissect_del_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
994 case ERROR_CAUSE_INDICATION_PARAMETER_ID:
995 dissect_error_cause_indication_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
997 case SET_PRIMARY_ADDRESS_PARAMETER_ID:
998 dissect_set_primary_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1000 case SUCCESS_REPORT_PARAMETER_ID:
1001 dissect_success_report_parameter(parameter_tvb, parameter_tree, parameter_item);
1003 case ADAP_LAYER_INDICATION_PARAMETER_ID:
1004 dissect_adap_indication_parameter(parameter_tvb, parameter_tree, parameter_item);
1007 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1010 if ((padding_length > 0) && (type != UNREC_PARA_PARAMETER_ID))
1011 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
1012 "Padding: %u byte%s",
1013 padding_length, plurality(padding_length, "", "s"));
1017 * Code to handle error causes for ABORT and ERROR chunks
1020 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1022 guint16 stream_identifier;
1024 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
1025 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
1026 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
1028 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
1029 "Reserved (2 bytes)");
1031 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
1036 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1038 guint32 number_of_missing_parameters, missing_parameter_number;
1039 guint16 parameter_type;
1042 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
1043 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
1044 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
1045 number_of_missing_parameters);
1046 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
1047 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
1048 parameter_type = tvb_get_ntohs(cause_tvb, offset);
1049 proto_tree_add_uint(cause_tree, hf_sctp_cause_missing_parameter_type,
1050 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
1052 offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
1055 proto_item_set_text(cause_item, "Error cause reporting %u missing mandatory parameter%s",
1056 number_of_missing_parameters, plurality(number_of_missing_parameters, "", "s") );
1060 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1062 guint32 measure_of_staleness;
1064 measure_of_staleness = tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
1066 proto_tree_add_uint(cause_tree, hf_sctp_cause_measure_of_staleness, cause_tvb,
1067 CAUSE_MEASURE_OF_STALENESS_OFFSET,
1068 CAUSE_MEASURE_OF_STALENESS_LENGTH,
1069 measure_of_staleness);
1071 proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
1072 measure_of_staleness);
1076 dissect_out_of_resource_cause(proto_item *cause_item)
1078 proto_item_set_text(cause_item, "Error cause reporting lack of resources");
1082 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1084 guint16 code, length, parameter_length, parameter_type;
1085 tvbuff_t *parameter_tvb;
1087 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1088 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1090 parameter_length = length - CAUSE_HEADER_LENGTH;
1091 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
1092 parameter_length, parameter_length);
1094 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1095 parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
1097 proto_item_set_text(cause_item, "Error cause reporting unresolvable address of type 0x%04x (%s)",
1098 parameter_type, val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown") );
1102 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo,
1103 proto_tree *cause_tree, proto_item *cause_item)
1105 guint16 length, chunk_length;
1106 guint8 unrecognized_type;
1107 tvbuff_t *unrecognized_chunk_tvb;
1109 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1111 chunk_length = length - CAUSE_HEADER_LENGTH;
1113 unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, chunk_length, chunk_length);
1114 dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree);
1116 unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
1118 proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
1120 val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
1124 dissect_invalid_mandatory_parameter_cause(proto_item *cause_item)
1126 proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
1130 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1132 guint16 length, padding_length, cause_info_length;
1133 tvbuff_t *unrecognized_parameters_tvb;
1135 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1136 padding_length = nr_of_padding_bytes(length);
1137 cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
1139 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1140 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, cause_tree);
1142 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
1146 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1150 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
1151 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
1156 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
1161 dissect_cookie_received_while_shutting_down_cause(proto_item *cause_item)
1163 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
1167 dissect_delete_last_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1169 guint16 length, cause_info_length;
1170 tvbuff_t *parameter_tvb;
1172 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1173 cause_info_length = length - CAUSE_HEADER_LENGTH;
1174 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1175 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1176 proto_item_set_text(cause_item, "Delete last address cause");
1180 dissect_resource_outage_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1182 guint16 length, cause_info_length;
1183 tvbuff_t *parameter_tvb;
1185 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1186 cause_info_length = length - CAUSE_HEADER_LENGTH;
1187 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1188 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1189 proto_item_set_text(cause_item, "Operation refused due to resource shortage");
1193 dissect_delete_source_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1195 guint16 length, cause_info_length;
1196 tvbuff_t *parameter_tvb;
1198 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1199 cause_info_length = length - CAUSE_HEADER_LENGTH;
1200 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1201 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1202 proto_item_set_text(cause_item, "Delete source address cause");
1206 dissect_unknown_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 "Cause specific information (%u byte%s)",
1217 cause_info_length, plurality(cause_info_length, "", "s"));
1219 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
1220 code, cause_info_length, plurality(cause_info_length, "", "s"));
1224 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
1226 guint16 code, length, padding_length, total_length;
1227 proto_item *cause_item;
1228 proto_tree *cause_tree;
1230 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1231 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1232 padding_length = nr_of_padding_bytes(length);
1233 total_length = length + padding_length;
1235 cause_item = proto_tree_add_text(chunk_tree, cause_tvb,
1236 CAUSE_HEADER_OFFSET, total_length,
1238 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
1240 proto_tree_add_uint(cause_tree, hf_sctp_cause_code,
1241 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
1243 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
1244 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
1248 case INVALID_STREAM_IDENTIFIER:
1249 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
1251 case MISSING_MANDATORY_PARAMETERS:
1252 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
1254 case STALE_COOKIE_ERROR:
1255 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
1257 case OUT_OF_RESOURCE:
1258 dissect_out_of_resource_cause(cause_item);
1260 case UNRESOLVABLE_ADDRESS:
1261 dissect_unresolvable_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1263 case UNRECOGNIZED_CHUNK_TYPE:
1264 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
1266 case INVALID_MANDATORY_PARAMETER:
1267 dissect_invalid_mandatory_parameter_cause(cause_item);
1269 case UNRECOGNIZED_PARAMETERS:
1270 dissect_unrecognized_parameters_cause(cause_tvb, pinfo, cause_tree, cause_item);
1273 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
1275 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
1276 dissect_cookie_received_while_shutting_down_cause(cause_item);
1278 case REQUEST_TO_DELETE_LAST_ADDRESS:
1279 dissect_delete_last_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1281 case OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE:
1282 dissect_resource_outage_cause(cause_tvb, pinfo, cause_tree, cause_item);
1284 case REQUEST_TO_DELETE_SOURCE_ADDRESS:
1285 dissect_delete_source_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1288 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
1291 if ((padding_length > 0) && (code != UNRECOGNIZED_PARAMETERS))
1292 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
1293 "Padding: %u byte%s",
1294 padding_length, plurality(padding_length, "", "s"));
1298 * Code to actually dissect the packets
1302 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree, guint32 ppi)
1304 guint32 low_port, high_port;
1306 /* Do lookups with the subdissector table.
1308 When trying port numbers, we try the port number with the lower value
1309 first, followed by the port number with the higher value. This means
1310 that, for packets where a dissector is registered for *both* port
1311 numbers, and where there's no match on the PPI:
1313 1) we pick the same dissector for traffic going in both directions;
1315 2) we prefer the port number that's more likely to be the right
1316 one (as that prefers well-known ports to reserved ports);
1318 although there is, of course, no guarantee that any such strategy
1319 will always pick the right port number.
1321 XXX - we ignore port numbers of 0, as some dissectors use a port
1322 number of 0 to disable the port. */
1323 if (dissector_try_port(sctp_ppi_dissector_table, ppi, payload_tvb, pinfo, tree))
1325 if (pinfo->srcport > pinfo->destport) {
1326 low_port = pinfo->destport;
1327 high_port = pinfo->srcport;
1329 low_port = pinfo->srcport;
1330 high_port = pinfo->destport;
1332 if (low_port != 0 &&
1333 dissector_try_port(sctp_port_dissector_table, low_port, payload_tvb, pinfo, tree))
1335 if (high_port != 0 &&
1336 dissector_try_port(sctp_port_dissector_table, high_port, payload_tvb, pinfo, tree))
1339 if (check_col(pinfo->cinfo, COL_INFO))
1340 col_append_str(pinfo->cinfo, COL_INFO, "DATA ");
1341 call_dissector(data_handle, payload_tvb, pinfo, tree);
1346 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1347 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1350 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
1351 guint32 tsn, payload_proto_id;
1352 proto_tree *flag_tree;
1353 tvbuff_t *payload_tvb;
1355 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1356 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1357 padding_length = nr_of_padding_bytes(length);
1358 total_payload_length = payload_length + padding_length;
1359 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1360 payload_length, payload_length);
1361 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1364 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1366 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1367 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
1368 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1369 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1370 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1371 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1372 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1374 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1375 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1376 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1378 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1380 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1382 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1384 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1386 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1388 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1390 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1391 chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1393 if (padding_length > 0)
1394 proto_tree_add_text(chunk_tree, chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET + payload_length, padding_length,
1395 "Padding: %u byte%s",
1396 padding_length, plurality(padding_length, "", "s"));
1398 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1399 tsn, stream_id, stream_seq_number,
1400 payload_length, plurality(payload_length, "", "s"));
1401 proto_item_set_len(chunk_item, DATA_CHUNK_HEADER_LENGTH);
1404 return dissect_payload(payload_tvb, pinfo, tree, payload_proto_id);
1408 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1409 proto_tree *chunk_tree, proto_item *chunk_item)
1411 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1412 guint16 number_of_inbound_streams, number_of_outbound_streams;
1414 tvbuff_t *parameter_list_tvb;
1416 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1418 if (check_col(pinfo->cinfo, COL_INFO)) {
1419 if (type == SCTP_INIT_CHUNK_ID) {
1420 col_append_str(pinfo->cinfo, COL_INFO, "INIT ");
1422 col_append_str(pinfo->cinfo, COL_INFO, "INIT_ACK ");
1427 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1428 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1429 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1430 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1431 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1433 /* handle fixed parameters */
1434 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1436 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1438 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1440 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1441 adv_rec_window_credit);
1442 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1444 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1445 number_of_outbound_streams);
1446 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1448 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1449 number_of_inbound_streams);
1450 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1452 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1455 /* handle variable paramters */
1456 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1457 dissect_tlv_parameter_list(parameter_list_tvb, pinfo, chunk_tree);
1459 proto_item_set_text(chunk_item,
1460 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1461 val_to_str(type, sctp_chunk_type_values, "unknown"),
1462 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1463 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1468 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1469 proto_tree *chunk_tree, proto_item *chunk_item)
1471 dissect_init_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1475 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1476 proto_tree *chunk_tree, proto_item *chunk_item)
1478 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1479 guint16 number_of_gap_blocks, number_of_dup_tsns;
1480 guint16 gap_block_number, dup_tsn_number, start, end;
1481 gint gap_block_offset, dup_tsn_offset;
1482 proto_item *block_item;
1483 proto_tree *block_tree;
1485 if (check_col(pinfo->cinfo, COL_INFO))
1486 col_append_str(pinfo->cinfo, COL_INFO, "SACK ");
1489 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1490 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1491 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1492 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1494 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1496 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1497 cumulative_tsn_ack);
1498 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1500 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1501 adv_rec_window_credit);
1502 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1504 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1505 number_of_gap_blocks);
1506 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1508 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1509 number_of_dup_tsns);
1511 /* handle the gap acknowledgement blocks */
1512 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1513 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1514 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1515 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1516 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1517 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1518 "Gap Acknowledgement for %u TSN%s",
1519 1 + end - start, plurality(1 + end - start, "", "s"));
1520 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1521 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1523 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1525 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1527 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1528 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1530 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1533 /* handle the duplicate TSNs */
1534 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1535 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1536 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1537 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1539 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1541 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1544 proto_item_set_text(chunk_item,
1545 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1547 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1548 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1553 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1554 proto_tree *chunk_tree, proto_item *chunk_item)
1556 tvbuff_t *parameter_tvb;
1557 guint chunk_length, info_length, padding_length, total_length;
1559 if (check_col(pinfo->cinfo, COL_INFO))
1560 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT ");
1563 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1564 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1565 padding_length = nr_of_padding_bytes(info_length);
1566 total_length = info_length + padding_length;
1567 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1569 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1571 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1576 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1577 proto_tree *chunk_tree, proto_item *chunk_item)
1579 tvbuff_t *parameter_tvb;
1580 guint chunk_length, info_length, padding_length, total_length;
1582 if (check_col(pinfo->cinfo, COL_INFO))
1583 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT_ACK ");
1586 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1587 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1588 padding_length = nr_of_padding_bytes(info_length);
1589 total_length = info_length + padding_length;
1591 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1593 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1595 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1600 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1603 guint offset, number_of_causes;
1604 guint16 length, padding_length, total_length;
1605 tvbuff_t *cause_tvb;
1606 proto_tree *flag_tree;
1607 if (check_col(pinfo->cinfo, COL_INFO))
1608 col_append_str(pinfo->cinfo, COL_INFO, "ABORT ");
1611 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1612 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_abort_chunk_flags);
1613 proto_tree_add_boolean(flag_tree, hf_sctp_abort_chunk_t_bit, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1615 number_of_causes = 0;
1616 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1617 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1618 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1619 padding_length = nr_of_padding_bytes(length);
1620 total_length = length + padding_length;
1621 /* create a tvb for the chunk including the padding bytes */
1622 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1623 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1624 /* get rid of the handled parameter */
1625 offset += total_length;
1629 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s", number_of_causes, plurality(number_of_causes, "", "s"));
1634 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1635 proto_tree *chunk_tree, proto_item *chunk_item)
1637 guint32 cumulative_tsn_ack;
1639 if (check_col(pinfo->cinfo, COL_INFO))
1640 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN ");
1643 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1644 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1646 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1647 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1648 cumulative_tsn_ack);
1650 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1651 cumulative_tsn_ack);
1656 dissect_shutdown_ack_chunk(packet_info *pinfo,
1657 proto_tree *chunk_tree, proto_item *chunk_item)
1659 if (check_col(pinfo->cinfo, COL_INFO))
1660 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_ACK ");
1663 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1668 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1669 proto_tree *chunk_tree, proto_item *chunk_item)
1671 guint offset, number_of_causes;
1672 guint16 length, padding_length, total_length;
1673 tvbuff_t *cause_tvb;
1675 if (check_col(pinfo->cinfo, COL_INFO))
1676 col_append_str(pinfo->cinfo, COL_INFO, "ERROR ");
1679 number_of_causes = 0;
1680 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1682 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1683 padding_length = nr_of_padding_bytes(length);
1684 total_length = length + padding_length;
1685 /* create a tvb for the chunk including the padding bytes */
1686 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1687 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1688 /* get rid of the handled parameter */
1689 offset += total_length;
1691 } while(tvb_reported_length_remaining(chunk_tvb, offset));
1693 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1694 number_of_causes, plurality(number_of_causes, "", "s"));
1699 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1700 proto_tree *chunk_tree, proto_item *chunk_item)
1702 guint length, cookie_length, padding_length;
1704 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1705 padding_length = nr_of_padding_bytes(length);
1706 cookie_length = length - CHUNK_HEADER_LENGTH;
1708 if (check_col(pinfo->cinfo, COL_INFO))
1709 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ECHO ");
1712 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1713 "Cookie (%u byte%s)",
1714 cookie_length, plurality(cookie_length, "", "s"));
1715 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1716 cookie_length, plurality(cookie_length, "", "s"));
1718 if (padding_length > 0)
1719 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1720 "Padding: %u byte%s",
1721 padding_length, plurality(padding_length, "", "s"));
1726 dissect_cookie_ack_chunk(packet_info *pinfo,
1727 proto_tree *chunk_tree, proto_item *chunk_item)
1729 if (check_col(pinfo->cinfo, COL_INFO))
1730 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ACK ");
1733 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1738 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1739 proto_tree *chunk_tree, proto_item *chunk_item)
1743 if (check_col(pinfo->cinfo, COL_INFO))
1744 col_append_str(pinfo->cinfo, COL_INFO, "ECNE ");
1747 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1748 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1750 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1753 proto_item_set_text(chunk_item, "ECNE chunk");
1758 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1759 proto_tree *chunk_tree, proto_item *chunk_item)
1763 if (check_col(pinfo->cinfo, COL_INFO))
1764 col_append_str(pinfo->cinfo, COL_INFO, "CWR ");
1767 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1768 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1770 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1773 proto_item_set_text(chunk_item, "CWR chunk");
1778 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1779 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1783 proto_tree *flag_tree;
1785 if (check_col(pinfo->cinfo, COL_INFO))
1786 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_COMPLETE ");
1789 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1790 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1792 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_shutdown_complete_chunk_flags);
1793 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1794 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1796 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1800 #define FORWARD_TSN_CHUNK_TSN_LENGTH 4
1801 #define FORWARD_TSN_CHUNK_SID_LENGTH 2
1802 #define FORWARD_TSN_CHUNK_SSN_LENGTH 2
1803 #define FORWARD_TSN_CHUNK_TSN_OFFSET CHUNK_VALUE_OFFSET
1804 #define FORWARD_TSN_CHUNK_SID_OFFSET 0
1805 #define FORWARD_TSN_CHUNK_SSN_OFFSET (FORWARD_TSN_CHUNK_SID_OFFSET + FORWARD_TSN_CHUNK_SID_LENGTH)
1808 dissect_forward_tsn_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1812 guint16 number_of_affected_streams, affected_stream, length, sid, ssn;
1814 if (check_col(pinfo->cinfo, COL_INFO))
1815 col_append_str(pinfo->cinfo, COL_INFO, "FORWARD TSN ");
1818 tsn = tvb_get_ntohl(chunk_tvb, FORWARD_TSN_CHUNK_TSN_OFFSET);
1819 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);
1820 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1821 number_of_affected_streams = (length - CHUNK_HEADER_LENGTH - FORWARD_TSN_CHUNK_TSN_LENGTH) /
1822 (FORWARD_TSN_CHUNK_SID_LENGTH + FORWARD_TSN_CHUNK_SSN_LENGTH);
1823 offset = CHUNK_VALUE_OFFSET + FORWARD_TSN_CHUNK_TSN_LENGTH;
1825 for(affected_stream = 0; affected_stream < number_of_affected_streams; affected_stream++) {
1826 sid = tvb_get_ntohs(chunk_tvb, offset + FORWARD_TSN_CHUNK_SID_OFFSET);
1827 ssn = tvb_get_ntohs(chunk_tvb, offset + FORWARD_TSN_CHUNK_SSN_OFFSET);
1828 proto_tree_add_uint(chunk_tree, hf_sctp_forward_tsn_chunk_sid,
1829 chunk_tvb, offset + FORWARD_TSN_CHUNK_SID_OFFSET, FORWARD_TSN_CHUNK_SID_LENGTH, sid);
1830 proto_tree_add_uint(chunk_tree, hf_sctp_forward_tsn_chunk_ssn,
1831 chunk_tvb, offset + FORWARD_TSN_CHUNK_SSN_OFFSET, FORWARD_TSN_CHUNK_SSN_LENGTH, ssn);
1832 offset = offset + (FORWARD_TSN_CHUNK_SID_LENGTH + FORWARD_TSN_CHUNK_SSN_LENGTH);
1834 proto_item_set_text(chunk_item, "FORWARD TSN chunk (new cumulative TSN %u)", tsn);
1838 #define SERIAL_NUMBER_LENGTH 4
1839 #define SERIAL_NUMBER_OFFSET PARAMETER_VALUE_OFFSET
1842 dissect_asconf_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1844 guint32 serial_number;
1845 guint offset, length, padding_length, total_length;
1846 tvbuff_t *parameter_tvb;
1848 if (check_col(pinfo->cinfo, COL_INFO))
1849 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF ");
1852 offset = SERIAL_NUMBER_OFFSET;
1853 serial_number = tvb_get_ntohl(chunk_tvb, offset);
1854 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_serial, chunk_tvb, offset, SERIAL_NUMBER_LENGTH, serial_number);
1855 offset += SERIAL_NUMBER_LENGTH;
1856 proto_item_set_text(chunk_item, "ASCONF chunk");
1858 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1859 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1860 padding_length = nr_of_padding_bytes(length);
1861 total_length = length + padding_length;
1862 /* create a tvb for the chunk including the padding bytes */
1863 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1864 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1865 /* get rid of the handled parameter */
1866 offset += total_length;
1872 dissect_asconf_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1874 guint32 serial_number;
1875 guint offset, length, padding_length, total_length;
1876 tvbuff_t *parameter_tvb;
1878 if (check_col(pinfo->cinfo, COL_INFO))
1879 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF-ACK ");
1882 serial_number = tvb_get_ntohl(chunk_tvb, SERIAL_NUMBER_OFFSET);
1883 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_serial, chunk_tvb, SERIAL_NUMBER_OFFSET, SERIAL_NUMBER_LENGTH, serial_number);
1884 proto_item_set_text(chunk_item, "ASCONF-ACK chunk");
1886 offset = SERIAL_NUMBER_OFFSET + SERIAL_NUMBER_LENGTH;
1887 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1888 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1889 padding_length = nr_of_padding_bytes(length);
1890 total_length = length + padding_length;
1891 /* create a tvb for the chunk including the padding bytes */
1892 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1893 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1894 /* get rid of the handled parameter */
1895 offset += total_length;
1901 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1902 proto_tree *chunk_tree, proto_item *chunk_item)
1904 guint length, chunk_value_length, padding_length;
1907 if (check_col(pinfo->cinfo, COL_INFO))
1908 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN ");
1911 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1912 padding_length = nr_of_padding_bytes(length);
1913 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1915 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1917 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1918 "Chunk value (%u byte%s)",
1919 chunk_value_length, plurality(chunk_value_length, "", "s"));
1921 if (padding_length > 0)
1922 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1923 "Padding: %u byte%s",
1924 padding_length, plurality(padding_length, "", "s"));
1926 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1927 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1933 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1938 proto_item *flags_item;
1939 proto_item *chunk_item;
1940 proto_tree *chunk_tree;
1944 /* first extract the chunk header */
1945 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1946 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1947 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1950 /* create proto_tree stuff */
1951 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb, CHUNK_HEADER_OFFSET, -1, "Incomplete chunk");
1952 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
1954 /* then insert the chunk header components into the protocol tree */
1955 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_type, chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH, type);
1956 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1957 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length, chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH, length);
1964 /* now dissect the chunk value */
1967 case SCTP_DATA_CHUNK_ID:
1968 result = dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1970 case SCTP_INIT_CHUNK_ID:
1971 dissect_init_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1973 case SCTP_INIT_ACK_CHUNK_ID:
1974 dissect_init_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1976 case SCTP_SACK_CHUNK_ID:
1977 dissect_sack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1979 case SCTP_HEARTBEAT_CHUNK_ID:
1980 dissect_heartbeat_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1982 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1983 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1985 case SCTP_ABORT_CHUNK_ID:
1986 dissect_abort_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item, flags_item);
1988 case SCTP_SHUTDOWN_CHUNK_ID:
1989 dissect_shutdown_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1991 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
1992 dissect_shutdown_ack_chunk(pinfo, chunk_tree, chunk_item);
1994 case SCTP_ERROR_CHUNK_ID:
1995 dissect_error_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1997 case SCTP_COOKIE_ECHO_CHUNK_ID:
1998 dissect_cookie_echo_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2000 case SCTP_COOKIE_ACK_CHUNK_ID:
2001 dissect_cookie_ack_chunk(pinfo, chunk_tree, chunk_item);
2003 case SCTP_ECNE_CHUNK_ID:
2004 dissect_ecne_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2006 case SCTP_CWR_CHUNK_ID:
2007 dissect_cwr_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2009 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
2010 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item, flags_item);
2012 case SCTP_FORWARD_TSN_CHUNK_ID:
2013 dissect_forward_tsn_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2015 case SCTP_ASCONF_ACK_CHUNK_ID:
2016 dissect_asconf_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2018 case SCTP_ASCONF_CHUNK_ID:
2019 dissect_asconf_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2022 dissect_unknown_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2029 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *sctp_item, proto_tree *sctp_tree)
2031 tvbuff_t *chunk_tvb;
2032 guint16 length, padding_length, total_length;
2033 gint last_offset, offset;
2034 gboolean sctp_item_length_set;
2036 /* the common header of the datagram is already handled */
2038 offset = COMMON_HEADER_LENGTH;
2039 sctp_item_length_set = FALSE;
2041 while(tvb_reported_length_remaining(tvb, offset) > 0) {
2042 /* extract the chunk length and compute number of padding bytes */
2043 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
2044 padding_length = nr_of_padding_bytes(length);
2045 total_length = length + padding_length;
2046 /* create a tvb for the chunk including the padding bytes */
2047 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
2048 /* call dissect_sctp_chunk for a actual work */
2049 if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree) && (tree)) {
2050 proto_item_set_len(sctp_item, offset - last_offset + DATA_CHUNK_HEADER_LENGTH);
2051 sctp_item_length_set = TRUE;
2052 offset += total_length;
2053 last_offset = offset;
2054 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2055 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, offset, -1, FALSE);
2056 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2057 sctp_item_length_set = FALSE;
2060 /* get rid of the dissected chunk */
2061 offset += total_length;
2064 if (!sctp_item_length_set && (tree)) {
2065 proto_item_set_len(sctp_item, offset - last_offset);
2069 /* dissect_sctp handles the common header of a SCTP datagram.
2070 * For the handling of the chunks dissect_sctp_chunks is called.
2074 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2076 guint16 source_port, destination_port;
2077 guint32 verification_tag, checksum, calculated_crc32c, calculated_adler32;
2079 gboolean crc32c_correct, adler32_correct;
2080 proto_item *sctp_item;
2081 proto_tree *sctp_tree;
2083 /* Extract the common header */
2084 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
2085 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
2086 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
2087 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
2089 /* update pi structure */
2090 pinfo->ptype = PT_SCTP;
2091 pinfo->srcport = source_port;
2092 pinfo->destport = destination_port;
2094 /* make entry in the Protocol column on summary display */
2095 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2096 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCTP");
2098 /* Clear entries in Info column on summary display */
2099 if (check_col(pinfo->cinfo, COL_INFO))
2100 col_add_str(pinfo->cinfo, COL_INFO, "");
2102 /* In the interest of speed, if "tree" is NULL, don't do any work not
2103 necessary to generate protocol tree items. */
2105 /* create the sctp protocol tree */
2106 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, 0, -1, FALSE);
2107 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2109 /* add the components of the common header to the protocol tree */
2110 proto_tree_add_uint(sctp_tree, hf_sctp_source_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2111 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2112 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag, tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH, verification_tag);
2113 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2114 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2116 length = tvb_length(tvb);
2117 switch(sctp_checksum) {
2118 case SCTP_CHECKSUM_NONE:
2119 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum, "Checksum: 0x%08x (not verified)", checksum);
2121 case SCTP_CHECKSUM_ADLER32:
2122 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2123 adler32_correct = (checksum == calculated_adler32);
2124 if (adler32_correct)
2125 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2126 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2128 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2129 checksum, "Checksum: 0x%08x (incorrect Adler32, should be 0x%08x)", checksum, calculated_adler32);
2130 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(adler32_correct));
2132 case SCTP_CHECKSUM_CRC32C:
2133 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2134 crc32c_correct = (checksum == calculated_crc32c);
2136 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2137 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2139 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2140 checksum, "Checksum: 0x%08x (incorrect CRC32C, should be 0x%08x)", checksum, calculated_crc32c);
2141 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct));
2143 case SCTP_CHECKSUM_AUTOMATIC:
2144 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2145 adler32_correct = (checksum == calculated_adler32);
2146 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2147 crc32c_correct = (checksum == calculated_crc32c);
2148 if ((adler32_correct) && !(crc32c_correct))
2149 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2150 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2151 else if (!(adler32_correct) && (crc32c_correct))
2152 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2153 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2154 else if ((adler32_correct) && (crc32c_correct))
2155 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2156 checksum, "Checksum: 0x%08x (correct Adler32 and CRC32C)", checksum);
2158 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2159 checksum, "Checksum: 0x%08x (incorrect, should be 0x%08x (Adler32) or 0x%08x (CRC32C))",
2160 checksum, calculated_adler32, calculated_crc32c);
2161 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct || adler32_correct));
2168 /* add all chunks of the sctp datagram to the protocol tree */
2169 dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree);
2172 /* Register the protocol with Ethereal */
2174 proto_register_sctp(void)
2177 /* Setup list of header fields */
2178 static hf_register_info hf[] = {
2179 { &hf_sctp_source_port,
2180 { "Source port", "sctp.srcport",
2181 FT_UINT16, BASE_DEC, NULL, 0x0,
2184 { &hf_sctp_destination_port,
2185 { "Destination port", "sctp.dstport",
2186 FT_UINT16, BASE_DEC, NULL, 0x0,
2190 { "Port", "sctp.port",
2191 FT_UINT16, BASE_DEC, NULL, 0x0,
2194 { &hf_sctp_verification_tag,
2195 { "Verification tag", "sctp.verfication_tag",
2196 FT_UINT32, BASE_HEX, NULL, 0x0,
2199 { &hf_sctp_checksum,
2200 { "Checksum", "sctp.checksum",
2201 FT_UINT32, BASE_HEX, NULL, 0x0,
2204 { &hf_sctp_checksum_bad,
2205 { "Bad checksum", "sctp.checksum_bad",
2206 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2209 { &hf_sctp_chunk_type,
2210 { "Identifier", "sctp.chunk_type",
2211 FT_UINT8, BASE_DEC, VALS(sctp_chunk_type_values), 0x0,
2214 { &hf_sctp_chunk_flags,
2215 { "Flags", "sctp.chunk_flags",
2216 FT_UINT8, BASE_BIN, NULL, 0x0,
2219 { &hf_sctp_chunk_length,
2220 { "Length", "sctp.chunk_length",
2221 FT_UINT16, BASE_DEC, NULL, 0x0,
2224 { &hf_sctp_init_chunk_initiate_tag,
2225 { "Initiate tag", "sctp.init.chunk.initiate.tag",
2226 FT_UINT32, BASE_HEX, NULL, 0x0,
2229 { &hf_sctp_init_chunk_adv_rec_window_credit,
2230 { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
2231 FT_UINT32, BASE_DEC, NULL, 0x0,
2234 { &hf_sctp_init_chunk_number_of_outbound_streams,
2235 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
2236 FT_UINT16, BASE_DEC, NULL, 0x0,
2239 { &hf_sctp_init_chunk_number_of_inbound_streams,
2240 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
2241 FT_UINT16, BASE_DEC, NULL, 0x0,
2244 {&hf_sctp_init_chunk_initial_tsn,
2245 { "Initial TSN", "sctp.init.chunk.initial.tsn",
2246 FT_UINT32, BASE_DEC, NULL, 0x0,
2249 {&hf_sctp_cumulative_tsn_ack,
2250 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
2251 FT_UINT32, BASE_DEC, NULL, 0x0,
2254 {&hf_sctp_data_chunk_tsn,
2255 { "TSN", "sctp.tsn",
2256 FT_UINT32, BASE_DEC, NULL, 0x0,
2259 {&hf_sctp_data_chunk_stream_id,
2260 { "Stream Identifier", "sctp.stream_id",
2261 FT_UINT16, BASE_HEX, NULL, 0x0,
2264 {&hf_sctp_data_chunk_stream_seq_number,
2265 { "Stream sequence number", "sctp.stream_seq_number",
2266 FT_UINT16, BASE_DEC, NULL, 0x0,
2269 {&hf_sctp_data_chunk_payload_proto_id,
2270 { "Payload protocol identifier", "sctp.payload_proto_id",
2271 FT_UINT32, BASE_DEC, VALS(sctp_payload_proto_id_values), 0x0,
2274 {&hf_sctp_data_chunk_e_bit,
2275 { "E-Bit", "sctp.data.e_bit",
2276 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
2279 {&hf_sctp_data_chunk_b_bit,
2280 { "B-Bit", "sctp.data.b_bit",
2281 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
2284 {&hf_sctp_data_chunk_u_bit,
2285 { "U-Bit", "sctp.data.u.bit",
2286 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
2289 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
2290 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
2291 FT_UINT32, BASE_DEC, NULL, 0x0,
2294 {&hf_sctp_sack_chunk_adv_rec_window_credit,
2295 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
2296 FT_UINT32, BASE_DEC, NULL, 0x0,
2299 {&hf_sctp_sack_chunk_number_of_gap_blocks,
2300 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
2301 FT_UINT16, BASE_DEC, NULL, 0x0,
2304 {&hf_sctp_sack_chunk_number_of_dup_tsns,
2305 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
2306 FT_UINT16, BASE_DEC, NULL, 0x0,
2309 {&hf_sctp_sack_chunk_gap_block_start,
2310 { "Start", "sctp.sack.gap_block_start",
2311 FT_UINT16, BASE_DEC, NULL, 0x0,
2314 {&hf_sctp_sack_chunk_gap_block_end,
2315 { "End", "sctp.sack.gap_block_end",
2316 FT_UINT16, BASE_DEC, NULL, 0x0,
2319 {&hf_sctp_sack_chunk_duplicate_tsn,
2320 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
2321 FT_UINT16, BASE_DEC, NULL, 0x0,
2324 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
2325 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
2326 FT_UINT32, BASE_DEC, NULL, 0x0,
2329 {&hf_sctp_ecne_chunk_lowest_tsn,
2330 { "Lowest TSN", "sctp.ecne.lowest_tsn",
2331 FT_UINT32, BASE_DEC, NULL, 0x0,
2334 {&hf_sctp_cwr_chunk_lowest_tsn,
2335 { "Lowest TSN", "sctp.cwr.lowest_tsn",
2336 FT_UINT32, BASE_DEC, NULL, 0x0,
2339 {&hf_sctp_shutdown_complete_chunk_t_bit,
2340 { "T-Bit", "sctp.shutdown_complete.t_bit",
2341 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2344 {&hf_sctp_abort_chunk_t_bit,
2345 { "T-Bit", "sctp.abort.t_bit",
2346 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2349 {&hf_sctp_forward_tsn_chunk_tsn,
2350 { "New cumulative TSN", "sctp.forward_tsn.tsn",
2351 FT_UINT32, BASE_DEC, NULL, 0x0,
2354 {&hf_sctp_forward_tsn_chunk_sid,
2355 { "Stream identifier", "sctp.forward_tsn.sid",
2356 FT_UINT16, BASE_DEC, NULL, 0x0,
2359 {&hf_sctp_forward_tsn_chunk_ssn,
2360 { "Stream sequence number", "sctp.forward_tsn.ssn",
2361 FT_UINT16, BASE_DEC, NULL, 0x0,
2364 {&hf_sctp_chunk_parameter_type,
2365 { "Parameter type", "sctp.parameter.type",
2366 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2369 {&hf_sctp_chunk_parameter_length,
2370 { "Parameter length", "sctp.parameter.length",
2371 FT_UINT16, BASE_DEC, NULL, 0x0,
2374 {&hf_sctp_parameter_ipv4_address,
2375 { "IP Version 4 address", "sctp.parameter.ipv4_address",
2376 FT_IPv4, BASE_NONE, NULL, 0x0,
2379 {&hf_sctp_parameter_ipv6_address,
2380 { "IP Version 6 address", "sctp.parameter.ipv6_address",
2381 FT_IPv6, BASE_NONE, NULL, 0x0,
2384 {&hf_sctp_parameter_cookie_preservative_increment,
2385 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
2386 FT_UINT32, BASE_DEC, NULL, 0x0,
2389 {&hf_sctp_parameter_hostname_hostname,
2390 { "Hostname", "sctp.parameter.hostname.hostname",
2391 FT_STRING, BASE_NONE, NULL, 0x0,
2394 {&hf_sctp_supported_address_types_parameter,
2395 { "Supported address type", "sctp.parameter.supported_addres_type",
2396 FT_UINT16, BASE_DEC, NULL, 0x0,
2399 {&hf_sctp_asconf_serial,
2400 { "Serial Number", "sctp.asconf.serial_number",
2401 FT_UINT32, BASE_HEX, NULL, 0x0,
2404 {&hf_sctp_asconf_ack_serial,
2405 { "Serial Number", "sctp.asconf_ack.serial_number",
2406 FT_UINT32, BASE_HEX, NULL, 0x0,
2409 {&hf_sctp_correlation_id,
2410 { "Correlation_id", "sctp.correlation_id",
2411 FT_UINT32, BASE_HEX, NULL, 0x0,
2414 {&hf_sctp_adap_indication,
2415 { "Indication", "sctp.adapation_layer_indication.indication",
2416 FT_UINT32, BASE_HEX, NULL, 0x0,
2419 {&hf_sctp_cause_code,
2420 { "Cause code", "sctp.cause.code",
2421 FT_UINT16, BASE_HEX, VALS(sctp_cause_code_values), 0x0,
2424 {&hf_sctp_cause_length,
2425 { "Cause length", "sctp.cause.length",
2426 FT_UINT16, BASE_DEC, NULL, 0x0,
2429 {&hf_sctp_cause_stream_identifier,
2430 { "Stream identifier", "sctp.cause.stream_identifier",
2431 FT_UINT16, BASE_DEC, NULL, 0x0,
2434 {&hf_sctp_cause_number_of_missing_parameters,
2435 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
2436 FT_UINT32, BASE_DEC, NULL, 0x0,
2439 {&hf_sctp_cause_missing_parameter_type,
2440 { "Missing parameter type", "sctp.cause.missing_parameter_type",
2441 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2444 {&hf_sctp_cause_measure_of_staleness,
2445 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
2446 FT_UINT32, BASE_DEC, NULL, 0x0,
2449 {&hf_sctp_cause_tsn,
2450 { "TSN", "sctp.cause.tsn",
2451 FT_UINT32, BASE_DEC, NULL, 0x0,
2456 /* Setup protocol subtree array */
2457 static gint *ett[] = {
2460 &ett_sctp_chunk_parameter,
2461 &ett_sctp_chunk_cause,
2462 &ett_sctp_data_chunk_flags,
2463 &ett_sctp_shutdown_complete_chunk_flags,
2464 &ett_sctp_abort_chunk_flags,
2465 &ett_sctp_sack_chunk_gap_block,
2466 &ett_sctp_supported_address_types_parameter,
2467 &ett_sctp_unrecognized_parameter_parameter,
2470 static enum_val_t sctp_checksum_options[] = {
2471 { "None", SCTP_CHECKSUM_NONE },
2472 { "Adler 32", SCTP_CHECKSUM_ADLER32 },
2473 { "CRC 32c", SCTP_CHECKSUM_CRC32C },
2474 { "Automatic", SCTP_CHECKSUM_AUTOMATIC},
2478 /* Register the protocol name and description */
2479 proto_sctp = proto_register_protocol("Stream Control Transmission Protocol", "SCTP", "sctp");
2480 sctp_module = prefs_register_protocol(proto_sctp, NULL);
2481 prefs_register_enum_preference(sctp_module, "checksum",
2483 "The type of checksum used in SCTP packets",
2484 &sctp_checksum, sctp_checksum_options, FALSE);
2486 /* Required function calls to register the header fields and subtrees used */
2487 proto_register_field_array(proto_sctp, hf, array_length(hf));
2488 proto_register_subtree_array(ett, array_length(ett));
2490 /* subdissector code */
2491 sctp_port_dissector_table = register_dissector_table("sctp.port", "SCTP port", FT_UINT16, BASE_DEC);
2492 sctp_ppi_dissector_table = register_dissector_table("sctp.ppi", "SCTP payload protocol identifier", FT_UINT32, BASE_HEX);
2497 proto_reg_handoff_sctp(void)
2499 dissector_handle_t sctp_handle;
2501 data_handle = find_dissector("data");
2502 sctp_handle = create_dissector_handle(dissect_sctp, proto_sctp);
2503 dissector_add("ip.proto", IP_PROTO_SCTP, sctp_handle);