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-03.txt for the add-IP extension
6 * - http://www.sctp.org/draft-ietf-tsvwg-usctp-01.txt for the 'Limited Retransmission' extension
7 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpcsum-03.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.33 2002/03/03 22:42:08 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.
44 #ifdef HAVE_SYS_TYPES_H
45 # include <sys/types.h>
48 #ifdef HAVE_NETINET_IN_H
49 # include <netinet/in.h>
55 #ifdef NEED_SNPRINTF_H
56 # include "snprintf.h"
60 #include <epan/packet.h>
63 /* Initialize the protocol and registered fields */
64 static int proto_sctp = -1;
65 static int hf_sctp_port = -1;
66 static int hf_sctp_source_port = -1;
67 static int hf_sctp_destination_port = -1;
68 static int hf_sctp_verification_tag = -1;
69 static int hf_sctp_checksum = -1;
70 static int hf_sctp_checksum_bad = -1;
72 static int hf_sctp_chunk_type = -1;
73 static int hf_sctp_chunk_flags = -1;
74 static int hf_sctp_chunk_length = -1;
76 static int hf_sctp_init_chunk_initiate_tag = -1;
77 static int hf_sctp_init_chunk_adv_rec_window_credit = -1;
78 static int hf_sctp_init_chunk_number_of_outbound_streams = -1;
79 static int hf_sctp_init_chunk_number_of_inbound_streams = -1;
80 static int hf_sctp_init_chunk_initial_tsn = -1;
82 static int hf_sctp_cumulative_tsn_ack = -1;
84 static int hf_sctp_data_chunk_tsn = -1;
85 static int hf_sctp_data_chunk_stream_id = -1;
86 static int hf_sctp_data_chunk_stream_seq_number = -1;
87 static int hf_sctp_data_chunk_payload_proto_id = -1;
89 static int hf_sctp_data_chunk_e_bit = -1;
90 static int hf_sctp_data_chunk_b_bit = -1;
91 static int hf_sctp_data_chunk_u_bit = -1;
93 static int hf_sctp_sack_chunk_cumulative_tsn_ack = -1;
94 static int hf_sctp_sack_chunk_adv_rec_window_credit = -1;
95 static int hf_sctp_sack_chunk_number_of_gap_blocks = -1;
96 static int hf_sctp_sack_chunk_number_of_dup_tsns = -1;
97 static int hf_sctp_sack_chunk_gap_block_start = -1;
98 static int hf_sctp_sack_chunk_gap_block_end = -1;
99 static int hf_sctp_sack_chunk_duplicate_tsn = -1;
101 static int hf_sctp_shutdown_chunk_cumulative_tsn_ack = -1;
103 static int hf_sctp_cwr_chunk_lowest_tsn = -1;
105 static int hf_sctp_ecne_chunk_lowest_tsn = -1;
107 static int hf_sctp_shutdown_complete_chunk_t_bit = -1;
109 static int hf_sctp_chunk_parameter_type = -1;
110 static int hf_sctp_chunk_parameter_length = -1;
111 static int hf_sctp_parameter_ipv4_address = -1;
112 static int hf_sctp_parameter_ipv6_address = -1;
113 static int hf_sctp_parameter_cookie_preservative_increment = -1;
114 static int hf_sctp_parameter_hostname_hostname = -1;
115 static int hf_sctp_supported_address_types_parameter = -1;
117 static int hf_sctp_cause_code = -1;
118 static int hf_sctp_cause_length = -1;
119 static int hf_sctp_cause_stream_identifier = -1;
121 static int hf_sctp_cause_number_of_missing_parameters = -1;
122 static int hf_sctp_cause_missing_parameter_type = -1;
124 static int hf_sctp_cause_measure_of_staleness = -1;
126 static int hf_sctp_cause_tsn = -1;
128 static int hf_sctp_forward_tsn_chunk_tsn = -1;
130 static int hf_sctp_ustreams_start = -1;
131 static int hf_sctp_ustreams_end = -1;
133 static int hf_sctp_asconf_ack_serial = -1;
134 static int hf_sctp_asconf_ack_correlation_id = -1;
136 static int hf_sctp_asconf_serial = -1;
137 static int hf_sctp_asconf_correlation_id = -1;
138 static int hf_sctp_asconf_reserved = -1;
139 static int hf_sctp_asconf_addr_type = -1;
140 static int hf_sctp_asconf_addr = -1;
141 static int hf_sctp_asconf_ipv4_address = -1;
142 static int hf_sctp_asconf_ipv6_address = -1;
143 static int hf_sctp_adap_indication = -1;
145 static dissector_table_t sctp_port_dissector_table;
146 static dissector_table_t sctp_ppi_dissector_table;
148 static module_t *sctp_module;
150 /* Initialize the subtree pointers */
151 static gint ett_sctp = -1;
152 static gint ett_sctp_chunk = -1;
153 static gint ett_sctp_chunk_parameter = -1;
154 static gint ett_sctp_chunk_cause = -1;
155 static gint ett_sctp_data_chunk_flags = -1;
156 static gint ett_sctp_sack_chunk_gap_block = -1;
157 static gint ett_sctp_supported_address_types_parameter = -1;
158 static gint ett_sctp_unrecognized_parameter_parameter = -1;
159 static gint ett_sctp_unreliable_streams_interval = -1;
161 #define SCTP_DATA_CHUNK_ID 0
162 #define SCTP_INIT_CHUNK_ID 1
163 #define SCTP_INIT_ACK_CHUNK_ID 2
164 #define SCTP_SACK_CHUNK_ID 3
165 #define SCTP_HEARTBEAT_CHUNK_ID 4
166 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
167 #define SCTP_ABORT_CHUNK_ID 6
168 #define SCTP_SHUTDOWN_CHUNK_ID 7
169 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
170 #define SCTP_ERROR_CHUNK_ID 9
171 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
172 #define SCTP_COOKIE_ACK_CHUNK_ID 11
173 #define SCTP_ECNE_CHUNK_ID 12
174 #define SCTP_CWR_CHUNK_ID 13
175 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
176 #define SCTP_FORWARD_TSN_CHUNK_ID 192
177 #define SCTP_ASCONF_ACK_CHUNK_ID 0x80
178 #define SCTP_ASCONF_CHUNK_ID 0XC1
180 #define SCTP_IETF_EXT 255
182 static const value_string sctp_chunk_type_values[] = {
183 { SCTP_DATA_CHUNK_ID, "DATA" },
184 { SCTP_INIT_CHUNK_ID, "INIT" },
185 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
186 { SCTP_SACK_CHUNK_ID, "SACK" },
187 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
188 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
189 { SCTP_ABORT_CHUNK_ID, "ABORT" },
190 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
191 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
192 { SCTP_ERROR_CHUNK_ID, "ERROR" },
193 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
194 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
195 { SCTP_ECNE_CHUNK_ID, "ECNE" },
196 { SCTP_CWR_CHUNK_ID, "CWR" },
197 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
198 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
199 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
200 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
201 { SCTP_IETF_EXT, "IETF_EXTENSION" },
204 #define HEARTBEAT_INFO_PARAMETER_ID 0x0001
205 #define IPV4ADDRESS_PARAMETER_ID 0x0005
206 #define IPV6ADDRESS_PARAMETER_ID 0x0006
207 #define STATE_COOKIE_PARAMETER_ID 0x0007
208 #define UNREC_PARA_PARAMETER_ID 0x0008
209 #define COOKIE_PRESERVATIVE_PARAMETER_ID 0x0009
210 #define HOSTNAME_ADDRESS_PARAMETER_ID 0x000b
211 #define SUPPORTED_ADDRESS_TYPES_PARAMETER_ID 0x000c
212 #define ECN_PARAMETER_ID 0x8000
213 #define UNRELIABLE_STREAMS_PARAMETER_ID 0xC000
214 #define ADD_IP_ADDRESS_PARAMETER_ID 0xC001
215 #define DEL_IP_ADDRESS_PARAMETER_ID 0xC002
216 #define ERROR_CAUSE_INDICATION_PARAMETER_ID 0xC003
217 #define SET_PRIMARY_ADDRESS_PARAMETER_ID 0xC004
218 #define SUCCESS_REPORT_PARAMETER_ID 0xC005
219 #define ADAP_LAYER_INDICATION_PARAMETER_ID 0xC006
221 static const value_string sctp_parameter_identifier_values[] = {
222 { HEARTBEAT_INFO_PARAMETER_ID, "Heartbeat info" },
223 { IPV4ADDRESS_PARAMETER_ID, "IPv4 address" },
224 { IPV6ADDRESS_PARAMETER_ID, "IPv6 address" },
225 { STATE_COOKIE_PARAMETER_ID, "State cookie" },
226 { UNREC_PARA_PARAMETER_ID, "Unrecognized parameters" },
227 { COOKIE_PRESERVATIVE_PARAMETER_ID, "Cookie preservative" },
228 { HOSTNAME_ADDRESS_PARAMETER_ID, "Hostname address" },
229 { SUPPORTED_ADDRESS_TYPES_PARAMETER_ID, "Supported address types" },
230 { ECN_PARAMETER_ID, "ECN" },
231 { UNRELIABLE_STREAMS_PARAMETER_ID, "Unreliable streams" },
232 { ADD_IP_ADDRESS_PARAMETER_ID, "Add IP address" },
233 { DEL_IP_ADDRESS_PARAMETER_ID, "Delete IP address" },
234 { ERROR_CAUSE_INDICATION_PARAMETER_ID, "Error cause indication" },
235 { SET_PRIMARY_ADDRESS_PARAMETER_ID, "Set primary address" },
236 { SUCCESS_REPORT_PARAMETER_ID, "Success report" },
237 { ADAP_LAYER_INDICATION_PARAMETER_ID, "Adaptation Layer Indication" },
240 #define PARAMETER_TYPE_LENGTH 2
241 #define PARAMETER_LENGTH_LENGTH 2
242 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
244 #define PARAMETER_HEADER_OFFSET 0
245 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
246 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
247 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
249 #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET
250 #define HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
252 #define IPV4_ADDRESS_LENGTH 4
253 #define IPV6_ADDRESS_LENGTH 16
255 #define STATE_COOKIE_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
256 #define STATE_COOKIE_PARAMETER_COOKIE_OFFSET PARAMETER_VALUE_OFFSET
258 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET PARAMETER_VALUE_OFFSET
259 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH 4
260 #define SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH 2
262 #define CAUSE_CODE_LENGTH 2
263 #define CAUSE_LENGTH_LENGTH 2
264 #define CAUSE_HEADER_LENGTH (CAUSE_CODE_LENGTH + CAUSE_LENGTH_LENGTH)
266 #define CAUSE_HEADER_OFFSET 0
267 #define CAUSE_CODE_OFFSET CAUSE_HEADER_OFFSET
268 #define CAUSE_LENGTH_OFFSET (CAUSE_CODE_OFFSET + CAUSE_CODE_LENGTH)
269 #define CAUSE_INFO_OFFSET (CAUSE_LENGTH_OFFSET + CAUSE_LENGTH_LENGTH)
271 #define CAUSE_STREAM_IDENTIFIER_LENGTH 2
272 #define CAUSE_RESERVED_LENGTH 2
273 #define CAUSE_STREAM_IDENTIFIER_OFFSET CAUSE_INFO_OFFSET
274 #define CAUSE_RESERVED_OFFSET (CAUSE_STREAM_IDENTIFIER_OFFSET + CAUSE_STREAM_IDENTIFIER_LENGTH)
276 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH 4
277 #define CAUSE_MISSING_PARAMETER_TYPE_LENGTH 2
279 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET CAUSE_INFO_OFFSET
280 #define CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET (CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET + \
281 CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH )
283 #define CAUSE_MEASURE_OF_STALENESS_LENGTH 4
284 #define CAUSE_MEASURE_OF_STALENESS_OFFSET CAUSE_INFO_OFFSET
286 #define CAUSE_TSN_LENGTH 4
287 #define CAUSE_TSN_OFFSET CAUSE_INFO_OFFSET
289 #define INVALID_STREAM_IDENTIFIER 0x01
290 #define MISSING_MANDATORY_PARAMETERS 0x02
291 #define STALE_COOKIE_ERROR 0x03
292 #define OUT_OF_RESOURCE 0x04
293 #define UNRESOLVABLE_ADDRESS 0x05
294 #define UNRECOGNIZED_CHUNK_TYPE 0x06
295 #define INVALID_MANDATORY_PARAMETER 0x07
296 #define UNRECOGNIZED_PARAMETERS 0x08
297 #define NO_USER_DATA 0x09
298 #define COOKIE_RECEIVED_WHILE_SHUTTING_DOWN 0x0a
299 #define REQUEST_TO_DELETE_LAST_ADDRESS 0x0c
300 #define OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE 0X0d
301 #define REQUEST_TO_DELETE_SOURCE_ADDRESS 0x0e
303 static const value_string sctp_cause_code_values[] = {
304 { INVALID_STREAM_IDENTIFIER, "Invalid stream identifier" },
305 { MISSING_MANDATORY_PARAMETERS, "Missing mandator parameter" },
306 { STALE_COOKIE_ERROR, "Stale cookie error" },
307 { OUT_OF_RESOURCE, "Out of resource" },
308 { UNRESOLVABLE_ADDRESS, "Unresolvable address" },
309 { UNRECOGNIZED_CHUNK_TYPE, "Unrecognized chunk type " },
310 { INVALID_MANDATORY_PARAMETER, "Invalid mandatory parameter" },
311 { UNRECOGNIZED_PARAMETERS, "Unrecognized parameters" },
312 { NO_USER_DATA, "No user data" },
313 { COOKIE_RECEIVED_WHILE_SHUTTING_DOWN, "Cookie received while shutting down" },
314 { REQUEST_TO_DELETE_LAST_ADDRESS, "Request to delete last address" },
315 { OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE, "Operation refused due to resource shortage" },
316 { REQUEST_TO_DELETE_SOURCE_ADDRESS, "Request to delete source address" },
319 #define NOT_SPECIFIED_PROTOCOL_ID 0
320 #define IUA_PAYLOAD_PROTOCOL_ID 1
321 #define M2UA_PAYLOAD_PROTOCOL_ID 2
322 #define M3UA_PAYLOAD_PROTOCOL_ID 3
323 #define SUA_PAYLOAD_PROTOCOL_ID 4
324 #define M2PA_PAYLOAD_PROTOCOL_ID 5
325 #define V5UA_PAYLOAD_PROTOCOL_ID 6
327 static const value_string sctp_payload_proto_id_values[] = {
328 { NOT_SPECIFIED_PROTOCOL_ID, "not specified" },
329 { IUA_PAYLOAD_PROTOCOL_ID, "IUA" },
330 { M2UA_PAYLOAD_PROTOCOL_ID, "M2UA" },
331 { M3UA_PAYLOAD_PROTOCOL_ID, "M3UA" },
332 { SUA_PAYLOAD_PROTOCOL_ID, "SUA" },
333 { M2PA_PAYLOAD_PROTOCOL_ID, "M2PA" },
334 { V5UA_PAYLOAD_PROTOCOL_ID, "V5UA" },
337 /* The structure of the common header is described by the following constants */
338 #define SOURCE_PORT_LENGTH 2
339 #define DESTINATION_PORT_LENGTH 2
340 #define VERIFICATION_TAG_LENGTH 4
341 #define CHECKSUM_LENGTH 4
342 #define COMMON_HEADER_LENGTH (SOURCE_PORT_LENGTH + \
343 DESTINATION_PORT_LENGTH + \
344 VERIFICATION_TAG_LENGTH + \
346 #define SOURCE_PORT_OFFSET 0
347 #define DESTINATION_PORT_OFFSET (SOURCE_PORT_OFFSET + SOURCE_PORT_LENGTH)
348 #define VERIFICATION_TAG_OFFSET (DESTINATION_PORT_OFFSET + DESTINATION_PORT_LENGTH)
349 #define CHECKSUM_OFFSET (VERIFICATION_TAG_OFFSET + VERIFICATION_TAG_LENGTH)
351 /* The structure of the chunk header is described by the following constants */
352 #define CHUNK_TYPE_LENGTH 1
353 #define CHUNK_FLAGS_LENGTH 1
354 #define CHUNK_LENGTH_LENGTH 2
355 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
356 CHUNK_FLAGS_LENGTH + \
358 #define CHUNK_HEADER_OFFSET 0
359 #define CHUNK_TYPE_OFFSET CHUNK_HEADER_OFFSET
360 #define CHUNK_FLAGS_OFFSET (CHUNK_TYPE_OFFSET + CHUNK_TYPE_LENGTH)
361 #define CHUNK_LENGTH_OFFSET (CHUNK_FLAGS_OFFSET + CHUNK_FLAGS_LENGTH)
362 #define CHUNK_VALUE_OFFSET (CHUNK_LENGTH_OFFSET + CHUNK_LENGTH_LENGTH)
364 /* The following constants describe the structure of DATA chunks */
365 #define DATA_CHUNK_TSN_LENGTH 4
366 #define DATA_CHUNK_STREAM_ID_LENGTH 2
367 #define DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH 2
368 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
370 #define DATA_CHUNK_TSN_OFFSET (CHUNK_VALUE_OFFSET + 0)
371 #define DATA_CHUNK_STREAM_ID_OFFSET (DATA_CHUNK_TSN_OFFSET + DATA_CHUNK_TSN_LENGTH)
372 #define DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET (DATA_CHUNK_STREAM_ID_OFFSET + \
373 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
374 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET (DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET + \
375 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
376 #define DATA_CHUNK_PAYLOAD_OFFSET (DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET + \
377 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
379 #define DATA_CHUNK_HEADER_LENGTH (CHUNK_HEADER_LENGTH + \
380 DATA_CHUNK_TSN_LENGTH + \
381 DATA_CHUNK_STREAM_ID_LENGTH + \
382 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH + \
383 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
385 #define SCTP_DATA_CHUNK_E_BIT 0x01
386 #define SCTP_DATA_CHUNK_B_BIT 0x02
387 #define SCTP_DATA_CHUNK_U_BIT 0x04
389 #define INIT_CHUNK_INITIATE_TAG_LENGTH 4
390 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
391 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH 2
392 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH 2
393 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
395 #define INIT_CHUNK_INITIATE_TAG_OFFSET CHUNK_VALUE_OFFSET
396 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (INIT_CHUNK_INITIATE_TAG_OFFSET + \
397 INIT_CHUNK_INITIATE_TAG_LENGTH )
398 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET (INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
399 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH )
400 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET (INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET + \
401 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH )
402 #define INIT_CHUNK_INITIAL_TSN_OFFSET (INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET + \
403 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH )
404 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
405 INIT_CHUNK_INITIAL_TSN_LENGTH )
408 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
409 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
410 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH 2
411 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH 2
412 #define SACK_CHUNK_GAP_BLOCK_LENGTH 4
413 #define SACK_CHUNK_GAP_BLOCK_START_LENGTH 2
414 #define SACK_CHUNK_GAP_BLOCK_END_LENGTH 2
415 #define SACK_CHUNK_DUP_TSN_LENGTH 4
417 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
418 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
419 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
420 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET (SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
421 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH)
422 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET (SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET + \
423 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH)
424 #define SACK_CHUNK_GAP_BLOCK_OFFSET (SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET + \
425 SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH)
427 #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET
429 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET CHUNK_VALUE_OFFSET
430 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
432 #define ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
433 #define ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
435 #define COOKIE_ECHO_CHUNK_COOKIE_OFFSET CHUNK_VALUE_OFFSET
437 #define ECNE_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
438 #define ECNE_CHUNK_LOWEST_TSN_LENGTH 4
440 #define CWR_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
441 #define CWR_CHUNK_LOWEST_TSN_LENGTH 4
443 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT 0x01
445 static const true_false_string sctp_data_chunk_e_bit_value = {
447 "Not the last segment"
450 static const true_false_string sctp_data_chunk_b_bit_value = {
455 static const true_false_string sctp_data_chunk_u_bit_value = {
456 "Unordered delivery",
460 static const true_false_string sctp_shutdown_complete_chunk_t_bit_value = {
465 #define SCTP_CHECKSUM_NONE 0
466 #define SCTP_CHECKSUM_ADLER32 1
467 #define SCTP_CHECKSUM_CRC32C 2
468 #define SCTP_CHECKSUM_AUTOMATIC 3
470 static gint sctp_checksum = SCTP_CHECKSUM_ADLER32;
472 /* adler32.c -- compute the Adler-32 checksum of a data stream
473 * Copyright (C) 1995-1996 Mark Adler
474 * For conditions of distribution and use, see copyright notice in zlib.h
475 * available, e.g. from http://www.cdrom.com/pub/infozip/zlib/
477 * It was modified for the use in this dissector.
480 #define BASE 65521L /* largest prime smaller than 65536 */
481 #define NMAX 5540 /* NMAX is the largest n - 12 such that */
482 /* 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
484 #define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
485 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
486 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
487 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
488 #define DO16(buf) DO8(buf,0); DO8(buf,8);
491 sctp_adler32(const unsigned char* buf, unsigned int len)
493 unsigned int s1 = 1L;
494 unsigned int s2 = 0L;
497 /* handle the first 8 bytes of the datagram */
499 buf += SOURCE_PORT_LENGTH +
500 DESTINATION_PORT_LENGTH +
501 VERIFICATION_TAG_LENGTH;
503 /* handle four 0 bytes as checksum */
504 s2 += CHECKSUM_LENGTH * s1;
505 buf += CHECKSUM_LENGTH;
507 /* now we have 12 bytes handled */
508 len -= COMMON_HEADER_LENGTH;
510 /* handle the rest of the datagram */
512 k = len < NMAX ? len : NMAX;
526 return (s2 << 16) | s1;
529 /* The CRC32C code is taken from draft-ietf-tsvwg-sctpcsum-01.txt.
530 * That code is copyrighted by D. Otis and has been modified.
533 #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
534 static unsigned long crc_c[256] =
536 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
537 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
538 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
539 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
540 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
541 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
542 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
543 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
544 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
545 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
546 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
547 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
548 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
549 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
550 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
551 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
552 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
553 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
554 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
555 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
556 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
557 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
558 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
559 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
560 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
561 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
562 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
563 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
564 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
565 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
566 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
567 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
568 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
569 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
570 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
571 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
572 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
573 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
574 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
575 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
576 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
577 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
578 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
579 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
580 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
581 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
582 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
583 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
584 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
585 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
586 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
587 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
588 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
589 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
590 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
591 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
592 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
593 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
594 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
595 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
596 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
597 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
598 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
599 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
603 sctp_crc32c(const unsigned char* buf, unsigned int len)
606 unsigned long crc32 = ~0L;
607 unsigned long result;
608 unsigned char byte0,byte1,byte2,byte3;
610 for (i = 0; i < SOURCE_PORT_LENGTH + DESTINATION_PORT_LENGTH + VERIFICATION_TAG_LENGTH; i++)
612 CRC32C(crc32, buf[i]);
618 for (i = COMMON_HEADER_LENGTH; i < len; i++)
620 CRC32C(crc32, buf[i]);
624 byte0 = result & 0xff;
625 byte1 = (result>>8) & 0xff;
626 byte2 = (result>>16) & 0xff;
627 byte3 = (result>>24) & 0xff;
628 crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
633 nr_of_padding_bytes (guint length)
637 remainder = length % 4;
642 return 4 - remainder;
646 * TLV parameter stuff for INIT and INIT-ACK chunks
650 dissect_parameter(tvbuff_t *, packet_info *, proto_tree *);
653 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree);
656 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
659 dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, packet_info *pinfo, proto_tree *tree)
661 guint offset, length, padding_length, total_length;
662 tvbuff_t *parameter_tvb;
665 while(tvb_reported_length_remaining(parameter_list_tvb, offset)) {
666 length = tvb_get_ntohs(parameter_list_tvb, offset + PARAMETER_LENGTH_OFFSET);
667 padding_length = nr_of_padding_bytes(length);
668 total_length = length + padding_length;
669 /* create a tvb for the chunk including the padding bytes */
670 parameter_tvb = tvb_new_subset(parameter_list_tvb, offset, total_length, total_length);
671 dissect_parameter(parameter_tvb, pinfo, tree);
672 /* get rid of the handled parameter */
673 offset += total_length;
678 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
680 guint16 length, heartbeat_info_length;
682 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
684 heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
686 proto_tree_add_text(parameter_tree, parameter_tvb, HEARTBEAT_INFO_PARAMETER_INFO_OFFSET, heartbeat_info_length,
687 "Heartbeat info (%u byte%s)",
688 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
690 proto_item_set_text(parameter_item, "Heartbeat info parameter with %u byte%s of info",
691 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
695 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
697 guint32 ipv4_address;
699 tvb_memcpy(parameter_tvb, (guint8 *)&ipv4_address, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH);
700 proto_tree_add_ipv4(parameter_tree, hf_sctp_parameter_ipv4_address,
701 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH,
703 proto_item_set_text(parameter_item, "IPV4 address parameter");
707 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
709 proto_tree_add_ipv6(parameter_tree, hf_sctp_parameter_ipv6_address,
710 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH,
711 tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH));
713 proto_item_set_text(parameter_item, "IPV6 address parameter");
717 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
719 guint16 length, state_cookie_length;
721 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
723 state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
725 proto_tree_add_text(parameter_tree, parameter_tvb, STATE_COOKIE_PARAMETER_COOKIE_OFFSET, state_cookie_length,
726 "State cookie (%u byte%s)",
727 state_cookie_length, plurality(state_cookie_length, "", "s"));
729 proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
730 state_cookie_length, plurality(state_cookie_length, "", "s"));
734 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
736 guint16 length, padding_length, parameter_value_length, unrecognized_parameter_type;
737 tvbuff_t *unrecognized_parameters_tvb;
739 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
740 padding_length = nr_of_padding_bytes(length);
742 parameter_value_length = length - PARAMETER_HEADER_LENGTH + padding_length;
744 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
745 parameter_value_length, parameter_value_length);
746 unrecognized_parameter_type = tvb_get_ntohs(unrecognized_parameters_tvb, PARAMETER_TYPE_OFFSET);
747 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, parameter_tree);
749 proto_item_set_text(parameter_item, "Unrecognized parameter of type %s (0x%x)",
750 val_to_str(unrecognized_parameter_type, sctp_parameter_identifier_values, "unknown"), unrecognized_parameter_type);
754 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
758 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
760 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
761 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
762 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
765 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
770 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
772 guint16 length, hostname_length;
775 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
777 hostname_length = length - PARAMETER_HEADER_LENGTH;
778 hostname = (char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
779 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
780 PARAMETER_VALUE_OFFSET, hostname_length,
783 proto_item_set_text(parameter_item, "Hostname parameter");
787 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
789 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
791 proto_item *address_list_item;
792 proto_tree *address_list_tree;
794 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
795 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
796 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
798 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
799 "Supported Address Types (%u address type%s)",
800 number_of_address_types, plurality(number_of_address_types, "", "s"));
801 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
803 offset = PARAMETER_VALUE_OFFSET;
804 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
805 address_type = tvb_get_ntohs(parameter_tvb, offset);
806 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
807 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
808 address_type, "Supported address type: 0x%04x (%s)",
809 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
810 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
813 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
814 number_of_address_types, plurality(number_of_address_types, "", "s"));
818 dissect_ecn_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
820 proto_item_set_text(parameter_item, "ECN parameter");
823 #define USTREAMS_START_LENGTH 2
824 #define USTREAMS_END_LENGTH 2
825 #define USTREAMS_INTERVAL_LENGTH (USTREAMS_START_LENGTH + USTREAMS_END_LENGTH)
828 dissect_unreliable_streams_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
830 guint16 length, start, end, number_of_intervals, interval_number;
831 proto_item *interval_item;
832 proto_tree *interval_tree;
833 gint interval_offset;
835 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
836 number_of_intervals = (length - PARAMETER_HEADER_LENGTH) / USTREAMS_INTERVAL_LENGTH;
838 interval_offset = PARAMETER_VALUE_OFFSET;
839 for(interval_number = 1; interval_number <= number_of_intervals; interval_number++) {
840 start = tvb_get_ntohs(parameter_tvb, interval_offset);
841 end = tvb_get_ntohs(parameter_tvb, interval_offset + USTREAMS_START_LENGTH);
842 interval_item = proto_tree_add_text(parameter_tree, parameter_tvb, interval_offset, USTREAMS_INTERVAL_LENGTH, "Unreliable streams (%u-%u)", start, end);
843 interval_tree = proto_item_add_subtree(interval_item, ett_sctp_unreliable_streams_interval);
844 proto_tree_add_uint(interval_tree, hf_sctp_ustreams_start, parameter_tvb, interval_offset, USTREAMS_START_LENGTH, start);
845 proto_tree_add_uint(interval_tree, hf_sctp_ustreams_end, parameter_tvb, interval_offset + USTREAMS_START_LENGTH, USTREAMS_END_LENGTH, end);
846 interval_offset += USTREAMS_INTERVAL_LENGTH;
848 proto_item_set_text(parameter_item, "Unreliable streams parameter");
852 dissect_add_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
854 guint16 length, parameter_value_length;
855 tvbuff_t *address_tvb;
857 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
858 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
860 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
861 dissect_parameter(address_tvb, pinfo, parameter_tree);
863 proto_item_set_text(parameter_item, "Add IP address parameter");
867 dissect_del_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
869 guint16 length, parameter_value_length;
870 tvbuff_t *address_tvb;
872 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
873 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
875 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
876 dissect_parameter(address_tvb, pinfo, parameter_tree);
878 proto_item_set_text(parameter_item, "Delete IP address parameter");
882 dissect_error_cause_indication_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
884 guint16 length, padding_length, total_length;
886 tvbuff_t *error_cause_tvb;
888 offset = PARAMETER_VALUE_OFFSET;
889 while(tvb_reported_length_remaining(parameter_tvb, offset)) {
890 length = tvb_get_ntohs(parameter_tvb, offset + CAUSE_LENGTH_OFFSET);
891 padding_length = nr_of_padding_bytes(length);
892 total_length = length + padding_length;
893 /* create a tvb for the chunk including the padding bytes */
894 error_cause_tvb = tvb_new_subset(parameter_tvb, offset , total_length, total_length);
895 dissect_error_cause(error_cause_tvb, pinfo, parameter_tree);
896 /* get rid of the handled parameter */
897 offset += total_length;
899 proto_item_set_text(parameter_item, "Error cause indication");
903 dissect_set_primary_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
905 guint16 length, parameter_value_length;
906 tvbuff_t *address_tvb;
908 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
909 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
911 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
912 dissect_parameter(address_tvb, pinfo, parameter_tree);
914 proto_item_set_text(parameter_item, "Set primary address parameter");
918 dissect_success_report_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
920 proto_item_set_text(parameter_item, "Success report parameter");
923 #define ADAP_INDICATION_LENGTH 4
924 #define ADAP_INDICATION_OFFSET PARAMETER_VALUE_OFFSET
927 dissect_adap_indication_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
931 indication = tvb_get_ntohl(parameter_tvb, ADAP_INDICATION_OFFSET);
932 proto_tree_add_uint(parameter_tree, hf_sctp_adap_indication, parameter_tvb, ADAP_INDICATION_OFFSET, ADAP_INDICATION_LENGTH, indication);
933 proto_item_set_text(parameter_item, "Adaptation layer indication");
937 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
939 guint16 type, length, parameter_value_length;
941 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
942 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
944 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
946 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
947 "Parameter value (%u byte%s)",
948 parameter_value_length, plurality(parameter_value_length, "", "s"));
950 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
951 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
955 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *chunk_tree)
957 guint16 type, length, padding_length, total_length;
958 proto_item *parameter_item;
959 proto_tree *parameter_tree;
961 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
962 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
963 padding_length = nr_of_padding_bytes(length);
964 total_length = length + padding_length;
966 parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb,
967 PARAMETER_HEADER_OFFSET, total_length, "%s parameter",
968 val_to_str(type, sctp_parameter_identifier_values, "Unknown"));
969 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
971 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_type,
972 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
974 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
975 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
979 case HEARTBEAT_INFO_PARAMETER_ID:
980 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
982 case IPV4ADDRESS_PARAMETER_ID:
983 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
985 case IPV6ADDRESS_PARAMETER_ID:
986 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
988 case STATE_COOKIE_PARAMETER_ID:
989 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
991 case UNREC_PARA_PARAMETER_ID:
992 dissect_unrecognized_parameters_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
994 case COOKIE_PRESERVATIVE_PARAMETER_ID:
995 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
997 case HOSTNAME_ADDRESS_PARAMETER_ID:
998 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
1000 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
1001 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
1003 case ECN_PARAMETER_ID:
1004 dissect_ecn_parameter(parameter_tvb, parameter_tree, parameter_item);
1006 case UNRELIABLE_STREAMS_PARAMETER_ID:
1007 dissect_unreliable_streams_parameter(parameter_tvb, parameter_tree, parameter_item);
1009 case ADD_IP_ADDRESS_PARAMETER_ID:
1010 dissect_add_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1012 case DEL_IP_ADDRESS_PARAMETER_ID:
1013 dissect_del_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1015 case ERROR_CAUSE_INDICATION_PARAMETER_ID:
1016 dissect_error_cause_indication_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1018 case SET_PRIMARY_ADDRESS_PARAMETER_ID:
1019 dissect_set_primary_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1021 case SUCCESS_REPORT_PARAMETER_ID:
1022 dissect_success_report_parameter(parameter_tvb, parameter_tree, parameter_item);
1024 case ADAP_LAYER_INDICATION_PARAMETER_ID:
1025 dissect_adap_indication_parameter(parameter_tvb, parameter_tree, parameter_item);
1028 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1031 if ((padding_length > 0) && (type != UNREC_PARA_PARAMETER_ID))
1032 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
1033 "Padding: %u byte%s",
1034 padding_length, plurality(padding_length, "", "s"));
1038 * Code to handle error causes for ABORT and ERROR chunks
1041 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1043 guint16 stream_identifier;
1045 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
1046 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
1047 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
1049 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
1050 "Reserved (2 bytes)");
1052 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
1057 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1059 guint32 number_of_missing_parameters, missing_parameter_number;
1060 guint16 parameter_type;
1063 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
1064 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
1065 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
1066 number_of_missing_parameters);
1067 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
1068 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
1069 parameter_type = tvb_get_ntohs(cause_tvb, offset);
1070 proto_tree_add_uint(cause_tree, hf_sctp_cause_missing_parameter_type,
1071 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
1073 offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
1076 proto_item_set_text(cause_item, "Error cause reporting %u missing mandatory parameter%s",
1077 number_of_missing_parameters, plurality(number_of_missing_parameters, "", "s") );
1081 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1083 guint32 measure_of_staleness;
1085 measure_of_staleness = tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
1087 proto_tree_add_uint(cause_tree, hf_sctp_cause_measure_of_staleness, cause_tvb,
1088 CAUSE_MEASURE_OF_STALENESS_OFFSET,
1089 CAUSE_MEASURE_OF_STALENESS_LENGTH,
1090 measure_of_staleness);
1092 proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
1093 measure_of_staleness);
1097 dissect_out_of_resource_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1099 proto_item_set_text(cause_item, "Error cause reporting lack of resources");
1103 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1105 guint16 code, length, parameter_length, parameter_type;
1106 tvbuff_t *parameter_tvb;
1108 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1109 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1111 parameter_length = length - CAUSE_HEADER_LENGTH;
1112 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
1113 parameter_length, parameter_length);
1115 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1116 parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
1118 proto_item_set_text(cause_item, "Error cause reporting unresolvable address of type 0x%04x (%s)",
1119 parameter_type, val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown") );
1123 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo,
1124 proto_tree *cause_tree, proto_item *cause_item)
1126 guint16 length, chunk_length;
1127 guint8 unrecognized_type;
1128 tvbuff_t *unrecognized_chunk_tvb;
1130 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1132 chunk_length = length - CAUSE_HEADER_LENGTH;
1134 unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, chunk_length, chunk_length);
1135 dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree);
1137 unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
1139 proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
1141 val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
1145 dissect_invalid_mandatory_parameter_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1147 proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
1151 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1153 guint16 length, padding_length, cause_info_length;
1154 tvbuff_t *unrecognized_parameters_tvb;
1156 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1157 padding_length = nr_of_padding_bytes(length);
1158 cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
1160 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1161 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, cause_tree);
1163 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
1167 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1171 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
1172 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
1177 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
1182 dissect_cookie_received_while_shutting_down_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1184 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
1188 dissect_delete_last_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1190 guint16 length, cause_info_length;
1191 tvbuff_t *parameter_tvb;
1193 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1194 cause_info_length = length - CAUSE_HEADER_LENGTH;
1195 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1196 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1197 proto_item_set_text(cause_item, "Delete last address cause");
1201 dissect_resource_outage_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1203 guint16 length, cause_info_length;
1204 tvbuff_t *parameter_tvb;
1206 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1207 cause_info_length = length - CAUSE_HEADER_LENGTH;
1208 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1209 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1210 proto_item_set_text(cause_item, "Operation refused due to resource shortage");
1214 dissect_delete_source_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1216 guint16 length, cause_info_length;
1217 tvbuff_t *parameter_tvb;
1219 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1220 cause_info_length = length - CAUSE_HEADER_LENGTH;
1221 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1222 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1223 proto_item_set_text(cause_item, "Delete source address cause");
1227 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1229 guint16 code, length, cause_info_length;
1231 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1232 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1234 cause_info_length = length - CAUSE_HEADER_LENGTH;
1236 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
1237 "Cause specific information (%u byte%s)",
1238 cause_info_length, plurality(cause_info_length, "", "s"));
1240 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
1241 code, cause_info_length, plurality(cause_info_length, "", "s"));
1245 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
1247 guint16 code, length, padding_length, total_length;
1248 proto_item *cause_item;
1249 proto_tree *cause_tree;
1251 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1252 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1253 padding_length = nr_of_padding_bytes(length);
1254 total_length = length + padding_length;
1256 cause_item = proto_tree_add_text(chunk_tree, cause_tvb,
1257 CAUSE_HEADER_OFFSET, total_length,
1259 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
1261 proto_tree_add_uint(cause_tree, hf_sctp_cause_code,
1262 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
1264 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
1265 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
1269 case INVALID_STREAM_IDENTIFIER:
1270 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
1272 case MISSING_MANDATORY_PARAMETERS:
1273 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
1275 case STALE_COOKIE_ERROR:
1276 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
1278 case OUT_OF_RESOURCE:
1279 dissect_out_of_resource_cause(cause_tvb, cause_tree, cause_item);
1281 case UNRESOLVABLE_ADDRESS:
1282 dissect_unresolvable_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1284 case UNRECOGNIZED_CHUNK_TYPE:
1285 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
1287 case INVALID_MANDATORY_PARAMETER:
1288 dissect_invalid_mandatory_parameter_cause(cause_tvb, cause_tree, cause_item);
1290 case UNRECOGNIZED_PARAMETERS:
1291 dissect_unrecognized_parameters_cause(cause_tvb, pinfo, cause_tree, cause_item);
1294 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
1296 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
1297 dissect_cookie_received_while_shutting_down_cause(cause_tvb, cause_tree, cause_item);
1299 case REQUEST_TO_DELETE_LAST_ADDRESS:
1300 dissect_delete_last_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1302 case OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE:
1303 dissect_resource_outage_cause(cause_tvb, pinfo, cause_tree, cause_item);
1305 case REQUEST_TO_DELETE_SOURCE_ADDRESS:
1306 dissect_delete_source_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1309 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
1312 if ((padding_length > 0) && (code != UNRECOGNIZED_PARAMETERS))
1313 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
1314 "Padding: %u byte%s",
1315 padding_length, plurality(padding_length, "", "s"));
1319 * Code to actually dissect the packets
1323 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
1324 proto_tree *chunk_tree, guint32 ppi, guint16 payload_length, guint16 padding_length)
1326 /* do lookup with the subdissector table */
1327 if (dissector_try_port (sctp_ppi_dissector_table, ppi, payload_tvb, pinfo, tree) ||
1328 dissector_try_port(sctp_port_dissector_table, pinfo->srcport, payload_tvb, pinfo, tree) ||
1329 dissector_try_port(sctp_port_dissector_table, pinfo->destport, payload_tvb, pinfo, tree)){
1333 if (check_col(pinfo->cinfo, COL_INFO))
1334 col_append_str(pinfo->cinfo, COL_INFO, "DATA ");
1335 proto_tree_add_text(chunk_tree, payload_tvb, 0, payload_length,
1336 "Payload (%u byte%s)",
1337 payload_length, plurality(payload_length, "", "s"));
1338 if (padding_length > 0)
1339 proto_tree_add_text(chunk_tree, payload_tvb, payload_length, padding_length,
1340 "Padding: %u byte%s",
1341 padding_length, plurality(padding_length, "", "s"));
1347 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1348 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1351 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
1352 guint32 tsn, payload_proto_id;
1353 proto_tree *flag_tree;
1354 tvbuff_t *payload_tvb;
1356 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1357 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1358 padding_length = nr_of_padding_bytes(length);
1359 total_payload_length = payload_length + padding_length;
1360 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1361 total_payload_length, total_payload_length);
1362 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1365 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1367 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1368 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
1369 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1370 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1371 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1372 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1373 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1375 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1376 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1377 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1379 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1381 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1383 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1385 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1387 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1389 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1391 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1392 chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1394 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1395 tsn, stream_id, stream_seq_number,
1396 payload_length, plurality(payload_length, "", "s"));
1398 return dissect_payload(payload_tvb, pinfo, tree, chunk_tree, payload_proto_id, payload_length, padding_length);
1402 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1403 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1405 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1406 guint16 number_of_inbound_streams, number_of_outbound_streams;
1408 tvbuff_t *parameter_list_tvb;
1410 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1412 if (check_col(pinfo->cinfo, COL_INFO)) {
1413 if (type == SCTP_INIT_CHUNK_ID) {
1414 col_append_str(pinfo->cinfo, COL_INFO, "INIT ");
1416 col_append_str(pinfo->cinfo, COL_INFO, "INIT_ACK ");
1421 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1422 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1423 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1424 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1425 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1427 /* handle fixed parameters */
1428 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1430 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1432 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1434 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1435 adv_rec_window_credit);
1436 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1438 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1439 number_of_outbound_streams);
1440 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1442 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1443 number_of_inbound_streams);
1444 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1446 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1449 /* handle variable paramters */
1450 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1451 dissect_tlv_parameter_list(parameter_list_tvb, pinfo, chunk_tree);
1453 proto_item_set_text(chunk_item,
1454 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1455 val_to_str(type, sctp_chunk_type_values, "unknown"),
1456 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1457 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1462 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1463 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1465 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1469 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1470 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1472 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1473 guint16 number_of_gap_blocks, number_of_dup_tsns;
1474 guint16 gap_block_number, dup_tsn_number, start, end;
1475 gint gap_block_offset, dup_tsn_offset;
1476 proto_item *block_item;
1477 proto_tree *block_tree;
1479 if (check_col(pinfo->cinfo, COL_INFO))
1480 col_append_str(pinfo->cinfo, COL_INFO, "SACK ");
1483 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1484 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1485 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1486 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1488 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1490 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1491 cumulative_tsn_ack);
1492 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1494 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1495 adv_rec_window_credit);
1496 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1498 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1499 number_of_gap_blocks);
1500 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1502 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1503 number_of_dup_tsns);
1505 /* handle the gap acknowledgement blocks */
1506 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1507 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1508 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1509 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1510 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1511 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1512 "Gap Acknowledgement for %u TSN%s",
1513 1 + end - start, plurality(1 + end - start, "", "s"));
1514 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1515 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1517 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1519 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1521 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1522 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1524 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1527 /* handle the duplicate TSNs */
1528 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1529 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1530 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1531 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1533 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1535 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1538 proto_item_set_text(chunk_item,
1539 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1541 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1542 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1547 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1548 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1550 tvbuff_t *parameter_tvb;
1551 guint chunk_length, info_length, padding_length, total_length;
1553 if (check_col(pinfo->cinfo, COL_INFO))
1554 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT ");
1557 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1558 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1559 padding_length = nr_of_padding_bytes(info_length);
1560 total_length = info_length + padding_length;
1561 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1563 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1565 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1570 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1571 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1573 tvbuff_t *parameter_tvb;
1574 guint chunk_length, info_length, padding_length, total_length;
1576 if (check_col(pinfo->cinfo, COL_INFO))
1577 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT_ACK ");
1580 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1581 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1582 padding_length = nr_of_padding_bytes(info_length);
1583 total_length = info_length + padding_length;
1585 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1587 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1589 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1594 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1595 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1597 guint offset, number_of_causes;
1598 guint16 length, padding_length, total_length;
1599 tvbuff_t *cause_tvb;
1601 if (check_col(pinfo->cinfo, COL_INFO))
1602 col_append_str(pinfo->cinfo, COL_INFO, "ABORT ");
1605 number_of_causes = 0;
1606 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1607 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1608 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1609 padding_length = nr_of_padding_bytes(length);
1610 total_length = length + padding_length;
1611 /* create a tvb for the chunk including the padding bytes */
1612 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1613 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1614 /* get rid of the handled parameter */
1615 offset += total_length;
1619 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s",
1620 number_of_causes, plurality(number_of_causes, "", "s"));
1625 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1626 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1628 guint32 cumulative_tsn_ack;
1630 if (check_col(pinfo->cinfo, COL_INFO))
1631 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN ");
1634 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1635 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1637 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1638 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1639 cumulative_tsn_ack);
1641 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1642 cumulative_tsn_ack);
1647 dissect_shutdown_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1648 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1650 if (check_col(pinfo->cinfo, COL_INFO))
1651 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_ACK ");
1654 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1659 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1660 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1662 guint offset, number_of_causes;
1663 guint16 length, padding_length, total_length;
1664 tvbuff_t *cause_tvb;
1666 if (check_col(pinfo->cinfo, COL_INFO))
1667 col_append_str(pinfo->cinfo, COL_INFO, "ERROR ");
1670 number_of_causes = 0;
1671 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1673 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1674 padding_length = nr_of_padding_bytes(length);
1675 total_length = length + padding_length;
1676 /* create a tvb for the chunk including the padding bytes */
1677 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1678 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1679 /* get rid of the handled parameter */
1680 offset += total_length;
1682 } while(tvb_reported_length_remaining(chunk_tvb, offset));
1684 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1685 number_of_causes, plurality(number_of_causes, "", "s"));
1690 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1691 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1693 guint length, cookie_length, padding_length;
1695 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1696 padding_length = nr_of_padding_bytes(length);
1697 cookie_length = length - CHUNK_HEADER_LENGTH;
1699 if (check_col(pinfo->cinfo, COL_INFO))
1700 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ECHO ");
1703 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1704 "Cookie (%u byte%s)",
1705 cookie_length, plurality(cookie_length, "", "s"));
1706 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1707 cookie_length, plurality(cookie_length, "", "s"));
1709 if (padding_length > 0)
1710 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1711 "Padding: %u byte%s",
1712 padding_length, plurality(padding_length, "", "s"));
1717 dissect_cookie_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1718 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1720 if (check_col(pinfo->cinfo, COL_INFO))
1721 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ACK ");
1724 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1729 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1730 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1734 if (check_col(pinfo->cinfo, COL_INFO))
1735 col_append_str(pinfo->cinfo, COL_INFO, "ECNE ");
1738 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1739 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1741 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1744 proto_item_set_text(chunk_item, "ECNE chunk");
1749 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1750 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1754 if (check_col(pinfo->cinfo, COL_INFO))
1755 col_append_str(pinfo->cinfo, COL_INFO, "CWR ");
1758 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1759 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1761 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1764 proto_item_set_text(chunk_item, "CWR chunk");
1769 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1770 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1774 proto_tree *flag_tree;
1776 if (check_col(pinfo->cinfo, COL_INFO))
1777 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_COMPLETE ");
1780 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1781 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1783 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1784 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1785 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1787 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1791 #define FORWARD_TSN_CHUNK_TSN_OFFSET CHUNK_VALUE_OFFSET
1792 #define FORWARD_TSN_CHUNK_TSN_LENGTH 4
1795 dissect_forward_tsn_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1799 if (check_col(pinfo->cinfo, COL_INFO))
1800 col_append_str(pinfo->cinfo, COL_INFO, "FORWARD TSN ");
1803 tsn = tvb_get_ntohl(chunk_tvb, FORWARD_TSN_CHUNK_TSN_OFFSET);
1804 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);
1805 proto_item_set_text(chunk_item, "FORWARD TSN chunk (new cumulative TSN %u)", tsn);
1809 #define SERIAL_NUMBER_LENGTH 4
1810 #define CORRELATION_ID_LENGTH 4
1811 #define ASCONF_RESERVED_LENGTH 3
1812 #define ASCONF_ADDR_TYPE_LENGTH 1
1813 #define ASCONF_ADDR_LENGTH 16
1814 #define SERIAL_NUMBER_OFFSET PARAMETER_VALUE_OFFSET
1816 #define IP_V4_ADDRESS_TYPE 5
1817 #define IP_V6_ADDRESS_TYPE 6
1819 static const value_string sctp_address_type_values[] = {
1820 { IP_V4_ADDRESS_TYPE, "IP V4 address" },
1821 { IP_V6_ADDRESS_TYPE, "IP V6 address" },
1825 dissect_asconf_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1827 guint32 serial_number, correlation_id, ipv4_address;
1828 guint offset, length, padding_length, total_length;
1830 tvbuff_t *parameter_tvb;
1832 if (check_col(pinfo->cinfo, COL_INFO))
1833 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF ");
1836 offset = SERIAL_NUMBER_OFFSET;
1837 serial_number = tvb_get_ntohl(chunk_tvb, offset);
1838 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_serial, chunk_tvb, offset, SERIAL_NUMBER_LENGTH, serial_number);
1839 offset += SERIAL_NUMBER_LENGTH;
1840 proto_tree_add_bytes(chunk_tree, hf_sctp_asconf_reserved, chunk_tvb, offset, ASCONF_RESERVED_LENGTH, tvb_get_ptr(chunk_tvb, offset, ASCONF_RESERVED_LENGTH));
1841 offset += ASCONF_RESERVED_LENGTH;
1842 addr_type = tvb_get_guint8(chunk_tvb, offset);
1843 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_addr_type, chunk_tvb, offset, ASCONF_ADDR_TYPE_LENGTH, addr_type);
1844 offset += ASCONF_ADDR_TYPE_LENGTH;
1845 switch (addr_type) {
1846 case IP_V4_ADDRESS_TYPE:
1847 tvb_memcpy(chunk_tvb, (guint8 *)&ipv4_address, offset, IPV4_ADDRESS_LENGTH);
1848 proto_tree_add_ipv4(chunk_tree, hf_sctp_asconf_ipv4_address, chunk_tvb, offset, IPV4_ADDRESS_LENGTH, ipv4_address);
1849 proto_tree_add_bytes(chunk_tree, hf_sctp_asconf_addr, chunk_tvb, offset + IPV4_ADDRESS_LENGTH, ASCONF_ADDR_LENGTH - IPV4_ADDRESS_LENGTH,
1850 tvb_get_ptr(chunk_tvb, offset + IPV4_ADDRESS_LENGTH, ASCONF_ADDR_LENGTH - IPV4_ADDRESS_LENGTH));
1852 case IP_V6_ADDRESS_TYPE:
1853 proto_tree_add_ipv6(chunk_tree, hf_sctp_asconf_ipv6_address, chunk_tvb, offset, IPV6_ADDRESS_LENGTH,
1854 tvb_get_ptr(chunk_tvb, offset, IPV6_ADDRESS_LENGTH));
1857 proto_tree_add_bytes(chunk_tree, hf_sctp_asconf_addr, chunk_tvb, offset, ASCONF_ADDR_LENGTH, tvb_get_ptr(chunk_tvb, offset, ASCONF_ADDR_LENGTH));
1860 offset += ASCONF_ADDR_LENGTH;
1861 proto_item_set_text(chunk_item, "ASCONF chunk");
1863 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1864 correlation_id = tvb_get_ntohl(chunk_tvb, offset);
1865 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_correlation_id, chunk_tvb, offset, CORRELATION_ID_LENGTH, correlation_id);
1866 offset += CORRELATION_ID_LENGTH;
1867 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1868 padding_length = nr_of_padding_bytes(length);
1869 total_length = length + padding_length;
1870 /* create a tvb for the chunk including the padding bytes */
1871 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1872 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1873 /* get rid of the handled parameter */
1874 offset += total_length;
1880 dissect_asconf_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1882 guint32 serial_number, correlation_id;
1883 guint offset, length, padding_length, total_length;
1884 tvbuff_t *parameter_tvb;
1886 if (check_col(pinfo->cinfo, COL_INFO))
1887 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF-ACK ");
1890 serial_number = tvb_get_ntohl(chunk_tvb, SERIAL_NUMBER_OFFSET);
1891 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_serial, chunk_tvb, SERIAL_NUMBER_OFFSET, SERIAL_NUMBER_LENGTH, serial_number);
1892 proto_item_set_text(chunk_item, "ASCONF-ACK chunk");
1894 offset = SERIAL_NUMBER_OFFSET + SERIAL_NUMBER_LENGTH;
1895 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1896 correlation_id = tvb_get_ntohl(chunk_tvb, offset);
1897 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_correlation_id, chunk_tvb, offset, CORRELATION_ID_LENGTH, correlation_id);
1898 offset += CORRELATION_ID_LENGTH;
1899 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1900 padding_length = nr_of_padding_bytes(length);
1901 total_length = length + padding_length;
1902 /* create a tvb for the chunk including the padding bytes */
1903 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1904 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1905 /* get rid of the handled parameter */
1906 offset += total_length;
1912 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1913 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1915 guint length, chunk_value_length, padding_length;
1918 if (check_col(pinfo->cinfo, COL_INFO))
1919 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN ");
1922 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1923 padding_length = nr_of_padding_bytes(length);
1924 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1926 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1928 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1929 "Chunk value (%u byte%s)",
1930 chunk_value_length, plurality(chunk_value_length, "", "s"));
1932 if (padding_length > 0)
1933 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1934 "Padding: %u byte%s",
1935 padding_length, plurality(padding_length, "", "s"));
1937 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1938 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1944 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1949 proto_item *flags_item;
1950 proto_item *chunk_item;
1951 proto_tree *chunk_tree;
1955 /* first extract the chunk header */
1956 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1957 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1958 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1961 /* create proto_tree stuff */
1962 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb, CHUNK_HEADER_OFFSET, -1, "Incomplete chunk");
1963 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
1965 /* then insert the chunk header components into the protocol tree */
1966 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_type, chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH, type);
1967 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1968 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length, chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH, length);
1975 /* now dissect the chunk value */
1978 case SCTP_DATA_CHUNK_ID:
1979 result = dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1981 case SCTP_INIT_CHUNK_ID:
1982 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1984 case SCTP_INIT_ACK_CHUNK_ID:
1985 dissect_init_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1987 case SCTP_SACK_CHUNK_ID:
1988 dissect_sack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1990 case SCTP_HEARTBEAT_CHUNK_ID:
1991 dissect_heartbeat_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1993 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1994 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1996 case SCTP_ABORT_CHUNK_ID:
1997 dissect_abort_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1999 case SCTP_SHUTDOWN_CHUNK_ID:
2000 dissect_shutdown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2002 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
2003 dissect_shutdown_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2005 case SCTP_ERROR_CHUNK_ID:
2006 dissect_error_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2008 case SCTP_COOKIE_ECHO_CHUNK_ID:
2009 dissect_cookie_echo_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2011 case SCTP_COOKIE_ACK_CHUNK_ID:
2012 dissect_cookie_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2014 case SCTP_ECNE_CHUNK_ID:
2015 dissect_ecne_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2017 case SCTP_CWR_CHUNK_ID:
2018 dissect_cwr_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2020 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
2021 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2023 case SCTP_FORWARD_TSN_CHUNK_ID:
2024 dissect_forward_tsn_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2026 case SCTP_ASCONF_ACK_CHUNK_ID:
2027 dissect_asconf_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2029 case SCTP_ASCONF_CHUNK_ID:
2030 dissect_asconf_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2033 dissect_unknown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2040 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *sctp_item, proto_tree *sctp_tree)
2042 tvbuff_t *chunk_tvb;
2043 guint16 length, padding_length, total_length;
2044 gint last_offset, offset;
2045 gboolean sctp_item_length_set;
2047 /* the common header of the datagram is already handled */
2049 offset = COMMON_HEADER_LENGTH;
2050 sctp_item_length_set = FALSE;
2052 while(tvb_reported_length_remaining(tvb, offset) > 0) {
2053 /* extract the chunk length and compute number of padding bytes */
2054 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
2055 padding_length = nr_of_padding_bytes(length);
2056 total_length = length + padding_length;
2057 /* create a tvb for the chunk including the padding bytes */
2058 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
2059 /* call dissect_sctp_chunk for a actual work */
2060 if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree) && (tree)) {
2061 proto_item_set_len(sctp_item, offset - last_offset + DATA_CHUNK_HEADER_LENGTH);
2062 sctp_item_length_set = TRUE;
2063 offset += total_length;
2064 last_offset = offset;
2065 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2066 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, offset, -1, FALSE);
2067 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2068 sctp_item_length_set = FALSE;
2071 /* get rid of the dissected chunk */
2072 offset += total_length;
2075 if (!sctp_item_length_set && (tree)) {
2076 proto_item_set_len(sctp_item, offset - last_offset);
2080 /* dissect_sctp handles the common header of a SCTP datagram.
2081 * For the handling of the chunks dissect_sctp_chunks is called.
2085 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2087 guint16 source_port, destination_port;
2088 guint32 verification_tag, checksum, calculated_crc32c, calculated_adler32;
2090 gboolean crc32c_correct, adler32_correct;
2091 proto_item *sctp_item;
2092 proto_tree *sctp_tree;
2094 /* Extract the common header */
2095 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
2096 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
2097 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
2098 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
2100 /* update pi structure */
2101 pinfo->ptype = PT_SCTP;
2102 pinfo->srcport = source_port;
2103 pinfo->destport = destination_port;
2105 /* make entry in the Protocol column on summary display */
2106 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2107 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCTP");
2109 /* Clear entries in Info column on summary display */
2110 if (check_col(pinfo->cinfo, COL_INFO))
2111 col_add_str(pinfo->cinfo, COL_INFO, "");
2113 /* In the interest of speed, if "tree" is NULL, don't do any work not
2114 necessary to generate protocol tree items. */
2116 /* create the sctp protocol tree */
2117 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, 0, -1, FALSE);
2118 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2120 /* add the components of the common header to the protocol tree */
2121 proto_tree_add_uint(sctp_tree, hf_sctp_source_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2122 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2123 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag, tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH, verification_tag);
2124 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2125 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2127 length = tvb_length(tvb);
2128 switch(sctp_checksum) {
2129 case SCTP_CHECKSUM_NONE:
2130 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum, "Checksum: 0x%08x (not verified)", checksum);
2132 case SCTP_CHECKSUM_ADLER32:
2133 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2134 adler32_correct = (checksum == calculated_adler32);
2135 if (adler32_correct)
2136 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2137 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2139 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2140 checksum, "Checksum: 0x%08x (incorrect Adler32, should be 0x%08x)", checksum, calculated_adler32);
2141 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(adler32_correct));
2143 case SCTP_CHECKSUM_CRC32C:
2144 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2145 crc32c_correct = (checksum == calculated_crc32c);
2147 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2148 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2150 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2151 checksum, "Checksum: 0x%08x (incorrect CRC32C, should be 0x%08x)", checksum, calculated_crc32c);
2152 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct));
2154 case SCTP_CHECKSUM_AUTOMATIC:
2155 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2156 adler32_correct = (checksum == calculated_adler32);
2157 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2158 crc32c_correct = (checksum == calculated_crc32c);
2159 if ((adler32_correct) && !(crc32c_correct))
2160 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2161 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2162 else if (!(adler32_correct) && (crc32c_correct))
2163 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2164 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2165 else if ((adler32_correct) && (crc32c_correct))
2166 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2167 checksum, "Checksum: 0x%08x (correct Adler32 and CRC32C)", checksum);
2169 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2170 checksum, "Checksum: 0x%08x (incorrect, should be 0x%08x (Adler32) or 0x%08x (CRC32C))",
2171 checksum, calculated_adler32, calculated_crc32c);
2172 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct || adler32_correct));
2179 /* add all chunks of the sctp datagram to the protocol tree */
2180 dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree);
2183 /* Register the protocol with Ethereal */
2185 proto_register_sctp(void)
2188 /* Setup list of header fields */
2189 static hf_register_info hf[] = {
2190 { &hf_sctp_source_port,
2191 { "Source port", "sctp.srcport",
2192 FT_UINT16, BASE_DEC, NULL, 0x0,
2195 { &hf_sctp_destination_port,
2196 { "Destination port", "sctp.dstport",
2197 FT_UINT16, BASE_DEC, NULL, 0x0,
2201 { "Port", "sctp.port",
2202 FT_UINT16, BASE_DEC, NULL, 0x0,
2205 { &hf_sctp_verification_tag,
2206 { "Verification tag", "sctp.verfication_tag",
2207 FT_UINT32, BASE_HEX, NULL, 0x0,
2210 { &hf_sctp_checksum,
2211 { "Checksum", "sctp.checksum",
2212 FT_UINT32, BASE_HEX, NULL, 0x0,
2215 { &hf_sctp_checksum_bad,
2216 { "Bad checksum", "sctp.checksum_bad",
2217 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2220 { &hf_sctp_chunk_type,
2221 { "Identifier", "sctp.chunk_type",
2222 FT_UINT8, BASE_DEC, VALS(sctp_chunk_type_values), 0x0,
2225 { &hf_sctp_chunk_flags,
2226 { "Flags", "sctp.chunk_flags",
2227 FT_UINT8, BASE_BIN, NULL, 0x0,
2230 { &hf_sctp_chunk_length,
2231 { "Length", "sctp.chunk_length",
2232 FT_UINT16, BASE_DEC, NULL, 0x0,
2235 { &hf_sctp_init_chunk_initiate_tag,
2236 { "Initiate tag", "sctp.init.chunk.initiate.tag",
2237 FT_UINT32, BASE_HEX, NULL, 0x0,
2240 { &hf_sctp_init_chunk_adv_rec_window_credit,
2241 { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
2242 FT_UINT32, BASE_DEC, NULL, 0x0,
2245 { &hf_sctp_init_chunk_number_of_outbound_streams,
2246 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
2247 FT_UINT16, BASE_DEC, NULL, 0x0,
2250 { &hf_sctp_init_chunk_number_of_inbound_streams,
2251 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
2252 FT_UINT16, BASE_DEC, NULL, 0x0,
2255 {&hf_sctp_init_chunk_initial_tsn,
2256 { "Initial TSN", "sctp.init.chunk.initial.tsn",
2257 FT_UINT32, BASE_DEC, NULL, 0x0,
2260 {&hf_sctp_cumulative_tsn_ack,
2261 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
2262 FT_UINT32, BASE_DEC, NULL, 0x0,
2265 {&hf_sctp_data_chunk_tsn,
2266 { "TSN", "sctp.tsn",
2267 FT_UINT32, BASE_DEC, NULL, 0x0,
2270 {&hf_sctp_data_chunk_stream_id,
2271 { "Stream Identifier", "sctp.stream_id",
2272 FT_UINT16, BASE_HEX, NULL, 0x0,
2275 {&hf_sctp_data_chunk_stream_seq_number,
2276 { "Stream sequence number", "sctp.stream_seq_number",
2277 FT_UINT16, BASE_DEC, NULL, 0x0,
2280 {&hf_sctp_data_chunk_payload_proto_id,
2281 { "Payload protocol identifier", "sctp.payload_proto_id",
2282 FT_UINT32, BASE_DEC, VALS(sctp_payload_proto_id_values), 0x0,
2285 {&hf_sctp_data_chunk_e_bit,
2286 { "E-Bit", "sctp.data.e_bit",
2287 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
2290 {&hf_sctp_data_chunk_b_bit,
2291 { "B-Bit", "sctp.data.b_bit",
2292 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
2295 {&hf_sctp_data_chunk_u_bit,
2296 { "U-Bit", "sctp.data.u.bit",
2297 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
2300 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
2301 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
2302 FT_UINT32, BASE_DEC, NULL, 0x0,
2305 {&hf_sctp_sack_chunk_adv_rec_window_credit,
2306 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
2307 FT_UINT32, BASE_DEC, NULL, 0x0,
2310 {&hf_sctp_sack_chunk_number_of_gap_blocks,
2311 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
2312 FT_UINT16, BASE_DEC, NULL, 0x0,
2315 {&hf_sctp_sack_chunk_number_of_dup_tsns,
2316 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
2317 FT_UINT16, BASE_DEC, NULL, 0x0,
2320 {&hf_sctp_sack_chunk_gap_block_start,
2321 { "Start", "sctp.sack.gap_block_start",
2322 FT_UINT16, BASE_DEC, NULL, 0x0,
2325 {&hf_sctp_sack_chunk_gap_block_end,
2326 { "End", "sctp.sack.gap_block_end",
2327 FT_UINT16, BASE_DEC, NULL, 0x0,
2330 {&hf_sctp_sack_chunk_duplicate_tsn,
2331 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
2332 FT_UINT16, BASE_DEC, NULL, 0x0,
2335 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
2336 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
2337 FT_UINT32, BASE_DEC, NULL, 0x0,
2340 {&hf_sctp_ecne_chunk_lowest_tsn,
2341 { "Lowest TSN", "sctp.ecne.lowest_tsn",
2342 FT_UINT32, BASE_DEC, NULL, 0x0,
2345 {&hf_sctp_cwr_chunk_lowest_tsn,
2346 { "Lowest TSN", "sctp.cwr.lowest_tsn",
2347 FT_UINT32, BASE_DEC, NULL, 0x0,
2350 {&hf_sctp_shutdown_complete_chunk_t_bit,
2351 { "E-Bit", "sctp.shutdown_complete.t_bit",
2352 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2355 {&hf_sctp_forward_tsn_chunk_tsn,
2356 { "New cumulative TSN", "sctp.forward_tsn.tsn",
2357 FT_UINT32, BASE_DEC, NULL, 0x0,
2360 {&hf_sctp_chunk_parameter_type,
2361 { "Parameter type", "sctp.parameter.type",
2362 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2365 {&hf_sctp_chunk_parameter_length,
2366 { "Parameter length", "sctp.parameter.length",
2367 FT_UINT16, BASE_DEC, NULL, 0x0,
2370 {&hf_sctp_parameter_ipv4_address,
2371 { "IP Version 4 address", "sctp.parameter.ipv4_address",
2372 FT_IPv4, BASE_NONE, NULL, 0x0,
2375 {&hf_sctp_parameter_ipv6_address,
2376 { "IP Version 6 address", "sctp.parameter.ipv6_address",
2377 FT_IPv6, BASE_NONE, NULL, 0x0,
2380 {&hf_sctp_parameter_cookie_preservative_increment,
2381 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
2382 FT_UINT32, BASE_DEC, NULL, 0x0,
2385 {&hf_sctp_parameter_hostname_hostname,
2386 { "Hostname", "sctp.parameter.hostname.hostname",
2387 FT_STRING, BASE_NONE, NULL, 0x0,
2390 {&hf_sctp_supported_address_types_parameter,
2391 { "Supported address type", "sctp.parameter.supported_addres_type",
2392 FT_UINT16, BASE_DEC, NULL, 0x0,
2395 {&hf_sctp_ustreams_start,
2396 { "Start", "sctp.unreliable_streams.start",
2397 FT_UINT16, BASE_DEC, NULL, 0x0,
2400 {&hf_sctp_ustreams_end,
2401 { "End", "sctp.unreliable_streams.end",
2402 FT_UINT16, BASE_DEC, NULL, 0x0,
2405 {&hf_sctp_asconf_serial,
2406 { "Serial Number", "sctp.asconf.serial_number",
2407 FT_UINT32, BASE_HEX, NULL, 0x0,
2410 {&hf_sctp_asconf_correlation_id,
2411 { "Correlation_id", "sctp.asconf.correlation_id",
2412 FT_UINT32, BASE_HEX, NULL, 0x0,
2415 {&hf_sctp_asconf_reserved,
2416 { "Reserved", "sctp.asconf.reserved",
2417 FT_BYTES, BASE_NONE, NULL, 0x0,
2420 {&hf_sctp_asconf_addr_type,
2421 { "Address type", "sctp.asconf.address_type",
2422 FT_UINT8, BASE_HEX, VALS(sctp_address_type_values), 0x0,
2425 {&hf_sctp_asconf_addr,
2426 { "Address bytes", "sctp.asconf.address_bytes",
2427 FT_BYTES, BASE_NONE, NULL, 0x0,
2430 {&hf_sctp_asconf_ipv4_address,
2431 { "IP Version 4 address", "sctp.asconf.ipv4_address",
2432 FT_IPv4, BASE_NONE, NULL, 0x0,
2435 {&hf_sctp_asconf_ipv6_address,
2436 { "IP Version 6 address", "sctp.asconf.ipv6_address",
2437 FT_IPv6, BASE_NONE, NULL, 0x0,
2440 {&hf_sctp_asconf_ack_serial,
2441 { "Serial Number", "sctp.asconf_ack.serial_number",
2442 FT_UINT32, BASE_HEX, NULL, 0x0,
2445 {&hf_sctp_asconf_ack_correlation_id,
2446 { "Correlation_id", "sctp.asconf_ack.correlation_id",
2447 FT_UINT32, BASE_HEX, NULL, 0x0,
2450 {&hf_sctp_adap_indication,
2451 { "Indication", "sctp.adapation_layer_indication.indication",
2452 FT_UINT32, BASE_HEX, NULL, 0x0,
2455 {&hf_sctp_cause_code,
2456 { "Cause code", "sctp.cause.code",
2457 FT_UINT16, BASE_HEX, VALS(sctp_cause_code_values), 0x0,
2460 {&hf_sctp_cause_length,
2461 { "Cause length", "sctp.cause.length",
2462 FT_UINT16, BASE_DEC, NULL, 0x0,
2465 {&hf_sctp_cause_stream_identifier,
2466 { "Stream identifier", "sctp.cause.stream_identifier",
2467 FT_UINT16, BASE_DEC, NULL, 0x0,
2470 {&hf_sctp_cause_number_of_missing_parameters,
2471 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
2472 FT_UINT32, BASE_DEC, NULL, 0x0,
2475 {&hf_sctp_cause_missing_parameter_type,
2476 { "Missing parameter type", "sctp.cause.missing_parameter_type",
2477 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2480 {&hf_sctp_cause_measure_of_staleness,
2481 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
2482 FT_UINT32, BASE_DEC, NULL, 0x0,
2485 {&hf_sctp_cause_tsn,
2486 { "TSN", "sctp.cause.tsn",
2487 FT_UINT32, BASE_DEC, NULL, 0x0,
2492 /* Setup protocol subtree array */
2493 static gint *ett[] = {
2496 &ett_sctp_chunk_parameter,
2497 &ett_sctp_chunk_cause,
2498 &ett_sctp_data_chunk_flags,
2499 &ett_sctp_sack_chunk_gap_block,
2500 &ett_sctp_supported_address_types_parameter,
2501 &ett_sctp_unrecognized_parameter_parameter,
2502 &ett_sctp_unreliable_streams_interval
2505 static enum_val_t sctp_checksum_options[] = {
2506 { "None", SCTP_CHECKSUM_NONE },
2507 { "Adler 32", SCTP_CHECKSUM_ADLER32 },
2508 { "CRC 32c", SCTP_CHECKSUM_CRC32C },
2509 { "Automatic", SCTP_CHECKSUM_AUTOMATIC},
2513 /* Register the protocol name and description */
2514 proto_sctp = proto_register_protocol("Stream Control Transmission Protocol", "SCTP", "sctp");
2515 sctp_module = prefs_register_protocol(proto_sctp, NULL);
2516 prefs_register_enum_preference(sctp_module, "checksum",
2518 "The type of checksum used in SCTP packets",
2519 &sctp_checksum, sctp_checksum_options, FALSE);
2521 /* Required function calls to register the header fields and subtrees used */
2522 proto_register_field_array(proto_sctp, hf, array_length(hf));
2523 proto_register_subtree_array(ett, array_length(ett));
2525 /* subdissector code */
2526 sctp_port_dissector_table = register_dissector_table("sctp.port", "SCTP port", FT_UINT16, BASE_DEC);
2527 sctp_ppi_dissector_table = register_dissector_table("sctp.ppi", "SCTP payload protocol identifier", FT_UINT32, BASE_HEX);
2532 proto_reg_handoff_sctp(void)
2534 dissector_handle_t sctp_handle;
2536 sctp_handle = create_dissector_handle(dissect_sctp, proto_sctp);
2537 dissector_add("ip.proto", IP_PROTO_SCTP, sctp_handle);