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.8 2001/01/03 06:55:32 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_dissector_table;
119 /* Initialize the subtree pointers */
120 static gint ett_sctp = -1;
121 static gint ett_sctp_chunk = -1;
122 static gint ett_sctp_chunk_parameter = -1;
123 static gint ett_sctp_chunk_cause = -1;
124 static gint ett_sctp_data_chunk_flags = -1;
125 static gint ett_sctp_sack_chunk_gap_block = -1;
126 static gint ett_sctp_supported_address_types_parameter = -1;
127 static gint ett_sctp_unrecognized_parameter_parameter = -1;
129 #define SCTP_DATA_CHUNK_ID 0
130 #define SCTP_INIT_CHUNK_ID 1
131 #define SCTP_INIT_ACK_CHUNK_ID 2
132 #define SCTP_SACK_CHUNK_ID 3
133 #define SCTP_HEARTBEAT_CHUNK_ID 4
134 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
135 #define SCTP_ABORT_CHUNK_ID 6
136 #define SCTP_SHUTDOWN_CHUNK_ID 7
137 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
138 #define SCTP_ERROR_CHUNK_ID 9
139 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
140 #define SCTP_COOKIE_ACK_CHUNK_ID 11
141 #define SCTP_ECNE_CHUNK_ID 12
142 #define SCTP_CWR_CHUNK_ID 13
143 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
144 #define SCTP_IETF_EXT 255
146 static const value_string sctp_chunk_type_values[] = {
147 { SCTP_DATA_CHUNK_ID, "DATA" },
148 { SCTP_INIT_CHUNK_ID, "INIT" },
149 { SCTP_INIT_ACK_CHUNK_ID, "INIT ACK" },
150 { SCTP_SACK_CHUNK_ID, "SACK" },
151 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
152 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT ACK" },
153 { SCTP_ABORT_CHUNK_ID, "ABORT" },
154 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
155 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN ACK" },
156 { SCTP_ERROR_CHUNK_ID, "ERROR" },
157 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE ECHO" },
158 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE ACK" },
159 { SCTP_ECNE_CHUNK_ID, "ECNE" },
160 { SCTP_CWR_CHUNK_ID, "CWR" },
161 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN COMPLETE" },
162 { SCTP_IETF_EXT, "IETF EXTENSION" },
165 #define HEARTBEAT_INFO_PARAMETER_ID 0x0001
166 #define IPV4ADDRESS_PARAMETER_ID 0x0005
167 #define IPV6ADDRESS_PARAMETER_ID 0x0006
168 #define STATE_COOKIE_PARAMETER_ID 0x0007
169 #define UNREC_PARA_PARAMETER_ID 0x0008
170 #define COOKIE_PRESERVATIVE_PARAMETER_ID 0x0009
171 #define HOSTNAME_ADDRESS_PARAMETER_ID 0x000b
172 #define SUPPORTED_ADDRESS_TYPES_PARAMETER_ID 0x000c
173 #define ECN_PARAMETER_ID 0x8000
175 static const value_string sctp_parameter_identifier_values[] = {
176 { HEARTBEAT_INFO_PARAMETER_ID, "Heartbeat info" },
177 { IPV4ADDRESS_PARAMETER_ID, "IPv4 address" },
178 { IPV6ADDRESS_PARAMETER_ID, "IPv6 address" },
179 { STATE_COOKIE_PARAMETER_ID, "State cookie" },
180 { UNREC_PARA_PARAMETER_ID, "Unrecognized parameters" },
181 { COOKIE_PRESERVATIVE_PARAMETER_ID, "Cookie preservative" },
182 { HOSTNAME_ADDRESS_PARAMETER_ID, "Hostname address" },
183 { SUPPORTED_ADDRESS_TYPES_PARAMETER_ID, "Supported address types" },
184 { ECN_PARAMETER_ID, "ECN" },
187 #define PARAMETER_TYPE_LENGTH 2
188 #define PARAMETER_LENGTH_LENGTH 2
189 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
191 #define PARAMETER_HEADER_OFFSET 0
192 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
193 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
194 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
196 #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET
197 #define HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
199 #define IPV4_ADDRESS_LENGTH 4
200 #define IPV6_ADDRESS_LENGTH 16
202 #define STATE_COOKIE_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
203 #define STATE_COOKIE_PARAMETER_COOKIE_OFFSET PARAMETER_VALUE_OFFSET
205 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET PARAMETER_VALUE_OFFSET
206 #define COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH 4
207 #define SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH 2
209 #define CAUSE_CODE_LENGTH 2
210 #define CAUSE_LENGTH_LENGTH 2
211 #define CAUSE_HEADER_LENGTH (CAUSE_CODE_LENGTH + CAUSE_LENGTH_LENGTH)
213 #define CAUSE_HEADER_OFFSET 0
214 #define CAUSE_CODE_OFFSET CAUSE_HEADER_OFFSET
215 #define CAUSE_LENGTH_OFFSET (CAUSE_CODE_OFFSET + CAUSE_CODE_LENGTH)
216 #define CAUSE_INFO_OFFSET (CAUSE_LENGTH_OFFSET + CAUSE_LENGTH_LENGTH)
218 #define CAUSE_STREAM_IDENTIFIER_LENGTH 2
219 #define CAUSE_RESERVED_LENGTH 2
220 #define CAUSE_STREAM_IDENTIFIER_OFFSET CAUSE_INFO_OFFSET
221 #define CAUSE_RESERVED_OFFSET (CAUSE_STREAM_IDENTIFIER_OFFSET + CAUSE_STREAM_IDENTIFIER_LENGTH)
223 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH 4
224 #define CAUSE_MISSING_PARAMETER_TYPE_LENGTH 2
226 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET CAUSE_INFO_OFFSET
227 #define CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET (CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET + \
228 CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH )
230 #define CAUSE_MEASURE_OF_STALENESS_LENGTH 4
231 #define CAUSE_MEASURE_OF_STALENESS_OFFSET CAUSE_INFO_OFFSET
233 #define CAUSE_TSN_LENGTH 4
234 #define CAUSE_TSN_OFFSET CAUSE_INFO_OFFSET
236 #define INVALID_STREAM_IDENTIFIER 0x01
237 #define MISSING_MANDATORY_PARAMETERS 0x02
238 #define STALE_COOKIE_ERROR 0x03
239 #define OUT_OF_RESOURCE 0x04
240 #define UNRESOLVABLE_ADDRESS 0x05
241 #define UNRECOGNIZED_CHUNK_TYPE 0x06
242 #define INVALID_MANDATORY_PARAMETER 0x07
243 #define UNRECOGNIZED_PARAMETERS 0x08
244 #define NO_USER_DATA 0x09
245 #define COOKIE_RECEIVED_WHILE_SHUTTING_DOWN 0x0a
247 static const value_string sctp_cause_code_values[] = {
248 { INVALID_STREAM_IDENTIFIER, "Invalid stream idetifier" },
249 { MISSING_MANDATORY_PARAMETERS, "Missing mandator parameter" },
250 { STALE_COOKIE_ERROR, "Stale cookie error" },
251 { OUT_OF_RESOURCE, "Out of resource" },
252 { UNRESOLVABLE_ADDRESS, "Unresolvable address" },
253 { UNRECOGNIZED_CHUNK_TYPE, "Unrecognized chunk type " },
254 { INVALID_MANDATORY_PARAMETER, "Invalid mandatory parameter" },
255 { UNRECOGNIZED_PARAMETERS, "Unrecognized parameters" },
256 { NO_USER_DATA, "No user data" },
257 { COOKIE_RECEIVED_WHILE_SHUTTING_DOWN, "Cookie received while shutting down" },
260 /* The structure of the common header is described by the following constants */
261 #define SOURCE_PORT_LENGTH 2
262 #define DESTINATION_PORT_LENGTH 2
263 #define VERIFICATION_TAG_LENGTH 4
264 #define CHECKSUM_LENGTH 4
265 #define COMMON_HEADER_LENGTH (SOURCE_PORT_LENGTH + \
266 DESTINATION_PORT_LENGTH + \
267 VERIFICATION_TAG_LENGTH + \
269 #define SOURCE_PORT_OFFSET 0
270 #define DESTINATION_PORT_OFFSET (SOURCE_PORT_OFFSET + SOURCE_PORT_LENGTH)
271 #define VERIFICATION_TAG_OFFSET (DESTINATION_PORT_OFFSET + DESTINATION_PORT_LENGTH)
272 #define CHECKSUM_OFFSET (VERIFICATION_TAG_OFFSET + VERIFICATION_TAG_LENGTH)
274 /* The structure of the chunk header is described by the following constants */
275 #define CHUNK_TYPE_LENGTH 1
276 #define CHUNK_FLAGS_LENGTH 1
277 #define CHUNK_LENGTH_LENGTH 2
278 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
279 CHUNK_FLAGS_LENGTH + \
281 #define CHUNK_HEADER_OFFSET 0
282 #define CHUNK_TYPE_OFFSET CHUNK_HEADER_OFFSET
283 #define CHUNK_FLAGS_OFFSET (CHUNK_TYPE_OFFSET + CHUNK_TYPE_LENGTH)
284 #define CHUNK_LENGTH_OFFSET (CHUNK_FLAGS_OFFSET + CHUNK_FLAGS_LENGTH)
285 #define CHUNK_VALUE_OFFSET (CHUNK_LENGTH_OFFSET + CHUNK_LENGTH_LENGTH)
287 /* The following constants describe the structure of DATA chunks */
288 #define DATA_CHUNK_TSN_LENGTH 4
289 #define DATA_CHUNK_STREAM_ID_LENGTH 2
290 #define DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH 2
291 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH 4
293 #define DATA_CHUNK_TSN_OFFSET (CHUNK_VALUE_OFFSET + 0)
294 #define DATA_CHUNK_STREAM_ID_OFFSET (DATA_CHUNK_TSN_OFFSET + DATA_CHUNK_TSN_LENGTH)
295 #define DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET (DATA_CHUNK_STREAM_ID_OFFSET + \
296 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
297 #define DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET (DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET + \
298 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH)
299 #define DATA_CHUNK_PAYLOAD_OFFSET (DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET + \
300 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
302 #define DATA_CHUNK_HEADER_LENGTH (CHUNK_HEADER_LENGTH + \
303 DATA_CHUNK_TSN_LENGTH + \
304 DATA_CHUNK_STREAM_ID_LENGTH + \
305 DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH + \
306 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH)
308 #define SCTP_DATA_CHUNK_E_BIT 0x01
309 #define SCTP_DATA_CHUNK_B_BIT 0x02
310 #define SCTP_DATA_CHUNK_U_BIT 0x04
312 #define INIT_CHUNK_INITIATE_TAG_LENGTH 4
313 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
314 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH 2
315 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH 2
316 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
318 #define INIT_CHUNK_INITIATE_TAG_OFFSET CHUNK_VALUE_OFFSET
319 #define INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (INIT_CHUNK_INITIATE_TAG_OFFSET + \
320 INIT_CHUNK_INITIATE_TAG_LENGTH )
321 #define INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET (INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
322 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH )
323 #define INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET (INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET + \
324 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH )
325 #define INIT_CHUNK_INITIAL_TSN_OFFSET (INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET + \
326 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH )
327 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
328 INIT_CHUNK_INITIAL_TSN_LENGTH )
331 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
332 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
333 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH 2
334 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH 2
335 #define SACK_CHUNK_GAP_BLOCK_LENGTH 4
336 #define SACK_CHUNK_GAP_BLOCK_START_LENGTH 2
337 #define SACK_CHUNK_GAP_BLOCK_END_LENGTH 2
338 #define SACK_CHUNK_DUP_TSN_LENGTH 4
340 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
341 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
342 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
343 #define SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET (SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET + \
344 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH)
345 #define SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET (SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET + \
346 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH)
347 #define SACK_CHUNK_GAP_BLOCK_OFFSET (SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET + \
348 SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH)
350 #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET
352 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET CHUNK_VALUE_OFFSET
353 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
355 #define ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
356 #define ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4
358 #define COOKIE_ECHO_CHUNK_COOKIE_OFFSET CHUNK_VALUE_OFFSET
360 #define ECNE_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
361 #define ECNE_CHUNK_LOWEST_TSN_LENGTH 4
363 #define CWR_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
364 #define CWR_CHUNK_LOWEST_TSN_LENGTH 4
366 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT 0x01
368 static const true_false_string sctp_data_chunk_e_bit_value = {
370 "Not the last segment"
373 static const true_false_string sctp_data_chunk_b_bit_value = {
378 static const true_false_string sctp_data_chunk_u_bit_value = {
379 "Unordered delivery",
383 static const true_false_string sctp_shutdown_complete_chunk_t_bit_value = {
388 /* adler32.c -- compute the Adler-32 checksum of a data stream
389 * Copyright (C) 1995-1996 Mark Adler
390 * For conditions of distribution and use, see copyright notice in zlib.h
391 * available, e.g. from http://www.cdrom.com/pub/infozip/zlib/
393 * It was modified for the use in this dissector.
396 #define BASE 65521L /* largest prime smaller than 65536 */
397 #define NMAX 5540 /* NMAX is the largest n - 12 such that */
398 /* 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
400 #define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
401 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
402 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
403 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
404 #define DO16(buf) DO8(buf,0); DO8(buf,8);
406 unsigned int sctp_adler_32(const unsigned char* buf,
409 unsigned int s1 = 1L;
410 unsigned int s2 = 0L;
413 /* handle the first 8 bytes of the datagram */
415 buf += SOURCE_PORT_LENGTH +
416 DESTINATION_PORT_LENGTH +
417 VERIFICATION_TAG_LENGTH;
419 /* handle four 0 bytes as checksum */
420 s2 += CHECKSUM_LENGTH * s1;
421 buf += CHECKSUM_LENGTH;
423 /* now we have 12 bytes handled */
424 len -= COMMON_HEADER_LENGTH;
426 /* handle the rest of the datagram */
428 k = len < NMAX ? len : NMAX;
442 return (s2 << 16) | s1;
445 static char *sctp_checksum_state(tvbuff_t *tvb, guint orig_checksum)
449 length = tvb_length(tvb);
450 if (orig_checksum == sctp_adler_32(tvb_get_ptr(tvb, 0, length), length))
457 nr_of_padding_bytes (guint length)
461 remainder = length % 4;
466 return 4 - remainder;
470 * TLV parameter stuff for INIT and INIT-ACK chunks
474 dissect_parameter(tvbuff_t *, proto_tree *);
477 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
479 void dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, proto_tree *tree)
481 guint offset, length, padding_length, total_length;
482 tvbuff_t *parameter_tvb;
485 while(tvb_length_remaining(parameter_list_tvb, offset)) {
486 length = tvb_get_ntohs(parameter_list_tvb, offset + PARAMETER_LENGTH_OFFSET);
487 padding_length = nr_of_padding_bytes(length);
488 total_length = length + padding_length;
489 /* create a tvb for the chunk including the padding bytes */
490 parameter_tvb = tvb_new_subset(parameter_list_tvb, offset, total_length, total_length);
491 dissect_parameter(parameter_tvb, tree);
492 /* get rid of the handled parameter */
493 offset += total_length;
498 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
500 guint16 length, heartbeat_info_length;
502 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
504 heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
506 proto_tree_add_text(parameter_tree, parameter_tvb, HEARTBEAT_INFO_PARAMETER_INFO_OFFSET, heartbeat_info_length,
507 "Heartbeat info (%u byte%s)",
508 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
510 proto_item_set_text(parameter_item, "Heartbeat info parameter with %u byte%s of info",
511 heartbeat_info_length, plurality(heartbeat_info_length, "", "s"));
515 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
517 guint32 ipv4_address;
519 tvb_memcpy(parameter_tvb, (guint8 *)&ipv4_address, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH);
520 proto_tree_add_ipv4(parameter_tree, hf_sctp_parameter_ipv4_address,
521 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV4_ADDRESS_LENGTH,
523 proto_item_set_text(parameter_item, "IPV4 address parameter");
527 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
529 proto_tree_add_ipv6(parameter_tree, hf_sctp_parameter_ipv6_address,
530 parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH,
531 tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, IPV6_ADDRESS_LENGTH));
533 proto_item_set_text(parameter_item, "IPV6 address parameter");
537 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
539 guint16 length, state_cookie_length;
541 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
543 state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
545 proto_tree_add_text(parameter_tree, parameter_tvb, STATE_COOKIE_PARAMETER_COOKIE_OFFSET, state_cookie_length,
546 "State cookie (%u byte%s)",
547 state_cookie_length, plurality(state_cookie_length, "", "s"));
549 proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
550 state_cookie_length, plurality(state_cookie_length, "", "s"));
554 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
556 guint16 length, parameter_value_length;
557 tvbuff_t *unrecognized_parameters_tvb;
559 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
561 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
563 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
564 parameter_value_length, parameter_value_length);
565 dissect_tlv_parameter_list(unrecognized_parameters_tvb, parameter_tree);
567 proto_item_set_text(parameter_item, "Unrecognized parameter of type");
571 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
575 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
577 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
578 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
579 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
582 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
587 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
589 guint16 length, hostname_length;
592 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
594 hostname_length = length - PARAMETER_HEADER_LENGTH;
595 hostname = (char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
596 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
597 PARAMETER_VALUE_OFFSET, hostname_length,
600 proto_item_set_text(parameter_item, "Hostname parameter");
604 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
606 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
608 proto_item *address_list_item;
609 proto_tree *address_list_tree;
611 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
612 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
613 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
615 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
616 "Supported Address Types (%u address type%s)",
617 number_of_address_types, plurality(number_of_address_types, "", "s"));
618 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
620 offset = PARAMETER_VALUE_OFFSET;
621 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
622 address_type = tvb_get_ntohs(parameter_tvb, offset);
623 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
624 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
625 address_type, "Supported address type: %u (%s)",
626 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
627 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
630 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
631 number_of_address_types, plurality(number_of_address_types, "", "s"));
635 dissect_ecn_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
637 proto_item_set_text(parameter_item, "ECN parameter");
641 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
643 guint16 type, length, parameter_value_length;
645 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
646 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
648 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
650 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
651 "Parameter value (%u byte%s)",
652 parameter_value_length, plurality(parameter_value_length, "", "s"));
654 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
655 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
659 dissect_parameter(tvbuff_t *parameter_tvb, proto_tree *chunk_tree)
661 guint16 type, length, padding_length, total_length;
662 proto_item *parameter_item;
663 proto_tree *parameter_tree;
665 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
666 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
667 padding_length = nr_of_padding_bytes(length);
668 total_length = length + padding_length;
670 parameter_item = proto_tree_add_notext(chunk_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, total_length);
671 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
673 proto_tree_add_uint_format(parameter_tree, hf_sctp_chunk_parameter_type,
674 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
675 type, "Parameter type: %u (%s)",
676 type, val_to_str(type, sctp_parameter_identifier_values, "unknown"));
677 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
678 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
682 case HEARTBEAT_INFO_PARAMETER_ID:
683 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
685 case IPV4ADDRESS_PARAMETER_ID:
686 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
688 case IPV6ADDRESS_PARAMETER_ID:
689 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
691 case STATE_COOKIE_PARAMETER_ID:
692 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
694 case UNREC_PARA_PARAMETER_ID:
695 dissect_unrecognized_parameters_parameter(parameter_tvb, parameter_tree, parameter_item);
697 case COOKIE_PRESERVATIVE_PARAMETER_ID:
698 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
700 case HOSTNAME_ADDRESS_PARAMETER_ID:
701 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
703 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
704 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
706 case ECN_PARAMETER_ID:
707 dissect_ecn_parameter(parameter_tvb, parameter_tree, parameter_item);
710 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
713 if (padding_length > 0)
714 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
715 "Padding: %u byte%s",
716 padding_length, plurality(padding_length, "", "s"));
720 * Code to handle error causes for ABORT and ERROR chunks
723 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
725 guint16 stream_identifier;
727 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
728 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
729 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
731 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
732 "Reserved (2 bytes)");
734 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
739 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
741 guint32 number_of_missing_parameters, missing_parameter_number;
742 guint16 parameter_type;
745 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
746 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
747 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
748 number_of_missing_parameters);
749 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
750 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
751 parameter_type = tvb_get_ntohs(cause_tvb, offset);
752 proto_tree_add_uint_format(cause_tree, hf_sctp_cause_missing_parameter_type,
753 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
754 parameter_type, "Missing parameter type: %u (%s)",
756 val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown"));
757 offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
760 proto_item_set_text(cause_item, "Error cause reporting %u missing mandatory parameter%s",
761 number_of_missing_parameters, plurality(number_of_missing_parameters, "", "s") );
765 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
767 guint32 measure_of_staleness;
769 measure_of_staleness = tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
771 proto_tree_add_uint(cause_tree, hf_sctp_cause_measure_of_staleness, cause_tvb,
772 CAUSE_MEASURE_OF_STALENESS_OFFSET,
773 CAUSE_MEASURE_OF_STALENESS_LENGTH,
774 measure_of_staleness);
776 proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
777 measure_of_staleness);
781 dissect_out_of_resource_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
783 proto_item_set_text(cause_item, "Error cause reporting lack of resources");
787 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
789 guint16 code, length, parameter_length, parameter_type;
790 tvbuff_t *parameter_tvb;
792 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
793 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
795 parameter_length = length - CAUSE_HEADER_LENGTH;
796 parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
797 parameter_length, parameter_length);
799 dissect_parameter(parameter_tvb, cause_tree);
800 parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
802 proto_item_set_text(cause_item, "Error cause reporting unresolvable address of type %u (%s)",
803 parameter_type, val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown") );
807 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo,
808 proto_tree *cause_tree, proto_item *cause_item)
810 guint16 length, chunk_length;
811 guint8 unrecognized_type;
812 tvbuff_t *unrecognized_chunk_tvb;
814 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
816 chunk_length = length - CAUSE_HEADER_LENGTH;
818 unrecognized_chunk_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
819 chunk_length, chunk_length);
820 dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree);
822 unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
824 proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
826 val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
830 dissect_invalid_mandatory_parameter_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
832 proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
836 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
838 guint16 length, cause_info_length;
839 tvbuff_t *unrecognized_parameters_tvb;
841 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
843 cause_info_length = length - CAUSE_HEADER_LENGTH;
845 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
846 cause_info_length, cause_info_length);
847 dissect_tlv_parameter_list(unrecognized_parameters_tvb, cause_tree);
849 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
853 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
857 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
858 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
863 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
868 dissect_cookie_received_while_shutting_down_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
870 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
874 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
876 guint16 code, length, cause_info_length;
878 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
879 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
881 cause_info_length = length - CAUSE_HEADER_LENGTH;
883 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
884 "Cause specific information (%u byte%s)",
885 cause_info_length, plurality(cause_info_length, "", "s"));
887 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
888 code, cause_info_length, plurality(cause_info_length, "", "s"));
892 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
894 guint16 code, length, padding_length, total_length;
895 proto_item *cause_item;
896 proto_tree *cause_tree;
898 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
899 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
900 padding_length = nr_of_padding_bytes(length);
901 total_length = length + padding_length;
903 cause_item = proto_tree_add_notext(chunk_tree, cause_tvb, CAUSE_HEADER_OFFSET, total_length);
904 proto_item_set_text(cause_item, "BAD ERROR CAUSE");
905 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
907 proto_tree_add_uint_format(cause_tree, hf_sctp_cause_code,
908 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
909 code, "Cause code: %u (%s)",
910 code, val_to_str(code, sctp_cause_code_values, "unknown"));
911 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
912 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
916 case INVALID_STREAM_IDENTIFIER:
917 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
919 case MISSING_MANDATORY_PARAMETERS:
920 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
922 case STALE_COOKIE_ERROR:
923 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
925 case OUT_OF_RESOURCE:
926 dissect_out_of_resource_cause(cause_tvb, cause_tree, cause_item);
928 case UNRESOLVABLE_ADDRESS:
929 dissect_unresolvable_address_cause(cause_tvb, cause_tree, cause_item);
931 case UNRECOGNIZED_CHUNK_TYPE:
932 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
934 case INVALID_MANDATORY_PARAMETER:
935 dissect_invalid_mandatory_parameter_cause(cause_tvb, cause_tree, cause_item);
937 case UNRECOGNIZED_PARAMETERS:
938 dissect_unrecognized_parameters_cause(cause_tvb, cause_tree, cause_item);
941 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
943 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
944 dissect_cookie_received_while_shutting_down_cause(cause_tvb, cause_tree, cause_item);
947 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
950 if (padding_length > 0)
951 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
952 "Padding: %u byte%s",
953 padding_length, plurality(padding_length, "", "s"));
957 * Code to actually dissect the packets
961 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
962 proto_tree *chunk_tree, guint16 payload_length, guint16 padding_length)
964 /* do lookup with the subdissector table */
965 if (dissector_try_port(sctp_dissector_table, pi.srcport, payload_tvb, pinfo, tree) ||
966 dissector_try_port(sctp_dissector_table, pi.destport, payload_tvb, pinfo, tree))
969 proto_tree_add_text(chunk_tree, payload_tvb, 0, payload_length,
970 "Payload (%u byte%s)",
971 payload_length, plurality(payload_length, "", "s"));
972 if (padding_length > 0)
973 proto_tree_add_text(chunk_tree, payload_tvb, payload_length, padding_length,
974 "Padding: %u byte%s",
975 padding_length, plurality(padding_length, "", "s"));
984 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
985 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
988 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
989 guint32 tsn, payload_proto_id;
990 proto_tree *flag_tree;
991 tvbuff_t *payload_tvb;
993 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
994 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
996 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
997 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
998 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
999 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1000 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1001 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1002 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1004 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1005 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1006 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1007 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1009 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1010 padding_length = nr_of_padding_bytes(length);
1011 total_payload_length = payload_length + padding_length;
1012 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1013 total_payload_length, total_payload_length);
1015 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1017 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1019 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1021 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1023 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1025 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1027 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1029 DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1031 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1032 tsn, stream_id, stream_seq_number,
1033 payload_length, plurality(payload_length, "", "s"));
1035 dissect_payload(payload_tvb, pinfo, tree, chunk_tree, payload_length, padding_length);
1039 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1040 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1042 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1043 guint16 number_of_inbound_streams, number_of_outbound_streams;
1045 tvbuff_t *parameter_list_tvb;
1047 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1049 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1050 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1051 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1052 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1053 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1055 /* handle fixed parameters */
1056 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1058 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1060 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1062 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1063 adv_rec_window_credit);
1064 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1066 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1067 number_of_outbound_streams);
1068 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1070 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1071 number_of_inbound_streams);
1072 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1074 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1077 /* handle variable paramters */
1078 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1079 dissect_tlv_parameter_list(parameter_list_tvb, chunk_tree);
1081 proto_item_set_text(chunk_item,
1082 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1083 val_to_str(type, sctp_chunk_type_values, "unknown"),
1084 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1085 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1089 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1090 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1092 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1096 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1097 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1099 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1100 guint16 number_of_gap_blocks, number_of_dup_tsns;
1101 guint16 gap_block_number, dup_tsn_number, start, end;
1102 gint gap_block_offset, dup_tsn_offset;
1103 proto_item *block_item;
1104 proto_tree *block_tree;
1106 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1107 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1108 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1109 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1111 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1113 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1114 cumulative_tsn_ack);
1115 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1117 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1118 adv_rec_window_credit);
1119 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1121 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1122 number_of_gap_blocks);
1123 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1125 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1126 number_of_dup_tsns);
1128 /* handle the gap acknowledgement blocks */
1129 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1130 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1131 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1132 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1133 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1134 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1135 "Gap Acknowledgement for %u TSN%s",
1136 1 + end - start, plurality(1 + end - start, "", "s"));
1137 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1138 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1140 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1142 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1144 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1145 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1147 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1150 /* handle the duplicate TSNs */
1151 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1152 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1153 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1154 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1156 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1158 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1161 proto_item_set_text(chunk_item,
1162 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1164 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1165 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1169 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1170 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1172 tvbuff_t *parameter_tvb;
1173 guint chunk_length, info_length, padding_length, total_length;
1175 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1176 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1177 padding_length = nr_of_padding_bytes(info_length);
1178 total_length = info_length + padding_length;
1179 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1181 dissect_parameter(parameter_tvb, chunk_tree);
1183 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1187 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1188 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1190 tvbuff_t *parameter_tvb;
1191 guint chunk_length, info_length, padding_length, total_length;
1193 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1194 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1195 padding_length = nr_of_padding_bytes(info_length);
1196 total_length = info_length + padding_length;
1198 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1200 dissect_parameter(parameter_tvb, chunk_tree);
1202 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1206 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1207 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1209 guint offset, number_of_causes;
1210 guint16 length, padding_length, total_length;
1211 tvbuff_t *cause_tvb;
1213 number_of_causes = 0;
1214 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1215 while(tvb_length_remaining(chunk_tvb, offset)) {
1216 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1217 padding_length = nr_of_padding_bytes(length);
1218 total_length = length + padding_length;
1219 /* create a tvb for the chunk including the padding bytes */
1220 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1221 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1222 /* get rid of the handled parameter */
1223 offset += total_length;
1227 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s",
1228 number_of_causes, plurality(number_of_causes, "", "s"));
1232 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1233 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1235 guint32 cumulative_tsn_ack;
1237 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1238 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1240 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1241 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1242 cumulative_tsn_ack);
1244 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1245 cumulative_tsn_ack);
1249 dissect_shutdown_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1250 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1252 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1256 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1257 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1259 guint offset, number_of_causes;
1260 guint16 length, padding_length, total_length;
1261 tvbuff_t *cause_tvb;
1263 number_of_causes = 0;
1264 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1266 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1267 padding_length = nr_of_padding_bytes(length);
1268 total_length = length + padding_length;
1269 /* create a tvb for the chunk including the padding bytes */
1270 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1271 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1272 /* get rid of the handled parameter */
1273 offset += total_length;
1275 } while(tvb_length_remaining(chunk_tvb, offset));
1277 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1278 number_of_causes, plurality(number_of_causes, "", "s"));
1282 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1283 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1285 guint length, cookie_length, padding_length;
1287 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1288 padding_length = nr_of_padding_bytes(length);
1289 cookie_length = length - CHUNK_HEADER_LENGTH;
1291 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1292 "Cookie (%u byte%s)",
1293 cookie_length, plurality(cookie_length, "", "s"));
1294 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1295 cookie_length, plurality(cookie_length, "", "s"));
1297 if (padding_length > 0)
1298 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1299 "Padding: %u byte%s",
1300 padding_length, plurality(padding_length, "", "s"));
1304 dissect_cookie_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1305 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1307 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1311 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1312 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1316 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1317 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1319 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1322 proto_item_set_text(chunk_item, "ECNE chunk");
1326 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1327 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1331 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1332 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1334 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1337 proto_item_set_text(chunk_item, "CWR chunk");
1341 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1342 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1346 proto_tree *flag_tree;
1348 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1349 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1351 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1352 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1353 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1355 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1359 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1360 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1362 guint length, chunk_value_length, padding_length;
1365 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1366 padding_length = nr_of_padding_bytes(length);
1367 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1369 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1371 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1372 "Chunk value (%u byte%s)",
1373 chunk_value_length, plurality(chunk_value_length, "", "s"));
1375 if (padding_length > 0)
1376 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1377 "Padding: %u byte%s",
1378 padding_length, plurality(padding_length, "", "s"));
1380 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1381 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1388 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1392 proto_item *flags_item;
1393 proto_item *chunk_item;
1394 proto_tree *chunk_tree;
1396 /* first extract the chunk header */
1397 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1398 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1399 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1401 /* create proto_tree stuff */
1402 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb,
1403 CHUNK_HEADER_OFFSET, tvb_length(chunk_tvb), "Incomplete chunk");
1404 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
1406 /* then insert the chunk header components into the protocol tree */
1407 proto_tree_add_uint_format(chunk_tree, hf_sctp_chunk_type,
1408 chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH,
1409 type, "Identifier: %u (%s)",
1410 type, val_to_str(type, sctp_chunk_type_values, "unknown"));
1411 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags,
1412 chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH,
1414 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length,
1415 chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH,
1418 /* now dissect the chunk value */
1420 case SCTP_DATA_CHUNK_ID:
1421 dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1423 case SCTP_INIT_CHUNK_ID:
1424 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1426 case SCTP_INIT_ACK_CHUNK_ID:
1427 dissect_init_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1429 case SCTP_SACK_CHUNK_ID:
1430 dissect_sack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1432 case SCTP_HEARTBEAT_CHUNK_ID:
1433 dissect_heartbeat_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1435 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1436 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1438 case SCTP_ABORT_CHUNK_ID:
1439 dissect_abort_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1441 case SCTP_SHUTDOWN_CHUNK_ID:
1442 dissect_shutdown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1444 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
1445 dissect_shutdown_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1447 case SCTP_ERROR_CHUNK_ID:
1448 dissect_error_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1450 case SCTP_COOKIE_ECHO_CHUNK_ID:
1451 dissect_cookie_echo_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1453 case SCTP_COOKIE_ACK_CHUNK_ID:
1454 dissect_cookie_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1456 case SCTP_ECNE_CHUNK_ID:
1457 dissect_ecne_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1459 case SCTP_CWR_CHUNK_ID:
1460 dissect_cwr_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1462 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
1463 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1466 dissect_unknown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1472 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1474 tvbuff_t *chunk_tvb;
1475 guint16 length, padding_length, total_length;
1478 /* the common header of the datagram is already handled */
1479 offset = COMMON_HEADER_LENGTH;
1481 while(tvb_length_remaining(tvb, offset) > 0) {
1482 /* extract the chunk length and compute number of padding bytes */
1483 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
1484 padding_length = nr_of_padding_bytes(length);
1485 total_length = length + padding_length;
1486 /* create a tvb for the chunk including the padding bytes */
1487 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
1488 /* call dissect_sctp_chunk for a actual work */
1489 dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree);
1490 /* get rid of the dissected chunk */
1491 offset += total_length;
1497 /* dissect_sctp handles the common header of a SCTP datagram.
1498 * For the handling of the chunks dissect_sctp_chunks is called.
1502 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1504 guint16 source_port, destination_port;
1505 guint32 verification_tag, checksum;
1507 proto_tree *sctp_tree;
1509 CHECK_DISPLAY_AS_DATA(proto_sctp, tvb, pinfo, tree);
1511 pinfo->current_proto = "SCTP";
1513 /* Extract the common header */
1514 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
1515 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
1516 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
1517 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
1519 /* update pi structure */
1521 pi.srcport = source_port;
1522 pi.destport = destination_port;
1524 /* make entry in the Protocol column on summary display */
1525 if (check_col(pinfo->fd, COL_PROTOCOL))
1526 col_set_str(pinfo->fd, COL_PROTOCOL, "SCTP");
1528 /* Make entries in Info column on summary display */
1529 if (check_col(pinfo->fd, COL_INFO))
1530 col_add_fstr(pinfo->fd, COL_INFO, "%u > %u: tag 0x%x",
1531 source_port, destination_port, verification_tag);
1533 /* In the interest of speed, if "tree" is NULL, don't do any work not
1534 necessary to generate protocol tree items. */
1536 /* create the sctp protocol tree */
1537 ti = proto_tree_add_protocol_format(tree, proto_sctp, tvb, 0, tvb_length(tvb),
1538 "Stream Control Transmission Protocol");
1539 sctp_tree = proto_item_add_subtree(ti, ett_sctp);
1541 /* add the components of the common header to the protocol tree */
1542 proto_tree_add_uint(sctp_tree, hf_sctp_source_port,
1543 tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH,
1545 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port,
1546 tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH,
1548 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag,
1549 tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH,
1551 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum,
1552 tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum,
1553 "Adler-32 checksum: 0x%08x (%s)",
1554 checksum, sctp_checksum_state(tvb, checksum));
1556 /* add all chunks of the sctp datagram to the protocol tree */
1557 dissect_sctp_chunks(tvb, pinfo, tree, sctp_tree);
1561 /* Register the protocol with Ethereal */
1563 proto_register_sctp(void)
1566 /* Setup list of header fields */
1567 static hf_register_info hf[] = {
1568 { &hf_sctp_source_port,
1569 { "Source port", "sctp.srcport",
1570 FT_UINT16, BASE_DEC, NULL, 0x0,
1573 { &hf_sctp_destination_port,
1574 { "Destination port", "sctp.dstport",
1575 FT_UINT16, BASE_DEC, NULL, 0x0,
1578 { &hf_sctp_verification_tag,
1579 { "Verification tag", "sctp.verfication_tag",
1580 FT_UINT32, BASE_HEX, NULL, 0x0,
1583 { &hf_sctp_checksum,
1584 { "Adler-32 checksum", "sctp.checksum",
1585 FT_UINT32, BASE_HEX, NULL, 0x0,
1588 { &hf_sctp_chunk_type,
1589 { "Identifier", "sctp.chunk_type",
1590 FT_UINT8, BASE_DEC, NULL, 0x0,
1593 { &hf_sctp_chunk_flags,
1594 { "Flags", "sctp.chunk_flags",
1595 FT_UINT8, BASE_BIN, NULL, 0x0,
1598 { &hf_sctp_chunk_length,
1599 { "Length", "sctp.chunk_length",
1600 FT_UINT16, BASE_DEC, NULL, 0x0,
1603 { &hf_sctp_init_chunk_initiate_tag,
1604 { "Initiate tag", "sctp.init.chunk.initiate.tag",
1605 FT_UINT32, BASE_HEX, NULL, 0x0,
1608 { &hf_sctp_init_chunk_adv_rec_window_credit,
1609 { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
1610 FT_UINT32, BASE_DEC, NULL, 0x0,
1613 { &hf_sctp_init_chunk_number_of_outbound_streams,
1614 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
1615 FT_UINT16, BASE_DEC, NULL, 0x0,
1618 { &hf_sctp_init_chunk_number_of_inbound_streams,
1619 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
1620 FT_UINT16, BASE_DEC, NULL, 0x0,
1623 {&hf_sctp_init_chunk_initial_tsn,
1624 { "Initial TSN", "sctp.init.chunk.initial.tsn",
1625 FT_UINT32, BASE_DEC, NULL, 0x0,
1628 {&hf_sctp_cumulative_tsn_ack,
1629 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
1630 FT_UINT32, BASE_DEC, NULL, 0x0,
1633 {&hf_sctp_data_chunk_tsn,
1634 { "TSN", "sctp.tsn",
1635 FT_UINT32, BASE_DEC, NULL, 0x0,
1638 {&hf_sctp_data_chunk_stream_id,
1639 { "Stream Identifier", "sctp.stream_id",
1640 FT_UINT16, BASE_HEX, NULL, 0x0,
1643 {&hf_sctp_data_chunk_stream_seq_number,
1644 { "Stream sequence number", "sctp.stream_seq_number",
1645 FT_UINT16, BASE_DEC, NULL, 0x0,
1648 {&hf_sctp_data_chunk_payload_proto_id,
1649 { "Payload Protocol identifier", "sctp.payload_proto_id",
1650 FT_UINT32, BASE_HEX, NULL, 0x0,
1653 {&hf_sctp_data_chunk_e_bit,
1654 { "E-Bit", "sctp.data.e_bit",
1655 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
1658 {&hf_sctp_data_chunk_b_bit,
1659 { "B-Bit", "sctp.data.b_bit",
1660 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
1663 {&hf_sctp_data_chunk_u_bit,
1664 { "U-Bit", "sctp.data.u.bit",
1665 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
1668 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
1669 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
1670 FT_UINT32, BASE_DEC, NULL, 0x0,
1673 {&hf_sctp_sack_chunk_adv_rec_window_credit,
1674 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
1675 FT_UINT32, BASE_DEC, NULL, 0x0,
1678 {&hf_sctp_sack_chunk_number_of_gap_blocks,
1679 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
1680 FT_UINT16, BASE_DEC, NULL, 0x0,
1683 {&hf_sctp_sack_chunk_number_of_dup_tsns,
1684 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
1685 FT_UINT16, BASE_DEC, NULL, 0x0,
1688 {&hf_sctp_sack_chunk_gap_block_start,
1689 { "Start", "sctp.sack.gap_block_start",
1690 FT_UINT16, BASE_DEC, NULL, 0x0,
1693 {&hf_sctp_sack_chunk_gap_block_end,
1694 { "End", "sctp.sack.gap_block_end",
1695 FT_UINT16, BASE_DEC, NULL, 0x0,
1698 {&hf_sctp_sack_chunk_duplicate_tsn,
1699 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
1700 FT_UINT16, BASE_DEC, NULL, 0x0,
1703 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1704 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
1705 FT_UINT32, BASE_DEC, NULL, 0x0,
1708 {&hf_sctp_ecne_chunk_lowest_tsn,
1709 { "Lowest TSN", "sctp.ecne.lowest_tsn",
1710 FT_UINT32, BASE_DEC, NULL, 0x0,
1713 {&hf_sctp_cwr_chunk_lowest_tsn,
1714 { "Lowest TSN", "sctp.cwr.lowest_tsn",
1715 FT_UINT32, BASE_DEC, NULL, 0x0,
1718 {&hf_sctp_shutdown_complete_chunk_t_bit,
1719 { "E-Bit", "sctp.shutdown_complete.t_bit",
1720 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
1723 {&hf_sctp_chunk_parameter_type,
1724 { "Parameter type", "sctp.parameter.type",
1725 FT_UINT16, BASE_HEX, NULL, 0x0,
1728 {&hf_sctp_chunk_parameter_length,
1729 { "Parameter length", "sctp.parameter.length",
1730 FT_UINT16, BASE_DEC, NULL, 0x0,
1733 {&hf_sctp_parameter_ipv4_address,
1734 { "IP Version 4 address", "sctp.parameter.ipv4_address",
1735 FT_IPv4, BASE_NONE, NULL, 0x0,
1738 {&hf_sctp_parameter_ipv6_address,
1739 { "IP Version 6 address", "sctp.parameter.ipv6_address",
1740 FT_IPv6, BASE_NONE, NULL, 0x0,
1743 {&hf_sctp_parameter_cookie_preservative_increment,
1744 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
1745 FT_UINT32, BASE_DEC, NULL, 0x0,
1748 {&hf_sctp_parameter_hostname_hostname,
1749 { "Hostname", "sctp.parameter.hostname.hostname",
1750 FT_STRING, BASE_NONE, NULL, 0x0,
1753 {&hf_sctp_supported_address_types_parameter,
1754 { "Supported address type", "sctp.parameter.supported_addres_type",
1755 FT_UINT16, BASE_DEC, NULL, 0x0,
1758 {&hf_sctp_cause_code,
1759 { "Cause code", "sctp.cause.code",
1760 FT_UINT16, BASE_DEC, NULL, 0x0,
1763 {&hf_sctp_cause_length,
1764 { "Cause length", "sctp.cause.length",
1765 FT_UINT16, BASE_DEC, NULL, 0x0,
1768 {&hf_sctp_cause_stream_identifier,
1769 { "Stream identifier", "sctp.cause.stream_identifier",
1770 FT_UINT16, BASE_DEC, NULL, 0x0,
1773 {&hf_sctp_cause_number_of_missing_parameters,
1774 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
1775 FT_UINT32, BASE_DEC, NULL, 0x0,
1778 {&hf_sctp_cause_missing_parameter_type,
1779 { "Missing parameters type", "sctp.cause.missing_parameter_type",
1780 FT_UINT16, BASE_DEC, NULL, 0x0,
1783 {&hf_sctp_cause_measure_of_staleness,
1784 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
1785 FT_UINT32, BASE_DEC, NULL, 0x0,
1788 {&hf_sctp_cause_tsn,
1789 { "TSN", "sctp.cause.tsn",
1790 FT_UINT32, BASE_DEC, NULL, 0x0,
1795 /* Setup protocol subtree array */
1796 static gint *ett[] = {
1799 &ett_sctp_chunk_parameter,
1800 &ett_sctp_chunk_cause,
1801 &ett_sctp_data_chunk_flags,
1802 &ett_sctp_sack_chunk_gap_block,
1803 &ett_sctp_supported_address_types_parameter,
1804 &ett_sctp_unrecognized_parameter_parameter
1807 /* Register the protocol name and description */
1808 proto_sctp = proto_register_protocol("Stream Control Transmission Protcol",
1811 /* Required function calls to register the header fields and subtrees used */
1812 proto_register_field_array(proto_sctp, hf, array_length(hf));
1813 proto_register_subtree_array(ett, array_length(ett));
1815 /* subdissector code */
1816 sctp_dissector_table = register_dissector_table("sctp.port");
1821 proto_reg_handoff_sctp(void)
1823 dissector_add("ip.proto", IP_PROTO_SCTP, dissect_sctp);