2 * Routines for Stream Control Transmission Protocol dissection
3 * Copyright 2000, Michael Tüxen <Michael.Tuexen@icn.siemens.de>
5 * $Id: packet-sctp.c,v 1.11 2001/01/13 04:30:20 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
9 * Copyright 1998 Gerald Combs
11 * Copied from README.developer
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
40 #ifdef HAVE_NETINET_IN_H
41 # include <netinet/in.h>
47 #ifdef NEED_SNPRINTF_H
48 # include "snprintf.h"
52 #include "packet-ip.h"
54 /* Initialize the protocol and registered fields */
55 static int proto_sctp = -1;
56 static int hf_sctp_source_port = -1;
57 static int hf_sctp_destination_port = -1;
58 static int hf_sctp_verification_tag = -1;
59 static int hf_sctp_checksum = -1;
61 static int hf_sctp_chunk_type = -1;
62 static int hf_sctp_chunk_flags = -1;
63 static int hf_sctp_chunk_length = -1;
65 static int hf_sctp_init_chunk_initiate_tag = -1;
66 static int hf_sctp_init_chunk_adv_rec_window_credit = -1;
67 static int hf_sctp_init_chunk_number_of_outbound_streams = -1;
68 static int hf_sctp_init_chunk_number_of_inbound_streams = -1;
69 static int hf_sctp_init_chunk_initial_tsn = -1;
71 static int hf_sctp_cumulative_tsn_ack = -1;
73 static int hf_sctp_data_chunk_tsn = -1;
74 static int hf_sctp_data_chunk_stream_id = -1;
75 static int hf_sctp_data_chunk_stream_seq_number = -1;
76 static int hf_sctp_data_chunk_payload_proto_id = -1;
78 static int hf_sctp_data_chunk_e_bit = -1;
79 static int hf_sctp_data_chunk_b_bit = -1;
80 static int hf_sctp_data_chunk_u_bit = -1;
82 static int hf_sctp_sack_chunk_cumulative_tsn_ack = -1;
83 static int hf_sctp_sack_chunk_adv_rec_window_credit = -1;
84 static int hf_sctp_sack_chunk_number_of_gap_blocks = -1;
85 static int hf_sctp_sack_chunk_number_of_dup_tsns = -1;
86 static int hf_sctp_sack_chunk_gap_block_start = -1;
87 static int hf_sctp_sack_chunk_gap_block_end = -1;
88 static int hf_sctp_sack_chunk_duplicate_tsn = -1;
90 static int hf_sctp_shutdown_chunk_cumulative_tsn_ack = -1;
92 static int hf_sctp_cwr_chunk_lowest_tsn = -1;
94 static int hf_sctp_ecne_chunk_lowest_tsn = -1;
96 static int hf_sctp_shutdown_complete_chunk_t_bit = -1;
98 static int hf_sctp_chunk_parameter_type = -1;
99 static int hf_sctp_chunk_parameter_length = -1;
100 static int hf_sctp_parameter_ipv4_address = -1;
101 static int hf_sctp_parameter_ipv6_address = -1;
102 static int hf_sctp_parameter_cookie_preservative_increment = -1;
103 static int hf_sctp_parameter_hostname_hostname = -1;
104 static int hf_sctp_supported_address_types_parameter = -1;
106 static int hf_sctp_cause_code = -1;
107 static int hf_sctp_cause_length = -1;
108 static int hf_sctp_cause_stream_identifier = -1;
110 static int hf_sctp_cause_number_of_missing_parameters = -1;
111 static int hf_sctp_cause_missing_parameter_type = -1;
113 static int hf_sctp_cause_measure_of_staleness = -1;
115 static int hf_sctp_cause_tsn = -1;
117 static dissector_table_t sctp_port_dissector_table;
118 static dissector_table_t sctp_ppi_dissector_table;
120 /* Initialize the subtree pointers */
121 static gint ett_sctp = -1;
122 static gint ett_sctp_chunk = -1;
123 static gint ett_sctp_chunk_parameter = -1;
124 static gint ett_sctp_chunk_cause = -1;
125 static gint ett_sctp_data_chunk_flags = -1;
126 static gint ett_sctp_sack_chunk_gap_block = -1;
127 static gint ett_sctp_supported_address_types_parameter = -1;
128 static gint ett_sctp_unrecognized_parameter_parameter = -1;
130 #define SCTP_DATA_CHUNK_ID 0
131 #define SCTP_INIT_CHUNK_ID 1
132 #define SCTP_INIT_ACK_CHUNK_ID 2
133 #define SCTP_SACK_CHUNK_ID 3
134 #define SCTP_HEARTBEAT_CHUNK_ID 4
135 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
136 #define SCTP_ABORT_CHUNK_ID 6
137 #define SCTP_SHUTDOWN_CHUNK_ID 7
138 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
139 #define SCTP_ERROR_CHUNK_ID 9
140 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
141 #define SCTP_COOKIE_ACK_CHUNK_ID 11
142 #define SCTP_ECNE_CHUNK_ID 12
143 #define SCTP_CWR_CHUNK_ID 13
144 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
145 #define SCTP_IETF_EXT 255
147 static const value_string sctp_chunk_type_values[] = {
148 { SCTP_DATA_CHUNK_ID, "DATA" },
149 { SCTP_INIT_CHUNK_ID, "INIT" },
150 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
151 { SCTP_SACK_CHUNK_ID, "SACK" },
152 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
153 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
154 { SCTP_ABORT_CHUNK_ID, "ABORT" },
155 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
156 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
157 { SCTP_ERROR_CHUNK_ID, "ERROR" },
158 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
159 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
160 { SCTP_ECNE_CHUNK_ID, "ECNE" },
161 { SCTP_CWR_CHUNK_ID, "CWR" },
162 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
163 { SCTP_IETF_EXT, "IETF_EXTENSION" },
166 #define HEARTBEAT_INFO_PARAMETER_ID 0x0001
167 #define IPV4ADDRESS_PARAMETER_ID 0x0005
168 #define IPV6ADDRESS_PARAMETER_ID 0x0006
169 #define STATE_COOKIE_PARAMETER_ID 0x0007
170 #define UNREC_PARA_PARAMETER_ID 0x0008
171 #define COOKIE_PRESERVATIVE_PARAMETER_ID 0x0009
172 #define HOSTNAME_ADDRESS_PARAMETER_ID 0x000b
173 #define SUPPORTED_ADDRESS_TYPES_PARAMETER_ID 0x000c
174 #define ECN_PARAMETER_ID 0x8000
176 static const value_string sctp_parameter_identifier_values[] = {
177 { HEARTBEAT_INFO_PARAMETER_ID, "Heartbeat info" },
178 { IPV4ADDRESS_PARAMETER_ID, "IPv4 address" },
179 { IPV6ADDRESS_PARAMETER_ID, "IPv6 address" },
180 { STATE_COOKIE_PARAMETER_ID, "State cookie" },
181 { UNREC_PARA_PARAMETER_ID, "Unrecognized parameters" },
182 { COOKIE_PRESERVATIVE_PARAMETER_ID, "Cookie preservative" },
183 { HOSTNAME_ADDRESS_PARAMETER_ID, "Hostname address" },
184 { SUPPORTED_ADDRESS_TYPES_PARAMETER_ID, "Supported address types" },
185 { ECN_PARAMETER_ID, "ECN" },
188 #define PARAMETER_TYPE_LENGTH 2
189 #define PARAMETER_LENGTH_LENGTH 2
190 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
192 #define PARAMETER_HEADER_OFFSET 0
193 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
194 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
195 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
197 #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET
198 #define HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
200 #define IPV4_ADDRESS_LENGTH 4
201 #define IPV6_ADDRESS_LENGTH 16
203 #define STATE_COOKIE_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
204 #define STATE_COOKIE_PARAMETER_COOKIE_OFFSET PARAMETER_VALUE_OFFSET
206 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET PARAMETER_VALUE_OFFSET
207 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH 4
208 #define SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH 2
210 #define CAUSE_CODE_LENGTH 2
211 #define CAUSE_LENGTH_LENGTH 2
212 #define CAUSE_HEADER_LENGTH (CAUSE_CODE_LENGTH + CAUSE_LENGTH_LENGTH)
214 #define CAUSE_HEADER_OFFSET 0
215 #define CAUSE_CODE_OFFSET CAUSE_HEADER_OFFSET
216 #define CAUSE_LENGTH_OFFSET (CAUSE_CODE_OFFSET + CAUSE_CODE_LENGTH)
217 #define CAUSE_INFO_OFFSET (CAUSE_LENGTH_OFFSET + CAUSE_LENGTH_LENGTH)
219 #define CAUSE_STREAM_IDENTIFIER_LENGTH 2
220 #define CAUSE_RESERVED_LENGTH 2
221 #define CAUSE_STREAM_IDENTIFIER_OFFSET CAUSE_INFO_OFFSET
222 #define CAUSE_RESERVED_OFFSET (CAUSE_STREAM_IDENTIFIER_OFFSET + CAUSE_STREAM_IDENTIFIER_LENGTH)
224 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH 4
225 #define CAUSE_MISSING_PARAMETER_TYPE_LENGTH 2
227 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET CAUSE_INFO_OFFSET
228 #define CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET (CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET + \
229 CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH )
231 #define CAUSE_MEASURE_OF_STALENESS_LENGTH 4
232 #define CAUSE_MEASURE_OF_STALENESS_OFFSET CAUSE_INFO_OFFSET
234 #define CAUSE_TSN_LENGTH 4
235 #define CAUSE_TSN_OFFSET CAUSE_INFO_OFFSET
237 #define INVALID_STREAM_IDENTIFIER 0x01
238 #define MISSING_MANDATORY_PARAMETERS 0x02
239 #define STALE_COOKIE_ERROR 0x03
240 #define OUT_OF_RESOURCE 0x04
241 #define UNRESOLVABLE_ADDRESS 0x05
242 #define UNRECOGNIZED_CHUNK_TYPE 0x06
243 #define INVALID_MANDATORY_PARAMETER 0x07
244 #define UNRECOGNIZED_PARAMETERS 0x08
245 #define NO_USER_DATA 0x09
246 #define COOKIE_RECEIVED_WHILE_SHUTTING_DOWN 0x0a
248 static const value_string sctp_cause_code_values[] = {
249 { INVALID_STREAM_IDENTIFIER, "Invalid stream idetifier" },
250 { MISSING_MANDATORY_PARAMETERS, "Missing mandator parameter" },
251 { STALE_COOKIE_ERROR, "Stale cookie error" },
252 { OUT_OF_RESOURCE, "Out of resource" },
253 { UNRESOLVABLE_ADDRESS, "Unresolvable address" },
254 { UNRECOGNIZED_CHUNK_TYPE, "Unrecognized chunk type " },
255 { INVALID_MANDATORY_PARAMETER, "Invalid mandatory parameter" },
256 { UNRECOGNIZED_PARAMETERS, "Unrecognized parameters" },
257 { NO_USER_DATA, "No user data" },
258 { COOKIE_RECEIVED_WHILE_SHUTTING_DOWN, "Cookie received while shutting down" },
261 #define NOT_SPECIFIED_PROTOCOL_ID 0
262 #define IUA_PAYLOAD_PROTOCOL_ID 1
263 #define M2UA_PAYLOAD_PROTOCOL_ID 2
264 #define M3UA_PAYLOAD_PROTOCOL_ID 3
265 #define SUA_PAYLOAD_PROTOCOL_ID 4
266 #define M2PA_PAYLOAD_PROTOCOL_ID 5
267 #define V5UA_PAYLOAD_PROTOCOL_ID 6
269 static const value_string sctp_payload_proto_id_values[] = {
270 { NOT_SPECIFIED_PROTOCOL_ID, "not specified" },
271 { IUA_PAYLOAD_PROTOCOL_ID, "IUA" },
272 { M2UA_PAYLOAD_PROTOCOL_ID, "M2UA" },
273 { M3UA_PAYLOAD_PROTOCOL_ID, "M3UA" },
274 { SUA_PAYLOAD_PROTOCOL_ID, "SUA" },
275 { M2PA_PAYLOAD_PROTOCOL_ID, "M2PA" },
276 { V5UA_PAYLOAD_PROTOCOL_ID, "V5UA" },
279 /* The structure of the common header is described by the following constants */
280 #define SOURCE_PORT_LENGTH 2
281 #define DESTINATION_PORT_LENGTH 2
282 #define VERIFICATION_TAG_LENGTH 4
283 #define CHECKSUM_LENGTH 4
284 #define COMMON_HEADER_LENGTH (SOURCE_PORT_LENGTH + \
285 DESTINATION_PORT_LENGTH + \
286 VERIFICATION_TAG_LENGTH + \
288 #define SOURCE_PORT_OFFSET 0
289 #define DESTINATION_PORT_OFFSET (SOURCE_PORT_OFFSET + SOURCE_PORT_LENGTH)
290 #define VERIFICATION_TAG_OFFSET (DESTINATION_PORT_OFFSET + DESTINATION_PORT_LENGTH)
291 #define CHECKSUM_OFFSET (VERIFICATION_TAG_OFFSET + VERIFICATION_TAG_LENGTH)
293 /* The structure of the chunk header is described by the following constants */
294 #define CHUNK_TYPE_LENGTH 1
295 #define CHUNK_FLAGS_LENGTH 1
296 #define CHUNK_LENGTH_LENGTH 2
297 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
298 CHUNK_FLAGS_LENGTH + \
300 #define CHUNK_HEADER_OFFSET 0
301 #define CHUNK_TYPE_OFFSET CHUNK_HEADER_OFFSET
302 #define CHUNK_FLAGS_OFFSET (CHUNK_TYPE_OFFSET + CHUNK_TYPE_LENGTH)
303 #define CHUNK_LENGTH_OFFSET (CHUNK_FLAGS_OFFSET + CHUNK_FLAGS_LENGTH)
304 #define CHUNK_VALUE_OFFSET (CHUNK_LENGTH_OFFSET + CHUNK_LENGTH_LENGTH)
306 /* The following constants describe the structure of DATA chunks */
307 #define DATA_CHUNK_TSN_LENGTH 4
308 #define DATA_CHUNK_STREAM_ID_LENGTH 2
309 #define DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH 2
310 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
312 #define DATA_CHUNK_TSN_OFFSET (CHUNK_VALUE_OFFSET + 0)
313 #define DATA_CHUNK_STREAM_ID_OFFSET (DATA_CHUNK_TSN_OFFSET + DATA_CHUNK_TSN_LENGTH)
314 #define DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET (DATA_CHUNK_STREAM_ID_OFFSET + \
315 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
316 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET (DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET + \
317 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
318 #define DATA_CHUNK_PAYLOAD_OFFSET (DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET + \
319 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
321 #define DATA_CHUNK_HEADER_LENGTH (CHUNK_HEADER_LENGTH + \
322 DATA_CHUNK_TSN_LENGTH + \
323 DATA_CHUNK_STREAM_ID_LENGTH + \
324 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH + \
325 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
327 #define SCTP_DATA_CHUNK_E_BIT 0x01
328 #define SCTP_DATA_CHUNK_B_BIT 0x02
329 #define SCTP_DATA_CHUNK_U_BIT 0x04
331 #define INIT_CHUNK_INITIATE_TAG_LENGTH 4
332 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
333 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH 2
334 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH 2
335 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
337 #define INIT_CHUNK_INITIATE_TAG_OFFSET CHUNK_VALUE_OFFSET
338 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (INIT_CHUNK_INITIATE_TAG_OFFSET + \
339 INIT_CHUNK_INITIATE_TAG_LENGTH )
340 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET (INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
341 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH )
342 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET (INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET + \
343 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH )
344 #define INIT_CHUNK_INITIAL_TSN_OFFSET (INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET + \
345 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH )
346 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
347 INIT_CHUNK_INITIAL_TSN_LENGTH )
350 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
351 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
352 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH 2
353 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH 2
354 #define SACK_CHUNK_GAP_BLOCK_LENGTH 4
355 #define SACK_CHUNK_GAP_BLOCK_START_LENGTH 2
356 #define SACK_CHUNK_GAP_BLOCK_END_LENGTH 2
357 #define SACK_CHUNK_DUP_TSN_LENGTH 4
359 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
360 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
361 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
362 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET (SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
363 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH)
364 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET (SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET + \
365 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH)
366 #define SACK_CHUNK_GAP_BLOCK_OFFSET (SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET + \
367 SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH)
369 #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET
371 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET CHUNK_VALUE_OFFSET
372 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
374 #define ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
375 #define ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
377 #define COOKIE_ECHO_CHUNK_COOKIE_OFFSET CHUNK_VALUE_OFFSET
379 #define ECNE_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
380 #define ECNE_CHUNK_LOWEST_TSN_LENGTH 4
382 #define CWR_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
383 #define CWR_CHUNK_LOWEST_TSN_LENGTH 4
385 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT 0x01
387 static const true_false_string sctp_data_chunk_e_bit_value = {
389 "Not the last segment"
392 static const true_false_string sctp_data_chunk_b_bit_value = {
397 static const true_false_string sctp_data_chunk_u_bit_value = {
398 "Unordered delivery",
402 static const true_false_string sctp_shutdown_complete_chunk_t_bit_value = {
407 /* adler32.c -- compute the Adler-32 checksum of a data stream
408 * Copyright (C) 1995-1996 Mark Adler
409 * For conditions of distribution and use, see copyright notice in zlib.h
410 * available, e.g. from http://www.cdrom.com/pub/infozip/zlib/
412 * It was modified for the use in this dissector.
415 #define BASE 65521L /* largest prime smaller than 65536 */
416 #define NMAX 5540 /* NMAX is the largest n - 12 such that */
417 /* 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
419 #define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
420 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
421 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
422 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
423 #define DO16(buf) DO8(buf,0); DO8(buf,8);
426 sctp_adler_32(const unsigned char* buf,
429 unsigned int s1 = 1L;
430 unsigned int s2 = 0L;
433 /* handle the first 8 bytes of the datagram */
435 buf += SOURCE_PORT_LENGTH +
436 DESTINATION_PORT_LENGTH +
437 VERIFICATION_TAG_LENGTH;
439 /* handle four 0 bytes as checksum */
440 s2 += CHECKSUM_LENGTH * s1;
441 buf += CHECKSUM_LENGTH;
443 /* now we have 12 bytes handled */
444 len -= COMMON_HEADER_LENGTH;
446 /* handle the rest of the datagram */
448 k = len < NMAX ? len : NMAX;
462 return (s2 << 16) | s1;
466 *sctp_checksum_state(tvbuff_t *tvb, guint orig_checksum)
470 length = tvb_length(tvb);
471 if (orig_checksum == sctp_adler_32(tvb_get_ptr(tvb, 0, length), length))
478 nr_of_padding_bytes (guint length)
482 remainder = length % 4;
487 return 4 - remainder;
491 * TLV parameter stuff for INIT and INIT-ACK chunks
495 dissect_parameter(tvbuff_t *, proto_tree *);
498 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
501 dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, proto_tree *tree)
503 guint offset, length, padding_length, total_length;
504 tvbuff_t *parameter_tvb;
507 while(tvb_length_remaining(parameter_list_tvb, offset)) {
508 length = tvb_get_ntohs(parameter_list_tvb, offset + PARAMETER_LENGTH_OFFSET);
509 padding_length = nr_of_padding_bytes(length);
510 total_length = length + padding_length;
511 /* create a tvb for the chunk including the padding bytes */
512 parameter_tvb = tvb_new_subset(parameter_list_tvb, offset, total_length, total_length);
513 dissect_parameter(parameter_tvb, tree);
514 /* get rid of the handled parameter */
515 offset += total_length;
520 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
522 guint16 length, heartbeat_info_length;
524 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
526 heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
528 proto_tree_add_text(parameter_tree, parameter_tvb, HEARTBEAT_INFO_PARAMETER_INFO_OFFSET, heartbeat_info_length,
529 "Heartbeat info (%u byte%s)",
530 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
532 proto_item_set_text(parameter_item, "Heartbeat info parameter with %u byte%s of info",
533 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
537 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
539 guint32 ipv4_address;
541 tvb_memcpy(parameter_tvb, (guint8 *)&ipv4_address, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH);
542 proto_tree_add_ipv4(parameter_tree, hf_sctp_parameter_ipv4_address,
543 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH,
545 proto_item_set_text(parameter_item, "IPV4 address parameter");
549 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
551 proto_tree_add_ipv6(parameter_tree, hf_sctp_parameter_ipv6_address,
552 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH,
553 tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH));
555 proto_item_set_text(parameter_item, "IPV6 address parameter");
559 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
561 guint16 length, state_cookie_length;
563 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
565 state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
567 proto_tree_add_text(parameter_tree, parameter_tvb, STATE_COOKIE_PARAMETER_COOKIE_OFFSET, state_cookie_length,
568 "State cookie (%u byte%s)",
569 state_cookie_length, plurality(state_cookie_length, "", "s"));
571 proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
572 state_cookie_length, plurality(state_cookie_length, "", "s"));
576 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
578 guint16 length, parameter_value_length;
579 tvbuff_t *unrecognized_parameters_tvb;
581 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
583 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
585 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
586 parameter_value_length, parameter_value_length);
587 dissect_tlv_parameter_list(unrecognized_parameters_tvb, parameter_tree);
589 proto_item_set_text(parameter_item, "Unrecognized parameter of type");
593 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
597 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
599 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
600 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
601 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
604 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
609 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
611 guint16 length, hostname_length;
614 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
616 hostname_length = length - PARAMETER_HEADER_LENGTH;
617 hostname = (char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
618 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
619 PARAMETER_VALUE_OFFSET, hostname_length,
622 proto_item_set_text(parameter_item, "Hostname parameter");
626 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
628 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
630 proto_item *address_list_item;
631 proto_tree *address_list_tree;
633 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
634 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
635 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
637 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
638 "Supported Address Types (%u address type%s)",
639 number_of_address_types, plurality(number_of_address_types, "", "s"));
640 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
642 offset = PARAMETER_VALUE_OFFSET;
643 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
644 address_type = tvb_get_ntohs(parameter_tvb, offset);
645 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
646 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
647 address_type, "Supported address type: %u (%s)",
648 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
649 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
652 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
653 number_of_address_types, plurality(number_of_address_types, "", "s"));
657 dissect_ecn_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
659 proto_item_set_text(parameter_item, "ECN parameter");
663 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
665 guint16 type, length, parameter_value_length;
667 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
668 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
670 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
672 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
673 "Parameter value (%u byte%s)",
674 parameter_value_length, plurality(parameter_value_length, "", "s"));
676 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
677 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
681 dissect_parameter(tvbuff_t *parameter_tvb, proto_tree *chunk_tree)
683 guint16 type, length, padding_length, total_length;
684 proto_item *parameter_item;
685 proto_tree *parameter_tree;
687 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
688 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
689 padding_length = nr_of_padding_bytes(length);
690 total_length = length + padding_length;
692 parameter_item = proto_tree_add_notext(chunk_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, total_length);
693 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
695 proto_tree_add_uint_format(parameter_tree, hf_sctp_chunk_parameter_type,
696 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
697 type, "Parameter type: %u (%s)",
698 type, val_to_str(type, sctp_parameter_identifier_values, "unknown"));
699 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
700 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
704 case HEARTBEAT_INFO_PARAMETER_ID:
705 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
707 case IPV4ADDRESS_PARAMETER_ID:
708 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
710 case IPV6ADDRESS_PARAMETER_ID:
711 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
713 case STATE_COOKIE_PARAMETER_ID:
714 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
716 case UNREC_PARA_PARAMETER_ID:
717 dissect_unrecognized_parameters_parameter(parameter_tvb, parameter_tree, parameter_item);
719 case COOKIE_PRESERVATIVE_PARAMETER_ID:
720 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
722 case HOSTNAME_ADDRESS_PARAMETER_ID:
723 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
725 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
726 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
728 case ECN_PARAMETER_ID:
729 dissect_ecn_parameter(parameter_tvb, parameter_tree, parameter_item);
732 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
735 if (padding_length > 0)
736 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
737 "Padding: %u byte%s",
738 padding_length, plurality(padding_length, "", "s"));
742 * Code to handle error causes for ABORT and ERROR chunks
745 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
747 guint16 stream_identifier;
749 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
750 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
751 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
753 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
754 "Reserved (2 bytes)");
756 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
761 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
763 guint32 number_of_missing_parameters, missing_parameter_number;
764 guint16 parameter_type;
767 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
768 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
769 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
770 number_of_missing_parameters);
771 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
772 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
773 parameter_type = tvb_get_ntohs(cause_tvb, offset);
774 proto_tree_add_uint_format(cause_tree, hf_sctp_cause_missing_parameter_type,
775 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
776 parameter_type, "Missing parameter type: %u (%s)",
778 val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown"));
779 offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
782 proto_item_set_text(cause_item, "Error cause reporting %u missing mandatory parameter%s",
783 number_of_missing_parameters, plurality(number_of_missing_parameters, "", "s") );
787 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
789 guint32 measure_of_staleness;
791 measure_of_staleness = tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
793 proto_tree_add_uint(cause_tree, hf_sctp_cause_measure_of_staleness, cause_tvb,
794 CAUSE_MEASURE_OF_STALENESS_OFFSET,
795 CAUSE_MEASURE_OF_STALENESS_LENGTH,
796 measure_of_staleness);
798 proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
799 measure_of_staleness);
803 dissect_out_of_resource_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
805 proto_item_set_text(cause_item, "Error cause reporting lack of resources");
809 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
811 guint16 code, length, parameter_length, parameter_type;
812 tvbuff_t *parameter_tvb;
814 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
815 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
817 parameter_length = length - CAUSE_HEADER_LENGTH;
818 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
819 parameter_length, parameter_length);
821 dissect_parameter(parameter_tvb, cause_tree);
822 parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
824 proto_item_set_text(cause_item, "Error cause reporting unresolvable address of type %u (%s)",
825 parameter_type, val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown") );
829 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo,
830 proto_tree *cause_tree, proto_item *cause_item)
832 guint16 length, chunk_length;
833 guint8 unrecognized_type;
834 tvbuff_t *unrecognized_chunk_tvb;
836 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
838 chunk_length = length - CAUSE_HEADER_LENGTH;
840 unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
841 chunk_length, chunk_length);
842 dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree);
844 unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
846 proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
848 val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
852 dissect_invalid_mandatory_parameter_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
854 proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
858 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
860 guint16 length, cause_info_length;
861 tvbuff_t *unrecognized_parameters_tvb;
863 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
865 cause_info_length = length - CAUSE_HEADER_LENGTH;
867 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
868 cause_info_length, cause_info_length);
869 dissect_tlv_parameter_list(unrecognized_parameters_tvb, cause_tree);
871 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
875 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
879 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
880 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
885 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
890 dissect_cookie_received_while_shutting_down_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
892 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
896 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
898 guint16 code, length, cause_info_length;
900 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
901 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
903 cause_info_length = length - CAUSE_HEADER_LENGTH;
905 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
906 "Cause specific information (%u byte%s)",
907 cause_info_length, plurality(cause_info_length, "", "s"));
909 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
910 code, cause_info_length, plurality(cause_info_length, "", "s"));
914 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
916 guint16 code, length, padding_length, total_length;
917 proto_item *cause_item;
918 proto_tree *cause_tree;
920 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
921 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
922 padding_length = nr_of_padding_bytes(length);
923 total_length = length + padding_length;
925 cause_item = proto_tree_add_notext(chunk_tree, cause_tvb, CAUSE_HEADER_OFFSET, total_length);
926 proto_item_set_text(cause_item, "BAD ERROR CAUSE");
927 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
929 proto_tree_add_uint_format(cause_tree, hf_sctp_cause_code,
930 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
931 code, "Cause code: %u (%s)",
932 code, val_to_str(code, sctp_cause_code_values, "unknown"));
933 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
934 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
938 case INVALID_STREAM_IDENTIFIER:
939 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
941 case MISSING_MANDATORY_PARAMETERS:
942 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
944 case STALE_COOKIE_ERROR:
945 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
947 case OUT_OF_RESOURCE:
948 dissect_out_of_resource_cause(cause_tvb, cause_tree, cause_item);
950 case UNRESOLVABLE_ADDRESS:
951 dissect_unresolvable_address_cause(cause_tvb, cause_tree, cause_item);
953 case UNRECOGNIZED_CHUNK_TYPE:
954 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
956 case INVALID_MANDATORY_PARAMETER:
957 dissect_invalid_mandatory_parameter_cause(cause_tvb, cause_tree, cause_item);
959 case UNRECOGNIZED_PARAMETERS:
960 dissect_unrecognized_parameters_cause(cause_tvb, cause_tree, cause_item);
963 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
965 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
966 dissect_cookie_received_while_shutting_down_cause(cause_tvb, cause_tree, cause_item);
969 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
972 if (padding_length > 0)
973 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
974 "Padding: %u byte%s",
975 padding_length, plurality(padding_length, "", "s"));
979 * Code to actually dissect the packets
983 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
984 proto_tree *chunk_tree, guint32 ppi, guint16 payload_length, guint16 padding_length)
986 /* do lookup with the subdissector table */
987 if (dissector_try_port (sctp_ppi_dissector_table, ppi, payload_tvb, pinfo, tree) ||
988 dissector_try_port(sctp_port_dissector_table, pi.srcport, payload_tvb, pinfo, tree) ||
989 dissector_try_port(sctp_port_dissector_table, pi.destport, payload_tvb, pinfo, tree))
993 if (check_col(pinfo->fd, COL_INFO))
994 col_append_str(pinfo->fd, COL_INFO, "DATA ");
995 proto_tree_add_text(chunk_tree, payload_tvb, 0, payload_length,
996 "Payload (%u byte%s)",
997 payload_length, plurality(payload_length, "", "s"));
998 if (padding_length > 0)
999 proto_tree_add_text(chunk_tree, payload_tvb, payload_length, padding_length,
1000 "Padding: %u byte%s",
1001 padding_length, plurality(padding_length, "", "s"));
1006 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1007 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1010 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
1011 guint32 tsn, payload_proto_id;
1012 proto_tree *flag_tree;
1013 tvbuff_t *payload_tvb;
1015 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1016 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1017 padding_length = nr_of_padding_bytes(length);
1018 total_payload_length = payload_length + padding_length;
1019 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1020 total_payload_length, total_payload_length);
1021 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1024 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1026 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1027 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
1028 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1029 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1030 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1031 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1032 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1034 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1035 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1036 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1038 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1040 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1042 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1044 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1046 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1048 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1050 proto_tree_add_uint_format(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1051 chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1052 payload_proto_id, "Payload protocol identifier: %u (%s)",
1053 payload_proto_id, val_to_str(payload_proto_id, sctp_payload_proto_id_values, "unknown"));
1054 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1055 tsn, stream_id, stream_seq_number,
1056 payload_length, plurality(payload_length, "", "s"));
1058 dissect_payload(payload_tvb, pinfo, tree, chunk_tree, payload_proto_id, payload_length, padding_length);
1062 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1063 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1065 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1066 guint16 number_of_inbound_streams, number_of_outbound_streams;
1068 tvbuff_t *parameter_list_tvb;
1070 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1072 if (check_col(pinfo->fd, COL_INFO)) {
1073 if (type == SCTP_INIT_CHUNK_ID) {
1074 col_append_str(pinfo->fd, COL_INFO, "INIT ");
1076 col_append_str(pinfo->fd, COL_INFO, "INIT_ACK ");
1081 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1082 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1083 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1084 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1085 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1087 /* handle fixed parameters */
1088 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1090 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1092 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1094 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1095 adv_rec_window_credit);
1096 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1098 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1099 number_of_outbound_streams);
1100 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1102 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1103 number_of_inbound_streams);
1104 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1106 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1109 /* handle variable paramters */
1110 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1111 dissect_tlv_parameter_list(parameter_list_tvb, chunk_tree);
1113 proto_item_set_text(chunk_item,
1114 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1115 val_to_str(type, sctp_chunk_type_values, "unknown"),
1116 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1117 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1122 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1123 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1125 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1129 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1130 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1132 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1133 guint16 number_of_gap_blocks, number_of_dup_tsns;
1134 guint16 gap_block_number, dup_tsn_number, start, end;
1135 gint gap_block_offset, dup_tsn_offset;
1136 proto_item *block_item;
1137 proto_tree *block_tree;
1139 if (check_col(pinfo->fd, COL_INFO))
1140 col_append_str(pinfo->fd, COL_INFO, "SACK ");
1143 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1144 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1145 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1146 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1148 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1150 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1151 cumulative_tsn_ack);
1152 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1154 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1155 adv_rec_window_credit);
1156 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1158 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1159 number_of_gap_blocks);
1160 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1162 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1163 number_of_dup_tsns);
1165 /* handle the gap acknowledgement blocks */
1166 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1167 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1168 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1169 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1170 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1171 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1172 "Gap Acknowledgement for %u TSN%s",
1173 1 + end - start, plurality(1 + end - start, "", "s"));
1174 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1175 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1177 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1179 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1181 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1182 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1184 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1187 /* handle the duplicate TSNs */
1188 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1189 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1190 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1191 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1193 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1195 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1198 proto_item_set_text(chunk_item,
1199 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1201 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1202 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1207 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1208 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1210 tvbuff_t *parameter_tvb;
1211 guint chunk_length, info_length, padding_length, total_length;
1213 if (check_col(pinfo->fd, COL_INFO))
1214 col_append_str(pinfo->fd, COL_INFO, "HEARTBEAT ");
1217 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1218 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1219 padding_length = nr_of_padding_bytes(info_length);
1220 total_length = info_length + padding_length;
1221 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1223 dissect_parameter(parameter_tvb, chunk_tree);
1225 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1230 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1231 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1233 tvbuff_t *parameter_tvb;
1234 guint chunk_length, info_length, padding_length, total_length;
1236 if (check_col(pinfo->fd, COL_INFO))
1237 col_append_str(pinfo->fd, COL_INFO, "HEARTBEAT_ACK ");
1240 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1241 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1242 padding_length = nr_of_padding_bytes(info_length);
1243 total_length = info_length + padding_length;
1245 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1247 dissect_parameter(parameter_tvb, chunk_tree);
1249 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1254 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1255 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1257 guint offset, number_of_causes;
1258 guint16 length, padding_length, total_length;
1259 tvbuff_t *cause_tvb;
1261 if (check_col(pinfo->fd, COL_INFO))
1262 col_append_str(pinfo->fd, COL_INFO, "ABORT ");
1265 number_of_causes = 0;
1266 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1267 while(tvb_length_remaining(chunk_tvb, offset)) {
1268 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1269 padding_length = nr_of_padding_bytes(length);
1270 total_length = length + padding_length;
1271 /* create a tvb for the chunk including the padding bytes */
1272 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1273 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1274 /* get rid of the handled parameter */
1275 offset += total_length;
1279 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s",
1280 number_of_causes, plurality(number_of_causes, "", "s"));
1285 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1286 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1288 guint32 cumulative_tsn_ack;
1290 if (check_col(pinfo->fd, COL_INFO))
1291 col_append_str(pinfo->fd, COL_INFO, "SHUTDOWN ");
1294 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1295 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1297 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1298 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1299 cumulative_tsn_ack);
1301 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1302 cumulative_tsn_ack);
1307 dissect_shutdown_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1308 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1310 if (check_col(pinfo->fd, COL_INFO))
1311 col_append_str(pinfo->fd, COL_INFO, "SHUTDOWN_ACK ");
1314 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1319 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1320 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1322 guint offset, number_of_causes;
1323 guint16 length, padding_length, total_length;
1324 tvbuff_t *cause_tvb;
1326 if (check_col(pinfo->fd, COL_INFO))
1327 col_append_str(pinfo->fd, COL_INFO, "ERROR ");
1330 number_of_causes = 0;
1331 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1333 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1334 padding_length = nr_of_padding_bytes(length);
1335 total_length = length + padding_length;
1336 /* create a tvb for the chunk including the padding bytes */
1337 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1338 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1339 /* get rid of the handled parameter */
1340 offset += total_length;
1342 } while(tvb_length_remaining(chunk_tvb, offset));
1344 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1345 number_of_causes, plurality(number_of_causes, "", "s"));
1350 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1351 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1353 guint length, cookie_length, padding_length;
1355 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1356 padding_length = nr_of_padding_bytes(length);
1357 cookie_length = length - CHUNK_HEADER_LENGTH;
1359 if (check_col(pinfo->fd, COL_INFO))
1360 col_append_str(pinfo->fd, COL_INFO, "COOKIE_ECHO ");
1363 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1364 "Cookie (%u byte%s)",
1365 cookie_length, plurality(cookie_length, "", "s"));
1366 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1367 cookie_length, plurality(cookie_length, "", "s"));
1369 if (padding_length > 0)
1370 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1371 "Padding: %u byte%s",
1372 padding_length, plurality(padding_length, "", "s"));
1377 dissect_cookie_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1378 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1380 if (check_col(pinfo->fd, COL_INFO))
1381 col_append_str(pinfo->fd, COL_INFO, "COOKIE_ACK ");
1384 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1389 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1390 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1394 if (check_col(pinfo->fd, COL_INFO))
1395 col_append_str(pinfo->fd, COL_INFO, "ECNE ");
1398 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1399 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1401 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1404 proto_item_set_text(chunk_item, "ECNE chunk");
1409 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1410 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1414 if (check_col(pinfo->fd, COL_INFO))
1415 col_append_str(pinfo->fd, COL_INFO, "CWR ");
1418 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1419 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1421 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1424 proto_item_set_text(chunk_item, "CWR chunk");
1429 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1430 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1434 proto_tree *flag_tree;
1436 if (check_col(pinfo->fd, COL_INFO))
1437 col_append_str(pinfo->fd, COL_INFO, "SHUTDOWN_COMPLETE ");
1440 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1441 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1443 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1444 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1445 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1447 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1452 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1453 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1455 guint length, chunk_value_length, padding_length;
1458 if (check_col(pinfo->fd, COL_INFO))
1459 col_append_str(pinfo->fd, COL_INFO, "UNKNOWN ");
1462 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1463 padding_length = nr_of_padding_bytes(length);
1464 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1466 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1468 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1469 "Chunk value (%u byte%s)",
1470 chunk_value_length, plurality(chunk_value_length, "", "s"));
1472 if (padding_length > 0)
1473 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1474 "Padding: %u byte%s",
1475 padding_length, plurality(padding_length, "", "s"));
1477 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1478 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1484 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1488 proto_item *flags_item;
1489 proto_item *chunk_item;
1490 proto_tree *chunk_tree;
1492 /* first extract the chunk header */
1493 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1494 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1495 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1498 /* create proto_tree stuff */
1499 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb,
1500 CHUNK_HEADER_OFFSET, tvb_length(chunk_tvb), "Incomplete chunk");
1501 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
1503 /* then insert the chunk header components into the protocol tree */
1504 proto_tree_add_uint_format(chunk_tree, hf_sctp_chunk_type,
1505 chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH,
1506 type, "Identifier: %u (%s)",
1507 type, val_to_str(type, sctp_chunk_type_values, "unknown"));
1508 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags,
1509 chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH,
1511 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length,
1512 chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH,
1520 /* now dissect the chunk value */
1523 case SCTP_DATA_CHUNK_ID:
1524 dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1526 case SCTP_INIT_CHUNK_ID:
1527 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1529 case SCTP_INIT_ACK_CHUNK_ID:
1530 dissect_init_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1532 case SCTP_SACK_CHUNK_ID:
1533 dissect_sack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1535 case SCTP_HEARTBEAT_CHUNK_ID:
1536 dissect_heartbeat_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1538 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1539 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1541 case SCTP_ABORT_CHUNK_ID:
1542 dissect_abort_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1544 case SCTP_SHUTDOWN_CHUNK_ID:
1545 dissect_shutdown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1547 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
1548 dissect_shutdown_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1550 case SCTP_ERROR_CHUNK_ID:
1551 dissect_error_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1553 case SCTP_COOKIE_ECHO_CHUNK_ID:
1554 dissect_cookie_echo_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1556 case SCTP_COOKIE_ACK_CHUNK_ID:
1557 dissect_cookie_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1559 case SCTP_ECNE_CHUNK_ID:
1560 dissect_ecne_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1562 case SCTP_CWR_CHUNK_ID:
1563 dissect_cwr_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1565 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
1566 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1569 dissect_unknown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1575 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1577 tvbuff_t *chunk_tvb;
1578 guint16 length, padding_length, total_length;
1581 /* the common header of the datagram is already handled */
1582 offset = COMMON_HEADER_LENGTH;
1584 while(tvb_length_remaining(tvb, offset) > 0) {
1585 /* extract the chunk length and compute number of padding bytes */
1586 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
1587 padding_length = nr_of_padding_bytes(length);
1588 total_length = length + padding_length;
1589 /* create a tvb for the chunk including the padding bytes */
1590 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
1591 /* call dissect_sctp_chunk for a actual work */
1592 dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree);
1593 /* get rid of the dissected chunk */
1594 offset += total_length;
1600 /* dissect_sctp handles the common header of a SCTP datagram.
1601 * For the handling of the chunks dissect_sctp_chunks is called.
1605 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1607 guint16 source_port, destination_port;
1608 guint32 verification_tag, checksum;
1610 proto_tree *sctp_tree;
1612 CHECK_DISPLAY_AS_DATA(proto_sctp, tvb, pinfo, tree);
1614 pinfo->current_proto = "SCTP";
1616 /* Extract the common header */
1617 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
1618 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
1619 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
1620 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
1622 /* update pi structure */
1624 pi.srcport = source_port;
1625 pi.destport = destination_port;
1627 /* make entry in the Protocol column on summary display */
1628 if (check_col(pinfo->fd, COL_PROTOCOL))
1629 col_set_str(pinfo->fd, COL_PROTOCOL, "SCTP");
1631 /* Clear entries in Info column on summary display */
1632 if (check_col(pinfo->fd, COL_INFO))
1633 col_add_str(pinfo->fd, COL_INFO, "");
1635 /* In the interest of speed, if "tree" is NULL, don't do any work not
1636 necessary to generate protocol tree items. */
1638 /* create the sctp protocol tree */
1639 ti = proto_tree_add_protocol_format(tree, proto_sctp, tvb, 0, tvb_length(tvb),
1640 "Stream Control Transmission Protocol");
1641 sctp_tree = proto_item_add_subtree(ti, ett_sctp);
1643 /* add the components of the common header to the protocol tree */
1644 proto_tree_add_uint(sctp_tree, hf_sctp_source_port,
1645 tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH,
1647 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port,
1648 tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH,
1650 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag,
1651 tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH,
1653 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum,
1654 tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum,
1655 "Adler-32 checksum: 0x%08x (%s)",
1656 checksum, sctp_checksum_state(tvb, checksum));
1660 /* add all chunks of the sctp datagram to the protocol tree */
1661 dissect_sctp_chunks(tvb, pinfo, tree, sctp_tree);
1664 /* Register the protocol with Ethereal */
1666 proto_register_sctp(void)
1669 /* Setup list of header fields */
1670 static hf_register_info hf[] = {
1671 { &hf_sctp_source_port,
1672 { "Source port", "sctp.srcport",
1673 FT_UINT16, BASE_DEC, NULL, 0x0,
1676 { &hf_sctp_destination_port,
1677 { "Destination port", "sctp.dstport",
1678 FT_UINT16, BASE_DEC, NULL, 0x0,
1681 { &hf_sctp_verification_tag,
1682 { "Verification tag", "sctp.verfication_tag",
1683 FT_UINT32, BASE_HEX, NULL, 0x0,
1686 { &hf_sctp_checksum,
1687 { "Adler-32 checksum", "sctp.checksum",
1688 FT_UINT32, BASE_HEX, NULL, 0x0,
1691 { &hf_sctp_chunk_type,
1692 { "Identifier", "sctp.chunk_type",
1693 FT_UINT8, BASE_DEC, NULL, 0x0,
1696 { &hf_sctp_chunk_flags,
1697 { "Flags", "sctp.chunk_flags",
1698 FT_UINT8, BASE_BIN, NULL, 0x0,
1701 { &hf_sctp_chunk_length,
1702 { "Length", "sctp.chunk_length",
1703 FT_UINT16, BASE_DEC, NULL, 0x0,
1706 { &hf_sctp_init_chunk_initiate_tag,
1707 { "Initiate tag", "sctp.init.chunk.initiate.tag",
1708 FT_UINT32, BASE_HEX, NULL, 0x0,
1711 { &hf_sctp_init_chunk_adv_rec_window_credit,
1712 { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
1713 FT_UINT32, BASE_DEC, NULL, 0x0,
1716 { &hf_sctp_init_chunk_number_of_outbound_streams,
1717 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
1718 FT_UINT16, BASE_DEC, NULL, 0x0,
1721 { &hf_sctp_init_chunk_number_of_inbound_streams,
1722 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
1723 FT_UINT16, BASE_DEC, NULL, 0x0,
1726 {&hf_sctp_init_chunk_initial_tsn,
1727 { "Initial TSN", "sctp.init.chunk.initial.tsn",
1728 FT_UINT32, BASE_DEC, NULL, 0x0,
1731 {&hf_sctp_cumulative_tsn_ack,
1732 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
1733 FT_UINT32, BASE_DEC, NULL, 0x0,
1736 {&hf_sctp_data_chunk_tsn,
1737 { "TSN", "sctp.tsn",
1738 FT_UINT32, BASE_DEC, NULL, 0x0,
1741 {&hf_sctp_data_chunk_stream_id,
1742 { "Stream Identifier", "sctp.stream_id",
1743 FT_UINT16, BASE_HEX, NULL, 0x0,
1746 {&hf_sctp_data_chunk_stream_seq_number,
1747 { "Stream sequence number", "sctp.stream_seq_number",
1748 FT_UINT16, BASE_DEC, NULL, 0x0,
1751 {&hf_sctp_data_chunk_payload_proto_id,
1752 { "Payload Protocol identifier", "sctp.payload_proto_id",
1753 FT_UINT32, BASE_HEX, NULL, 0x0,
1756 {&hf_sctp_data_chunk_e_bit,
1757 { "E-Bit", "sctp.data.e_bit",
1758 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
1761 {&hf_sctp_data_chunk_b_bit,
1762 { "B-Bit", "sctp.data.b_bit",
1763 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
1766 {&hf_sctp_data_chunk_u_bit,
1767 { "U-Bit", "sctp.data.u.bit",
1768 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
1771 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
1772 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
1773 FT_UINT32, BASE_DEC, NULL, 0x0,
1776 {&hf_sctp_sack_chunk_adv_rec_window_credit,
1777 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
1778 FT_UINT32, BASE_DEC, NULL, 0x0,
1781 {&hf_sctp_sack_chunk_number_of_gap_blocks,
1782 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
1783 FT_UINT16, BASE_DEC, NULL, 0x0,
1786 {&hf_sctp_sack_chunk_number_of_dup_tsns,
1787 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
1788 FT_UINT16, BASE_DEC, NULL, 0x0,
1791 {&hf_sctp_sack_chunk_gap_block_start,
1792 { "Start", "sctp.sack.gap_block_start",
1793 FT_UINT16, BASE_DEC, NULL, 0x0,
1796 {&hf_sctp_sack_chunk_gap_block_end,
1797 { "End", "sctp.sack.gap_block_end",
1798 FT_UINT16, BASE_DEC, NULL, 0x0,
1801 {&hf_sctp_sack_chunk_duplicate_tsn,
1802 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
1803 FT_UINT16, BASE_DEC, NULL, 0x0,
1806 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1807 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
1808 FT_UINT32, BASE_DEC, NULL, 0x0,
1811 {&hf_sctp_ecne_chunk_lowest_tsn,
1812 { "Lowest TSN", "sctp.ecne.lowest_tsn",
1813 FT_UINT32, BASE_DEC, NULL, 0x0,
1816 {&hf_sctp_cwr_chunk_lowest_tsn,
1817 { "Lowest TSN", "sctp.cwr.lowest_tsn",
1818 FT_UINT32, BASE_DEC, NULL, 0x0,
1821 {&hf_sctp_shutdown_complete_chunk_t_bit,
1822 { "E-Bit", "sctp.shutdown_complete.t_bit",
1823 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
1826 {&hf_sctp_chunk_parameter_type,
1827 { "Parameter type", "sctp.parameter.type",
1828 FT_UINT16, BASE_HEX, NULL, 0x0,
1831 {&hf_sctp_chunk_parameter_length,
1832 { "Parameter length", "sctp.parameter.length",
1833 FT_UINT16, BASE_DEC, NULL, 0x0,
1836 {&hf_sctp_parameter_ipv4_address,
1837 { "IP Version 4 address", "sctp.parameter.ipv4_address",
1838 FT_IPv4, BASE_NONE, NULL, 0x0,
1841 {&hf_sctp_parameter_ipv6_address,
1842 { "IP Version 6 address", "sctp.parameter.ipv6_address",
1843 FT_IPv6, BASE_NONE, NULL, 0x0,
1846 {&hf_sctp_parameter_cookie_preservative_increment,
1847 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
1848 FT_UINT32, BASE_DEC, NULL, 0x0,
1851 {&hf_sctp_parameter_hostname_hostname,
1852 { "Hostname", "sctp.parameter.hostname.hostname",
1853 FT_STRING, BASE_NONE, NULL, 0x0,
1856 {&hf_sctp_supported_address_types_parameter,
1857 { "Supported address type", "sctp.parameter.supported_addres_type",
1858 FT_UINT16, BASE_DEC, NULL, 0x0,
1861 {&hf_sctp_cause_code,
1862 { "Cause code", "sctp.cause.code",
1863 FT_UINT16, BASE_DEC, NULL, 0x0,
1866 {&hf_sctp_cause_length,
1867 { "Cause length", "sctp.cause.length",
1868 FT_UINT16, BASE_DEC, NULL, 0x0,
1871 {&hf_sctp_cause_stream_identifier,
1872 { "Stream identifier", "sctp.cause.stream_identifier",
1873 FT_UINT16, BASE_DEC, NULL, 0x0,
1876 {&hf_sctp_cause_number_of_missing_parameters,
1877 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
1878 FT_UINT32, BASE_DEC, NULL, 0x0,
1881 {&hf_sctp_cause_missing_parameter_type,
1882 { "Missing parameters type", "sctp.cause.missing_parameter_type",
1883 FT_UINT16, BASE_DEC, NULL, 0x0,
1886 {&hf_sctp_cause_measure_of_staleness,
1887 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
1888 FT_UINT32, BASE_DEC, NULL, 0x0,
1891 {&hf_sctp_cause_tsn,
1892 { "TSN", "sctp.cause.tsn",
1893 FT_UINT32, BASE_DEC, NULL, 0x0,
1898 /* Setup protocol subtree array */
1899 static gint *ett[] = {
1902 &ett_sctp_chunk_parameter,
1903 &ett_sctp_chunk_cause,
1904 &ett_sctp_data_chunk_flags,
1905 &ett_sctp_sack_chunk_gap_block,
1906 &ett_sctp_supported_address_types_parameter,
1907 &ett_sctp_unrecognized_parameter_parameter
1910 /* Register the protocol name and description */
1911 proto_sctp = proto_register_protocol("Stream Control Transmission Protcol",
1914 /* Required function calls to register the header fields and subtrees used */
1915 proto_register_field_array(proto_sctp, hf, array_length(hf));
1916 proto_register_subtree_array(ett, array_length(ett));
1918 /* subdissector code */
1919 sctp_port_dissector_table = register_dissector_table("sctp.port");
1920 sctp_ppi_dissector_table = register_dissector_table("sctp.ppi");
1925 proto_reg_handoff_sctp(void)
1927 dissector_add("ip.proto", IP_PROTO_SCTP, dissect_sctp, proto_sctp);