2 * Routines for Stream Control Transmission Protocol dissection
3 * It should be compilant to
4 * - RFC 2960, for basic SCTP support
5 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-addip-sctp-03.txt for the add-IP extension
6 * - http://www.sctp.org/draft-ietf-tsvwg-usctp-01.txt for the 'Limited Retransmission' extension
7 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpcsum-03.txt
8 * Copyright 2000, 2001, 2002, Michael Tuexen <Michael.Tuexen@icn.siemens.de>
9 * Still to do (so stay tuned)
10 * - support for reassembly
13 * $Id: packet-sctp.c,v 1.35 2002/04/16 19:58:53 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;
144 static int hf_sctp_abort_chunk_t_bit = -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_shutdown_complete_chunk_flags = -1;
157 static gint ett_sctp_abort_chunk_flags = -1;
158 static gint ett_sctp_sack_chunk_gap_block = -1;
159 static gint ett_sctp_supported_address_types_parameter = -1;
160 static gint ett_sctp_unrecognized_parameter_parameter = -1;
161 static gint ett_sctp_unreliable_streams_interval = -1;
163 #define SCTP_DATA_CHUNK_ID 0
164 #define SCTP_INIT_CHUNK_ID 1
165 #define SCTP_INIT_ACK_CHUNK_ID 2
166 #define SCTP_SACK_CHUNK_ID 3
167 #define SCTP_HEARTBEAT_CHUNK_ID 4
168 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
169 #define SCTP_ABORT_CHUNK_ID 6
170 #define SCTP_SHUTDOWN_CHUNK_ID 7
171 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
172 #define SCTP_ERROR_CHUNK_ID 9
173 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
174 #define SCTP_COOKIE_ACK_CHUNK_ID 11
175 #define SCTP_ECNE_CHUNK_ID 12
176 #define SCTP_CWR_CHUNK_ID 13
177 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
178 #define SCTP_FORWARD_TSN_CHUNK_ID 192
179 #define SCTP_ASCONF_ACK_CHUNK_ID 0x80
180 #define SCTP_ASCONF_CHUNK_ID 0XC1
182 #define SCTP_IETF_EXT 255
184 static const value_string sctp_chunk_type_values[] = {
185 { SCTP_DATA_CHUNK_ID, "DATA" },
186 { SCTP_INIT_CHUNK_ID, "INIT" },
187 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
188 { SCTP_SACK_CHUNK_ID, "SACK" },
189 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
190 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
191 { SCTP_ABORT_CHUNK_ID, "ABORT" },
192 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
193 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
194 { SCTP_ERROR_CHUNK_ID, "ERROR" },
195 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
196 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
197 { SCTP_ECNE_CHUNK_ID, "ECNE" },
198 { SCTP_CWR_CHUNK_ID, "CWR" },
199 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
200 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
201 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
202 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
203 { SCTP_IETF_EXT, "IETF_EXTENSION" },
206 #define HEARTBEAT_INFO_PARAMETER_ID 0x0001
207 #define IPV4ADDRESS_PARAMETER_ID 0x0005
208 #define IPV6ADDRESS_PARAMETER_ID 0x0006
209 #define STATE_COOKIE_PARAMETER_ID 0x0007
210 #define UNREC_PARA_PARAMETER_ID 0x0008
211 #define COOKIE_PRESERVATIVE_PARAMETER_ID 0x0009
212 #define HOSTNAME_ADDRESS_PARAMETER_ID 0x000b
213 #define SUPPORTED_ADDRESS_TYPES_PARAMETER_ID 0x000c
214 #define ECN_PARAMETER_ID 0x8000
215 #define UNRELIABLE_STREAMS_PARAMETER_ID 0xC000
216 #define ADD_IP_ADDRESS_PARAMETER_ID 0xC001
217 #define DEL_IP_ADDRESS_PARAMETER_ID 0xC002
218 #define ERROR_CAUSE_INDICATION_PARAMETER_ID 0xC003
219 #define SET_PRIMARY_ADDRESS_PARAMETER_ID 0xC004
220 #define SUCCESS_REPORT_PARAMETER_ID 0xC005
221 #define ADAP_LAYER_INDICATION_PARAMETER_ID 0xC006
223 static const value_string sctp_parameter_identifier_values[] = {
224 { HEARTBEAT_INFO_PARAMETER_ID, "Heartbeat info" },
225 { IPV4ADDRESS_PARAMETER_ID, "IPv4 address" },
226 { IPV6ADDRESS_PARAMETER_ID, "IPv6 address" },
227 { STATE_COOKIE_PARAMETER_ID, "State cookie" },
228 { UNREC_PARA_PARAMETER_ID, "Unrecognized parameters" },
229 { COOKIE_PRESERVATIVE_PARAMETER_ID, "Cookie preservative" },
230 { HOSTNAME_ADDRESS_PARAMETER_ID, "Hostname address" },
231 { SUPPORTED_ADDRESS_TYPES_PARAMETER_ID, "Supported address types" },
232 { ECN_PARAMETER_ID, "ECN" },
233 { UNRELIABLE_STREAMS_PARAMETER_ID, "Unreliable streams" },
234 { ADD_IP_ADDRESS_PARAMETER_ID, "Add IP address" },
235 { DEL_IP_ADDRESS_PARAMETER_ID, "Delete IP address" },
236 { ERROR_CAUSE_INDICATION_PARAMETER_ID, "Error cause indication" },
237 { SET_PRIMARY_ADDRESS_PARAMETER_ID, "Set primary address" },
238 { SUCCESS_REPORT_PARAMETER_ID, "Success report" },
239 { ADAP_LAYER_INDICATION_PARAMETER_ID, "Adaptation Layer Indication" },
242 #define PARAMETER_TYPE_LENGTH 2
243 #define PARAMETER_LENGTH_LENGTH 2
244 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
246 #define PARAMETER_HEADER_OFFSET 0
247 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
248 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
249 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
251 #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET
252 #define HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
254 #define IPV4_ADDRESS_LENGTH 4
255 #define IPV6_ADDRESS_LENGTH 16
257 #define STATE_COOKIE_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
258 #define STATE_COOKIE_PARAMETER_COOKIE_OFFSET PARAMETER_VALUE_OFFSET
260 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET PARAMETER_VALUE_OFFSET
261 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH 4
262 #define SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH 2
264 #define CAUSE_CODE_LENGTH 2
265 #define CAUSE_LENGTH_LENGTH 2
266 #define CAUSE_HEADER_LENGTH (CAUSE_CODE_LENGTH + CAUSE_LENGTH_LENGTH)
268 #define CAUSE_HEADER_OFFSET 0
269 #define CAUSE_CODE_OFFSET CAUSE_HEADER_OFFSET
270 #define CAUSE_LENGTH_OFFSET (CAUSE_CODE_OFFSET + CAUSE_CODE_LENGTH)
271 #define CAUSE_INFO_OFFSET (CAUSE_LENGTH_OFFSET + CAUSE_LENGTH_LENGTH)
273 #define CAUSE_STREAM_IDENTIFIER_LENGTH 2
274 #define CAUSE_RESERVED_LENGTH 2
275 #define CAUSE_STREAM_IDENTIFIER_OFFSET CAUSE_INFO_OFFSET
276 #define CAUSE_RESERVED_OFFSET (CAUSE_STREAM_IDENTIFIER_OFFSET + CAUSE_STREAM_IDENTIFIER_LENGTH)
278 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH 4
279 #define CAUSE_MISSING_PARAMETER_TYPE_LENGTH 2
281 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET CAUSE_INFO_OFFSET
282 #define CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET (CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET + \
283 CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH )
285 #define CAUSE_MEASURE_OF_STALENESS_LENGTH 4
286 #define CAUSE_MEASURE_OF_STALENESS_OFFSET CAUSE_INFO_OFFSET
288 #define CAUSE_TSN_LENGTH 4
289 #define CAUSE_TSN_OFFSET CAUSE_INFO_OFFSET
291 #define INVALID_STREAM_IDENTIFIER 0x01
292 #define MISSING_MANDATORY_PARAMETERS 0x02
293 #define STALE_COOKIE_ERROR 0x03
294 #define OUT_OF_RESOURCE 0x04
295 #define UNRESOLVABLE_ADDRESS 0x05
296 #define UNRECOGNIZED_CHUNK_TYPE 0x06
297 #define INVALID_MANDATORY_PARAMETER 0x07
298 #define UNRECOGNIZED_PARAMETERS 0x08
299 #define NO_USER_DATA 0x09
300 #define COOKIE_RECEIVED_WHILE_SHUTTING_DOWN 0x0a
301 #define REQUEST_TO_DELETE_LAST_ADDRESS 0x0c
302 #define OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE 0X0d
303 #define REQUEST_TO_DELETE_SOURCE_ADDRESS 0x0e
305 static const value_string sctp_cause_code_values[] = {
306 { INVALID_STREAM_IDENTIFIER, "Invalid stream identifier" },
307 { MISSING_MANDATORY_PARAMETERS, "Missing mandator parameter" },
308 { STALE_COOKIE_ERROR, "Stale cookie error" },
309 { OUT_OF_RESOURCE, "Out of resource" },
310 { UNRESOLVABLE_ADDRESS, "Unresolvable address" },
311 { UNRECOGNIZED_CHUNK_TYPE, "Unrecognized chunk type " },
312 { INVALID_MANDATORY_PARAMETER, "Invalid mandatory parameter" },
313 { UNRECOGNIZED_PARAMETERS, "Unrecognized parameters" },
314 { NO_USER_DATA, "No user data" },
315 { COOKIE_RECEIVED_WHILE_SHUTTING_DOWN, "Cookie received while shutting down" },
316 { REQUEST_TO_DELETE_LAST_ADDRESS, "Request to delete last address" },
317 { OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE, "Operation refused due to resource shortage" },
318 { REQUEST_TO_DELETE_SOURCE_ADDRESS, "Request to delete source address" },
321 #define NOT_SPECIFIED_PROTOCOL_ID 0
322 #define IUA_PAYLOAD_PROTOCOL_ID 1
323 #define M2UA_PAYLOAD_PROTOCOL_ID 2
324 #define M3UA_PAYLOAD_PROTOCOL_ID 3
325 #define SUA_PAYLOAD_PROTOCOL_ID 4
326 #define M2PA_PAYLOAD_PROTOCOL_ID 5
327 #define V5UA_PAYLOAD_PROTOCOL_ID 6
329 static const value_string sctp_payload_proto_id_values[] = {
330 { NOT_SPECIFIED_PROTOCOL_ID, "not specified" },
331 { IUA_PAYLOAD_PROTOCOL_ID, "IUA" },
332 { M2UA_PAYLOAD_PROTOCOL_ID, "M2UA" },
333 { M3UA_PAYLOAD_PROTOCOL_ID, "M3UA" },
334 { SUA_PAYLOAD_PROTOCOL_ID, "SUA" },
335 { M2PA_PAYLOAD_PROTOCOL_ID, "M2PA" },
336 { V5UA_PAYLOAD_PROTOCOL_ID, "V5UA" },
339 /* The structure of the common header is described by the following constants */
340 #define SOURCE_PORT_LENGTH 2
341 #define DESTINATION_PORT_LENGTH 2
342 #define VERIFICATION_TAG_LENGTH 4
343 #define CHECKSUM_LENGTH 4
344 #define COMMON_HEADER_LENGTH (SOURCE_PORT_LENGTH + \
345 DESTINATION_PORT_LENGTH + \
346 VERIFICATION_TAG_LENGTH + \
348 #define SOURCE_PORT_OFFSET 0
349 #define DESTINATION_PORT_OFFSET (SOURCE_PORT_OFFSET + SOURCE_PORT_LENGTH)
350 #define VERIFICATION_TAG_OFFSET (DESTINATION_PORT_OFFSET + DESTINATION_PORT_LENGTH)
351 #define CHECKSUM_OFFSET (VERIFICATION_TAG_OFFSET + VERIFICATION_TAG_LENGTH)
353 /* The structure of the chunk header is described by the following constants */
354 #define CHUNK_TYPE_LENGTH 1
355 #define CHUNK_FLAGS_LENGTH 1
356 #define CHUNK_LENGTH_LENGTH 2
357 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
358 CHUNK_FLAGS_LENGTH + \
360 #define CHUNK_HEADER_OFFSET 0
361 #define CHUNK_TYPE_OFFSET CHUNK_HEADER_OFFSET
362 #define CHUNK_FLAGS_OFFSET (CHUNK_TYPE_OFFSET + CHUNK_TYPE_LENGTH)
363 #define CHUNK_LENGTH_OFFSET (CHUNK_FLAGS_OFFSET + CHUNK_FLAGS_LENGTH)
364 #define CHUNK_VALUE_OFFSET (CHUNK_LENGTH_OFFSET + CHUNK_LENGTH_LENGTH)
366 /* The following constants describe the structure of DATA chunks */
367 #define DATA_CHUNK_TSN_LENGTH 4
368 #define DATA_CHUNK_STREAM_ID_LENGTH 2
369 #define DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH 2
370 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
372 #define DATA_CHUNK_TSN_OFFSET (CHUNK_VALUE_OFFSET + 0)
373 #define DATA_CHUNK_STREAM_ID_OFFSET (DATA_CHUNK_TSN_OFFSET + DATA_CHUNK_TSN_LENGTH)
374 #define DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET (DATA_CHUNK_STREAM_ID_OFFSET + \
375 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
376 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET (DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET + \
377 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
378 #define DATA_CHUNK_PAYLOAD_OFFSET (DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET + \
379 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
381 #define DATA_CHUNK_HEADER_LENGTH (CHUNK_HEADER_LENGTH + \
382 DATA_CHUNK_TSN_LENGTH + \
383 DATA_CHUNK_STREAM_ID_LENGTH + \
384 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH + \
385 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
387 #define SCTP_DATA_CHUNK_E_BIT 0x01
388 #define SCTP_DATA_CHUNK_B_BIT 0x02
389 #define SCTP_DATA_CHUNK_U_BIT 0x04
391 #define INIT_CHUNK_INITIATE_TAG_LENGTH 4
392 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
393 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH 2
394 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH 2
395 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
397 #define INIT_CHUNK_INITIATE_TAG_OFFSET CHUNK_VALUE_OFFSET
398 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (INIT_CHUNK_INITIATE_TAG_OFFSET + \
399 INIT_CHUNK_INITIATE_TAG_LENGTH )
400 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET (INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
401 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH )
402 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET (INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET + \
403 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH )
404 #define INIT_CHUNK_INITIAL_TSN_OFFSET (INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET + \
405 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH )
406 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
407 INIT_CHUNK_INITIAL_TSN_LENGTH )
410 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
411 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
412 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH 2
413 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH 2
414 #define SACK_CHUNK_GAP_BLOCK_LENGTH 4
415 #define SACK_CHUNK_GAP_BLOCK_START_LENGTH 2
416 #define SACK_CHUNK_GAP_BLOCK_END_LENGTH 2
417 #define SACK_CHUNK_DUP_TSN_LENGTH 4
419 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
420 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
421 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
422 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET (SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
423 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH)
424 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET (SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET + \
425 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH)
426 #define SACK_CHUNK_GAP_BLOCK_OFFSET (SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET + \
427 SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH)
429 #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET
431 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET CHUNK_VALUE_OFFSET
432 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
434 #define ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
435 #define ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
437 #define COOKIE_ECHO_CHUNK_COOKIE_OFFSET CHUNK_VALUE_OFFSET
439 #define ECNE_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
440 #define ECNE_CHUNK_LOWEST_TSN_LENGTH 4
442 #define CWR_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
443 #define CWR_CHUNK_LOWEST_TSN_LENGTH 4
445 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT 0x01
447 static const true_false_string sctp_data_chunk_e_bit_value = {
449 "Not the last segment"
452 static const true_false_string sctp_data_chunk_b_bit_value = {
457 static const true_false_string sctp_data_chunk_u_bit_value = {
458 "Unordered delivery",
462 static const true_false_string sctp_shutdown_complete_chunk_t_bit_value = {
467 #define SCTP_CHECKSUM_NONE 0
468 #define SCTP_CHECKSUM_ADLER32 1
469 #define SCTP_CHECKSUM_CRC32C 2
470 #define SCTP_CHECKSUM_AUTOMATIC 3
472 static gint sctp_checksum = SCTP_CHECKSUM_ADLER32;
474 /* adler32.c -- compute the Adler-32 checksum of a data stream
475 * Copyright (C) 1995-1996 Mark Adler
476 * For conditions of distribution and use, see copyright notice in zlib.h
477 * available, e.g. from http://www.cdrom.com/pub/infozip/zlib/
479 * It was modified for the use in this dissector.
482 #define BASE 65521L /* largest prime smaller than 65536 */
483 #define NMAX 5540 /* NMAX is the largest n - 12 such that */
484 /* 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
486 #define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
487 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
488 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
489 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
490 #define DO16(buf) DO8(buf,0); DO8(buf,8);
493 sctp_adler32(const unsigned char* buf, unsigned int len)
495 unsigned int s1 = 1L;
496 unsigned int s2 = 0L;
499 /* handle the first 8 bytes of the datagram */
501 buf += SOURCE_PORT_LENGTH +
502 DESTINATION_PORT_LENGTH +
503 VERIFICATION_TAG_LENGTH;
505 /* handle four 0 bytes as checksum */
506 s2 += CHECKSUM_LENGTH * s1;
507 buf += CHECKSUM_LENGTH;
509 /* now we have 12 bytes handled */
510 len -= COMMON_HEADER_LENGTH;
512 /* handle the rest of the datagram */
514 k = len < NMAX ? len : NMAX;
528 return (s2 << 16) | s1;
531 /* The CRC32C code is taken from draft-ietf-tsvwg-sctpcsum-01.txt.
532 * That code is copyrighted by D. Otis and has been modified.
535 #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
536 static unsigned long crc_c[256] =
538 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
539 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
540 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
541 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
542 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
543 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
544 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
545 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
546 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
547 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
548 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
549 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
550 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
551 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
552 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
553 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
554 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
555 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
556 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
557 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
558 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
559 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
560 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
561 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
562 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
563 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
564 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
565 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
566 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
567 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
568 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
569 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
570 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
571 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
572 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
573 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
574 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
575 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
576 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
577 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
578 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
579 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
580 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
581 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
582 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
583 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
584 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
585 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
586 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
587 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
588 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
589 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
590 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
591 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
592 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
593 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
594 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
595 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
596 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
597 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
598 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
599 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
600 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
601 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
605 sctp_crc32c(const unsigned char* buf, unsigned int len)
608 unsigned long crc32 = ~0L;
609 unsigned long result;
610 unsigned char byte0,byte1,byte2,byte3;
612 for (i = 0; i < SOURCE_PORT_LENGTH + DESTINATION_PORT_LENGTH + VERIFICATION_TAG_LENGTH; i++)
614 CRC32C(crc32, buf[i]);
620 for (i = COMMON_HEADER_LENGTH; i < len; i++)
622 CRC32C(crc32, buf[i]);
626 byte0 = result & 0xff;
627 byte1 = (result>>8) & 0xff;
628 byte2 = (result>>16) & 0xff;
629 byte3 = (result>>24) & 0xff;
630 crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
635 nr_of_padding_bytes (guint length)
639 remainder = length % 4;
644 return 4 - remainder;
648 * TLV parameter stuff for INIT and INIT-ACK chunks
652 dissect_parameter(tvbuff_t *, packet_info *, proto_tree *);
655 dissect_error_cause(tvbuff_t *, packet_info *, proto_tree *);
658 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
661 dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, packet_info *pinfo, proto_tree *tree)
663 guint offset, length, padding_length, total_length;
664 tvbuff_t *parameter_tvb;
667 while(tvb_reported_length_remaining(parameter_list_tvb, offset)) {
668 length = tvb_get_ntohs(parameter_list_tvb, offset + PARAMETER_LENGTH_OFFSET);
669 padding_length = nr_of_padding_bytes(length);
670 total_length = length + padding_length;
671 /* create a tvb for the chunk including the padding bytes */
672 parameter_tvb = tvb_new_subset(parameter_list_tvb, offset, total_length, total_length);
673 dissect_parameter(parameter_tvb, pinfo, tree);
674 /* get rid of the handled parameter */
675 offset += total_length;
680 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
682 guint16 length, heartbeat_info_length;
684 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
686 heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
688 proto_tree_add_text(parameter_tree, parameter_tvb, HEARTBEAT_INFO_PARAMETER_INFO_OFFSET, heartbeat_info_length,
689 "Heartbeat info (%u byte%s)",
690 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
692 proto_item_set_text(parameter_item, "Heartbeat info parameter with %u byte%s of info",
693 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
697 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
699 guint32 ipv4_address;
701 tvb_memcpy(parameter_tvb, (guint8 *)&ipv4_address, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH);
702 proto_tree_add_ipv4(parameter_tree, hf_sctp_parameter_ipv4_address,
703 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH,
705 proto_item_set_text(parameter_item, "IPV4 address parameter");
709 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
711 proto_tree_add_ipv6(parameter_tree, hf_sctp_parameter_ipv6_address,
712 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH,
713 tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH));
715 proto_item_set_text(parameter_item, "IPV6 address parameter");
719 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
721 guint16 length, state_cookie_length;
723 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
725 state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
727 proto_tree_add_text(parameter_tree, parameter_tvb, STATE_COOKIE_PARAMETER_COOKIE_OFFSET, state_cookie_length,
728 "State cookie (%u byte%s)",
729 state_cookie_length, plurality(state_cookie_length, "", "s"));
731 proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
732 state_cookie_length, plurality(state_cookie_length, "", "s"));
736 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
738 guint16 length, padding_length, parameter_value_length, unrecognized_parameter_type;
739 tvbuff_t *unrecognized_parameters_tvb;
741 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
742 padding_length = nr_of_padding_bytes(length);
744 parameter_value_length = length - PARAMETER_HEADER_LENGTH + padding_length;
746 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
747 parameter_value_length, parameter_value_length);
748 unrecognized_parameter_type = tvb_get_ntohs(unrecognized_parameters_tvb, PARAMETER_TYPE_OFFSET);
749 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, parameter_tree);
751 proto_item_set_text(parameter_item, "Unrecognized parameter of type %s (0x%x)",
752 val_to_str(unrecognized_parameter_type, sctp_parameter_identifier_values, "unknown"), unrecognized_parameter_type);
756 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
760 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
762 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
763 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
764 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
767 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
772 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
774 guint16 length, hostname_length;
777 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
779 hostname_length = length - PARAMETER_HEADER_LENGTH;
780 hostname = (char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
781 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
782 PARAMETER_VALUE_OFFSET, hostname_length,
785 proto_item_set_text(parameter_item, "Hostname parameter");
789 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
791 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
793 proto_item *address_list_item;
794 proto_tree *address_list_tree;
796 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
797 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
798 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
800 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
801 "Supported Address Types (%u address type%s)",
802 number_of_address_types, plurality(number_of_address_types, "", "s"));
803 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
805 offset = PARAMETER_VALUE_OFFSET;
806 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
807 address_type = tvb_get_ntohs(parameter_tvb, offset);
808 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
809 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
810 address_type, "Supported address type: 0x%04x (%s)",
811 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
812 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
815 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
816 number_of_address_types, plurality(number_of_address_types, "", "s"));
820 dissect_ecn_parameter(proto_item *parameter_item)
822 proto_item_set_text(parameter_item, "ECN parameter");
825 #define USTREAMS_START_LENGTH 2
826 #define USTREAMS_END_LENGTH 2
827 #define USTREAMS_INTERVAL_LENGTH (USTREAMS_START_LENGTH + USTREAMS_END_LENGTH)
830 dissect_unreliable_streams_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
832 guint16 length, start, end, number_of_intervals, interval_number;
833 proto_item *interval_item;
834 proto_tree *interval_tree;
835 gint interval_offset;
837 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
838 number_of_intervals = (length - PARAMETER_HEADER_LENGTH) / USTREAMS_INTERVAL_LENGTH;
840 interval_offset = PARAMETER_VALUE_OFFSET;
841 for(interval_number = 1; interval_number <= number_of_intervals; interval_number++) {
842 start = tvb_get_ntohs(parameter_tvb, interval_offset);
843 end = tvb_get_ntohs(parameter_tvb, interval_offset + USTREAMS_START_LENGTH);
844 interval_item = proto_tree_add_text(parameter_tree, parameter_tvb, interval_offset, USTREAMS_INTERVAL_LENGTH, "Unreliable streams (%u-%u)", start, end);
845 interval_tree = proto_item_add_subtree(interval_item, ett_sctp_unreliable_streams_interval);
846 proto_tree_add_uint(interval_tree, hf_sctp_ustreams_start, parameter_tvb, interval_offset, USTREAMS_START_LENGTH, start);
847 proto_tree_add_uint(interval_tree, hf_sctp_ustreams_end, parameter_tvb, interval_offset + USTREAMS_START_LENGTH, USTREAMS_END_LENGTH, end);
848 interval_offset += USTREAMS_INTERVAL_LENGTH;
850 proto_item_set_text(parameter_item, "Unreliable streams parameter");
854 dissect_add_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
856 guint16 length, parameter_value_length;
857 tvbuff_t *address_tvb;
859 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
860 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
862 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
863 dissect_parameter(address_tvb, pinfo, parameter_tree);
865 proto_item_set_text(parameter_item, "Add IP address parameter");
869 dissect_del_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
871 guint16 length, parameter_value_length;
872 tvbuff_t *address_tvb;
874 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
875 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
877 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
878 dissect_parameter(address_tvb, pinfo, parameter_tree);
880 proto_item_set_text(parameter_item, "Delete IP address parameter");
884 dissect_error_cause_indication_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
886 guint16 length, padding_length, total_length;
888 tvbuff_t *error_cause_tvb;
890 offset = PARAMETER_VALUE_OFFSET;
891 while(tvb_reported_length_remaining(parameter_tvb, offset)) {
892 length = tvb_get_ntohs(parameter_tvb, offset + CAUSE_LENGTH_OFFSET);
893 padding_length = nr_of_padding_bytes(length);
894 total_length = length + padding_length;
895 /* create a tvb for the chunk including the padding bytes */
896 error_cause_tvb = tvb_new_subset(parameter_tvb, offset , total_length, total_length);
897 dissect_error_cause(error_cause_tvb, pinfo, parameter_tree);
898 /* get rid of the handled parameter */
899 offset += total_length;
901 proto_item_set_text(parameter_item, "Error cause indication");
905 dissect_set_primary_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
907 guint16 length, parameter_value_length;
908 tvbuff_t *address_tvb;
910 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
911 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
913 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
914 dissect_parameter(address_tvb, pinfo, parameter_tree);
916 proto_item_set_text(parameter_item, "Set primary address parameter");
920 dissect_success_report_parameter(proto_item *parameter_item)
922 proto_item_set_text(parameter_item, "Success report parameter");
925 #define ADAP_INDICATION_LENGTH 4
926 #define ADAP_INDICATION_OFFSET PARAMETER_VALUE_OFFSET
929 dissect_adap_indication_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
933 indication = tvb_get_ntohl(parameter_tvb, ADAP_INDICATION_OFFSET);
934 proto_tree_add_uint(parameter_tree, hf_sctp_adap_indication, parameter_tvb, ADAP_INDICATION_OFFSET, ADAP_INDICATION_LENGTH, indication);
935 proto_item_set_text(parameter_item, "Adaptation layer indication");
939 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
941 guint16 type, length, parameter_value_length;
943 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
944 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
946 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
948 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
949 "Parameter value (%u byte%s)",
950 parameter_value_length, plurality(parameter_value_length, "", "s"));
952 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
953 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
957 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *chunk_tree)
959 guint16 type, length, padding_length, total_length;
960 proto_item *parameter_item;
961 proto_tree *parameter_tree;
963 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
964 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
965 padding_length = nr_of_padding_bytes(length);
966 total_length = length + padding_length;
968 parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb,
969 PARAMETER_HEADER_OFFSET, total_length, "%s parameter",
970 val_to_str(type, sctp_parameter_identifier_values, "Unknown"));
971 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
973 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_type,
974 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
976 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
977 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
981 case HEARTBEAT_INFO_PARAMETER_ID:
982 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
984 case IPV4ADDRESS_PARAMETER_ID:
985 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
987 case IPV6ADDRESS_PARAMETER_ID:
988 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
990 case STATE_COOKIE_PARAMETER_ID:
991 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
993 case UNREC_PARA_PARAMETER_ID:
994 dissect_unrecognized_parameters_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
996 case COOKIE_PRESERVATIVE_PARAMETER_ID:
997 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
999 case HOSTNAME_ADDRESS_PARAMETER_ID:
1000 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
1002 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
1003 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
1005 case ECN_PARAMETER_ID:
1006 dissect_ecn_parameter(parameter_item);
1008 case UNRELIABLE_STREAMS_PARAMETER_ID:
1009 dissect_unreliable_streams_parameter(parameter_tvb, parameter_tree, parameter_item);
1011 case ADD_IP_ADDRESS_PARAMETER_ID:
1012 dissect_add_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1014 case DEL_IP_ADDRESS_PARAMETER_ID:
1015 dissect_del_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1017 case ERROR_CAUSE_INDICATION_PARAMETER_ID:
1018 dissect_error_cause_indication_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1020 case SET_PRIMARY_ADDRESS_PARAMETER_ID:
1021 dissect_set_primary_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1023 case SUCCESS_REPORT_PARAMETER_ID:
1024 dissect_success_report_parameter(parameter_item);
1026 case ADAP_LAYER_INDICATION_PARAMETER_ID:
1027 dissect_adap_indication_parameter(parameter_tvb, parameter_tree, parameter_item);
1030 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1033 if ((padding_length > 0) && (type != UNREC_PARA_PARAMETER_ID))
1034 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
1035 "Padding: %u byte%s",
1036 padding_length, plurality(padding_length, "", "s"));
1040 * Code to handle error causes for ABORT and ERROR chunks
1043 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1045 guint16 stream_identifier;
1047 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
1048 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
1049 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
1051 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
1052 "Reserved (2 bytes)");
1054 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
1059 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1061 guint32 number_of_missing_parameters, missing_parameter_number;
1062 guint16 parameter_type;
1065 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
1066 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
1067 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
1068 number_of_missing_parameters);
1069 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
1070 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
1071 parameter_type = tvb_get_ntohs(cause_tvb, offset);
1072 proto_tree_add_uint(cause_tree, hf_sctp_cause_missing_parameter_type,
1073 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
1075 offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
1078 proto_item_set_text(cause_item, "Error cause reporting %u missing mandatory parameter%s",
1079 number_of_missing_parameters, plurality(number_of_missing_parameters, "", "s") );
1083 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1085 guint32 measure_of_staleness;
1087 measure_of_staleness = tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
1089 proto_tree_add_uint(cause_tree, hf_sctp_cause_measure_of_staleness, cause_tvb,
1090 CAUSE_MEASURE_OF_STALENESS_OFFSET,
1091 CAUSE_MEASURE_OF_STALENESS_LENGTH,
1092 measure_of_staleness);
1094 proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
1095 measure_of_staleness);
1099 dissect_out_of_resource_cause(proto_item *cause_item)
1101 proto_item_set_text(cause_item, "Error cause reporting lack of resources");
1105 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1107 guint16 code, length, parameter_length, parameter_type;
1108 tvbuff_t *parameter_tvb;
1110 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1111 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1113 parameter_length = length - CAUSE_HEADER_LENGTH;
1114 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
1115 parameter_length, parameter_length);
1117 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1118 parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
1120 proto_item_set_text(cause_item, "Error cause reporting unresolvable address of type 0x%04x (%s)",
1121 parameter_type, val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown") );
1125 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo,
1126 proto_tree *cause_tree, proto_item *cause_item)
1128 guint16 length, chunk_length;
1129 guint8 unrecognized_type;
1130 tvbuff_t *unrecognized_chunk_tvb;
1132 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1134 chunk_length = length - CAUSE_HEADER_LENGTH;
1136 unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, chunk_length, chunk_length);
1137 dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree);
1139 unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
1141 proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
1143 val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
1147 dissect_invalid_mandatory_parameter_cause(proto_item *cause_item)
1149 proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
1153 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1155 guint16 length, padding_length, cause_info_length;
1156 tvbuff_t *unrecognized_parameters_tvb;
1158 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1159 padding_length = nr_of_padding_bytes(length);
1160 cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
1162 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1163 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, cause_tree);
1165 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
1169 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1173 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
1174 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
1179 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
1184 dissect_cookie_received_while_shutting_down_cause(proto_item *cause_item)
1186 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
1190 dissect_delete_last_address_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, "Delete last address cause");
1203 dissect_resource_outage_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, "Operation refused due to resource shortage");
1216 dissect_delete_source_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1218 guint16 length, cause_info_length;
1219 tvbuff_t *parameter_tvb;
1221 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1222 cause_info_length = length - CAUSE_HEADER_LENGTH;
1223 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1224 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1225 proto_item_set_text(cause_item, "Delete source address cause");
1229 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1231 guint16 code, length, cause_info_length;
1233 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1234 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1236 cause_info_length = length - CAUSE_HEADER_LENGTH;
1238 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
1239 "Cause specific information (%u byte%s)",
1240 cause_info_length, plurality(cause_info_length, "", "s"));
1242 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
1243 code, cause_info_length, plurality(cause_info_length, "", "s"));
1247 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
1249 guint16 code, length, padding_length, total_length;
1250 proto_item *cause_item;
1251 proto_tree *cause_tree;
1253 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1254 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1255 padding_length = nr_of_padding_bytes(length);
1256 total_length = length + padding_length;
1258 cause_item = proto_tree_add_text(chunk_tree, cause_tvb,
1259 CAUSE_HEADER_OFFSET, total_length,
1261 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
1263 proto_tree_add_uint(cause_tree, hf_sctp_cause_code,
1264 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
1266 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
1267 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
1271 case INVALID_STREAM_IDENTIFIER:
1272 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
1274 case MISSING_MANDATORY_PARAMETERS:
1275 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
1277 case STALE_COOKIE_ERROR:
1278 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
1280 case OUT_OF_RESOURCE:
1281 dissect_out_of_resource_cause(cause_item);
1283 case UNRESOLVABLE_ADDRESS:
1284 dissect_unresolvable_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1286 case UNRECOGNIZED_CHUNK_TYPE:
1287 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
1289 case INVALID_MANDATORY_PARAMETER:
1290 dissect_invalid_mandatory_parameter_cause(cause_item);
1292 case UNRECOGNIZED_PARAMETERS:
1293 dissect_unrecognized_parameters_cause(cause_tvb, pinfo, cause_tree, cause_item);
1296 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
1298 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
1299 dissect_cookie_received_while_shutting_down_cause(cause_item);
1301 case REQUEST_TO_DELETE_LAST_ADDRESS:
1302 dissect_delete_last_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1304 case OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE:
1305 dissect_resource_outage_cause(cause_tvb, pinfo, cause_tree, cause_item);
1307 case REQUEST_TO_DELETE_SOURCE_ADDRESS:
1308 dissect_delete_source_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1311 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
1314 if ((padding_length > 0) && (code != UNRECOGNIZED_PARAMETERS))
1315 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
1316 "Padding: %u byte%s",
1317 padding_length, plurality(padding_length, "", "s"));
1321 * Code to actually dissect the packets
1325 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
1326 proto_tree *chunk_tree, guint32 ppi, guint16 payload_length, guint16 padding_length)
1328 /* do lookup with the subdissector table */
1329 if (dissector_try_port (sctp_ppi_dissector_table, ppi, payload_tvb, pinfo, tree) ||
1330 dissector_try_port(sctp_port_dissector_table, pinfo->srcport, payload_tvb, pinfo, tree) ||
1331 dissector_try_port(sctp_port_dissector_table, pinfo->destport, payload_tvb, pinfo, tree)){
1335 if (check_col(pinfo->cinfo, COL_INFO))
1336 col_append_str(pinfo->cinfo, COL_INFO, "DATA ");
1337 proto_tree_add_text(chunk_tree, payload_tvb, 0, payload_length,
1338 "Payload (%u byte%s)",
1339 payload_length, plurality(payload_length, "", "s"));
1340 if (padding_length > 0)
1341 proto_tree_add_text(chunk_tree, payload_tvb, payload_length, padding_length,
1342 "Padding: %u byte%s",
1343 padding_length, plurality(padding_length, "", "s"));
1349 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1350 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1353 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
1354 guint32 tsn, payload_proto_id;
1355 proto_tree *flag_tree;
1356 tvbuff_t *payload_tvb;
1358 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1359 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1360 padding_length = nr_of_padding_bytes(length);
1361 total_payload_length = payload_length + padding_length;
1362 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1363 total_payload_length, total_payload_length);
1364 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1367 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1369 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1370 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
1371 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1372 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1373 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1374 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1375 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1377 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1378 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1379 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1381 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1383 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1385 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1387 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1389 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1391 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1393 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1394 chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1396 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1397 tsn, stream_id, stream_seq_number,
1398 payload_length, plurality(payload_length, "", "s"));
1400 return dissect_payload(payload_tvb, pinfo, tree, chunk_tree, payload_proto_id, payload_length, padding_length);
1404 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1405 proto_tree *chunk_tree, proto_item *chunk_item)
1407 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1408 guint16 number_of_inbound_streams, number_of_outbound_streams;
1410 tvbuff_t *parameter_list_tvb;
1412 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1414 if (check_col(pinfo->cinfo, COL_INFO)) {
1415 if (type == SCTP_INIT_CHUNK_ID) {
1416 col_append_str(pinfo->cinfo, COL_INFO, "INIT ");
1418 col_append_str(pinfo->cinfo, COL_INFO, "INIT_ACK ");
1423 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1424 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1425 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1426 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1427 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1429 /* handle fixed parameters */
1430 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1432 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1434 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1436 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1437 adv_rec_window_credit);
1438 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1440 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1441 number_of_outbound_streams);
1442 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1444 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1445 number_of_inbound_streams);
1446 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1448 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1451 /* handle variable paramters */
1452 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1453 dissect_tlv_parameter_list(parameter_list_tvb, pinfo, chunk_tree);
1455 proto_item_set_text(chunk_item,
1456 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1457 val_to_str(type, sctp_chunk_type_values, "unknown"),
1458 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1459 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1464 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1465 proto_tree *chunk_tree, proto_item *chunk_item)
1467 dissect_init_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1471 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1472 proto_tree *chunk_tree, proto_item *chunk_item)
1474 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1475 guint16 number_of_gap_blocks, number_of_dup_tsns;
1476 guint16 gap_block_number, dup_tsn_number, start, end;
1477 gint gap_block_offset, dup_tsn_offset;
1478 proto_item *block_item;
1479 proto_tree *block_tree;
1481 if (check_col(pinfo->cinfo, COL_INFO))
1482 col_append_str(pinfo->cinfo, COL_INFO, "SACK ");
1485 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1486 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1487 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1488 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1490 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1492 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1493 cumulative_tsn_ack);
1494 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1496 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1497 adv_rec_window_credit);
1498 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1500 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1501 number_of_gap_blocks);
1502 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1504 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1505 number_of_dup_tsns);
1507 /* handle the gap acknowledgement blocks */
1508 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1509 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1510 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1511 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1512 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1513 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1514 "Gap Acknowledgement for %u TSN%s",
1515 1 + end - start, plurality(1 + end - start, "", "s"));
1516 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1517 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1519 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1521 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1523 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1524 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1526 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1529 /* handle the duplicate TSNs */
1530 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1531 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1532 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1533 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1535 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1537 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1540 proto_item_set_text(chunk_item,
1541 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1543 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1544 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1549 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1550 proto_tree *chunk_tree, proto_item *chunk_item)
1552 tvbuff_t *parameter_tvb;
1553 guint chunk_length, info_length, padding_length, total_length;
1555 if (check_col(pinfo->cinfo, COL_INFO))
1556 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT ");
1559 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1560 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1561 padding_length = nr_of_padding_bytes(info_length);
1562 total_length = info_length + padding_length;
1563 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1565 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1567 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1572 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1573 proto_tree *chunk_tree, proto_item *chunk_item)
1575 tvbuff_t *parameter_tvb;
1576 guint chunk_length, info_length, padding_length, total_length;
1578 if (check_col(pinfo->cinfo, COL_INFO))
1579 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT_ACK ");
1582 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1583 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1584 padding_length = nr_of_padding_bytes(info_length);
1585 total_length = info_length + padding_length;
1587 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1589 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1591 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1596 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1599 guint offset, number_of_causes;
1600 guint16 length, padding_length, total_length;
1601 tvbuff_t *cause_tvb;
1602 proto_tree *flag_tree;
1603 if (check_col(pinfo->cinfo, COL_INFO))
1604 col_append_str(pinfo->cinfo, COL_INFO, "ABORT ");
1607 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1608 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_abort_chunk_flags);
1609 proto_tree_add_boolean(flag_tree, hf_sctp_abort_chunk_t_bit, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1611 number_of_causes = 0;
1612 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1613 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1614 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1615 padding_length = nr_of_padding_bytes(length);
1616 total_length = length + padding_length;
1617 /* create a tvb for the chunk including the padding bytes */
1618 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1619 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1620 /* get rid of the handled parameter */
1621 offset += total_length;
1625 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s", number_of_causes, plurality(number_of_causes, "", "s"));
1630 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1631 proto_tree *chunk_tree, proto_item *chunk_item)
1633 guint32 cumulative_tsn_ack;
1635 if (check_col(pinfo->cinfo, COL_INFO))
1636 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN ");
1639 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1640 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1642 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1643 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1644 cumulative_tsn_ack);
1646 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1647 cumulative_tsn_ack);
1652 dissect_shutdown_ack_chunk(packet_info *pinfo,
1653 proto_tree *chunk_tree, proto_item *chunk_item)
1655 if (check_col(pinfo->cinfo, COL_INFO))
1656 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_ACK ");
1659 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1664 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1665 proto_tree *chunk_tree, proto_item *chunk_item)
1667 guint offset, number_of_causes;
1668 guint16 length, padding_length, total_length;
1669 tvbuff_t *cause_tvb;
1671 if (check_col(pinfo->cinfo, COL_INFO))
1672 col_append_str(pinfo->cinfo, COL_INFO, "ERROR ");
1675 number_of_causes = 0;
1676 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1678 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1679 padding_length = nr_of_padding_bytes(length);
1680 total_length = length + padding_length;
1681 /* create a tvb for the chunk including the padding bytes */
1682 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1683 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1684 /* get rid of the handled parameter */
1685 offset += total_length;
1687 } while(tvb_reported_length_remaining(chunk_tvb, offset));
1689 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1690 number_of_causes, plurality(number_of_causes, "", "s"));
1695 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1696 proto_tree *chunk_tree, proto_item *chunk_item)
1698 guint length, cookie_length, padding_length;
1700 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1701 padding_length = nr_of_padding_bytes(length);
1702 cookie_length = length - CHUNK_HEADER_LENGTH;
1704 if (check_col(pinfo->cinfo, COL_INFO))
1705 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ECHO ");
1708 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1709 "Cookie (%u byte%s)",
1710 cookie_length, plurality(cookie_length, "", "s"));
1711 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1712 cookie_length, plurality(cookie_length, "", "s"));
1714 if (padding_length > 0)
1715 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1716 "Padding: %u byte%s",
1717 padding_length, plurality(padding_length, "", "s"));
1722 dissect_cookie_ack_chunk(packet_info *pinfo,
1723 proto_tree *chunk_tree, proto_item *chunk_item)
1725 if (check_col(pinfo->cinfo, COL_INFO))
1726 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ACK ");
1729 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1734 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1735 proto_tree *chunk_tree, proto_item *chunk_item)
1739 if (check_col(pinfo->cinfo, COL_INFO))
1740 col_append_str(pinfo->cinfo, COL_INFO, "ECNE ");
1743 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1744 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1746 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1749 proto_item_set_text(chunk_item, "ECNE chunk");
1754 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1755 proto_tree *chunk_tree, proto_item *chunk_item)
1759 if (check_col(pinfo->cinfo, COL_INFO))
1760 col_append_str(pinfo->cinfo, COL_INFO, "CWR ");
1763 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1764 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1766 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1769 proto_item_set_text(chunk_item, "CWR chunk");
1774 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1775 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1779 proto_tree *flag_tree;
1781 if (check_col(pinfo->cinfo, COL_INFO))
1782 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_COMPLETE ");
1785 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1786 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1788 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_shutdown_complete_chunk_flags);
1789 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1790 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1792 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1796 #define FORWARD_TSN_CHUNK_TSN_OFFSET CHUNK_VALUE_OFFSET
1797 #define FORWARD_TSN_CHUNK_TSN_LENGTH 4
1800 dissect_forward_tsn_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1804 if (check_col(pinfo->cinfo, COL_INFO))
1805 col_append_str(pinfo->cinfo, COL_INFO, "FORWARD TSN ");
1808 tsn = tvb_get_ntohl(chunk_tvb, FORWARD_TSN_CHUNK_TSN_OFFSET);
1809 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);
1810 proto_item_set_text(chunk_item, "FORWARD TSN chunk (new cumulative TSN %u)", tsn);
1814 #define SERIAL_NUMBER_LENGTH 4
1815 #define CORRELATION_ID_LENGTH 4
1816 #define ASCONF_RESERVED_LENGTH 3
1817 #define ASCONF_ADDR_TYPE_LENGTH 1
1818 #define ASCONF_ADDR_LENGTH 16
1819 #define SERIAL_NUMBER_OFFSET PARAMETER_VALUE_OFFSET
1821 #define IP_V4_ADDRESS_TYPE 5
1822 #define IP_V6_ADDRESS_TYPE 6
1824 static const value_string sctp_address_type_values[] = {
1825 { IP_V4_ADDRESS_TYPE, "IP V4 address" },
1826 { IP_V6_ADDRESS_TYPE, "IP V6 address" },
1830 dissect_asconf_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1832 guint32 serial_number, correlation_id, ipv4_address;
1833 guint offset, length, padding_length, total_length;
1835 tvbuff_t *parameter_tvb;
1837 if (check_col(pinfo->cinfo, COL_INFO))
1838 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF ");
1841 offset = SERIAL_NUMBER_OFFSET;
1842 serial_number = tvb_get_ntohl(chunk_tvb, offset);
1843 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_serial, chunk_tvb, offset, SERIAL_NUMBER_LENGTH, serial_number);
1844 offset += SERIAL_NUMBER_LENGTH;
1845 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));
1846 offset += ASCONF_RESERVED_LENGTH;
1847 addr_type = tvb_get_guint8(chunk_tvb, offset);
1848 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_addr_type, chunk_tvb, offset, ASCONF_ADDR_TYPE_LENGTH, addr_type);
1849 offset += ASCONF_ADDR_TYPE_LENGTH;
1850 switch (addr_type) {
1851 case IP_V4_ADDRESS_TYPE:
1852 tvb_memcpy(chunk_tvb, (guint8 *)&ipv4_address, offset, IPV4_ADDRESS_LENGTH);
1853 proto_tree_add_ipv4(chunk_tree, hf_sctp_asconf_ipv4_address, chunk_tvb, offset, IPV4_ADDRESS_LENGTH, ipv4_address);
1854 proto_tree_add_bytes(chunk_tree, hf_sctp_asconf_addr, chunk_tvb, offset + IPV4_ADDRESS_LENGTH, ASCONF_ADDR_LENGTH - IPV4_ADDRESS_LENGTH,
1855 tvb_get_ptr(chunk_tvb, offset + IPV4_ADDRESS_LENGTH, ASCONF_ADDR_LENGTH - IPV4_ADDRESS_LENGTH));
1857 case IP_V6_ADDRESS_TYPE:
1858 proto_tree_add_ipv6(chunk_tree, hf_sctp_asconf_ipv6_address, chunk_tvb, offset, IPV6_ADDRESS_LENGTH,
1859 tvb_get_ptr(chunk_tvb, offset, IPV6_ADDRESS_LENGTH));
1862 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));
1865 offset += ASCONF_ADDR_LENGTH;
1866 proto_item_set_text(chunk_item, "ASCONF chunk");
1868 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1869 correlation_id = tvb_get_ntohl(chunk_tvb, offset);
1870 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_correlation_id, chunk_tvb, offset, CORRELATION_ID_LENGTH, correlation_id);
1871 offset += CORRELATION_ID_LENGTH;
1872 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1873 padding_length = nr_of_padding_bytes(length);
1874 total_length = length + padding_length;
1875 /* create a tvb for the chunk including the padding bytes */
1876 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1877 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1878 /* get rid of the handled parameter */
1879 offset += total_length;
1885 dissect_asconf_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *chunk_tree, proto_item *chunk_item)
1887 guint32 serial_number, correlation_id;
1888 guint offset, length, padding_length, total_length;
1889 tvbuff_t *parameter_tvb;
1891 if (check_col(pinfo->cinfo, COL_INFO))
1892 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF-ACK ");
1895 serial_number = tvb_get_ntohl(chunk_tvb, SERIAL_NUMBER_OFFSET);
1896 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_serial, chunk_tvb, SERIAL_NUMBER_OFFSET, SERIAL_NUMBER_LENGTH, serial_number);
1897 proto_item_set_text(chunk_item, "ASCONF-ACK chunk");
1899 offset = SERIAL_NUMBER_OFFSET + SERIAL_NUMBER_LENGTH;
1900 while(tvb_reported_length_remaining(chunk_tvb, offset)) {
1901 correlation_id = tvb_get_ntohl(chunk_tvb, offset);
1902 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_correlation_id, chunk_tvb, offset, CORRELATION_ID_LENGTH, correlation_id);
1903 offset += CORRELATION_ID_LENGTH;
1904 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1905 padding_length = nr_of_padding_bytes(length);
1906 total_length = length + padding_length;
1907 /* create a tvb for the chunk including the padding bytes */
1908 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1909 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1910 /* get rid of the handled parameter */
1911 offset += total_length;
1917 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo,
1918 proto_tree *chunk_tree, proto_item *chunk_item)
1920 guint length, chunk_value_length, padding_length;
1923 if (check_col(pinfo->cinfo, COL_INFO))
1924 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN ");
1927 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1928 padding_length = nr_of_padding_bytes(length);
1929 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1931 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1933 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1934 "Chunk value (%u byte%s)",
1935 chunk_value_length, plurality(chunk_value_length, "", "s"));
1937 if (padding_length > 0)
1938 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1939 "Padding: %u byte%s",
1940 padding_length, plurality(padding_length, "", "s"));
1942 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1943 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1949 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1954 proto_item *flags_item;
1955 proto_item *chunk_item;
1956 proto_tree *chunk_tree;
1960 /* first extract the chunk header */
1961 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1962 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1963 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1966 /* create proto_tree stuff */
1967 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb, CHUNK_HEADER_OFFSET, -1, "Incomplete chunk");
1968 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
1970 /* then insert the chunk header components into the protocol tree */
1971 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_type, chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH, type);
1972 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1973 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length, chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH, length);
1980 /* now dissect the chunk value */
1983 case SCTP_DATA_CHUNK_ID:
1984 result = dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1986 case SCTP_INIT_CHUNK_ID:
1987 dissect_init_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1989 case SCTP_INIT_ACK_CHUNK_ID:
1990 dissect_init_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1992 case SCTP_SACK_CHUNK_ID:
1993 dissect_sack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1995 case SCTP_HEARTBEAT_CHUNK_ID:
1996 dissect_heartbeat_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
1998 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1999 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2001 case SCTP_ABORT_CHUNK_ID:
2002 dissect_abort_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item, flags_item);
2004 case SCTP_SHUTDOWN_CHUNK_ID:
2005 dissect_shutdown_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2007 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
2008 dissect_shutdown_ack_chunk(pinfo, chunk_tree, chunk_item);
2010 case SCTP_ERROR_CHUNK_ID:
2011 dissect_error_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2013 case SCTP_COOKIE_ECHO_CHUNK_ID:
2014 dissect_cookie_echo_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2016 case SCTP_COOKIE_ACK_CHUNK_ID:
2017 dissect_cookie_ack_chunk(pinfo, chunk_tree, chunk_item);
2019 case SCTP_ECNE_CHUNK_ID:
2020 dissect_ecne_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2022 case SCTP_CWR_CHUNK_ID:
2023 dissect_cwr_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2025 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
2026 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item, flags_item);
2028 case SCTP_FORWARD_TSN_CHUNK_ID:
2029 dissect_forward_tsn_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2031 case SCTP_ASCONF_ACK_CHUNK_ID:
2032 dissect_asconf_ack_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2034 case SCTP_ASCONF_CHUNK_ID:
2035 dissect_asconf_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2038 dissect_unknown_chunk(chunk_tvb, pinfo, chunk_tree, chunk_item);
2045 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *sctp_item, proto_tree *sctp_tree)
2047 tvbuff_t *chunk_tvb;
2048 guint16 length, padding_length, total_length;
2049 gint last_offset, offset;
2050 gboolean sctp_item_length_set;
2052 /* the common header of the datagram is already handled */
2054 offset = COMMON_HEADER_LENGTH;
2055 sctp_item_length_set = FALSE;
2057 while(tvb_reported_length_remaining(tvb, offset) > 0) {
2058 /* extract the chunk length and compute number of padding bytes */
2059 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
2060 padding_length = nr_of_padding_bytes(length);
2061 total_length = length + padding_length;
2062 /* create a tvb for the chunk including the padding bytes */
2063 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
2064 /* call dissect_sctp_chunk for a actual work */
2065 if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree) && (tree)) {
2066 proto_item_set_len(sctp_item, offset - last_offset + DATA_CHUNK_HEADER_LENGTH);
2067 sctp_item_length_set = TRUE;
2068 offset += total_length;
2069 last_offset = offset;
2070 if (tvb_reported_length_remaining(tvb, offset) > 0) {
2071 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, offset, -1, FALSE);
2072 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2073 sctp_item_length_set = FALSE;
2076 /* get rid of the dissected chunk */
2077 offset += total_length;
2080 if (!sctp_item_length_set && (tree)) {
2081 proto_item_set_len(sctp_item, offset - last_offset);
2085 /* dissect_sctp handles the common header of a SCTP datagram.
2086 * For the handling of the chunks dissect_sctp_chunks is called.
2090 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2092 guint16 source_port, destination_port;
2093 guint32 verification_tag, checksum, calculated_crc32c, calculated_adler32;
2095 gboolean crc32c_correct, adler32_correct;
2096 proto_item *sctp_item;
2097 proto_tree *sctp_tree;
2099 /* Extract the common header */
2100 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
2101 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
2102 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
2103 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
2105 /* update pi structure */
2106 pinfo->ptype = PT_SCTP;
2107 pinfo->srcport = source_port;
2108 pinfo->destport = destination_port;
2110 /* make entry in the Protocol column on summary display */
2111 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2112 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCTP");
2114 /* Clear entries in Info column on summary display */
2115 if (check_col(pinfo->cinfo, COL_INFO))
2116 col_add_str(pinfo->cinfo, COL_INFO, "");
2118 /* In the interest of speed, if "tree" is NULL, don't do any work not
2119 necessary to generate protocol tree items. */
2121 /* create the sctp protocol tree */
2122 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, 0, -1, FALSE);
2123 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2125 /* add the components of the common header to the protocol tree */
2126 proto_tree_add_uint(sctp_tree, hf_sctp_source_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2127 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2128 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag, tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH, verification_tag);
2129 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2130 proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2132 length = tvb_length(tvb);
2133 switch(sctp_checksum) {
2134 case SCTP_CHECKSUM_NONE:
2135 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum, "Checksum: 0x%08x (not verified)", checksum);
2137 case SCTP_CHECKSUM_ADLER32:
2138 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2139 adler32_correct = (checksum == calculated_adler32);
2140 if (adler32_correct)
2141 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2142 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2144 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2145 checksum, "Checksum: 0x%08x (incorrect Adler32, should be 0x%08x)", checksum, calculated_adler32);
2146 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(adler32_correct));
2148 case SCTP_CHECKSUM_CRC32C:
2149 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2150 crc32c_correct = (checksum == calculated_crc32c);
2152 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2153 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2155 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2156 checksum, "Checksum: 0x%08x (incorrect CRC32C, should be 0x%08x)", checksum, calculated_crc32c);
2157 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct));
2159 case SCTP_CHECKSUM_AUTOMATIC:
2160 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2161 adler32_correct = (checksum == calculated_adler32);
2162 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2163 crc32c_correct = (checksum == calculated_crc32c);
2164 if ((adler32_correct) && !(crc32c_correct))
2165 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2166 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2167 else if (!(adler32_correct) && (crc32c_correct))
2168 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2169 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2170 else if ((adler32_correct) && (crc32c_correct))
2171 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2172 checksum, "Checksum: 0x%08x (correct Adler32 and CRC32C)", checksum);
2174 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2175 checksum, "Checksum: 0x%08x (incorrect, should be 0x%08x (Adler32) or 0x%08x (CRC32C))",
2176 checksum, calculated_adler32, calculated_crc32c);
2177 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct || adler32_correct));
2184 /* add all chunks of the sctp datagram to the protocol tree */
2185 dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree);
2188 /* Register the protocol with Ethereal */
2190 proto_register_sctp(void)
2193 /* Setup list of header fields */
2194 static hf_register_info hf[] = {
2195 { &hf_sctp_source_port,
2196 { "Source port", "sctp.srcport",
2197 FT_UINT16, BASE_DEC, NULL, 0x0,
2200 { &hf_sctp_destination_port,
2201 { "Destination port", "sctp.dstport",
2202 FT_UINT16, BASE_DEC, NULL, 0x0,
2206 { "Port", "sctp.port",
2207 FT_UINT16, BASE_DEC, NULL, 0x0,
2210 { &hf_sctp_verification_tag,
2211 { "Verification tag", "sctp.verfication_tag",
2212 FT_UINT32, BASE_HEX, NULL, 0x0,
2215 { &hf_sctp_checksum,
2216 { "Checksum", "sctp.checksum",
2217 FT_UINT32, BASE_HEX, NULL, 0x0,
2220 { &hf_sctp_checksum_bad,
2221 { "Bad checksum", "sctp.checksum_bad",
2222 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2225 { &hf_sctp_chunk_type,
2226 { "Identifier", "sctp.chunk_type",
2227 FT_UINT8, BASE_DEC, VALS(sctp_chunk_type_values), 0x0,
2230 { &hf_sctp_chunk_flags,
2231 { "Flags", "sctp.chunk_flags",
2232 FT_UINT8, BASE_BIN, NULL, 0x0,
2235 { &hf_sctp_chunk_length,
2236 { "Length", "sctp.chunk_length",
2237 FT_UINT16, BASE_DEC, NULL, 0x0,
2240 { &hf_sctp_init_chunk_initiate_tag,
2241 { "Initiate tag", "sctp.init.chunk.initiate.tag",
2242 FT_UINT32, BASE_HEX, NULL, 0x0,
2245 { &hf_sctp_init_chunk_adv_rec_window_credit,
2246 { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
2247 FT_UINT32, BASE_DEC, NULL, 0x0,
2250 { &hf_sctp_init_chunk_number_of_outbound_streams,
2251 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
2252 FT_UINT16, BASE_DEC, NULL, 0x0,
2255 { &hf_sctp_init_chunk_number_of_inbound_streams,
2256 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
2257 FT_UINT16, BASE_DEC, NULL, 0x0,
2260 {&hf_sctp_init_chunk_initial_tsn,
2261 { "Initial TSN", "sctp.init.chunk.initial.tsn",
2262 FT_UINT32, BASE_DEC, NULL, 0x0,
2265 {&hf_sctp_cumulative_tsn_ack,
2266 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
2267 FT_UINT32, BASE_DEC, NULL, 0x0,
2270 {&hf_sctp_data_chunk_tsn,
2271 { "TSN", "sctp.tsn",
2272 FT_UINT32, BASE_DEC, NULL, 0x0,
2275 {&hf_sctp_data_chunk_stream_id,
2276 { "Stream Identifier", "sctp.stream_id",
2277 FT_UINT16, BASE_HEX, NULL, 0x0,
2280 {&hf_sctp_data_chunk_stream_seq_number,
2281 { "Stream sequence number", "sctp.stream_seq_number",
2282 FT_UINT16, BASE_DEC, NULL, 0x0,
2285 {&hf_sctp_data_chunk_payload_proto_id,
2286 { "Payload protocol identifier", "sctp.payload_proto_id",
2287 FT_UINT32, BASE_DEC, VALS(sctp_payload_proto_id_values), 0x0,
2290 {&hf_sctp_data_chunk_e_bit,
2291 { "E-Bit", "sctp.data.e_bit",
2292 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
2295 {&hf_sctp_data_chunk_b_bit,
2296 { "B-Bit", "sctp.data.b_bit",
2297 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
2300 {&hf_sctp_data_chunk_u_bit,
2301 { "U-Bit", "sctp.data.u.bit",
2302 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
2305 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
2306 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
2307 FT_UINT32, BASE_DEC, NULL, 0x0,
2310 {&hf_sctp_sack_chunk_adv_rec_window_credit,
2311 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
2312 FT_UINT32, BASE_DEC, NULL, 0x0,
2315 {&hf_sctp_sack_chunk_number_of_gap_blocks,
2316 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
2317 FT_UINT16, BASE_DEC, NULL, 0x0,
2320 {&hf_sctp_sack_chunk_number_of_dup_tsns,
2321 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
2322 FT_UINT16, BASE_DEC, NULL, 0x0,
2325 {&hf_sctp_sack_chunk_gap_block_start,
2326 { "Start", "sctp.sack.gap_block_start",
2327 FT_UINT16, BASE_DEC, NULL, 0x0,
2330 {&hf_sctp_sack_chunk_gap_block_end,
2331 { "End", "sctp.sack.gap_block_end",
2332 FT_UINT16, BASE_DEC, NULL, 0x0,
2335 {&hf_sctp_sack_chunk_duplicate_tsn,
2336 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
2337 FT_UINT16, BASE_DEC, NULL, 0x0,
2340 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
2341 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
2342 FT_UINT32, BASE_DEC, NULL, 0x0,
2345 {&hf_sctp_ecne_chunk_lowest_tsn,
2346 { "Lowest TSN", "sctp.ecne.lowest_tsn",
2347 FT_UINT32, BASE_DEC, NULL, 0x0,
2350 {&hf_sctp_cwr_chunk_lowest_tsn,
2351 { "Lowest TSN", "sctp.cwr.lowest_tsn",
2352 FT_UINT32, BASE_DEC, NULL, 0x0,
2355 {&hf_sctp_shutdown_complete_chunk_t_bit,
2356 { "T-Bit", "sctp.shutdown_complete.t_bit",
2357 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2360 {&hf_sctp_abort_chunk_t_bit,
2361 { "T-Bit", "sctp.abort.t_bit",
2362 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2365 {&hf_sctp_forward_tsn_chunk_tsn,
2366 { "New cumulative TSN", "sctp.forward_tsn.tsn",
2367 FT_UINT32, BASE_DEC, NULL, 0x0,
2370 {&hf_sctp_chunk_parameter_type,
2371 { "Parameter type", "sctp.parameter.type",
2372 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2375 {&hf_sctp_chunk_parameter_length,
2376 { "Parameter length", "sctp.parameter.length",
2377 FT_UINT16, BASE_DEC, NULL, 0x0,
2380 {&hf_sctp_parameter_ipv4_address,
2381 { "IP Version 4 address", "sctp.parameter.ipv4_address",
2382 FT_IPv4, BASE_NONE, NULL, 0x0,
2385 {&hf_sctp_parameter_ipv6_address,
2386 { "IP Version 6 address", "sctp.parameter.ipv6_address",
2387 FT_IPv6, BASE_NONE, NULL, 0x0,
2390 {&hf_sctp_parameter_cookie_preservative_increment,
2391 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
2392 FT_UINT32, BASE_DEC, NULL, 0x0,
2395 {&hf_sctp_parameter_hostname_hostname,
2396 { "Hostname", "sctp.parameter.hostname.hostname",
2397 FT_STRING, BASE_NONE, NULL, 0x0,
2400 {&hf_sctp_supported_address_types_parameter,
2401 { "Supported address type", "sctp.parameter.supported_addres_type",
2402 FT_UINT16, BASE_DEC, NULL, 0x0,
2405 {&hf_sctp_ustreams_start,
2406 { "Start", "sctp.unreliable_streams.start",
2407 FT_UINT16, BASE_DEC, NULL, 0x0,
2410 {&hf_sctp_ustreams_end,
2411 { "End", "sctp.unreliable_streams.end",
2412 FT_UINT16, BASE_DEC, NULL, 0x0,
2415 {&hf_sctp_asconf_serial,
2416 { "Serial Number", "sctp.asconf.serial_number",
2417 FT_UINT32, BASE_HEX, NULL, 0x0,
2420 {&hf_sctp_asconf_correlation_id,
2421 { "Correlation_id", "sctp.asconf.correlation_id",
2422 FT_UINT32, BASE_HEX, NULL, 0x0,
2425 {&hf_sctp_asconf_reserved,
2426 { "Reserved", "sctp.asconf.reserved",
2427 FT_BYTES, BASE_NONE, NULL, 0x0,
2430 {&hf_sctp_asconf_addr_type,
2431 { "Address type", "sctp.asconf.address_type",
2432 FT_UINT8, BASE_HEX, VALS(sctp_address_type_values), 0x0,
2435 {&hf_sctp_asconf_addr,
2436 { "Address bytes", "sctp.asconf.address_bytes",
2437 FT_BYTES, BASE_NONE, NULL, 0x0,
2440 {&hf_sctp_asconf_ipv4_address,
2441 { "IP Version 4 address", "sctp.asconf.ipv4_address",
2442 FT_IPv4, BASE_NONE, NULL, 0x0,
2445 {&hf_sctp_asconf_ipv6_address,
2446 { "IP Version 6 address", "sctp.asconf.ipv6_address",
2447 FT_IPv6, BASE_NONE, NULL, 0x0,
2450 {&hf_sctp_asconf_ack_serial,
2451 { "Serial Number", "sctp.asconf_ack.serial_number",
2452 FT_UINT32, BASE_HEX, NULL, 0x0,
2455 {&hf_sctp_asconf_ack_correlation_id,
2456 { "Correlation_id", "sctp.asconf_ack.correlation_id",
2457 FT_UINT32, BASE_HEX, NULL, 0x0,
2460 {&hf_sctp_adap_indication,
2461 { "Indication", "sctp.adapation_layer_indication.indication",
2462 FT_UINT32, BASE_HEX, NULL, 0x0,
2465 {&hf_sctp_cause_code,
2466 { "Cause code", "sctp.cause.code",
2467 FT_UINT16, BASE_HEX, VALS(sctp_cause_code_values), 0x0,
2470 {&hf_sctp_cause_length,
2471 { "Cause length", "sctp.cause.length",
2472 FT_UINT16, BASE_DEC, NULL, 0x0,
2475 {&hf_sctp_cause_stream_identifier,
2476 { "Stream identifier", "sctp.cause.stream_identifier",
2477 FT_UINT16, BASE_DEC, NULL, 0x0,
2480 {&hf_sctp_cause_number_of_missing_parameters,
2481 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
2482 FT_UINT32, BASE_DEC, NULL, 0x0,
2485 {&hf_sctp_cause_missing_parameter_type,
2486 { "Missing parameter type", "sctp.cause.missing_parameter_type",
2487 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2490 {&hf_sctp_cause_measure_of_staleness,
2491 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
2492 FT_UINT32, BASE_DEC, NULL, 0x0,
2495 {&hf_sctp_cause_tsn,
2496 { "TSN", "sctp.cause.tsn",
2497 FT_UINT32, BASE_DEC, NULL, 0x0,
2502 /* Setup protocol subtree array */
2503 static gint *ett[] = {
2506 &ett_sctp_chunk_parameter,
2507 &ett_sctp_chunk_cause,
2508 &ett_sctp_data_chunk_flags,
2509 &ett_sctp_shutdown_complete_chunk_flags,
2510 &ett_sctp_abort_chunk_flags,
2511 &ett_sctp_sack_chunk_gap_block,
2512 &ett_sctp_supported_address_types_parameter,
2513 &ett_sctp_unrecognized_parameter_parameter,
2514 &ett_sctp_unreliable_streams_interval
2517 static enum_val_t sctp_checksum_options[] = {
2518 { "None", SCTP_CHECKSUM_NONE },
2519 { "Adler 32", SCTP_CHECKSUM_ADLER32 },
2520 { "CRC 32c", SCTP_CHECKSUM_CRC32C },
2521 { "Automatic", SCTP_CHECKSUM_AUTOMATIC},
2525 /* Register the protocol name and description */
2526 proto_sctp = proto_register_protocol("Stream Control Transmission Protocol", "SCTP", "sctp");
2527 sctp_module = prefs_register_protocol(proto_sctp, NULL);
2528 prefs_register_enum_preference(sctp_module, "checksum",
2530 "The type of checksum used in SCTP packets",
2531 &sctp_checksum, sctp_checksum_options, FALSE);
2533 /* Required function calls to register the header fields and subtrees used */
2534 proto_register_field_array(proto_sctp, hf, array_length(hf));
2535 proto_register_subtree_array(ett, array_length(ett));
2537 /* subdissector code */
2538 sctp_port_dissector_table = register_dissector_table("sctp.port", "SCTP port", FT_UINT16, BASE_DEC);
2539 sctp_ppi_dissector_table = register_dissector_table("sctp.ppi", "SCTP payload protocol identifier", FT_UINT32, BASE_HEX);
2544 proto_reg_handoff_sctp(void)
2546 dissector_handle_t sctp_handle;
2548 sctp_handle = create_dissector_handle(dissect_sctp, proto_sctp);
2549 dissector_add("ip.proto", IP_PROTO_SCTP, sctp_handle);