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-01.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.31 2002/02/02 21:17:10 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;
608 for (i = 0; i < SOURCE_PORT_LENGTH + DESTINATION_PORT_LENGTH + VERIFICATION_TAG_LENGTH; i++)
610 CRC32C(crc32, buf[i]);
616 for (i = COMMON_HEADER_LENGTH; i < len; i++)
618 CRC32C(crc32, buf[i]);
624 nr_of_padding_bytes (guint length)
628 remainder = length % 4;
633 return 4 - remainder;
637 * TLV parameter stuff for INIT and INIT-ACK chunks
641 dissect_parameter(tvbuff_t *, packet_info *, proto_tree *);
644 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree);
647 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
650 dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, packet_info *pinfo, proto_tree *tree)
652 guint offset, length, padding_length, total_length;
653 tvbuff_t *parameter_tvb;
656 while(tvb_reported_length_remaining(parameter_list_tvb, offset)) {
657 length = tvb_get_ntohs(parameter_list_tvb, offset + PARAMETER_LENGTH_OFFSET);
658 padding_length = nr_of_padding_bytes(length);
659 total_length = length + padding_length;
660 /* create a tvb for the chunk including the padding bytes */
661 parameter_tvb = tvb_new_subset(parameter_list_tvb, offset, total_length, total_length);
662 dissect_parameter(parameter_tvb, pinfo, tree);
663 /* get rid of the handled parameter */
664 offset += total_length;
669 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
671 guint16 length, heartbeat_info_length;
673 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
675 heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
677 proto_tree_add_text(parameter_tree, parameter_tvb, HEARTBEAT_INFO_PARAMETER_INFO_OFFSET, heartbeat_info_length,
678 "Heartbeat info (%u byte%s)",
679 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
681 proto_item_set_text(parameter_item, "Heartbeat info parameter with %u byte%s of info",
682 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
686 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
688 guint32 ipv4_address;
690 tvb_memcpy(parameter_tvb, (guint8 *)&ipv4_address, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH);
691 proto_tree_add_ipv4(parameter_tree, hf_sctp_parameter_ipv4_address,
692 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH,
694 proto_item_set_text(parameter_item, "IPV4 address parameter");
698 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
700 proto_tree_add_ipv6(parameter_tree, hf_sctp_parameter_ipv6_address,
701 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH,
702 tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH));
704 proto_item_set_text(parameter_item, "IPV6 address parameter");
708 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
710 guint16 length, state_cookie_length;
712 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
714 state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
716 proto_tree_add_text(parameter_tree, parameter_tvb, STATE_COOKIE_PARAMETER_COOKIE_OFFSET, state_cookie_length,
717 "State cookie (%u byte%s)",
718 state_cookie_length, plurality(state_cookie_length, "", "s"));
720 proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
721 state_cookie_length, plurality(state_cookie_length, "", "s"));
725 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
727 guint16 length, padding_length, parameter_value_length;
728 tvbuff_t *unrecognized_parameters_tvb;
730 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
731 padding_length = nr_of_padding_bytes(length);
733 parameter_value_length = length - PARAMETER_HEADER_LENGTH + padding_length;
735 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
736 parameter_value_length, parameter_value_length);
737 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, parameter_tree);
739 proto_item_set_text(parameter_item, "Unrecognized parameter of type");
743 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
747 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
749 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
750 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
751 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
754 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
759 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
761 guint16 length, hostname_length;
764 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
766 hostname_length = length - PARAMETER_HEADER_LENGTH;
767 hostname = (char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
768 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
769 PARAMETER_VALUE_OFFSET, hostname_length,
772 proto_item_set_text(parameter_item, "Hostname parameter");
776 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
778 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
780 proto_item *address_list_item;
781 proto_tree *address_list_tree;
783 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
784 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
785 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
787 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
788 "Supported Address Types (%u address type%s)",
789 number_of_address_types, plurality(number_of_address_types, "", "s"));
790 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
792 offset = PARAMETER_VALUE_OFFSET;
793 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
794 address_type = tvb_get_ntohs(parameter_tvb, offset);
795 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
796 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
797 address_type, "Supported address type: 0x%04x (%s)",
798 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
799 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
802 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
803 number_of_address_types, plurality(number_of_address_types, "", "s"));
807 dissect_ecn_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
809 proto_item_set_text(parameter_item, "ECN parameter");
812 #define USTREAMS_START_LENGTH 2
813 #define USTREAMS_END_LENGTH 2
814 #define USTREAMS_INTERVAL_LENGTH (USTREAMS_START_LENGTH + USTREAMS_END_LENGTH)
817 dissect_unreliable_streams_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
819 guint16 length, start, end, number_of_intervals, interval_number;
820 proto_item *interval_item;
821 proto_tree *interval_tree;
822 gint interval_offset;
824 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
825 number_of_intervals = (length - PARAMETER_HEADER_LENGTH) / USTREAMS_INTERVAL_LENGTH;
827 interval_offset = PARAMETER_VALUE_OFFSET;
828 for(interval_number = 1; interval_number <= number_of_intervals; interval_number++) {
829 start = tvb_get_ntohs(parameter_tvb, interval_offset);
830 end = tvb_get_ntohs(parameter_tvb, interval_offset + USTREAMS_START_LENGTH);
831 interval_item = proto_tree_add_text(parameter_tree, parameter_tvb, interval_offset, USTREAMS_INTERVAL_LENGTH, "Unreliable streams (%u-%u)", start, end);
832 interval_tree = proto_item_add_subtree(interval_item, ett_sctp_unreliable_streams_interval);
833 proto_tree_add_uint(interval_tree, hf_sctp_ustreams_start, parameter_tvb, interval_offset, USTREAMS_START_LENGTH, start);
834 proto_tree_add_uint(interval_tree, hf_sctp_ustreams_end, parameter_tvb, interval_offset + USTREAMS_START_LENGTH, USTREAMS_END_LENGTH, end);
835 interval_offset += USTREAMS_INTERVAL_LENGTH;
837 proto_item_set_text(parameter_item, "Unreliable streams parameter");
841 dissect_add_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
843 guint16 length, parameter_value_length;
844 tvbuff_t *address_tvb;
846 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
847 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
849 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
850 dissect_parameter(address_tvb, pinfo, parameter_tree);
852 proto_item_set_text(parameter_item, "Add IP address parameter");
856 dissect_del_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
858 guint16 length, parameter_value_length;
859 tvbuff_t *address_tvb;
861 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
862 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
864 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
865 dissect_parameter(address_tvb, pinfo, parameter_tree);
867 proto_item_set_text(parameter_item, "Delete IP address parameter");
871 dissect_error_cause_indication_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
873 guint16 length, padding_length, total_length;
875 tvbuff_t *error_cause_tvb;
877 offset = PARAMETER_VALUE_OFFSET;
878 while(tvb_reported_length_remaining(parameter_tvb, offset)) {
879 length = tvb_get_ntohs(parameter_tvb, offset + CAUSE_LENGTH_OFFSET);
880 padding_length = nr_of_padding_bytes(length);
881 total_length = length + padding_length;
882 /* create a tvb for the chunk including the padding bytes */
883 error_cause_tvb = tvb_new_subset(parameter_tvb, offset , total_length, total_length);
884 dissect_error_cause(error_cause_tvb, pinfo, parameter_tree);
885 /* get rid of the handled parameter */
886 offset += total_length;
888 proto_item_set_text(parameter_item, "Error cause indication");
892 dissect_set_primary_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
894 guint16 length, parameter_value_length;
895 tvbuff_t *address_tvb;
897 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
898 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
900 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
901 dissect_parameter(address_tvb, pinfo, parameter_tree);
903 proto_item_set_text(parameter_item, "Set primary address parameter");
907 dissect_success_report_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
909 proto_item_set_text(parameter_item, "Success report parameter");
912 #define ADAP_INDICATION_LENGTH 4
913 #define ADAP_INDICATION_OFFSET PARAMETER_VALUE_OFFSET
916 dissect_adap_indication_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
920 indication = tvb_get_ntohl(parameter_tvb, ADAP_INDICATION_OFFSET);
921 proto_tree_add_uint(parameter_tree, hf_sctp_adap_indication, parameter_tvb, ADAP_INDICATION_OFFSET, ADAP_INDICATION_LENGTH, indication);
922 proto_item_set_text(parameter_item, "Adaptation layer indication");
926 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
928 guint16 type, length, parameter_value_length;
930 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
931 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
933 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
935 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
936 "Parameter value (%u byte%s)",
937 parameter_value_length, plurality(parameter_value_length, "", "s"));
939 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
940 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
944 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *chunk_tree)
946 guint16 type, length, padding_length, total_length;
947 proto_item *parameter_item;
948 proto_tree *parameter_tree;
950 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
951 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
952 padding_length = nr_of_padding_bytes(length);
953 total_length = length + padding_length;
955 parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb,
956 PARAMETER_HEADER_OFFSET, total_length, "%s parameter",
957 val_to_str(type, sctp_parameter_identifier_values, "Unknown"));
958 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
960 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_type,
961 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
963 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
964 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
968 case HEARTBEAT_INFO_PARAMETER_ID:
969 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
971 case IPV4ADDRESS_PARAMETER_ID:
972 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
974 case IPV6ADDRESS_PARAMETER_ID:
975 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
977 case STATE_COOKIE_PARAMETER_ID:
978 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
980 case UNREC_PARA_PARAMETER_ID:
981 dissect_unrecognized_parameters_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
983 case COOKIE_PRESERVATIVE_PARAMETER_ID:
984 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
986 case HOSTNAME_ADDRESS_PARAMETER_ID:
987 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
989 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
990 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
992 case ECN_PARAMETER_ID:
993 dissect_ecn_parameter(parameter_tvb, parameter_tree, parameter_item);
995 case UNRELIABLE_STREAMS_PARAMETER_ID:
996 dissect_unreliable_streams_parameter(parameter_tvb, parameter_tree, parameter_item);
998 case ADD_IP_ADDRESS_PARAMETER_ID:
999 dissect_add_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1001 case DEL_IP_ADDRESS_PARAMETER_ID:
1002 dissect_del_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1004 case ERROR_CAUSE_INDICATION_PARAMETER_ID:
1005 dissect_error_cause_indication_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1007 case SET_PRIMARY_ADDRESS_PARAMETER_ID:
1008 dissect_set_primary_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1010 case SUCCESS_REPORT_PARAMETER_ID:
1011 dissect_success_report_parameter(parameter_tvb, parameter_tree, parameter_item);
1013 case ADAP_LAYER_INDICATION_PARAMETER_ID:
1014 dissect_adap_indication_parameter(parameter_tvb, parameter_tree, parameter_item);
1017 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1020 if ((padding_length > 0) && (type != UNREC_PARA_PARAMETER_ID))
1021 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
1022 "Padding: %u byte%s",
1023 padding_length, plurality(padding_length, "", "s"));
1027 * Code to handle error causes for ABORT and ERROR chunks
1030 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1032 guint16 stream_identifier;
1034 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
1035 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
1036 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
1038 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
1039 "Reserved (2 bytes)");
1041 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
1046 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1048 guint32 number_of_missing_parameters, missing_parameter_number;
1049 guint16 parameter_type;
1052 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
1053 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
1054 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
1055 number_of_missing_parameters);
1056 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
1057 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
1058 parameter_type = tvb_get_ntohs(cause_tvb, offset);
1059 proto_tree_add_uint(cause_tree, hf_sctp_cause_missing_parameter_type,
1060 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
1062 offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
1065 proto_item_set_text(cause_item, "Error cause reporting %u missing mandatory parameter%s",
1066 number_of_missing_parameters, plurality(number_of_missing_parameters, "", "s") );
1070 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1072 guint32 measure_of_staleness;
1074 measure_of_staleness = tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
1076 proto_tree_add_uint(cause_tree, hf_sctp_cause_measure_of_staleness, cause_tvb,
1077 CAUSE_MEASURE_OF_STALENESS_OFFSET,
1078 CAUSE_MEASURE_OF_STALENESS_LENGTH,
1079 measure_of_staleness);
1081 proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
1082 measure_of_staleness);
1086 dissect_out_of_resource_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1088 proto_item_set_text(cause_item, "Error cause reporting lack of resources");
1092 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1094 guint16 code, length, parameter_length, parameter_type;
1095 tvbuff_t *parameter_tvb;
1097 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1098 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1100 parameter_length = length - CAUSE_HEADER_LENGTH;
1101 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
1102 parameter_length, parameter_length);
1104 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1105 parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
1107 proto_item_set_text(cause_item, "Error cause reporting unresolvable address of type 0x%04x (%s)",
1108 parameter_type, val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown") );
1112 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo,
1113 proto_tree *cause_tree, proto_item *cause_item)
1115 guint16 length, chunk_length;
1116 guint8 unrecognized_type;
1117 tvbuff_t *unrecognized_chunk_tvb;
1119 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1121 chunk_length = length - CAUSE_HEADER_LENGTH;
1123 unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, chunk_length, chunk_length);
1124 dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree);
1126 unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
1128 proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
1130 val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
1134 dissect_invalid_mandatory_parameter_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1136 proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
1140 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1142 guint16 length, padding_length, cause_info_length;
1143 tvbuff_t *unrecognized_parameters_tvb;
1145 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1146 padding_length = nr_of_padding_bytes(length);
1147 cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
1149 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1150 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, cause_tree);
1152 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
1156 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1160 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
1161 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
1166 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
1171 dissect_cookie_received_while_shutting_down_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1173 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
1177 dissect_delete_last_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1179 guint16 length, cause_info_length;
1180 tvbuff_t *parameter_tvb;
1182 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1183 cause_info_length = length - CAUSE_HEADER_LENGTH;
1184 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1185 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1186 proto_item_set_text(cause_item, "Delete last address cause");
1190 dissect_resource_outage_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1192 guint16 length, cause_info_length;
1193 tvbuff_t *parameter_tvb;
1195 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1196 cause_info_length = length - CAUSE_HEADER_LENGTH;
1197 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1198 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1199 proto_item_set_text(cause_item, "Operation refused due to resource shortage");
1203 dissect_delete_source_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1205 guint16 length, cause_info_length;
1206 tvbuff_t *parameter_tvb;
1208 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1209 cause_info_length = length - CAUSE_HEADER_LENGTH;
1210 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1211 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1212 proto_item_set_text(cause_item, "Delete source address cause");
1216 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1218 guint16 code, length, cause_info_length;
1220 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1221 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1223 cause_info_length = length - CAUSE_HEADER_LENGTH;
1225 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
1226 "Cause specific information (%u byte%s)",
1227 cause_info_length, plurality(cause_info_length, "", "s"));
1229 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
1230 code, cause_info_length, plurality(cause_info_length, "", "s"));
1234 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
1236 guint16 code, length, padding_length, total_length;
1237 proto_item *cause_item;
1238 proto_tree *cause_tree;
1240 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1241 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1242 padding_length = nr_of_padding_bytes(length);
1243 total_length = length + padding_length;
1245 cause_item = proto_tree_add_text(chunk_tree, cause_tvb,
1246 CAUSE_HEADER_OFFSET, total_length,
1248 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
1250 proto_tree_add_uint(cause_tree, hf_sctp_cause_code,
1251 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
1253 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
1254 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
1258 case INVALID_STREAM_IDENTIFIER:
1259 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
1261 case MISSING_MANDATORY_PARAMETERS:
1262 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
1264 case STALE_COOKIE_ERROR:
1265 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
1267 case OUT_OF_RESOURCE:
1268 dissect_out_of_resource_cause(cause_tvb, cause_tree, cause_item);
1270 case UNRESOLVABLE_ADDRESS:
1271 dissect_unresolvable_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1273 case UNRECOGNIZED_CHUNK_TYPE:
1274 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
1276 case INVALID_MANDATORY_PARAMETER:
1277 dissect_invalid_mandatory_parameter_cause(cause_tvb, cause_tree, cause_item);
1279 case UNRECOGNIZED_PARAMETERS:
1280 dissect_unrecognized_parameters_cause(cause_tvb, pinfo, cause_tree, cause_item);
1283 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
1285 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
1286 dissect_cookie_received_while_shutting_down_cause(cause_tvb, cause_tree, cause_item);
1288 case REQUEST_TO_DELETE_LAST_ADDRESS:
1289 dissect_delete_last_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1291 case OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE:
1292 dissect_resource_outage_cause(cause_tvb, pinfo, cause_tree, cause_item);
1294 case REQUEST_TO_DELETE_SOURCE_ADDRESS:
1295 dissect_delete_source_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1298 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
1301 if ((padding_length > 0) && (code != UNRECOGNIZED_PARAMETERS))
1302 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
1303 "Padding: %u byte%s",
1304 padding_length, plurality(padding_length, "", "s"));
1308 * Code to actually dissect the packets
1312 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
1313 proto_tree *chunk_tree, guint32 ppi, guint16 payload_length, guint16 padding_length)
1315 /* do lookup with the subdissector table */
1316 if (dissector_try_port (sctp_ppi_dissector_table, ppi, payload_tvb, pinfo, tree) ||
1317 dissector_try_port(sctp_port_dissector_table, pinfo->srcport, payload_tvb, pinfo, tree) ||
1318 dissector_try_port(sctp_port_dissector_table, pinfo->destport, payload_tvb, pinfo, tree)){
1322 if (check_col(pinfo->cinfo, COL_INFO))
1323 col_append_str(pinfo->cinfo, COL_INFO, "DATA ");
1324 proto_tree_add_text(chunk_tree, payload_tvb, 0, payload_length,
1325 "Payload (%u byte%s)",
1326 payload_length, plurality(payload_length, "", "s"));
1327 if (padding_length > 0)
1328 proto_tree_add_text(chunk_tree, payload_tvb, payload_length, padding_length,
1329 "Padding: %u byte%s",
1330 padding_length, plurality(padding_length, "", "s"));
1336 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1337 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1340 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
1341 guint32 tsn, payload_proto_id;
1342 proto_tree *flag_tree;
1343 tvbuff_t *payload_tvb;
1345 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1346 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1347 padding_length = nr_of_padding_bytes(length);
1348 total_payload_length = payload_length + padding_length;
1349 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1350 total_payload_length, total_payload_length);
1351 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1354 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1356 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1357 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
1358 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1359 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1360 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1361 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1362 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1364 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1365 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1366 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1368 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1370 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1372 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1374 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1376 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1378 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1380 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1381 chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1383 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1384 tsn, stream_id, stream_seq_number,
1385 payload_length, plurality(payload_length, "", "s"));
1387 return dissect_payload(payload_tvb, pinfo, tree, chunk_tree, payload_proto_id, payload_length, padding_length);
1391 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1392 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1394 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1395 guint16 number_of_inbound_streams, number_of_outbound_streams;
1397 tvbuff_t *parameter_list_tvb;
1399 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1401 if (check_col(pinfo->cinfo, COL_INFO)) {
1402 if (type == SCTP_INIT_CHUNK_ID) {
1403 col_append_str(pinfo->cinfo, COL_INFO, "INIT ");
1405 col_append_str(pinfo->cinfo, COL_INFO, "INIT_ACK ");
1410 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1411 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1412 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1413 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1414 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1416 /* handle fixed parameters */
1417 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1419 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1421 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1423 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1424 adv_rec_window_credit);
1425 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1427 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1428 number_of_outbound_streams);
1429 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1431 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1432 number_of_inbound_streams);
1433 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1435 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1438 /* handle variable paramters */
1439 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1440 dissect_tlv_parameter_list(parameter_list_tvb, pinfo, chunk_tree);
1442 proto_item_set_text(chunk_item,
1443 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1444 val_to_str(type, sctp_chunk_type_values, "unknown"),
1445 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1446 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1451 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1452 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1454 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1458 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1459 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1461 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1462 guint16 number_of_gap_blocks, number_of_dup_tsns;
1463 guint16 gap_block_number, dup_tsn_number, start, end;
1464 gint gap_block_offset, dup_tsn_offset;
1465 proto_item *block_item;
1466 proto_tree *block_tree;
1468 if (check_col(pinfo->cinfo, COL_INFO))
1469 col_append_str(pinfo->cinfo, COL_INFO, "SACK ");
1472 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1473 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1474 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1475 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1477 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1479 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1480 cumulative_tsn_ack);
1481 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1483 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1484 adv_rec_window_credit);
1485 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1487 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1488 number_of_gap_blocks);
1489 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1491 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1492 number_of_dup_tsns);
1494 /* handle the gap acknowledgement blocks */
1495 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1496 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1497 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1498 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1499 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1500 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1501 "Gap Acknowledgement for %u TSN%s",
1502 1 + end - start, plurality(1 + end - start, "", "s"));
1503 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1504 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1506 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1508 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1510 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1511 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1513 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1516 /* handle the duplicate TSNs */
1517 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1518 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1519 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1520 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1522 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1524 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1527 proto_item_set_text(chunk_item,
1528 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1530 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1531 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1536 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1537 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1539 tvbuff_t *parameter_tvb;
1540 guint chunk_length, info_length, padding_length, total_length;
1542 if (check_col(pinfo->cinfo, COL_INFO))
1543 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT ");
1546 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1547 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1548 padding_length = nr_of_padding_bytes(info_length);
1549 total_length = info_length + padding_length;
1550 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1552 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1554 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1559 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1560 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1562 tvbuff_t *parameter_tvb;
1563 guint chunk_length, info_length, padding_length, total_length;
1565 if (check_col(pinfo->cinfo, COL_INFO))
1566 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT_ACK ");
1569 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1570 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1571 padding_length = nr_of_padding_bytes(info_length);
1572 total_length = info_length + padding_length;
1574 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1576 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1578 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1583 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1584 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1586 guint offset, number_of_causes;
1587 guint16 length, padding_length, total_length;
1588 tvbuff_t *cause_tvb;
1590 if (check_col(pinfo->cinfo, COL_INFO))
1591 col_append_str(pinfo->cinfo, COL_INFO, "ABORT ");
1594 number_of_causes = 0;
1595 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1596 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1597 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1598 padding_length = nr_of_padding_bytes(length);
1599 total_length = length + padding_length;
1600 /* create a tvb for the chunk including the padding bytes */
1601 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1602 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1603 /* get rid of the handled parameter */
1604 offset += total_length;
1608 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s",
1609 number_of_causes, plurality(number_of_causes, "", "s"));
1614 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1615 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1617 guint32 cumulative_tsn_ack;
1619 if (check_col(pinfo->cinfo, COL_INFO))
1620 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN ");
1623 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1624 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1626 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1627 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1628 cumulative_tsn_ack);
1630 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1631 cumulative_tsn_ack);
1636 dissect_shutdown_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1637 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1639 if (check_col(pinfo->cinfo, COL_INFO))
1640 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_ACK ");
1643 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1648 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1649 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1651 guint offset, number_of_causes;
1652 guint16 length, padding_length, total_length;
1653 tvbuff_t *cause_tvb;
1655 if (check_col(pinfo->cinfo, COL_INFO))
1656 col_append_str(pinfo->cinfo, COL_INFO, "ERROR ");
1659 number_of_causes = 0;
1660 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1662 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1663 padding_length = nr_of_padding_bytes(length);
1664 total_length = length + padding_length;
1665 /* create a tvb for the chunk including the padding bytes */
1666 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1667 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1668 /* get rid of the handled parameter */
1669 offset += total_length;
1671 } while(tvb_reported_length_remaining(chunk_tvb, offset));
1673 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1674 number_of_causes, plurality(number_of_causes, "", "s"));
1679 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1680 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1682 guint length, cookie_length, padding_length;
1684 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1685 padding_length = nr_of_padding_bytes(length);
1686 cookie_length = length - CHUNK_HEADER_LENGTH;
1688 if (check_col(pinfo->cinfo, COL_INFO))
1689 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ECHO ");
1692 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1693 "Cookie (%u byte%s)",
1694 cookie_length, plurality(cookie_length, "", "s"));
1695 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1696 cookie_length, plurality(cookie_length, "", "s"));
1698 if (padding_length > 0)
1699 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1700 "Padding: %u byte%s",
1701 padding_length, plurality(padding_length, "", "s"));
1706 dissect_cookie_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1707 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1709 if (check_col(pinfo->cinfo, COL_INFO))
1710 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ACK ");
1713 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1718 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1719 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1723 if (check_col(pinfo->cinfo, COL_INFO))
1724 col_append_str(pinfo->cinfo, COL_INFO, "ECNE ");
1727 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1728 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1730 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1733 proto_item_set_text(chunk_item, "ECNE chunk");
1738 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1739 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1743 if (check_col(pinfo->cinfo, COL_INFO))
1744 col_append_str(pinfo->cinfo, COL_INFO, "CWR ");
1747 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1748 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1750 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1753 proto_item_set_text(chunk_item, "CWR chunk");
1758 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1759 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1763 proto_tree *flag_tree;
1765 if (check_col(pinfo->cinfo, COL_INFO))
1766 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_COMPLETE ");
1769 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1770 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1772 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1773 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1774 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1776 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1780 #define FORWARD_TSN_CHUNK_TSN_OFFSET CHUNK_VALUE_OFFSET
1781 #define FORWARD_TSN_CHUNK_TSN_LENGTH 4
1784 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)
1788 if (check_col(pinfo->cinfo, COL_INFO))
1789 col_append_str(pinfo->cinfo, COL_INFO, "FORWARD TSN ");
1792 tsn = tvb_get_ntohl(chunk_tvb, FORWARD_TSN_CHUNK_TSN_OFFSET);
1793 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);
1794 proto_item_set_text(chunk_item, "FORWARD TSN chunk (new cumulative TSN %u)", tsn);
1798 #define SERIAL_NUMBER_LENGTH 4
1799 #define CORRELATION_ID_LENGTH 4
1800 #define ASCONF_RESERVED_LENGTH 3
1801 #define ASCONF_ADDR_TYPE_LENGTH 1
1802 #define ASCONF_ADDR_LENGTH 16
1803 #define SERIAL_NUMBER_OFFSET PARAMETER_VALUE_OFFSET
1805 #define IP_V4_ADDRESS_TYPE 5
1806 #define IP_V6_ADDRESS_TYPE 6
1808 static const value_string sctp_address_type_values[] = {
1809 { IP_V4_ADDRESS_TYPE, "IP V4 address" },
1810 { IP_V6_ADDRESS_TYPE, "IP V6 address" },
1814 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)
1816 guint32 serial_number, correlation_id, ipv4_address;
1817 guint offset, length, padding_length, total_length;
1819 tvbuff_t *parameter_tvb;
1821 if (check_col(pinfo->cinfo, COL_INFO))
1822 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF ");
1825 offset = SERIAL_NUMBER_OFFSET;
1826 serial_number = tvb_get_ntohl(chunk_tvb, offset);
1827 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_serial, chunk_tvb, offset, SERIAL_NUMBER_LENGTH, serial_number);
1828 offset += SERIAL_NUMBER_LENGTH;
1829 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));
1830 offset += ASCONF_RESERVED_LENGTH;
1831 addr_type = tvb_get_guint8(chunk_tvb, offset);
1832 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_addr_type, chunk_tvb, offset, ASCONF_ADDR_TYPE_LENGTH, addr_type);
1833 offset += ASCONF_ADDR_TYPE_LENGTH;
1834 switch (addr_type) {
1835 case IP_V4_ADDRESS_TYPE:
1836 tvb_memcpy(chunk_tvb, (guint8 *)&ipv4_address, offset, IPV4_ADDRESS_LENGTH);
1837 proto_tree_add_ipv4(chunk_tree, hf_sctp_asconf_ipv4_address, chunk_tvb, offset, IPV4_ADDRESS_LENGTH, ipv4_address);
1838 proto_tree_add_bytes(chunk_tree, hf_sctp_asconf_addr, chunk_tvb, offset + IPV4_ADDRESS_LENGTH, ASCONF_ADDR_LENGTH - IPV4_ADDRESS_LENGTH,
1839 tvb_get_ptr(chunk_tvb, offset + IPV4_ADDRESS_LENGTH, ASCONF_ADDR_LENGTH - IPV4_ADDRESS_LENGTH));
1841 case IP_V6_ADDRESS_TYPE:
1842 proto_tree_add_ipv6(chunk_tree, hf_sctp_asconf_ipv6_address, chunk_tvb, offset, IPV6_ADDRESS_LENGTH,
1843 tvb_get_ptr(chunk_tvb, offset, IPV6_ADDRESS_LENGTH));
1846 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));
1849 offset += ASCONF_ADDR_LENGTH;
1850 proto_item_set_text(chunk_item, "ASCONF chunk");
1852 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1853 correlation_id = tvb_get_ntohl(chunk_tvb, offset);
1854 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_correlation_id, chunk_tvb, offset, CORRELATION_ID_LENGTH, correlation_id);
1855 offset += CORRELATION_ID_LENGTH;
1856 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1857 padding_length = nr_of_padding_bytes(length);
1858 total_length = length + padding_length;
1859 /* create a tvb for the chunk including the padding bytes */
1860 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1861 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1862 /* get rid of the handled parameter */
1863 offset += total_length;
1869 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)
1871 guint32 serial_number, correlation_id;
1872 guint offset, length, padding_length, total_length;
1873 tvbuff_t *parameter_tvb;
1875 if (check_col(pinfo->cinfo, COL_INFO))
1876 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF-ACK ");
1879 serial_number = tvb_get_ntohl(chunk_tvb, SERIAL_NUMBER_OFFSET);
1880 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_serial, chunk_tvb, SERIAL_NUMBER_OFFSET, SERIAL_NUMBER_LENGTH, serial_number);
1881 proto_item_set_text(chunk_item, "ASCONF-ACK chunk");
1883 offset = SERIAL_NUMBER_OFFSET + SERIAL_NUMBER_LENGTH;
1884 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1885 correlation_id = tvb_get_ntohl(chunk_tvb, offset);
1886 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_correlation_id, chunk_tvb, offset, CORRELATION_ID_LENGTH, correlation_id);
1887 offset += CORRELATION_ID_LENGTH;
1888 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1889 padding_length = nr_of_padding_bytes(length);
1890 total_length = length + padding_length;
1891 /* create a tvb for the chunk including the padding bytes */
1892 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1893 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1894 /* get rid of the handled parameter */
1895 offset += total_length;
1901 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1902 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1904 guint length, chunk_value_length, padding_length;
1907 if (check_col(pinfo->cinfo, COL_INFO))
1908 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN ");
1911 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1912 padding_length = nr_of_padding_bytes(length);
1913 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1915 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1917 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1918 "Chunk value (%u byte%s)",
1919 chunk_value_length, plurality(chunk_value_length, "", "s"));
1921 if (padding_length > 0)
1922 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1923 "Padding: %u byte%s",
1924 padding_length, plurality(padding_length, "", "s"));
1926 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1927 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1933 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1938 proto_item *flags_item;
1939 proto_item *chunk_item;
1940 proto_tree *chunk_tree;
1944 /* first extract the chunk header */
1945 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1946 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1947 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1950 /* create proto_tree stuff */
1951 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb, CHUNK_HEADER_OFFSET, -1, "Incomplete chunk");
1952 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
1954 /* then insert the chunk header components into the protocol tree */
1955 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_type, chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH, type);
1956 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1957 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length, chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH, length);
1964 /* now dissect the chunk value */
1967 case SCTP_DATA_CHUNK_ID:
1968 result = dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1970 case SCTP_INIT_CHUNK_ID:
1971 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1973 case SCTP_INIT_ACK_CHUNK_ID:
1974 dissect_init_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1976 case SCTP_SACK_CHUNK_ID:
1977 dissect_sack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1979 case SCTP_HEARTBEAT_CHUNK_ID:
1980 dissect_heartbeat_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1982 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1983 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1985 case SCTP_ABORT_CHUNK_ID:
1986 dissect_abort_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1988 case SCTP_SHUTDOWN_CHUNK_ID:
1989 dissect_shutdown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1991 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
1992 dissect_shutdown_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1994 case SCTP_ERROR_CHUNK_ID:
1995 dissect_error_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1997 case SCTP_COOKIE_ECHO_CHUNK_ID:
1998 dissect_cookie_echo_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2000 case SCTP_COOKIE_ACK_CHUNK_ID:
2001 dissect_cookie_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2003 case SCTP_ECNE_CHUNK_ID:
2004 dissect_ecne_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2006 case SCTP_CWR_CHUNK_ID:
2007 dissect_cwr_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2009 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
2010 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2012 case SCTP_FORWARD_TSN_CHUNK_ID:
2013 dissect_forward_tsn_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2015 case SCTP_ASCONF_ACK_CHUNK_ID:
2016 dissect_asconf_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2018 case SCTP_ASCONF_CHUNK_ID:
2019 dissect_asconf_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2022 dissect_unknown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2029 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *sctp_item, proto_tree *sctp_tree)
2031 tvbuff_t *chunk_tvb;
2032 guint16 length, padding_length, total_length;
2033 gint last_offset, offset;
2034 gboolean sctp_item_length_set;
2036 /* the common header of the datagram is already handled */
2038 offset = COMMON_HEADER_LENGTH;
2039 sctp_item_length_set = FALSE;
2041 while(tvb_reported_length_remaining(tvb, offset) > 0) {
2042 /* extract the chunk length and compute number of padding bytes */
2043 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
2044 padding_length = nr_of_padding_bytes(length);
2045 total_length = length + padding_length;
2046 /* create a tvb for the chunk including the padding bytes */
2047 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
2048 /* call dissect_sctp_chunk for a actual work */
2049 if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree) && (tree)) {
2050 proto_item_set_len(sctp_item, offset - last_offset + DATA_CHUNK_HEADER_LENGTH);
2051 sctp_item_length_set = TRUE;
2052 offset += total_length;
2053 last_offset = offset;
2054 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2055 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, offset, -1, FALSE);
2056 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2057 sctp_item_length_set = FALSE;
2060 /* get rid of the dissected chunk */
2061 offset += total_length;
2064 if (!sctp_item_length_set && (tree)) {
2065 proto_item_set_len(sctp_item, offset - last_offset);
2069 /* dissect_sctp handles the common header of a SCTP datagram.
2070 * For the handling of the chunks dissect_sctp_chunks is called.
2074 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2076 guint16 source_port, destination_port;
2077 guint32 verification_tag, checksum, calculated_crc32c, calculated_adler32;
2079 gboolean crc32c_correct, adler32_correct;
2080 proto_item *sctp_item;
2081 proto_tree *sctp_tree;
2083 /* Extract the common header */
2084 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
2085 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
2086 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
2087 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
2089 /* update pi structure */
2090 pinfo->ptype = PT_SCTP;
2091 pinfo->srcport = source_port;
2092 pinfo->destport = destination_port;
2094 /* make entry in the Protocol column on summary display */
2095 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2096 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCTP");
2098 /* Clear entries in Info column on summary display */
2099 if (check_col(pinfo->cinfo, COL_INFO))
2100 col_add_str(pinfo->cinfo, COL_INFO, "");
2102 /* In the interest of speed, if "tree" is NULL, don't do any work not
2103 necessary to generate protocol tree items. */
2105 /* create the sctp protocol tree */
2106 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, 0, -1, FALSE);
2107 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2109 /* add the components of the common header to the protocol tree */
2110 proto_tree_add_uint(sctp_tree, hf_sctp_source_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2111 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2112 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag, tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH, verification_tag);
2113 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2114 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2116 length = tvb_length(tvb);
2117 switch(sctp_checksum) {
2118 case SCTP_CHECKSUM_NONE:
2119 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum, "Checksum: 0x%08x (not verified)", checksum);
2121 case SCTP_CHECKSUM_ADLER32:
2122 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2123 adler32_correct = (checksum == calculated_adler32);
2124 if (adler32_correct)
2125 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2126 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2128 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2129 checksum, "Checksum: 0x%08x (incorrect Adler32, should be 0x%08x)", checksum, calculated_adler32);
2130 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(adler32_correct));
2132 case SCTP_CHECKSUM_CRC32C:
2133 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2134 crc32c_correct = (checksum == calculated_crc32c);
2136 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2137 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2139 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2140 checksum, "Checksum: 0x%08x (incorrect CRC32C, should be 0x%08x)", checksum, calculated_crc32c);
2141 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct));
2143 case SCTP_CHECKSUM_AUTOMATIC:
2144 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2145 adler32_correct = (checksum == calculated_adler32);
2146 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2147 crc32c_correct = (checksum == calculated_crc32c);
2148 if ((adler32_correct) && !(crc32c_correct))
2149 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2150 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2151 else if (!(adler32_correct) && (crc32c_correct))
2152 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2153 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2154 else if ((adler32_correct) && (crc32c_correct))
2155 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2156 checksum, "Checksum: 0x%08x (correct Adler32 and CRC32C)", checksum);
2158 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2159 checksum, "Checksum: 0x%08x (incorrect, should be 0x%08x (Adler32) or 0x%08x (CRC32C))",
2160 checksum, calculated_adler32, calculated_crc32c);
2161 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct || adler32_correct));
2168 /* add all chunks of the sctp datagram to the protocol tree */
2169 dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree);
2172 /* Register the protocol with Ethereal */
2174 proto_register_sctp(void)
2177 /* Setup list of header fields */
2178 static hf_register_info hf[] = {
2179 { &hf_sctp_source_port,
2180 { "Source port", "sctp.srcport",
2181 FT_UINT16, BASE_DEC, NULL, 0x0,
2184 { &hf_sctp_destination_port,
2185 { "Destination port", "sctp.dstport",
2186 FT_UINT16, BASE_DEC, NULL, 0x0,
2190 { "Port", "sctp.port",
2191 FT_UINT16, BASE_DEC, NULL, 0x0,
2194 { &hf_sctp_verification_tag,
2195 { "Verification tag", "sctp.verfication_tag",
2196 FT_UINT32, BASE_HEX, NULL, 0x0,
2199 { &hf_sctp_checksum,
2200 { "Checksum", "sctp.checksum",
2201 FT_UINT32, BASE_HEX, NULL, 0x0,
2204 { &hf_sctp_checksum_bad,
2205 { "Bad checksum", "sctp.checksum_bad",
2206 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2209 { &hf_sctp_chunk_type,
2210 { "Identifier", "sctp.chunk_type",
2211 FT_UINT8, BASE_DEC, VALS(sctp_chunk_type_values), 0x0,
2214 { &hf_sctp_chunk_flags,
2215 { "Flags", "sctp.chunk_flags",
2216 FT_UINT8, BASE_BIN, NULL, 0x0,
2219 { &hf_sctp_chunk_length,
2220 { "Length", "sctp.chunk_length",
2221 FT_UINT16, BASE_DEC, NULL, 0x0,
2224 { &hf_sctp_init_chunk_initiate_tag,
2225 { "Initiate tag", "sctp.init.chunk.initiate.tag",
2226 FT_UINT32, BASE_HEX, NULL, 0x0,
2229 { &hf_sctp_init_chunk_adv_rec_window_credit,
2230 { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
2231 FT_UINT32, BASE_DEC, NULL, 0x0,
2234 { &hf_sctp_init_chunk_number_of_outbound_streams,
2235 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
2236 FT_UINT16, BASE_DEC, NULL, 0x0,
2239 { &hf_sctp_init_chunk_number_of_inbound_streams,
2240 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
2241 FT_UINT16, BASE_DEC, NULL, 0x0,
2244 {&hf_sctp_init_chunk_initial_tsn,
2245 { "Initial TSN", "sctp.init.chunk.initial.tsn",
2246 FT_UINT32, BASE_DEC, NULL, 0x0,
2249 {&hf_sctp_cumulative_tsn_ack,
2250 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
2251 FT_UINT32, BASE_DEC, NULL, 0x0,
2254 {&hf_sctp_data_chunk_tsn,
2255 { "TSN", "sctp.tsn",
2256 FT_UINT32, BASE_DEC, NULL, 0x0,
2259 {&hf_sctp_data_chunk_stream_id,
2260 { "Stream Identifier", "sctp.stream_id",
2261 FT_UINT16, BASE_HEX, NULL, 0x0,
2264 {&hf_sctp_data_chunk_stream_seq_number,
2265 { "Stream sequence number", "sctp.stream_seq_number",
2266 FT_UINT16, BASE_DEC, NULL, 0x0,
2269 {&hf_sctp_data_chunk_payload_proto_id,
2270 { "Payload protocol identifier", "sctp.payload_proto_id",
2271 FT_UINT32, BASE_DEC, VALS(sctp_payload_proto_id_values), 0x0,
2274 {&hf_sctp_data_chunk_e_bit,
2275 { "E-Bit", "sctp.data.e_bit",
2276 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
2279 {&hf_sctp_data_chunk_b_bit,
2280 { "B-Bit", "sctp.data.b_bit",
2281 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
2284 {&hf_sctp_data_chunk_u_bit,
2285 { "U-Bit", "sctp.data.u.bit",
2286 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
2289 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
2290 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
2291 FT_UINT32, BASE_DEC, NULL, 0x0,
2294 {&hf_sctp_sack_chunk_adv_rec_window_credit,
2295 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
2296 FT_UINT32, BASE_DEC, NULL, 0x0,
2299 {&hf_sctp_sack_chunk_number_of_gap_blocks,
2300 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
2301 FT_UINT16, BASE_DEC, NULL, 0x0,
2304 {&hf_sctp_sack_chunk_number_of_dup_tsns,
2305 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
2306 FT_UINT16, BASE_DEC, NULL, 0x0,
2309 {&hf_sctp_sack_chunk_gap_block_start,
2310 { "Start", "sctp.sack.gap_block_start",
2311 FT_UINT16, BASE_DEC, NULL, 0x0,
2314 {&hf_sctp_sack_chunk_gap_block_end,
2315 { "End", "sctp.sack.gap_block_end",
2316 FT_UINT16, BASE_DEC, NULL, 0x0,
2319 {&hf_sctp_sack_chunk_duplicate_tsn,
2320 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
2321 FT_UINT16, BASE_DEC, NULL, 0x0,
2324 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
2325 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
2326 FT_UINT32, BASE_DEC, NULL, 0x0,
2329 {&hf_sctp_ecne_chunk_lowest_tsn,
2330 { "Lowest TSN", "sctp.ecne.lowest_tsn",
2331 FT_UINT32, BASE_DEC, NULL, 0x0,
2334 {&hf_sctp_cwr_chunk_lowest_tsn,
2335 { "Lowest TSN", "sctp.cwr.lowest_tsn",
2336 FT_UINT32, BASE_DEC, NULL, 0x0,
2339 {&hf_sctp_shutdown_complete_chunk_t_bit,
2340 { "E-Bit", "sctp.shutdown_complete.t_bit",
2341 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2344 {&hf_sctp_forward_tsn_chunk_tsn,
2345 { "New cumulative TSN", "sctp.forward_tsn.tsn",
2346 FT_UINT32, BASE_DEC, NULL, 0x0,
2349 {&hf_sctp_chunk_parameter_type,
2350 { "Parameter type", "sctp.parameter.type",
2351 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2354 {&hf_sctp_chunk_parameter_length,
2355 { "Parameter length", "sctp.parameter.length",
2356 FT_UINT16, BASE_DEC, NULL, 0x0,
2359 {&hf_sctp_parameter_ipv4_address,
2360 { "IP Version 4 address", "sctp.parameter.ipv4_address",
2361 FT_IPv4, BASE_NONE, NULL, 0x0,
2364 {&hf_sctp_parameter_ipv6_address,
2365 { "IP Version 6 address", "sctp.parameter.ipv6_address",
2366 FT_IPv6, BASE_NONE, NULL, 0x0,
2369 {&hf_sctp_parameter_cookie_preservative_increment,
2370 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
2371 FT_UINT32, BASE_DEC, NULL, 0x0,
2374 {&hf_sctp_parameter_hostname_hostname,
2375 { "Hostname", "sctp.parameter.hostname.hostname",
2376 FT_STRING, BASE_NONE, NULL, 0x0,
2379 {&hf_sctp_supported_address_types_parameter,
2380 { "Supported address type", "sctp.parameter.supported_addres_type",
2381 FT_UINT16, BASE_DEC, NULL, 0x0,
2384 {&hf_sctp_ustreams_start,
2385 { "Start", "sctp.unreliable_streams.start",
2386 FT_UINT16, BASE_DEC, NULL, 0x0,
2389 {&hf_sctp_ustreams_end,
2390 { "End", "sctp.unreliable_streams.end",
2391 FT_UINT16, BASE_DEC, NULL, 0x0,
2394 {&hf_sctp_asconf_serial,
2395 { "Serial Number", "sctp.asconf.serial_number",
2396 FT_UINT32, BASE_HEX, NULL, 0x0,
2399 {&hf_sctp_asconf_correlation_id,
2400 { "Correlation_id", "sctp.asconf.correlation_id",
2401 FT_UINT32, BASE_HEX, NULL, 0x0,
2404 {&hf_sctp_asconf_reserved,
2405 { "Reserved", "sctp.asconf.reserved",
2406 FT_BYTES, BASE_NONE, NULL, 0x0,
2409 {&hf_sctp_asconf_addr_type,
2410 { "Address type", "sctp.asconf.address_type",
2411 FT_UINT8, BASE_HEX, VALS(sctp_address_type_values), 0x0,
2414 {&hf_sctp_asconf_addr,
2415 { "Address bytes", "sctp.asconf.address_bytes",
2416 FT_BYTES, BASE_NONE, NULL, 0x0,
2419 {&hf_sctp_asconf_ipv4_address,
2420 { "IP Version 4 address", "sctp.asconf.ipv4_address",
2421 FT_IPv4, BASE_NONE, NULL, 0x0,
2424 {&hf_sctp_asconf_ipv6_address,
2425 { "IP Version 6 address", "sctp.asconf.ipv6_address",
2426 FT_IPv6, BASE_NONE, NULL, 0x0,
2429 {&hf_sctp_asconf_ack_serial,
2430 { "Serial Number", "sctp.asconf_ack.serial_number",
2431 FT_UINT32, BASE_HEX, NULL, 0x0,
2434 {&hf_sctp_asconf_ack_correlation_id,
2435 { "Correlation_id", "sctp.asconf_ack.correlation_id",
2436 FT_UINT32, BASE_HEX, NULL, 0x0,
2439 {&hf_sctp_adap_indication,
2440 { "Indication", "sctp.adapation_layer_indication.indication",
2441 FT_UINT32, BASE_HEX, NULL, 0x0,
2444 {&hf_sctp_cause_code,
2445 { "Cause code", "sctp.cause.code",
2446 FT_UINT16, BASE_HEX, VALS(sctp_cause_code_values), 0x0,
2449 {&hf_sctp_cause_length,
2450 { "Cause length", "sctp.cause.length",
2451 FT_UINT16, BASE_DEC, NULL, 0x0,
2454 {&hf_sctp_cause_stream_identifier,
2455 { "Stream identifier", "sctp.cause.stream_identifier",
2456 FT_UINT16, BASE_DEC, NULL, 0x0,
2459 {&hf_sctp_cause_number_of_missing_parameters,
2460 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
2461 FT_UINT32, BASE_DEC, NULL, 0x0,
2464 {&hf_sctp_cause_missing_parameter_type,
2465 { "Missing parameter type", "sctp.cause.missing_parameter_type",
2466 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2469 {&hf_sctp_cause_measure_of_staleness,
2470 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
2471 FT_UINT32, BASE_DEC, NULL, 0x0,
2474 {&hf_sctp_cause_tsn,
2475 { "TSN", "sctp.cause.tsn",
2476 FT_UINT32, BASE_DEC, NULL, 0x0,
2481 /* Setup protocol subtree array */
2482 static gint *ett[] = {
2485 &ett_sctp_chunk_parameter,
2486 &ett_sctp_chunk_cause,
2487 &ett_sctp_data_chunk_flags,
2488 &ett_sctp_sack_chunk_gap_block,
2489 &ett_sctp_supported_address_types_parameter,
2490 &ett_sctp_unrecognized_parameter_parameter,
2491 &ett_sctp_unreliable_streams_interval
2494 static enum_val_t sctp_checksum_options[] = {
2495 { "None", SCTP_CHECKSUM_NONE },
2496 { "Adler 32", SCTP_CHECKSUM_ADLER32 },
2497 { "CRC 32c", SCTP_CHECKSUM_CRC32C },
2498 { "Automatic", SCTP_CHECKSUM_AUTOMATIC},
2502 /* Register the protocol name and description */
2503 proto_sctp = proto_register_protocol("Stream Control Transmission Protocol", "SCTP", "sctp");
2504 sctp_module = prefs_register_protocol(proto_sctp, NULL);
2505 prefs_register_enum_preference(sctp_module, "checksum",
2507 "The type of checksum used in SCTP packets",
2508 &sctp_checksum, sctp_checksum_options, FALSE);
2510 /* Required function calls to register the header fields and subtrees used */
2511 proto_register_field_array(proto_sctp, hf, array_length(hf));
2512 proto_register_subtree_array(ett, array_length(ett));
2514 /* subdissector code */
2515 sctp_port_dissector_table = register_dissector_table("sctp.port", "SCTP port", FT_UINT16, BASE_DEC);
2516 sctp_ppi_dissector_table = register_dissector_table("sctp.ppi", "SCTP payload protocol identifier", FT_UINT32, BASE_HEX);
2521 proto_reg_handoff_sctp(void)
2523 dissector_handle_t sctp_handle;
2525 sctp_handle = create_dissector_handle(dissect_sctp, proto_sctp);
2526 dissector_add("ip.proto", IP_PROTO_SCTP, sctp_handle);