2 * Routines for Stream Control Transmission Protocol dissection
3 * It should be compilant to
4 * - RFC 2960, for basic SCTP support
5 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-addip-sctp-03.txt for the add-IP extension
6 * - http://www.sctp.org/draft-ietf-tsvwg-usctp-01.txt for the 'Limited Retransmission' extension
7 * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpcsum-01.txt
8 * Copyright 2000, 2001, 2002, Michael Tuexen <Michael.Tuexen@icn.siemens.de>
9 * Still to do (so stay tuned)
10 * - support for reassembly
13 * $Id: packet-sctp.c,v 1.27 2002/01/15 23:05:36 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"
63 /* Initialize the protocol and registered fields */
64 static int proto_sctp = -1;
65 static int hf_sctp_source_port = -1;
66 static int hf_sctp_destination_port = -1;
67 static int hf_sctp_verification_tag = -1;
68 static int hf_sctp_checksum = -1;
69 static int hf_sctp_checksum_correct = -1;
71 static int hf_sctp_chunk_type = -1;
72 static int hf_sctp_chunk_flags = -1;
73 static int hf_sctp_chunk_length = -1;
75 static int hf_sctp_init_chunk_initiate_tag = -1;
76 static int hf_sctp_init_chunk_adv_rec_window_credit = -1;
77 static int hf_sctp_init_chunk_number_of_outbound_streams = -1;
78 static int hf_sctp_init_chunk_number_of_inbound_streams = -1;
79 static int hf_sctp_init_chunk_initial_tsn = -1;
81 static int hf_sctp_cumulative_tsn_ack = -1;
83 static int hf_sctp_data_chunk_tsn = -1;
84 static int hf_sctp_data_chunk_stream_id = -1;
85 static int hf_sctp_data_chunk_stream_seq_number = -1;
86 static int hf_sctp_data_chunk_payload_proto_id = -1;
88 static int hf_sctp_data_chunk_e_bit = -1;
89 static int hf_sctp_data_chunk_b_bit = -1;
90 static int hf_sctp_data_chunk_u_bit = -1;
92 static int hf_sctp_sack_chunk_cumulative_tsn_ack = -1;
93 static int hf_sctp_sack_chunk_adv_rec_window_credit = -1;
94 static int hf_sctp_sack_chunk_number_of_gap_blocks = -1;
95 static int hf_sctp_sack_chunk_number_of_dup_tsns = -1;
96 static int hf_sctp_sack_chunk_gap_block_start = -1;
97 static int hf_sctp_sack_chunk_gap_block_end = -1;
98 static int hf_sctp_sack_chunk_duplicate_tsn = -1;
100 static int hf_sctp_shutdown_chunk_cumulative_tsn_ack = -1;
102 static int hf_sctp_cwr_chunk_lowest_tsn = -1;
104 static int hf_sctp_ecne_chunk_lowest_tsn = -1;
106 static int hf_sctp_shutdown_complete_chunk_t_bit = -1;
108 static int hf_sctp_chunk_parameter_type = -1;
109 static int hf_sctp_chunk_parameter_length = -1;
110 static int hf_sctp_parameter_ipv4_address = -1;
111 static int hf_sctp_parameter_ipv6_address = -1;
112 static int hf_sctp_parameter_cookie_preservative_increment = -1;
113 static int hf_sctp_parameter_hostname_hostname = -1;
114 static int hf_sctp_supported_address_types_parameter = -1;
116 static int hf_sctp_cause_code = -1;
117 static int hf_sctp_cause_length = -1;
118 static int hf_sctp_cause_stream_identifier = -1;
120 static int hf_sctp_cause_number_of_missing_parameters = -1;
121 static int hf_sctp_cause_missing_parameter_type = -1;
123 static int hf_sctp_cause_measure_of_staleness = -1;
125 static int hf_sctp_cause_tsn = -1;
127 static int hf_sctp_forward_tsn_chunk_tsn = -1;
129 static int hf_sctp_ustreams_start = -1;
130 static int hf_sctp_ustreams_end = -1;
132 static int hf_sctp_asconf_ack_serial = -1;
133 static int hf_sctp_asconf_ack_correlation_id = -1;
135 static int hf_sctp_asconf_serial = -1;
136 static int hf_sctp_asconf_correlation_id = -1;
137 static int hf_sctp_asconf_reserved = -1;
138 static int hf_sctp_asconf_addr_type = -1;
139 static int hf_sctp_asconf_addr = -1;
140 static int hf_sctp_asconf_ipv4_address = -1;
141 static int hf_sctp_asconf_ipv6_address = -1;
142 static int hf_sctp_adap_indication = -1;
144 static dissector_table_t sctp_port_dissector_table;
145 static dissector_table_t sctp_ppi_dissector_table;
147 static module_t *sctp_module;
149 /* Initialize the subtree pointers */
150 static gint ett_sctp = -1;
151 static gint ett_sctp_chunk = -1;
152 static gint ett_sctp_chunk_parameter = -1;
153 static gint ett_sctp_chunk_cause = -1;
154 static gint ett_sctp_data_chunk_flags = -1;
155 static gint ett_sctp_sack_chunk_gap_block = -1;
156 static gint ett_sctp_supported_address_types_parameter = -1;
157 static gint ett_sctp_unrecognized_parameter_parameter = -1;
158 static gint ett_sctp_unreliable_streams_interval = -1;
160 #define SCTP_DATA_CHUNK_ID 0
161 #define SCTP_INIT_CHUNK_ID 1
162 #define SCTP_INIT_ACK_CHUNK_ID 2
163 #define SCTP_SACK_CHUNK_ID 3
164 #define SCTP_HEARTBEAT_CHUNK_ID 4
165 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
166 #define SCTP_ABORT_CHUNK_ID 6
167 #define SCTP_SHUTDOWN_CHUNK_ID 7
168 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
169 #define SCTP_ERROR_CHUNK_ID 9
170 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
171 #define SCTP_COOKIE_ACK_CHUNK_ID 11
172 #define SCTP_ECNE_CHUNK_ID 12
173 #define SCTP_CWR_CHUNK_ID 13
174 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
175 #define SCTP_FORWARD_TSN_CHUNK_ID 192
176 #define SCTP_ASCONF_ACK_CHUNK_ID 0x80
177 #define SCTP_ASCONF_CHUNK_ID 0XC1
179 #define SCTP_IETF_EXT 255
181 static const value_string sctp_chunk_type_values[] = {
182 { SCTP_DATA_CHUNK_ID, "DATA" },
183 { SCTP_INIT_CHUNK_ID, "INIT" },
184 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
185 { SCTP_SACK_CHUNK_ID, "SACK" },
186 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
187 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
188 { SCTP_ABORT_CHUNK_ID, "ABORT" },
189 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
190 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
191 { SCTP_ERROR_CHUNK_ID, "ERROR" },
192 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
193 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
194 { SCTP_ECNE_CHUNK_ID, "ECNE" },
195 { SCTP_CWR_CHUNK_ID, "CWR" },
196 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
197 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
198 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
199 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
200 { SCTP_IETF_EXT, "IETF_EXTENSION" },
203 #define HEARTBEAT_INFO_PARAMETER_ID 0x0001
204 #define IPV4ADDRESS_PARAMETER_ID 0x0005
205 #define IPV6ADDRESS_PARAMETER_ID 0x0006
206 #define STATE_COOKIE_PARAMETER_ID 0x0007
207 #define UNREC_PARA_PARAMETER_ID 0x0008
208 #define COOKIE_PRESERVATIVE_PARAMETER_ID 0x0009
209 #define HOSTNAME_ADDRESS_PARAMETER_ID 0x000b
210 #define SUPPORTED_ADDRESS_TYPES_PARAMETER_ID 0x000c
211 #define ECN_PARAMETER_ID 0x8000
212 #define UNRELIABLE_STREAMS_PARAMETER_ID 0xC000
213 #define ADD_IP_ADDRESS_PARAMETER_ID 0xC001
214 #define DEL_IP_ADDRESS_PARAMETER_ID 0xC002
215 #define ERROR_CAUSE_INDICATION_PARAMETER_ID 0xC003
216 #define SET_PRIMARY_ADDRESS_PARAMETER_ID 0xC004
217 #define SUCCESS_REPORT_PARAMETER_ID 0xC005
218 #define ADAP_LAYER_INDICATION_PARAMETER_ID 0xC006
220 static const value_string sctp_parameter_identifier_values[] = {
221 { HEARTBEAT_INFO_PARAMETER_ID, "Heartbeat info" },
222 { IPV4ADDRESS_PARAMETER_ID, "IPv4 address" },
223 { IPV6ADDRESS_PARAMETER_ID, "IPv6 address" },
224 { STATE_COOKIE_PARAMETER_ID, "State cookie" },
225 { UNREC_PARA_PARAMETER_ID, "Unrecognized parameters" },
226 { COOKIE_PRESERVATIVE_PARAMETER_ID, "Cookie preservative" },
227 { HOSTNAME_ADDRESS_PARAMETER_ID, "Hostname address" },
228 { SUPPORTED_ADDRESS_TYPES_PARAMETER_ID, "Supported address types" },
229 { ECN_PARAMETER_ID, "ECN" },
230 { UNRELIABLE_STREAMS_PARAMETER_ID, "Unreliable streams" },
231 { ADD_IP_ADDRESS_PARAMETER_ID, "Add IP address" },
232 { DEL_IP_ADDRESS_PARAMETER_ID, "Delete IP address" },
233 { ERROR_CAUSE_INDICATION_PARAMETER_ID, "Error cause indication" },
234 { SET_PRIMARY_ADDRESS_PARAMETER_ID, "Set primary address" },
235 { SUCCESS_REPORT_PARAMETER_ID, "Success report" },
236 { ADAP_LAYER_INDICATION_PARAMETER_ID, "Adaptation Layer Indication" },
239 #define PARAMETER_TYPE_LENGTH 2
240 #define PARAMETER_LENGTH_LENGTH 2
241 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
243 #define PARAMETER_HEADER_OFFSET 0
244 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
245 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
246 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
248 #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET
249 #define HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
251 #define IPV4_ADDRESS_LENGTH 4
252 #define IPV6_ADDRESS_LENGTH 16
254 #define STATE_COOKIE_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
255 #define STATE_COOKIE_PARAMETER_COOKIE_OFFSET PARAMETER_VALUE_OFFSET
257 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET PARAMETER_VALUE_OFFSET
258 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH 4
259 #define SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH 2
261 #define CAUSE_CODE_LENGTH 2
262 #define CAUSE_LENGTH_LENGTH 2
263 #define CAUSE_HEADER_LENGTH (CAUSE_CODE_LENGTH + CAUSE_LENGTH_LENGTH)
265 #define CAUSE_HEADER_OFFSET 0
266 #define CAUSE_CODE_OFFSET CAUSE_HEADER_OFFSET
267 #define CAUSE_LENGTH_OFFSET (CAUSE_CODE_OFFSET + CAUSE_CODE_LENGTH)
268 #define CAUSE_INFO_OFFSET (CAUSE_LENGTH_OFFSET + CAUSE_LENGTH_LENGTH)
270 #define CAUSE_STREAM_IDENTIFIER_LENGTH 2
271 #define CAUSE_RESERVED_LENGTH 2
272 #define CAUSE_STREAM_IDENTIFIER_OFFSET CAUSE_INFO_OFFSET
273 #define CAUSE_RESERVED_OFFSET (CAUSE_STREAM_IDENTIFIER_OFFSET + CAUSE_STREAM_IDENTIFIER_LENGTH)
275 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH 4
276 #define CAUSE_MISSING_PARAMETER_TYPE_LENGTH 2
278 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET CAUSE_INFO_OFFSET
279 #define CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET (CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET + \
280 CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH )
282 #define CAUSE_MEASURE_OF_STALENESS_LENGTH 4
283 #define CAUSE_MEASURE_OF_STALENESS_OFFSET CAUSE_INFO_OFFSET
285 #define CAUSE_TSN_LENGTH 4
286 #define CAUSE_TSN_OFFSET CAUSE_INFO_OFFSET
288 #define INVALID_STREAM_IDENTIFIER 0x01
289 #define MISSING_MANDATORY_PARAMETERS 0x02
290 #define STALE_COOKIE_ERROR 0x03
291 #define OUT_OF_RESOURCE 0x04
292 #define UNRESOLVABLE_ADDRESS 0x05
293 #define UNRECOGNIZED_CHUNK_TYPE 0x06
294 #define INVALID_MANDATORY_PARAMETER 0x07
295 #define UNRECOGNIZED_PARAMETERS 0x08
296 #define NO_USER_DATA 0x09
297 #define COOKIE_RECEIVED_WHILE_SHUTTING_DOWN 0x0a
298 #define REQUEST_TO_DELETE_LAST_ADDRESS 0x0c
299 #define OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE 0X0d
300 #define REQUEST_TO_DELETE_SOURCE_ADDRESS 0x0e
302 static const value_string sctp_cause_code_values[] = {
303 { INVALID_STREAM_IDENTIFIER, "Invalid stream identifier" },
304 { MISSING_MANDATORY_PARAMETERS, "Missing mandator parameter" },
305 { STALE_COOKIE_ERROR, "Stale cookie error" },
306 { OUT_OF_RESOURCE, "Out of resource" },
307 { UNRESOLVABLE_ADDRESS, "Unresolvable address" },
308 { UNRECOGNIZED_CHUNK_TYPE, "Unrecognized chunk type " },
309 { INVALID_MANDATORY_PARAMETER, "Invalid mandatory parameter" },
310 { UNRECOGNIZED_PARAMETERS, "Unrecognized parameters" },
311 { NO_USER_DATA, "No user data" },
312 { COOKIE_RECEIVED_WHILE_SHUTTING_DOWN, "Cookie received while shutting down" },
313 { REQUEST_TO_DELETE_LAST_ADDRESS, "Request to delete last address" },
314 { OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE, "Operation refused due to resource shortage" },
315 { REQUEST_TO_DELETE_SOURCE_ADDRESS, "Request to delete source address" },
318 #define NOT_SPECIFIED_PROTOCOL_ID 0
319 #define IUA_PAYLOAD_PROTOCOL_ID 1
320 #define M2UA_PAYLOAD_PROTOCOL_ID 2
321 #define M3UA_PAYLOAD_PROTOCOL_ID 3
322 #define SUA_PAYLOAD_PROTOCOL_ID 4
323 #define M2PA_PAYLOAD_PROTOCOL_ID 5
324 #define V5UA_PAYLOAD_PROTOCOL_ID 6
326 static const value_string sctp_payload_proto_id_values[] = {
327 { NOT_SPECIFIED_PROTOCOL_ID, "not specified" },
328 { IUA_PAYLOAD_PROTOCOL_ID, "IUA" },
329 { M2UA_PAYLOAD_PROTOCOL_ID, "M2UA" },
330 { M3UA_PAYLOAD_PROTOCOL_ID, "M3UA" },
331 { SUA_PAYLOAD_PROTOCOL_ID, "SUA" },
332 { M2PA_PAYLOAD_PROTOCOL_ID, "M2PA" },
333 { V5UA_PAYLOAD_PROTOCOL_ID, "V5UA" },
336 /* The structure of the common header is described by the following constants */
337 #define SOURCE_PORT_LENGTH 2
338 #define DESTINATION_PORT_LENGTH 2
339 #define VERIFICATION_TAG_LENGTH 4
340 #define CHECKSUM_LENGTH 4
341 #define COMMON_HEADER_LENGTH (SOURCE_PORT_LENGTH + \
342 DESTINATION_PORT_LENGTH + \
343 VERIFICATION_TAG_LENGTH + \
345 #define SOURCE_PORT_OFFSET 0
346 #define DESTINATION_PORT_OFFSET (SOURCE_PORT_OFFSET + SOURCE_PORT_LENGTH)
347 #define VERIFICATION_TAG_OFFSET (DESTINATION_PORT_OFFSET + DESTINATION_PORT_LENGTH)
348 #define CHECKSUM_OFFSET (VERIFICATION_TAG_OFFSET + VERIFICATION_TAG_LENGTH)
350 /* The structure of the chunk header is described by the following constants */
351 #define CHUNK_TYPE_LENGTH 1
352 #define CHUNK_FLAGS_LENGTH 1
353 #define CHUNK_LENGTH_LENGTH 2
354 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
355 CHUNK_FLAGS_LENGTH + \
357 #define CHUNK_HEADER_OFFSET 0
358 #define CHUNK_TYPE_OFFSET CHUNK_HEADER_OFFSET
359 #define CHUNK_FLAGS_OFFSET (CHUNK_TYPE_OFFSET + CHUNK_TYPE_LENGTH)
360 #define CHUNK_LENGTH_OFFSET (CHUNK_FLAGS_OFFSET + CHUNK_FLAGS_LENGTH)
361 #define CHUNK_VALUE_OFFSET (CHUNK_LENGTH_OFFSET + CHUNK_LENGTH_LENGTH)
363 /* The following constants describe the structure of DATA chunks */
364 #define DATA_CHUNK_TSN_LENGTH 4
365 #define DATA_CHUNK_STREAM_ID_LENGTH 2
366 #define DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH 2
367 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
369 #define DATA_CHUNK_TSN_OFFSET (CHUNK_VALUE_OFFSET + 0)
370 #define DATA_CHUNK_STREAM_ID_OFFSET (DATA_CHUNK_TSN_OFFSET + DATA_CHUNK_TSN_LENGTH)
371 #define DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET (DATA_CHUNK_STREAM_ID_OFFSET + \
372 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
373 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET (DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET + \
374 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
375 #define DATA_CHUNK_PAYLOAD_OFFSET (DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET + \
376 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
378 #define DATA_CHUNK_HEADER_LENGTH (CHUNK_HEADER_LENGTH + \
379 DATA_CHUNK_TSN_LENGTH + \
380 DATA_CHUNK_STREAM_ID_LENGTH + \
381 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH + \
382 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
384 #define SCTP_DATA_CHUNK_E_BIT 0x01
385 #define SCTP_DATA_CHUNK_B_BIT 0x02
386 #define SCTP_DATA_CHUNK_U_BIT 0x04
388 #define INIT_CHUNK_INITIATE_TAG_LENGTH 4
389 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
390 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH 2
391 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH 2
392 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
394 #define INIT_CHUNK_INITIATE_TAG_OFFSET CHUNK_VALUE_OFFSET
395 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (INIT_CHUNK_INITIATE_TAG_OFFSET + \
396 INIT_CHUNK_INITIATE_TAG_LENGTH )
397 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET (INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
398 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH )
399 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET (INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET + \
400 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH )
401 #define INIT_CHUNK_INITIAL_TSN_OFFSET (INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET + \
402 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH )
403 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
404 INIT_CHUNK_INITIAL_TSN_LENGTH )
407 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
408 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
409 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH 2
410 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH 2
411 #define SACK_CHUNK_GAP_BLOCK_LENGTH 4
412 #define SACK_CHUNK_GAP_BLOCK_START_LENGTH 2
413 #define SACK_CHUNK_GAP_BLOCK_END_LENGTH 2
414 #define SACK_CHUNK_DUP_TSN_LENGTH 4
416 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
417 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
418 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
419 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET (SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
420 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH)
421 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET (SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET + \
422 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH)
423 #define SACK_CHUNK_GAP_BLOCK_OFFSET (SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET + \
424 SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH)
426 #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET
428 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET CHUNK_VALUE_OFFSET
429 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
431 #define ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
432 #define ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
434 #define COOKIE_ECHO_CHUNK_COOKIE_OFFSET CHUNK_VALUE_OFFSET
436 #define ECNE_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
437 #define ECNE_CHUNK_LOWEST_TSN_LENGTH 4
439 #define CWR_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
440 #define CWR_CHUNK_LOWEST_TSN_LENGTH 4
442 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT 0x01
444 static const true_false_string sctp_data_chunk_e_bit_value = {
446 "Not the last segment"
449 static const true_false_string sctp_data_chunk_b_bit_value = {
454 static const true_false_string sctp_data_chunk_u_bit_value = {
455 "Unordered delivery",
459 static const true_false_string sctp_shutdown_complete_chunk_t_bit_value = {
464 #define SCTP_CHECKSUM_NONE 0
465 #define SCTP_CHECKSUM_ADLER32 1
466 #define SCTP_CHECKSUM_CRC32C 2
467 #define SCTP_CHECKSUM_AUTOMATIC 3
469 static gint sctp_checksum = SCTP_CHECKSUM_ADLER32;
471 /* adler32.c -- compute the Adler-32 checksum of a data stream
472 * Copyright (C) 1995-1996 Mark Adler
473 * For conditions of distribution and use, see copyright notice in zlib.h
474 * available, e.g. from http://www.cdrom.com/pub/infozip/zlib/
476 * It was modified for the use in this dissector.
479 #define BASE 65521L /* largest prime smaller than 65536 */
480 #define NMAX 5540 /* NMAX is the largest n - 12 such that */
481 /* 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
483 #define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
484 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
485 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
486 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
487 #define DO16(buf) DO8(buf,0); DO8(buf,8);
490 sctp_adler32(const unsigned char* buf, unsigned int len)
492 unsigned int s1 = 1L;
493 unsigned int s2 = 0L;
496 /* handle the first 8 bytes of the datagram */
498 buf += SOURCE_PORT_LENGTH +
499 DESTINATION_PORT_LENGTH +
500 VERIFICATION_TAG_LENGTH;
502 /* handle four 0 bytes as checksum */
503 s2 += CHECKSUM_LENGTH * s1;
504 buf += CHECKSUM_LENGTH;
506 /* now we have 12 bytes handled */
507 len -= COMMON_HEADER_LENGTH;
509 /* handle the rest of the datagram */
511 k = len < NMAX ? len : NMAX;
525 return (s2 << 16) | s1;
528 /* The CRC32C code is taken from the checksum draft. That code
529 * is copyrighted by D. Otis and has been modified.
532 #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
533 static unsigned long crc_c[256] =
535 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
536 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
537 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
538 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
539 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
540 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
541 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
542 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
543 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
544 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
545 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
546 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
547 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
548 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
549 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
550 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
551 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
552 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
553 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
554 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
555 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
556 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
557 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
558 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
559 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
560 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
561 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
562 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
563 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
564 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
565 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
566 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
567 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
568 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
569 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
570 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
571 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
572 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
573 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
574 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
575 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
576 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
577 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
578 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
579 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
580 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
581 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
582 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
583 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
584 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
585 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
586 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
587 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
588 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
589 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
590 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
591 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
592 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
593 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
594 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
595 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
596 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
597 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
598 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
602 sctp_crc32c(const unsigned char* buf, unsigned int len)
605 unsigned long crc32 = ~0L;
607 for (i = 0; i < SOURCE_PORT_LENGTH + DESTINATION_PORT_LENGTH + VERIFICATION_TAG_LENGTH; i++)
609 CRC32C(crc32, buf[i]);
615 for (i = COMMON_HEADER_LENGTH; i < len; i++)
617 CRC32C(crc32, buf[i]);
623 nr_of_padding_bytes (guint length)
627 remainder = length % 4;
632 return 4 - remainder;
636 * TLV parameter stuff for INIT and INIT-ACK chunks
640 dissect_parameter(tvbuff_t *, packet_info *, proto_tree *);
643 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree);
646 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
649 dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, packet_info *pinfo, proto_tree *tree)
651 guint offset, length, padding_length, total_length;
652 tvbuff_t *parameter_tvb;
655 while(tvb_length_remaining(parameter_list_tvb, offset)) {
656 length = tvb_get_ntohs(parameter_list_tvb, offset + PARAMETER_LENGTH_OFFSET);
657 padding_length = nr_of_padding_bytes(length);
658 total_length = length + padding_length;
659 /* create a tvb for the chunk including the padding bytes */
660 parameter_tvb = tvb_new_subset(parameter_list_tvb, offset, total_length, total_length);
661 dissect_parameter(parameter_tvb, pinfo, tree);
662 /* get rid of the handled parameter */
663 offset += total_length;
668 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
670 guint16 length, heartbeat_info_length;
672 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
674 heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
676 proto_tree_add_text(parameter_tree, parameter_tvb, HEARTBEAT_INFO_PARAMETER_INFO_OFFSET, heartbeat_info_length,
677 "Heartbeat info (%u byte%s)",
678 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
680 proto_item_set_text(parameter_item, "Heartbeat info parameter with %u byte%s of info",
681 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
685 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
687 guint32 ipv4_address;
689 tvb_memcpy(parameter_tvb, (guint8 *)&ipv4_address, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH);
690 proto_tree_add_ipv4(parameter_tree, hf_sctp_parameter_ipv4_address,
691 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH,
693 proto_item_set_text(parameter_item, "IPV4 address parameter");
697 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
699 proto_tree_add_ipv6(parameter_tree, hf_sctp_parameter_ipv6_address,
700 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH,
701 tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH));
703 proto_item_set_text(parameter_item, "IPV6 address parameter");
707 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
709 guint16 length, state_cookie_length;
711 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
713 state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
715 proto_tree_add_text(parameter_tree, parameter_tvb, STATE_COOKIE_PARAMETER_COOKIE_OFFSET, state_cookie_length,
716 "State cookie (%u byte%s)",
717 state_cookie_length, plurality(state_cookie_length, "", "s"));
719 proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
720 state_cookie_length, plurality(state_cookie_length, "", "s"));
724 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
726 guint16 length, padding_length, parameter_value_length;
727 tvbuff_t *unrecognized_parameters_tvb;
729 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
730 padding_length = nr_of_padding_bytes(length);
732 parameter_value_length = length - PARAMETER_HEADER_LENGTH + padding_length;
734 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
735 parameter_value_length, parameter_value_length);
736 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, parameter_tree);
738 proto_item_set_text(parameter_item, "Unrecognized parameter of type");
742 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
746 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
748 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
749 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
750 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
753 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
758 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
760 guint16 length, hostname_length;
763 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
765 hostname_length = length - PARAMETER_HEADER_LENGTH;
766 hostname = (char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
767 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
768 PARAMETER_VALUE_OFFSET, hostname_length,
771 proto_item_set_text(parameter_item, "Hostname parameter");
775 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
777 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
779 proto_item *address_list_item;
780 proto_tree *address_list_tree;
782 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
783 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
784 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
786 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
787 "Supported Address Types (%u address type%s)",
788 number_of_address_types, plurality(number_of_address_types, "", "s"));
789 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
791 offset = PARAMETER_VALUE_OFFSET;
792 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
793 address_type = tvb_get_ntohs(parameter_tvb, offset);
794 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
795 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
796 address_type, "Supported address type: 0x%04x (%s)",
797 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
798 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
801 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
802 number_of_address_types, plurality(number_of_address_types, "", "s"));
806 dissect_ecn_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
808 proto_item_set_text(parameter_item, "ECN parameter");
811 #define USTREAMS_START_LENGTH 2
812 #define USTREAMS_END_LENGTH 2
813 #define USTREAMS_INTERVAL_LENGTH (USTREAMS_START_LENGTH + USTREAMS_END_LENGTH)
816 dissect_unreliable_streams_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
818 guint16 length, start, end, number_of_intervals, interval_number;
819 proto_item *interval_item;
820 proto_tree *interval_tree;
821 gint interval_offset;
823 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
824 number_of_intervals = (length - PARAMETER_HEADER_LENGTH) / USTREAMS_INTERVAL_LENGTH;
826 interval_offset = PARAMETER_VALUE_OFFSET;
827 for(interval_number = 1; interval_number <= number_of_intervals; interval_number++) {
828 start = tvb_get_ntohs(parameter_tvb, interval_offset);
829 end = tvb_get_ntohs(parameter_tvb, interval_offset + USTREAMS_START_LENGTH);
830 interval_item = proto_tree_add_text(parameter_tree, parameter_tvb, interval_offset, USTREAMS_INTERVAL_LENGTH, "Unreliable streams (%u-%u)", start, end);
831 interval_tree = proto_item_add_subtree(interval_item, ett_sctp_unreliable_streams_interval);
832 proto_tree_add_uint(interval_tree, hf_sctp_ustreams_start, parameter_tvb, interval_offset, USTREAMS_START_LENGTH, start);
833 proto_tree_add_uint(interval_tree, hf_sctp_ustreams_end, parameter_tvb, interval_offset + USTREAMS_START_LENGTH, USTREAMS_END_LENGTH, end);
834 interval_offset += USTREAMS_INTERVAL_LENGTH;
836 proto_item_set_text(parameter_item, "Unreliable streams parameter");
840 dissect_add_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
842 guint16 length, parameter_value_length;
843 tvbuff_t *address_tvb;
845 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
846 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
848 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
849 dissect_parameter(address_tvb, pinfo, parameter_tree);
851 proto_item_set_text(parameter_item, "Add IP address parameter");
855 dissect_del_ip_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
857 guint16 length, parameter_value_length;
858 tvbuff_t *address_tvb;
860 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
861 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
863 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
864 dissect_parameter(address_tvb, pinfo, parameter_tree);
866 proto_item_set_text(parameter_item, "Delete IP address parameter");
870 dissect_error_cause_indication_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
872 guint16 length, padding_length, total_length;
874 tvbuff_t *error_cause_tvb;
876 offset = PARAMETER_VALUE_OFFSET;
877 while(tvb_length_remaining(parameter_tvb, offset)) {
878 length = tvb_get_ntohs(parameter_tvb, offset + CAUSE_LENGTH_OFFSET);
879 padding_length = nr_of_padding_bytes(length);
880 total_length = length + padding_length;
881 /* create a tvb for the chunk including the padding bytes */
882 error_cause_tvb = tvb_new_subset(parameter_tvb, offset , total_length, total_length);
883 dissect_error_cause(error_cause_tvb, pinfo, parameter_tree);
884 /* get rid of the handled parameter */
885 offset += total_length;
887 proto_item_set_text(parameter_item, "Error cause indication");
891 dissect_set_primary_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
893 guint16 length, parameter_value_length;
894 tvbuff_t *address_tvb;
896 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
897 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
899 address_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, parameter_value_length);
900 dissect_parameter(address_tvb, pinfo, parameter_tree);
902 proto_item_set_text(parameter_item, "Set primary address parameter");
906 dissect_success_report_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
908 proto_item_set_text(parameter_item, "Success report parameter");
911 #define ADAP_INDICATION_LENGTH 4
912 #define ADAP_INDICATION_OFFSET PARAMETER_VALUE_OFFSET
915 dissect_adap_indication_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
919 indication = tvb_get_ntohl(parameter_tvb, ADAP_INDICATION_OFFSET);
920 proto_tree_add_uint(parameter_tree, hf_sctp_adap_indication, parameter_tvb, ADAP_INDICATION_OFFSET, ADAP_INDICATION_LENGTH, indication);
921 proto_item_set_text(parameter_item, "Adaptation layer indication");
925 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
927 guint16 type, length, parameter_value_length;
929 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
930 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
932 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
934 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
935 "Parameter value (%u byte%s)",
936 parameter_value_length, plurality(parameter_value_length, "", "s"));
938 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
939 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
943 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *chunk_tree)
945 guint16 type, length, padding_length, total_length;
946 proto_item *parameter_item;
947 proto_tree *parameter_tree;
949 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
950 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
951 padding_length = nr_of_padding_bytes(length);
952 total_length = length + padding_length;
954 parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb,
955 PARAMETER_HEADER_OFFSET, total_length, "%s parameter",
956 val_to_str(type, sctp_parameter_identifier_values, "Unknown"));
957 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
959 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_type,
960 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
962 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
963 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
967 case HEARTBEAT_INFO_PARAMETER_ID:
968 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
970 case IPV4ADDRESS_PARAMETER_ID:
971 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
973 case IPV6ADDRESS_PARAMETER_ID:
974 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
976 case STATE_COOKIE_PARAMETER_ID:
977 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
979 case UNREC_PARA_PARAMETER_ID:
980 dissect_unrecognized_parameters_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
982 case COOKIE_PRESERVATIVE_PARAMETER_ID:
983 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
985 case HOSTNAME_ADDRESS_PARAMETER_ID:
986 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
988 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
989 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
991 case ECN_PARAMETER_ID:
992 dissect_ecn_parameter(parameter_tvb, parameter_tree, parameter_item);
994 case UNRELIABLE_STREAMS_PARAMETER_ID:
995 dissect_unreliable_streams_parameter(parameter_tvb, parameter_tree, parameter_item);
997 case ADD_IP_ADDRESS_PARAMETER_ID:
998 dissect_add_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1000 case DEL_IP_ADDRESS_PARAMETER_ID:
1001 dissect_del_ip_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1003 case ERROR_CAUSE_INDICATION_PARAMETER_ID:
1004 dissect_error_cause_indication_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1006 case SET_PRIMARY_ADDRESS_PARAMETER_ID:
1007 dissect_set_primary_address_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1009 case SUCCESS_REPORT_PARAMETER_ID:
1010 dissect_success_report_parameter(parameter_tvb, parameter_tree, parameter_item);
1012 case ADAP_LAYER_INDICATION_PARAMETER_ID:
1013 dissect_adap_indication_parameter(parameter_tvb, parameter_tree, parameter_item);
1016 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1019 if ((padding_length > 0) && (type != UNREC_PARA_PARAMETER_ID))
1020 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
1021 "Padding: %u byte%s",
1022 padding_length, plurality(padding_length, "", "s"));
1026 * Code to handle error causes for ABORT and ERROR chunks
1029 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1031 guint16 stream_identifier;
1033 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
1034 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
1035 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
1037 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
1038 "Reserved (2 bytes)");
1040 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
1045 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1047 guint32 number_of_missing_parameters, missing_parameter_number;
1048 guint16 parameter_type;
1051 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
1052 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
1053 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
1054 number_of_missing_parameters);
1055 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
1056 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
1057 parameter_type = tvb_get_ntohs(cause_tvb, offset);
1058 proto_tree_add_uint(cause_tree, hf_sctp_cause_missing_parameter_type,
1059 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
1061 offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
1064 proto_item_set_text(cause_item, "Error cause reporting %u missing mandatory parameter%s",
1065 number_of_missing_parameters, plurality(number_of_missing_parameters, "", "s") );
1069 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1071 guint32 measure_of_staleness;
1073 measure_of_staleness = tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
1075 proto_tree_add_uint(cause_tree, hf_sctp_cause_measure_of_staleness, cause_tvb,
1076 CAUSE_MEASURE_OF_STALENESS_OFFSET,
1077 CAUSE_MEASURE_OF_STALENESS_LENGTH,
1078 measure_of_staleness);
1080 proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
1081 measure_of_staleness);
1085 dissect_out_of_resource_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1087 proto_item_set_text(cause_item, "Error cause reporting lack of resources");
1091 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1093 guint16 code, length, parameter_length, parameter_type;
1094 tvbuff_t *parameter_tvb;
1096 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1097 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1099 parameter_length = length - CAUSE_HEADER_LENGTH;
1100 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
1101 parameter_length, parameter_length);
1103 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1104 parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
1106 proto_item_set_text(cause_item, "Error cause reporting unresolvable address of type 0x%04x (%s)",
1107 parameter_type, val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown") );
1111 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo,
1112 proto_tree *cause_tree, proto_item *cause_item)
1114 guint16 length, chunk_length;
1115 guint8 unrecognized_type;
1116 tvbuff_t *unrecognized_chunk_tvb;
1118 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1120 chunk_length = length - CAUSE_HEADER_LENGTH;
1122 unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, chunk_length, chunk_length);
1123 dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree);
1125 unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
1127 proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
1129 val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
1133 dissect_invalid_mandatory_parameter_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1135 proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
1139 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1141 guint16 length, padding_length, cause_info_length;
1142 tvbuff_t *unrecognized_parameters_tvb;
1144 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1145 padding_length = nr_of_padding_bytes(length);
1146 cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
1148 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1149 dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, cause_tree);
1151 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
1155 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1159 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
1160 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
1165 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
1170 dissect_cookie_received_while_shutting_down_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1172 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
1176 dissect_delete_last_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1178 guint16 length, cause_info_length;
1179 tvbuff_t *parameter_tvb;
1181 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1182 cause_info_length = length - CAUSE_HEADER_LENGTH;
1183 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1184 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1185 proto_item_set_text(cause_item, "Delete last address cause");
1189 dissect_resource_outage_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1191 guint16 length, cause_info_length;
1192 tvbuff_t *parameter_tvb;
1194 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1195 cause_info_length = length - CAUSE_HEADER_LENGTH;
1196 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1197 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1198 proto_item_set_text(cause_item, "Operation refused due to resource shortage");
1202 dissect_delete_source_address_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *cause_tree, proto_item *cause_item)
1204 guint16 length, cause_info_length;
1205 tvbuff_t *parameter_tvb;
1207 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1208 cause_info_length = length - CAUSE_HEADER_LENGTH;
1209 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, cause_info_length, cause_info_length);
1210 dissect_parameter(parameter_tvb, pinfo, cause_tree);
1211 proto_item_set_text(cause_item, "Delete source address cause");
1215 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
1217 guint16 code, length, cause_info_length;
1219 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1220 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1222 cause_info_length = length - CAUSE_HEADER_LENGTH;
1224 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
1225 "Cause specific information (%u byte%s)",
1226 cause_info_length, plurality(cause_info_length, "", "s"));
1228 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
1229 code, cause_info_length, plurality(cause_info_length, "", "s"));
1233 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
1235 guint16 code, length, padding_length, total_length;
1236 proto_item *cause_item;
1237 proto_tree *cause_tree;
1239 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
1240 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
1241 padding_length = nr_of_padding_bytes(length);
1242 total_length = length + padding_length;
1244 cause_item = proto_tree_add_text(chunk_tree, cause_tvb,
1245 CAUSE_HEADER_OFFSET, total_length,
1247 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
1249 proto_tree_add_uint(cause_tree, hf_sctp_cause_code,
1250 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
1252 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
1253 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
1257 case INVALID_STREAM_IDENTIFIER:
1258 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
1260 case MISSING_MANDATORY_PARAMETERS:
1261 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
1263 case STALE_COOKIE_ERROR:
1264 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
1266 case OUT_OF_RESOURCE:
1267 dissect_out_of_resource_cause(cause_tvb, cause_tree, cause_item);
1269 case UNRESOLVABLE_ADDRESS:
1270 dissect_unresolvable_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1272 case UNRECOGNIZED_CHUNK_TYPE:
1273 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
1275 case INVALID_MANDATORY_PARAMETER:
1276 dissect_invalid_mandatory_parameter_cause(cause_tvb, cause_tree, cause_item);
1278 case UNRECOGNIZED_PARAMETERS:
1279 dissect_unrecognized_parameters_cause(cause_tvb, pinfo, cause_tree, cause_item);
1282 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
1284 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
1285 dissect_cookie_received_while_shutting_down_cause(cause_tvb, cause_tree, cause_item);
1287 case REQUEST_TO_DELETE_LAST_ADDRESS:
1288 dissect_delete_last_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1290 case OPERATION_REFUSED_DUE_TO_RESOURCE_SHORTAGE:
1291 dissect_resource_outage_cause(cause_tvb, pinfo, cause_tree, cause_item);
1293 case REQUEST_TO_DELETE_SOURCE_ADDRESS:
1294 dissect_delete_source_address_cause(cause_tvb, pinfo, cause_tree, cause_item);
1297 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
1300 if ((padding_length > 0) && (code != UNRECOGNIZED_PARAMETERS))
1301 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
1302 "Padding: %u byte%s",
1303 padding_length, plurality(padding_length, "", "s"));
1307 * Code to actually dissect the packets
1311 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
1312 proto_tree *chunk_tree, guint32 ppi, guint16 payload_length, guint16 padding_length)
1314 /* do lookup with the subdissector table */
1315 if (dissector_try_port (sctp_ppi_dissector_table, ppi, payload_tvb, pinfo, tree) ||
1316 dissector_try_port(sctp_port_dissector_table, pinfo->srcport, payload_tvb, pinfo, tree) ||
1317 dissector_try_port(sctp_port_dissector_table, pinfo->destport, payload_tvb, pinfo, tree)){
1321 if (check_col(pinfo->cinfo, COL_INFO))
1322 col_append_str(pinfo->cinfo, COL_INFO, "DATA ");
1323 proto_tree_add_text(chunk_tree, payload_tvb, 0, payload_length,
1324 "Payload (%u byte%s)",
1325 payload_length, plurality(payload_length, "", "s"));
1326 if (padding_length > 0)
1327 proto_tree_add_text(chunk_tree, payload_tvb, payload_length, padding_length,
1328 "Padding: %u byte%s",
1329 padding_length, plurality(padding_length, "", "s"));
1335 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1336 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1339 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
1340 guint32 tsn, payload_proto_id;
1341 proto_tree *flag_tree;
1342 tvbuff_t *payload_tvb;
1344 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1345 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1346 padding_length = nr_of_padding_bytes(length);
1347 total_payload_length = payload_length + padding_length;
1348 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1349 total_payload_length, total_payload_length);
1350 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1353 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1355 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1356 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
1357 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1358 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1359 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1360 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1361 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1363 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1364 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1365 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1367 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1369 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1371 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1373 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1375 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1377 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1379 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1380 chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1382 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1383 tsn, stream_id, stream_seq_number,
1384 payload_length, plurality(payload_length, "", "s"));
1386 return dissect_payload(payload_tvb, pinfo, tree, chunk_tree, payload_proto_id, payload_length, padding_length);
1390 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1391 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1393 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1394 guint16 number_of_inbound_streams, number_of_outbound_streams;
1396 tvbuff_t *parameter_list_tvb;
1398 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1400 if (check_col(pinfo->cinfo, COL_INFO)) {
1401 if (type == SCTP_INIT_CHUNK_ID) {
1402 col_append_str(pinfo->cinfo, COL_INFO, "INIT ");
1404 col_append_str(pinfo->cinfo, COL_INFO, "INIT_ACK ");
1409 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1410 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1411 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1412 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1413 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1415 /* handle fixed parameters */
1416 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1418 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1420 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1422 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1423 adv_rec_window_credit);
1424 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1426 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1427 number_of_outbound_streams);
1428 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1430 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1431 number_of_inbound_streams);
1432 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1434 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1437 /* handle variable paramters */
1438 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1439 dissect_tlv_parameter_list(parameter_list_tvb, pinfo, chunk_tree);
1441 proto_item_set_text(chunk_item,
1442 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1443 val_to_str(type, sctp_chunk_type_values, "unknown"),
1444 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1445 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1450 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1451 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1453 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1457 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1458 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1460 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1461 guint16 number_of_gap_blocks, number_of_dup_tsns;
1462 guint16 gap_block_number, dup_tsn_number, start, end;
1463 gint gap_block_offset, dup_tsn_offset;
1464 proto_item *block_item;
1465 proto_tree *block_tree;
1467 if (check_col(pinfo->cinfo, COL_INFO))
1468 col_append_str(pinfo->cinfo, COL_INFO, "SACK ");
1471 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1472 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1473 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1474 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1476 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1478 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1479 cumulative_tsn_ack);
1480 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1482 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1483 adv_rec_window_credit);
1484 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1486 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1487 number_of_gap_blocks);
1488 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1490 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1491 number_of_dup_tsns);
1493 /* handle the gap acknowledgement blocks */
1494 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1495 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1496 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1497 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1498 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1499 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1500 "Gap Acknowledgement for %u TSN%s",
1501 1 + end - start, plurality(1 + end - start, "", "s"));
1502 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1503 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1505 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1507 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1509 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1510 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1512 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1515 /* handle the duplicate TSNs */
1516 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1517 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1518 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1519 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1521 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1523 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1526 proto_item_set_text(chunk_item,
1527 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1529 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1530 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1535 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1536 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1538 tvbuff_t *parameter_tvb;
1539 guint chunk_length, info_length, padding_length, total_length;
1541 if (check_col(pinfo->cinfo, COL_INFO))
1542 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT ");
1545 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1546 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1547 padding_length = nr_of_padding_bytes(info_length);
1548 total_length = info_length + padding_length;
1549 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1551 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1553 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1558 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1559 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1561 tvbuff_t *parameter_tvb;
1562 guint chunk_length, info_length, padding_length, total_length;
1564 if (check_col(pinfo->cinfo, COL_INFO))
1565 col_append_str(pinfo->cinfo, COL_INFO, "HEARTBEAT_ACK ");
1568 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1569 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1570 padding_length = nr_of_padding_bytes(info_length);
1571 total_length = info_length + padding_length;
1573 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1575 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1577 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1582 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1583 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1585 guint offset, number_of_causes;
1586 guint16 length, padding_length, total_length;
1587 tvbuff_t *cause_tvb;
1589 if (check_col(pinfo->cinfo, COL_INFO))
1590 col_append_str(pinfo->cinfo, COL_INFO, "ABORT ");
1593 number_of_causes = 0;
1594 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1595 while(tvb_length_remaining(chunk_tvb, offset)) {
1596 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1597 padding_length = nr_of_padding_bytes(length);
1598 total_length = length + padding_length;
1599 /* create a tvb for the chunk including the padding bytes */
1600 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1601 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1602 /* get rid of the handled parameter */
1603 offset += total_length;
1607 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s",
1608 number_of_causes, plurality(number_of_causes, "", "s"));
1613 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1614 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1616 guint32 cumulative_tsn_ack;
1618 if (check_col(pinfo->cinfo, COL_INFO))
1619 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN ");
1622 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1623 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1625 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1626 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1627 cumulative_tsn_ack);
1629 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1630 cumulative_tsn_ack);
1635 dissect_shutdown_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1636 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1638 if (check_col(pinfo->cinfo, COL_INFO))
1639 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_ACK ");
1642 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1647 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1648 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1650 guint offset, number_of_causes;
1651 guint16 length, padding_length, total_length;
1652 tvbuff_t *cause_tvb;
1654 if (check_col(pinfo->cinfo, COL_INFO))
1655 col_append_str(pinfo->cinfo, COL_INFO, "ERROR ");
1658 number_of_causes = 0;
1659 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1661 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1662 padding_length = nr_of_padding_bytes(length);
1663 total_length = length + padding_length;
1664 /* create a tvb for the chunk including the padding bytes */
1665 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1666 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1667 /* get rid of the handled parameter */
1668 offset += total_length;
1670 } while(tvb_length_remaining(chunk_tvb, offset));
1672 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1673 number_of_causes, plurality(number_of_causes, "", "s"));
1678 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1679 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1681 guint length, cookie_length, padding_length;
1683 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1684 padding_length = nr_of_padding_bytes(length);
1685 cookie_length = length - CHUNK_HEADER_LENGTH;
1687 if (check_col(pinfo->cinfo, COL_INFO))
1688 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ECHO ");
1691 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1692 "Cookie (%u byte%s)",
1693 cookie_length, plurality(cookie_length, "", "s"));
1694 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1695 cookie_length, plurality(cookie_length, "", "s"));
1697 if (padding_length > 0)
1698 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1699 "Padding: %u byte%s",
1700 padding_length, plurality(padding_length, "", "s"));
1705 dissect_cookie_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1706 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1708 if (check_col(pinfo->cinfo, COL_INFO))
1709 col_append_str(pinfo->cinfo, COL_INFO, "COOKIE_ACK ");
1712 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1717 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1718 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1722 if (check_col(pinfo->cinfo, COL_INFO))
1723 col_append_str(pinfo->cinfo, COL_INFO, "ECNE ");
1726 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1727 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1729 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1732 proto_item_set_text(chunk_item, "ECNE chunk");
1737 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1738 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1742 if (check_col(pinfo->cinfo, COL_INFO))
1743 col_append_str(pinfo->cinfo, COL_INFO, "CWR ");
1746 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1747 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1749 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1752 proto_item_set_text(chunk_item, "CWR chunk");
1757 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1758 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1762 proto_tree *flag_tree;
1764 if (check_col(pinfo->cinfo, COL_INFO))
1765 col_append_str(pinfo->cinfo, COL_INFO, "SHUTDOWN_COMPLETE ");
1768 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1769 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1771 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1772 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1773 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1775 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1779 #define FORWARD_TSN_CHUNK_TSN_OFFSET CHUNK_VALUE_OFFSET
1780 #define FORWARD_TSN_CHUNK_TSN_LENGTH 4
1783 dissect_forward_tsn_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1787 if (check_col(pinfo->cinfo, COL_INFO))
1788 col_append_str(pinfo->cinfo, COL_INFO, "FORWARD TSN ");
1791 tsn = tvb_get_ntohl(chunk_tvb, FORWARD_TSN_CHUNK_TSN_OFFSET);
1792 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);
1793 proto_item_set_text(chunk_item, "FORWARD TSN chunk (new cumulative TSN %u)", tsn);
1797 #define SERIAL_NUMBER_LENGTH 4
1798 #define CORRELATION_ID_LENGTH 4
1799 #define ASCONF_RESERVED_LENGTH 3
1800 #define ASCONF_ADDR_TYPE_LENGTH 1
1801 #define ASCONF_ADDR_LENGTH 16
1802 #define SERIAL_NUMBER_OFFSET PARAMETER_VALUE_OFFSET
1804 #define IP_V4_ADDRESS_TYPE 5
1805 #define IP_V6_ADDRESS_TYPE 6
1807 static const value_string sctp_address_type_values[] = {
1808 { IP_V4_ADDRESS_TYPE, "IP V4 address" },
1809 { IP_V6_ADDRESS_TYPE, "IP V6 address" },
1813 dissect_asconf_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1815 guint32 serial_number, correlation_id, ipv4_address;
1816 guint offset, length, padding_length, total_length;
1818 tvbuff_t *parameter_tvb;
1820 if (check_col(pinfo->cinfo, COL_INFO))
1821 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF ");
1824 offset = SERIAL_NUMBER_OFFSET;
1825 serial_number = tvb_get_ntohl(chunk_tvb, offset);
1826 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_serial, chunk_tvb, offset, SERIAL_NUMBER_LENGTH, serial_number);
1827 offset += SERIAL_NUMBER_LENGTH;
1828 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));
1829 offset += ASCONF_RESERVED_LENGTH;
1830 addr_type = tvb_get_guint8(chunk_tvb, offset);
1831 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_addr_type, chunk_tvb, offset, ASCONF_ADDR_TYPE_LENGTH, addr_type);
1832 offset += ASCONF_ADDR_TYPE_LENGTH;
1833 switch (addr_type) {
1834 case IP_V4_ADDRESS_TYPE:
1835 tvb_memcpy(chunk_tvb, (guint8 *)&ipv4_address, offset, IPV4_ADDRESS_LENGTH);
1836 proto_tree_add_ipv4(chunk_tree, hf_sctp_asconf_ipv4_address, chunk_tvb, offset, IPV4_ADDRESS_LENGTH, ipv4_address);
1837 proto_tree_add_bytes(chunk_tree, hf_sctp_asconf_addr, chunk_tvb, offset + IPV4_ADDRESS_LENGTH, ASCONF_ADDR_LENGTH - IPV4_ADDRESS_LENGTH,
1838 tvb_get_ptr(chunk_tvb, offset + IPV4_ADDRESS_LENGTH, ASCONF_ADDR_LENGTH - IPV4_ADDRESS_LENGTH));
1840 case IP_V6_ADDRESS_TYPE:
1841 proto_tree_add_ipv6(chunk_tree, hf_sctp_asconf_ipv6_address, chunk_tvb, offset, IPV6_ADDRESS_LENGTH,
1842 tvb_get_ptr(chunk_tvb, offset, IPV6_ADDRESS_LENGTH));
1845 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));
1848 offset += ASCONF_ADDR_LENGTH;
1849 proto_item_set_text(chunk_item, "ASCONF chunk");
1851 while(tvb_length_remaining(chunk_tvb, offset)) {
1852 correlation_id = tvb_get_ntohl(chunk_tvb, offset);
1853 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_correlation_id, chunk_tvb, offset, CORRELATION_ID_LENGTH, correlation_id);
1854 offset += CORRELATION_ID_LENGTH;
1855 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1856 padding_length = nr_of_padding_bytes(length);
1857 total_length = length + padding_length;
1858 /* create a tvb for the chunk including the padding bytes */
1859 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1860 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1861 /* get rid of the handled parameter */
1862 offset += total_length;
1868 dissect_asconf_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1870 guint32 serial_number, correlation_id;
1871 guint offset, length, padding_length, total_length;
1872 tvbuff_t *parameter_tvb;
1874 if (check_col(pinfo->cinfo, COL_INFO))
1875 col_append_str(pinfo->cinfo, COL_INFO, "ASCONF-ACK ");
1878 serial_number = tvb_get_ntohl(chunk_tvb, SERIAL_NUMBER_OFFSET);
1879 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_serial, chunk_tvb, SERIAL_NUMBER_OFFSET, SERIAL_NUMBER_LENGTH, serial_number);
1880 proto_item_set_text(chunk_item, "ASCONF-ACK chunk");
1882 offset = SERIAL_NUMBER_OFFSET + SERIAL_NUMBER_LENGTH;
1883 while(tvb_length_remaining(chunk_tvb, offset)) {
1884 correlation_id = tvb_get_ntohl(chunk_tvb, offset);
1885 proto_tree_add_uint(chunk_tree, hf_sctp_asconf_ack_correlation_id, chunk_tvb, offset, CORRELATION_ID_LENGTH, correlation_id);
1886 offset += CORRELATION_ID_LENGTH;
1887 length = tvb_get_ntohs(chunk_tvb, offset + PARAMETER_LENGTH_OFFSET);
1888 padding_length = nr_of_padding_bytes(length);
1889 total_length = length + padding_length;
1890 /* create a tvb for the chunk including the padding bytes */
1891 parameter_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1892 dissect_parameter(parameter_tvb, pinfo, chunk_tree);
1893 /* get rid of the handled parameter */
1894 offset += total_length;
1900 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1901 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1903 guint length, chunk_value_length, padding_length;
1906 if (check_col(pinfo->cinfo, COL_INFO))
1907 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN ");
1910 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1911 padding_length = nr_of_padding_bytes(length);
1912 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1914 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1916 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1917 "Chunk value (%u byte%s)",
1918 chunk_value_length, plurality(chunk_value_length, "", "s"));
1920 if (padding_length > 0)
1921 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1922 "Padding: %u byte%s",
1923 padding_length, plurality(padding_length, "", "s"));
1925 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1926 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1932 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1937 proto_item *flags_item;
1938 proto_item *chunk_item;
1939 proto_tree *chunk_tree;
1943 /* first extract the chunk header */
1944 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1945 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1946 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1949 /* create proto_tree stuff */
1950 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb, CHUNK_HEADER_OFFSET, tvb_length(chunk_tvb), "Incomplete chunk");
1951 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
1953 /* then insert the chunk header components into the protocol tree */
1954 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_type, chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH, type);
1955 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags, chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1956 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length, chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH, length);
1963 /* now dissect the chunk value */
1966 case SCTP_DATA_CHUNK_ID:
1967 result = dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1969 case SCTP_INIT_CHUNK_ID:
1970 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1972 case SCTP_INIT_ACK_CHUNK_ID:
1973 dissect_init_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1975 case SCTP_SACK_CHUNK_ID:
1976 dissect_sack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1978 case SCTP_HEARTBEAT_CHUNK_ID:
1979 dissect_heartbeat_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1981 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1982 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1984 case SCTP_ABORT_CHUNK_ID:
1985 dissect_abort_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1987 case SCTP_SHUTDOWN_CHUNK_ID:
1988 dissect_shutdown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1990 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
1991 dissect_shutdown_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1993 case SCTP_ERROR_CHUNK_ID:
1994 dissect_error_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1996 case SCTP_COOKIE_ECHO_CHUNK_ID:
1997 dissect_cookie_echo_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1999 case SCTP_COOKIE_ACK_CHUNK_ID:
2000 dissect_cookie_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2002 case SCTP_ECNE_CHUNK_ID:
2003 dissect_ecne_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2005 case SCTP_CWR_CHUNK_ID:
2006 dissect_cwr_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2008 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
2009 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2011 case SCTP_FORWARD_TSN_CHUNK_ID:
2012 dissect_forward_tsn_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2014 case SCTP_ASCONF_ACK_CHUNK_ID:
2015 dissect_asconf_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2017 case SCTP_ASCONF_CHUNK_ID:
2018 dissect_asconf_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2021 dissect_unknown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
2028 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *sctp_item, proto_tree *sctp_tree)
2030 tvbuff_t *chunk_tvb;
2031 guint16 length, padding_length, total_length;
2032 gint last_offset, offset;
2033 gboolean sctp_item_length_set;
2035 /* the common header of the datagram is already handled */
2037 offset = COMMON_HEADER_LENGTH;
2038 sctp_item_length_set = FALSE;
2040 while(tvb_length_remaining(tvb, offset) > 0) {
2041 /* extract the chunk length and compute number of padding bytes */
2042 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
2043 padding_length = nr_of_padding_bytes(length);
2044 total_length = length + padding_length;
2045 /* create a tvb for the chunk including the padding bytes */
2046 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
2047 /* call dissect_sctp_chunk for a actual work */
2048 if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree) && (tree)) {
2049 proto_item_set_len(sctp_item, offset - last_offset + DATA_CHUNK_HEADER_LENGTH);
2050 sctp_item_length_set = TRUE;
2051 offset += total_length;
2052 last_offset = offset;
2053 if (tvb_length_remaining(tvb, offset) > 0) {
2054 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, offset, 0, FALSE);
2055 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2056 sctp_item_length_set = FALSE;
2059 /* get rid of the dissected chunk */
2060 offset += total_length;
2063 if (!sctp_item_length_set && (tree)) {
2064 proto_item_set_len(sctp_item, offset - last_offset);
2068 /* dissect_sctp handles the common header of a SCTP datagram.
2069 * For the handling of the chunks dissect_sctp_chunks is called.
2073 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2075 guint16 source_port, destination_port;
2076 guint32 verification_tag, checksum, calculated_crc32c, calculated_adler32;
2078 gboolean crc32c_correct, adler32_correct;
2079 proto_item *sctp_item;
2080 proto_tree *sctp_tree;
2082 /* Extract the common header */
2083 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
2084 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
2085 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
2086 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
2088 /* update pi structure */
2089 pinfo->ptype = PT_SCTP;
2090 pinfo->srcport = source_port;
2091 pinfo->destport = destination_port;
2093 /* make entry in the Protocol column on summary display */
2094 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2095 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCTP");
2097 /* Clear entries in Info column on summary display */
2098 if (check_col(pinfo->cinfo, COL_INFO))
2099 col_add_str(pinfo->cinfo, COL_INFO, "");
2101 /* In the interest of speed, if "tree" is NULL, don't do any work not
2102 necessary to generate protocol tree items. */
2104 /* create the sctp protocol tree */
2105 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, 0, 0, FALSE);
2106 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
2108 /* add the components of the common header to the protocol tree */
2109 proto_tree_add_uint(sctp_tree, hf_sctp_source_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
2110 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
2111 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag, tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH, verification_tag);
2113 length = tvb_length(tvb);
2114 switch(sctp_checksum) {
2115 case SCTP_CHECKSUM_NONE:
2116 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum, "Checksum: 0x%08x (not verified)", checksum);
2118 case SCTP_CHECKSUM_ADLER32:
2119 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2120 adler32_correct = (checksum == calculated_adler32);
2121 if (adler32_correct)
2122 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2123 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2125 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2126 checksum, "Checksum: 0x%08x (incorrect Adler32, should be 0x%08x)", checksum, calculated_adler32);
2127 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_correct, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, adler32_correct);
2129 case SCTP_CHECKSUM_CRC32C:
2130 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2131 crc32c_correct = (checksum == calculated_crc32c);
2133 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2134 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2136 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2137 checksum, "Checksum: 0x%08x (incorrect CRC32C, should be 0x%08x)", checksum, calculated_crc32c);
2138 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_correct, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, crc32c_correct);
2140 case SCTP_CHECKSUM_AUTOMATIC:
2141 calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
2142 adler32_correct = (checksum == calculated_adler32);
2143 calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
2144 crc32c_correct = (checksum == calculated_crc32c);
2145 if ((adler32_correct) && !(crc32c_correct))
2146 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2147 checksum, "Checksum: 0x%08x (correct Adler32)", checksum);
2148 else if (!(adler32_correct) && (crc32c_correct))
2149 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2150 checksum, "Checksum: 0x%08x (correct CRC32C)", checksum);
2151 else if ((adler32_correct) && (crc32c_correct))
2152 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2153 checksum, "Checksum: 0x%08x (correct Adler32 and CRC32C)", checksum);
2155 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
2156 checksum, "Checksum: 0x%08x (incorrect, should be 0x%08x (Adler32) or 0x%08x (CRC32C))",
2157 checksum, calculated_adler32, calculated_crc32c);
2158 proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_correct, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, (crc32c_correct || adler32_correct));
2165 /* add all chunks of the sctp datagram to the protocol tree */
2166 dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree);
2169 /* Register the protocol with Ethereal */
2171 proto_register_sctp(void)
2174 /* Setup list of header fields */
2175 static hf_register_info hf[] = {
2176 { &hf_sctp_source_port,
2177 { "Source port", "sctp.srcport",
2178 FT_UINT16, BASE_DEC, NULL, 0x0,
2181 { &hf_sctp_destination_port,
2182 { "Destination port", "sctp.dstport",
2183 FT_UINT16, BASE_DEC, NULL, 0x0,
2186 { &hf_sctp_verification_tag,
2187 { "Verification tag", "sctp.verfication_tag",
2188 FT_UINT32, BASE_HEX, NULL, 0x0,
2191 { &hf_sctp_checksum,
2192 { "Adler-32 checksum", "sctp.checksum",
2193 FT_UINT32, BASE_HEX, NULL, 0x0,
2196 { &hf_sctp_checksum_correct,
2197 { "Adler-32 checksum correct", "sctp.checksum_correct",
2198 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2201 { &hf_sctp_chunk_type,
2202 { "Identifier", "sctp.chunk_type",
2203 FT_UINT8, BASE_DEC, VALS(sctp_chunk_type_values), 0x0,
2206 { &hf_sctp_chunk_flags,
2207 { "Flags", "sctp.chunk_flags",
2208 FT_UINT8, BASE_BIN, NULL, 0x0,
2211 { &hf_sctp_chunk_length,
2212 { "Length", "sctp.chunk_length",
2213 FT_UINT16, BASE_DEC, NULL, 0x0,
2216 { &hf_sctp_init_chunk_initiate_tag,
2217 { "Initiate tag", "sctp.init.chunk.initiate.tag",
2218 FT_UINT32, BASE_HEX, NULL, 0x0,
2221 { &hf_sctp_init_chunk_adv_rec_window_credit,
2222 { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
2223 FT_UINT32, BASE_DEC, NULL, 0x0,
2226 { &hf_sctp_init_chunk_number_of_outbound_streams,
2227 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
2228 FT_UINT16, BASE_DEC, NULL, 0x0,
2231 { &hf_sctp_init_chunk_number_of_inbound_streams,
2232 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
2233 FT_UINT16, BASE_DEC, NULL, 0x0,
2236 {&hf_sctp_init_chunk_initial_tsn,
2237 { "Initial TSN", "sctp.init.chunk.initial.tsn",
2238 FT_UINT32, BASE_DEC, NULL, 0x0,
2241 {&hf_sctp_cumulative_tsn_ack,
2242 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
2243 FT_UINT32, BASE_DEC, NULL, 0x0,
2246 {&hf_sctp_data_chunk_tsn,
2247 { "TSN", "sctp.tsn",
2248 FT_UINT32, BASE_DEC, NULL, 0x0,
2251 {&hf_sctp_data_chunk_stream_id,
2252 { "Stream Identifier", "sctp.stream_id",
2253 FT_UINT16, BASE_HEX, NULL, 0x0,
2256 {&hf_sctp_data_chunk_stream_seq_number,
2257 { "Stream sequence number", "sctp.stream_seq_number",
2258 FT_UINT16, BASE_DEC, NULL, 0x0,
2261 {&hf_sctp_data_chunk_payload_proto_id,
2262 { "Payload protocol identifier", "sctp.payload_proto_id",
2263 FT_UINT32, BASE_DEC, VALS(sctp_payload_proto_id_values), 0x0,
2266 {&hf_sctp_data_chunk_e_bit,
2267 { "E-Bit", "sctp.data.e_bit",
2268 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
2271 {&hf_sctp_data_chunk_b_bit,
2272 { "B-Bit", "sctp.data.b_bit",
2273 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
2276 {&hf_sctp_data_chunk_u_bit,
2277 { "U-Bit", "sctp.data.u.bit",
2278 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
2281 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
2282 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
2283 FT_UINT32, BASE_DEC, NULL, 0x0,
2286 {&hf_sctp_sack_chunk_adv_rec_window_credit,
2287 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
2288 FT_UINT32, BASE_DEC, NULL, 0x0,
2291 {&hf_sctp_sack_chunk_number_of_gap_blocks,
2292 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
2293 FT_UINT16, BASE_DEC, NULL, 0x0,
2296 {&hf_sctp_sack_chunk_number_of_dup_tsns,
2297 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
2298 FT_UINT16, BASE_DEC, NULL, 0x0,
2301 {&hf_sctp_sack_chunk_gap_block_start,
2302 { "Start", "sctp.sack.gap_block_start",
2303 FT_UINT16, BASE_DEC, NULL, 0x0,
2306 {&hf_sctp_sack_chunk_gap_block_end,
2307 { "End", "sctp.sack.gap_block_end",
2308 FT_UINT16, BASE_DEC, NULL, 0x0,
2311 {&hf_sctp_sack_chunk_duplicate_tsn,
2312 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
2313 FT_UINT16, BASE_DEC, NULL, 0x0,
2316 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
2317 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
2318 FT_UINT32, BASE_DEC, NULL, 0x0,
2321 {&hf_sctp_ecne_chunk_lowest_tsn,
2322 { "Lowest TSN", "sctp.ecne.lowest_tsn",
2323 FT_UINT32, BASE_DEC, NULL, 0x0,
2326 {&hf_sctp_cwr_chunk_lowest_tsn,
2327 { "Lowest TSN", "sctp.cwr.lowest_tsn",
2328 FT_UINT32, BASE_DEC, NULL, 0x0,
2331 {&hf_sctp_shutdown_complete_chunk_t_bit,
2332 { "E-Bit", "sctp.shutdown_complete.t_bit",
2333 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
2336 {&hf_sctp_forward_tsn_chunk_tsn,
2337 { "New cumulative TSN", "sctp.forward_tsn.tsn",
2338 FT_UINT32, BASE_DEC, NULL, 0x0,
2341 {&hf_sctp_chunk_parameter_type,
2342 { "Parameter type", "sctp.parameter.type",
2343 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2346 {&hf_sctp_chunk_parameter_length,
2347 { "Parameter length", "sctp.parameter.length",
2348 FT_UINT16, BASE_DEC, NULL, 0x0,
2351 {&hf_sctp_parameter_ipv4_address,
2352 { "IP Version 4 address", "sctp.parameter.ipv4_address",
2353 FT_IPv4, BASE_NONE, NULL, 0x0,
2356 {&hf_sctp_parameter_ipv6_address,
2357 { "IP Version 6 address", "sctp.parameter.ipv6_address",
2358 FT_IPv6, BASE_NONE, NULL, 0x0,
2361 {&hf_sctp_parameter_cookie_preservative_increment,
2362 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
2363 FT_UINT32, BASE_DEC, NULL, 0x0,
2366 {&hf_sctp_parameter_hostname_hostname,
2367 { "Hostname", "sctp.parameter.hostname.hostname",
2368 FT_STRING, BASE_NONE, NULL, 0x0,
2371 {&hf_sctp_supported_address_types_parameter,
2372 { "Supported address type", "sctp.parameter.supported_addres_type",
2373 FT_UINT16, BASE_DEC, NULL, 0x0,
2376 {&hf_sctp_ustreams_start,
2377 { "Start", "sctp.unreliable_streams.start",
2378 FT_UINT16, BASE_DEC, NULL, 0x0,
2381 {&hf_sctp_ustreams_end,
2382 { "End", "sctp.unreliable_streams.end",
2383 FT_UINT16, BASE_DEC, NULL, 0x0,
2386 {&hf_sctp_asconf_serial,
2387 { "Serial Number", "sctp.asconf.serial_number",
2388 FT_UINT32, BASE_HEX, NULL, 0x0,
2391 {&hf_sctp_asconf_correlation_id,
2392 { "Correlation_id", "sctp.asconf.correlation_id",
2393 FT_UINT32, BASE_HEX, NULL, 0x0,
2396 {&hf_sctp_asconf_reserved,
2397 { "Reserved", "sctp.asconf.reserved",
2398 FT_BYTES, BASE_NONE, NULL, 0x0,
2401 {&hf_sctp_asconf_addr_type,
2402 { "Address type", "sctp.asconf.address_type",
2403 FT_UINT8, BASE_HEX, VALS(sctp_address_type_values), 0x0,
2406 {&hf_sctp_asconf_addr,
2407 { "Address bytes", "sctp.asconf.address_bytes",
2408 FT_BYTES, BASE_NONE, NULL, 0x0,
2411 {&hf_sctp_asconf_ipv4_address,
2412 { "IP Version 4 address", "sctp.asconf.ipv4_address",
2413 FT_IPv4, BASE_NONE, NULL, 0x0,
2416 {&hf_sctp_asconf_ipv6_address,
2417 { "IP Version 6 address", "sctp.asconf.ipv6_address",
2418 FT_IPv6, BASE_NONE, NULL, 0x0,
2421 {&hf_sctp_asconf_ack_serial,
2422 { "Serial Number", "sctp.asconf_ack.serial_number",
2423 FT_UINT32, BASE_HEX, NULL, 0x0,
2426 {&hf_sctp_asconf_ack_correlation_id,
2427 { "Correlation_id", "sctp.asconf_ack.correlation_id",
2428 FT_UINT32, BASE_HEX, NULL, 0x0,
2431 {&hf_sctp_adap_indication,
2432 { "Indication", "sctp.adapation_layer_indication.indication",
2433 FT_UINT32, BASE_HEX, NULL, 0x0,
2436 {&hf_sctp_cause_code,
2437 { "Cause code", "sctp.cause.code",
2438 FT_UINT16, BASE_HEX, VALS(sctp_cause_code_values), 0x0,
2441 {&hf_sctp_cause_length,
2442 { "Cause length", "sctp.cause.length",
2443 FT_UINT16, BASE_DEC, NULL, 0x0,
2446 {&hf_sctp_cause_stream_identifier,
2447 { "Stream identifier", "sctp.cause.stream_identifier",
2448 FT_UINT16, BASE_DEC, NULL, 0x0,
2451 {&hf_sctp_cause_number_of_missing_parameters,
2452 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
2453 FT_UINT32, BASE_DEC, NULL, 0x0,
2456 {&hf_sctp_cause_missing_parameter_type,
2457 { "Missing parameter type", "sctp.cause.missing_parameter_type",
2458 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
2461 {&hf_sctp_cause_measure_of_staleness,
2462 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
2463 FT_UINT32, BASE_DEC, NULL, 0x0,
2466 {&hf_sctp_cause_tsn,
2467 { "TSN", "sctp.cause.tsn",
2468 FT_UINT32, BASE_DEC, NULL, 0x0,
2473 /* Setup protocol subtree array */
2474 static gint *ett[] = {
2477 &ett_sctp_chunk_parameter,
2478 &ett_sctp_chunk_cause,
2479 &ett_sctp_data_chunk_flags,
2480 &ett_sctp_sack_chunk_gap_block,
2481 &ett_sctp_supported_address_types_parameter,
2482 &ett_sctp_unrecognized_parameter_parameter,
2483 &ett_sctp_unreliable_streams_interval
2486 static enum_val_t sctp_checksum_options[] = {
2487 { "None", SCTP_CHECKSUM_NONE },
2488 { "Adler 32", SCTP_CHECKSUM_ADLER32 },
2489 { "CRC 32c", SCTP_CHECKSUM_CRC32C },
2490 { "Automatic", SCTP_CHECKSUM_AUTOMATIC},
2494 /* Register the protocol name and description */
2495 proto_sctp = proto_register_protocol("Stream Control Transmission Protocol", "SCTP", "sctp");
2496 sctp_module = prefs_register_protocol(proto_sctp, NULL);
2497 prefs_register_enum_preference(sctp_module, "checksum",
2499 "The type of checksum used in SCTP packets",
2500 &sctp_checksum, sctp_checksum_options, FALSE);
2502 /* Required function calls to register the header fields and subtrees used */
2503 proto_register_field_array(proto_sctp, hf, array_length(hf));
2504 proto_register_subtree_array(ett, array_length(ett));
2506 /* subdissector code */
2507 sctp_port_dissector_table = register_dissector_table("sctp.port", "SCTP port", FT_UINT16, BASE_DEC);
2508 sctp_ppi_dissector_table = register_dissector_table("sctp.ppi", "SCTP payload protocol identifier", FT_UINT32, BASE_HEX);
2513 proto_reg_handoff_sctp(void)
2515 dissector_handle_t sctp_handle;
2517 sctp_handle = create_dissector_handle(dissect_sctp, proto_sctp);
2518 dissector_add("ip.proto", IP_PROTO_SCTP, sctp_handle);