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.21 2001/10/23 20:14:20 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
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"
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 identifier" },
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, padding_length, parameter_value_length;
579 tvbuff_t *unrecognized_parameters_tvb;
581 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
582 padding_length = nr_of_padding_bytes(length);
584 parameter_value_length = length - PARAMETER_HEADER_LENGTH + padding_length;
586 unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
587 parameter_value_length, parameter_value_length);
588 dissect_tlv_parameter_list(unrecognized_parameters_tvb, parameter_tree);
590 proto_item_set_text(parameter_item, "Unrecognized parameter of type");
594 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
598 increment = tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
600 proto_tree_add_uint(parameter_tree, hf_sctp_parameter_cookie_preservative_increment, parameter_tvb,
601 COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET,
602 COOKIE_PRESERVATIVE_PARAMETER_INCR_LENGTH,
605 proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
610 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
612 guint16 length, hostname_length;
615 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
617 hostname_length = length - PARAMETER_HEADER_LENGTH;
618 hostname = (char *)tvb_get_ptr(parameter_tvb, PARAMETER_VALUE_OFFSET, hostname_length);
619 proto_tree_add_string(parameter_tree, hf_sctp_parameter_hostname_hostname, parameter_tvb,
620 PARAMETER_VALUE_OFFSET, hostname_length,
623 proto_item_set_text(parameter_item, "Hostname parameter");
627 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
629 guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
631 proto_item *address_list_item;
632 proto_tree *address_list_tree;
634 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
635 list_of_address_types_length = length - PARAMETER_HEADER_LENGTH;
636 number_of_address_types = list_of_address_types_length / SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
638 address_list_item = proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, list_of_address_types_length,
639 "Supported Address Types (%u address type%s)",
640 number_of_address_types, plurality(number_of_address_types, "", "s"));
641 address_list_tree = proto_item_add_subtree(address_list_item, ett_sctp_supported_address_types_parameter);
643 offset = PARAMETER_VALUE_OFFSET;
644 for(address_type_number = 1; address_type_number <= number_of_address_types; address_type_number++) {
645 address_type = tvb_get_ntohs(parameter_tvb, offset);
646 proto_tree_add_uint_format(address_list_tree, hf_sctp_supported_address_types_parameter,
647 parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH,
648 address_type, "Supported address type: 0x%04x (%s)",
649 address_type, val_to_str(address_type, sctp_parameter_identifier_values, "unknown"));
650 offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH;
653 proto_item_set_text(parameter_item, "Supported address types parameter reporting %u address type%s",
654 number_of_address_types, plurality(number_of_address_types, "", "s"));
658 dissect_ecn_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
660 proto_item_set_text(parameter_item, "ECN parameter");
664 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
666 guint16 type, length, parameter_value_length;
668 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
669 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
671 parameter_value_length = length - PARAMETER_HEADER_LENGTH;
673 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length,
674 "Parameter value (%u byte%s)",
675 parameter_value_length, plurality(parameter_value_length, "", "s"));
677 proto_item_set_text(parameter_item, "Parameter of type %u and %u byte%s value",
678 type, parameter_value_length, plurality(parameter_value_length, "", "s"));
682 dissect_parameter(tvbuff_t *parameter_tvb, proto_tree *chunk_tree)
684 guint16 type, length, padding_length, total_length;
685 proto_item *parameter_item;
686 proto_tree *parameter_tree;
688 type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
689 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
690 padding_length = nr_of_padding_bytes(length);
691 total_length = length + padding_length;
693 parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb,
694 PARAMETER_HEADER_OFFSET, total_length, "%s parameter",
695 val_to_str(type, sctp_parameter_identifier_values, "Unknown"));
696 parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter);
698 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_type,
699 parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH,
701 proto_tree_add_uint(parameter_tree, hf_sctp_chunk_parameter_length,
702 parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH,
706 case HEARTBEAT_INFO_PARAMETER_ID:
707 dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
709 case IPV4ADDRESS_PARAMETER_ID:
710 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
712 case IPV6ADDRESS_PARAMETER_ID:
713 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
715 case STATE_COOKIE_PARAMETER_ID:
716 dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
718 case UNREC_PARA_PARAMETER_ID:
719 dissect_unrecognized_parameters_parameter(parameter_tvb, parameter_tree, parameter_item);
721 case COOKIE_PRESERVATIVE_PARAMETER_ID:
722 dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
724 case HOSTNAME_ADDRESS_PARAMETER_ID:
725 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
727 case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
728 dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
730 case ECN_PARAMETER_ID:
731 dissect_ecn_parameter(parameter_tvb, parameter_tree, parameter_item);
734 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
737 if ((padding_length > 0) && (type != UNREC_PARA_PARAMETER_ID))
738 proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
739 "Padding: %u byte%s",
740 padding_length, plurality(padding_length, "", "s"));
744 * Code to handle error causes for ABORT and ERROR chunks
747 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
749 guint16 stream_identifier;
751 stream_identifier = tvb_get_ntohs(cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET);
752 proto_tree_add_uint(cause_tree, hf_sctp_cause_stream_identifier,
753 cause_tvb, CAUSE_STREAM_IDENTIFIER_OFFSET, CAUSE_STREAM_IDENTIFIER_LENGTH,
755 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
756 "Reserved (2 bytes)");
758 proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
763 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
765 guint32 number_of_missing_parameters, missing_parameter_number;
766 guint16 parameter_type;
769 number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET);
770 proto_tree_add_uint(cause_tree, hf_sctp_cause_number_of_missing_parameters,
771 cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH,
772 number_of_missing_parameters);
773 offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET;
774 for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) {
775 parameter_type = tvb_get_ntohs(cause_tvb, offset);
776 proto_tree_add_uint(cause_tree, hf_sctp_cause_missing_parameter_type,
777 cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH,
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 0x%04x (%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, padding_length, cause_info_length;
861 tvbuff_t *unrecognized_parameters_tvb;
863 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
864 padding_length = nr_of_padding_bytes(length);
866 cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
868 unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET,
869 cause_info_length, cause_info_length);
870 dissect_tlv_parameter_list(unrecognized_parameters_tvb, cause_tree);
872 proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
876 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
880 tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
881 proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb,
886 proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
891 dissect_cookie_received_while_shutting_down_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
893 proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
897 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
899 guint16 code, length, cause_info_length;
901 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
902 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
904 cause_info_length = length - CAUSE_HEADER_LENGTH;
906 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_INFO_OFFSET, cause_info_length,
907 "Cause specific information (%u byte%s)",
908 cause_info_length, plurality(cause_info_length, "", "s"));
910 proto_item_set_text(cause_item, "Error cause with code %u and %u byte%s information",
911 code, cause_info_length, plurality(cause_info_length, "", "s"));
915 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
917 guint16 code, length, padding_length, total_length;
918 proto_item *cause_item;
919 proto_tree *cause_tree;
921 code = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
922 length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
923 padding_length = nr_of_padding_bytes(length);
924 total_length = length + padding_length;
926 cause_item = proto_tree_add_text(chunk_tree, cause_tvb,
927 CAUSE_HEADER_OFFSET, total_length,
929 cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
931 proto_tree_add_uint(cause_tree, hf_sctp_cause_code,
932 cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH,
934 proto_tree_add_uint(cause_tree, hf_sctp_cause_length,
935 cause_tvb, CAUSE_LENGTH_OFFSET, CAUSE_LENGTH_LENGTH,
939 case INVALID_STREAM_IDENTIFIER:
940 dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
942 case MISSING_MANDATORY_PARAMETERS:
943 dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
945 case STALE_COOKIE_ERROR:
946 dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
948 case OUT_OF_RESOURCE:
949 dissect_out_of_resource_cause(cause_tvb, cause_tree, cause_item);
951 case UNRESOLVABLE_ADDRESS:
952 dissect_unresolvable_address_cause(cause_tvb, cause_tree, cause_item);
954 case UNRECOGNIZED_CHUNK_TYPE:
955 dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
957 case INVALID_MANDATORY_PARAMETER:
958 dissect_invalid_mandatory_parameter_cause(cause_tvb, cause_tree, cause_item);
960 case UNRECOGNIZED_PARAMETERS:
961 dissect_unrecognized_parameters_cause(cause_tvb, cause_tree, cause_item);
964 dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
966 case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
967 dissect_cookie_received_while_shutting_down_cause(cause_tvb, cause_tree, cause_item);
970 dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
973 if ((padding_length > 0) && (code != UNRECOGNIZED_PARAMETERS))
974 proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
975 "Padding: %u byte%s",
976 padding_length, plurality(padding_length, "", "s"));
980 * Code to actually dissect the packets
984 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
985 proto_tree *chunk_tree, guint32 ppi, guint16 payload_length, guint16 padding_length)
987 /* do lookup with the subdissector table */
988 if (dissector_try_port (sctp_ppi_dissector_table, ppi, payload_tvb, pinfo, tree) ||
989 dissector_try_port(sctp_port_dissector_table, pinfo->srcport, payload_tvb, pinfo, tree) ||
990 dissector_try_port(sctp_port_dissector_table, pinfo->destport, payload_tvb, pinfo, tree)){
994 if (check_col(pinfo->fd, COL_INFO))
995 col_append_str(pinfo->fd, COL_INFO, "DATA ");
996 proto_tree_add_text(chunk_tree, payload_tvb, 0, payload_length,
997 "Payload (%u byte%s)",
998 payload_length, plurality(payload_length, "", "s"));
999 if (padding_length > 0)
1000 proto_tree_add_text(chunk_tree, payload_tvb, payload_length, padding_length,
1001 "Padding: %u byte%s",
1002 padding_length, plurality(padding_length, "", "s"));
1008 dissect_data_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1009 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1012 guint16 length, total_payload_length, payload_length, padding_length, stream_id, stream_seq_number;
1013 guint32 tsn, payload_proto_id;
1014 proto_tree *flag_tree;
1015 tvbuff_t *payload_tvb;
1017 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1018 payload_length = length - DATA_CHUNK_HEADER_LENGTH;
1019 padding_length = nr_of_padding_bytes(length);
1020 total_payload_length = payload_length + padding_length;
1021 payload_tvb = tvb_new_subset(chunk_tvb, DATA_CHUNK_PAYLOAD_OFFSET,
1022 total_payload_length, total_payload_length);
1023 payload_proto_id = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET);
1026 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1028 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1029 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_e_bit, chunk_tvb,
1030 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1031 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_b_bit, chunk_tvb,
1032 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1033 proto_tree_add_boolean(flag_tree, hf_sctp_data_chunk_u_bit, chunk_tvb,
1034 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1036 tsn = tvb_get_ntohl(chunk_tvb, DATA_CHUNK_TSN_OFFSET);
1037 stream_id = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_ID_OFFSET);
1038 stream_seq_number = tvb_get_ntohs(chunk_tvb, DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET);
1040 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn,
1042 DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1044 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id,
1046 DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1048 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number,
1050 DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1052 proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id,
1053 chunk_tvb, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1055 proto_item_set_text(chunk_item, "DATA chunk with TSN %u (%u:%u) containing %u byte%s of payload",
1056 tsn, stream_id, stream_seq_number,
1057 payload_length, plurality(payload_length, "", "s"));
1059 return dissect_payload(payload_tvb, pinfo, tree, chunk_tree, payload_proto_id, payload_length, padding_length);
1063 dissect_init_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1064 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1066 guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1067 guint16 number_of_inbound_streams, number_of_outbound_streams;
1069 tvbuff_t *parameter_list_tvb;
1071 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1073 if (check_col(pinfo->fd, COL_INFO)) {
1074 if (type == SCTP_INIT_CHUNK_ID) {
1075 col_append_str(pinfo->fd, COL_INFO, "INIT ");
1077 col_append_str(pinfo->fd, COL_INFO, "INIT_ACK ");
1082 initiate_tag = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIATE_TAG_OFFSET);
1083 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1084 number_of_inbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1085 number_of_outbound_streams = tvb_get_ntohs(chunk_tvb, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1086 initial_tsn = tvb_get_ntohl(chunk_tvb, INIT_CHUNK_INITIAL_TSN_OFFSET);
1088 /* handle fixed parameters */
1089 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag,
1091 INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1093 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit,
1095 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1096 adv_rec_window_credit);
1097 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_outbound_streams,
1099 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH,
1100 number_of_outbound_streams);
1101 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_number_of_inbound_streams,
1103 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET, INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH,
1104 number_of_inbound_streams);
1105 proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initial_tsn,
1107 INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1110 /* handle variable paramters */
1111 parameter_list_tvb = tvb_new_subset(chunk_tvb, INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET, -1, -1);
1112 dissect_tlv_parameter_list(parameter_list_tvb, chunk_tree);
1114 proto_item_set_text(chunk_item,
1115 "%s chunk requesting for %u outbound stream%s and accepting up to %u inbound stream%s",
1116 val_to_str(type, sctp_chunk_type_values, "unknown"),
1117 number_of_outbound_streams, plurality(number_of_outbound_streams, "", "s"),
1118 number_of_inbound_streams, plurality(number_of_inbound_streams, "", "s"));
1123 dissect_init_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1124 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1126 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1130 dissect_sack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1131 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1133 guint32 cumulative_tsn_ack, adv_rec_window_credit, dup_tsn;
1134 guint16 number_of_gap_blocks, number_of_dup_tsns;
1135 guint16 gap_block_number, dup_tsn_number, start, end;
1136 gint gap_block_offset, dup_tsn_offset;
1137 proto_item *block_item;
1138 proto_tree *block_tree;
1140 if (check_col(pinfo->fd, COL_INFO))
1141 col_append_str(pinfo->fd, COL_INFO, "SACK ");
1144 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1145 adv_rec_window_credit = tvb_get_ntohl(chunk_tvb, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1146 number_of_gap_blocks = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET);
1147 number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET);
1149 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack,
1151 SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET, SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1152 cumulative_tsn_ack);
1153 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_adv_rec_window_credit,
1155 SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET, SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH,
1156 adv_rec_window_credit);
1157 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_gap_blocks,
1159 SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_OFFSET, SACK_CHUNK_NUMBER_OF_GAP_BLOCKS_LENGTH,
1160 number_of_gap_blocks);
1161 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_number_of_dup_tsns,
1163 SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1164 number_of_dup_tsns);
1166 /* handle the gap acknowledgement blocks */
1167 gap_block_offset = SACK_CHUNK_GAP_BLOCK_OFFSET;
1168 for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) {
1169 start = tvb_get_ntohs(chunk_tvb, gap_block_offset);
1170 end = tvb_get_ntohs(chunk_tvb, gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH);
1171 block_item = proto_tree_add_text(chunk_tree, chunk_tvb,
1172 gap_block_offset, SACK_CHUNK_GAP_BLOCK_LENGTH,
1173 "Gap Acknowledgement for %u TSN%s",
1174 1 + end - start, plurality(1 + end - start, "", "s"));
1175 block_tree = proto_item_add_subtree(block_item, ett_sctp_sack_chunk_gap_block);
1176 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_start,
1178 gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1180 proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end,
1182 gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1183 SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1185 gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1188 /* handle the duplicate TSNs */
1189 dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH;
1190 for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) {
1191 dup_tsn = tvb_get_ntohl(chunk_tvb, dup_tsn_offset);
1192 proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_duplicate_tsn,
1194 dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1196 dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1199 proto_item_set_text(chunk_item,
1200 "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1202 number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1203 number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1208 dissect_heartbeat_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1209 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1211 tvbuff_t *parameter_tvb;
1212 guint chunk_length, info_length, padding_length, total_length;
1214 if (check_col(pinfo->fd, COL_INFO))
1215 col_append_str(pinfo->fd, COL_INFO, "HEARTBEAT ");
1218 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1219 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1220 padding_length = nr_of_padding_bytes(info_length);
1221 total_length = info_length + padding_length;
1222 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1224 dissect_parameter(parameter_tvb, chunk_tree);
1226 proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1231 dissect_heartbeat_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1232 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1234 tvbuff_t *parameter_tvb;
1235 guint chunk_length, info_length, padding_length, total_length;
1237 if (check_col(pinfo->fd, COL_INFO))
1238 col_append_str(pinfo->fd, COL_INFO, "HEARTBEAT_ACK ");
1241 chunk_length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1242 info_length = chunk_length - CHUNK_HEADER_LENGTH;
1243 padding_length = nr_of_padding_bytes(info_length);
1244 total_length = info_length + padding_length;
1246 parameter_tvb = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1248 dissect_parameter(parameter_tvb, chunk_tree);
1250 proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1255 dissect_abort_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1256 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1258 guint offset, number_of_causes;
1259 guint16 length, padding_length, total_length;
1260 tvbuff_t *cause_tvb;
1262 if (check_col(pinfo->fd, COL_INFO))
1263 col_append_str(pinfo->fd, COL_INFO, "ABORT ");
1266 number_of_causes = 0;
1267 offset = ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1268 while(tvb_length_remaining(chunk_tvb, offset)) {
1269 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1270 padding_length = nr_of_padding_bytes(length);
1271 total_length = length + padding_length;
1272 /* create a tvb for the chunk including the padding bytes */
1273 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1274 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1275 /* get rid of the handled parameter */
1276 offset += total_length;
1280 proto_item_set_text(chunk_item, "Abort chunk with %u cause%s",
1281 number_of_causes, plurality(number_of_causes, "", "s"));
1286 dissect_shutdown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1287 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1289 guint32 cumulative_tsn_ack;
1291 if (check_col(pinfo->fd, COL_INFO))
1292 col_append_str(pinfo->fd, COL_INFO, "SHUTDOWN ");
1295 cumulative_tsn_ack = tvb_get_ntohl(chunk_tvb, SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1296 proto_tree_add_uint(chunk_tree, hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1298 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1299 SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1300 cumulative_tsn_ack);
1302 proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1303 cumulative_tsn_ack);
1308 dissect_shutdown_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1309 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1311 if (check_col(pinfo->fd, COL_INFO))
1312 col_append_str(pinfo->fd, COL_INFO, "SHUTDOWN_ACK ");
1315 proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1320 dissect_error_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1321 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1323 guint offset, number_of_causes;
1324 guint16 length, padding_length, total_length;
1325 tvbuff_t *cause_tvb;
1327 if (check_col(pinfo->fd, COL_INFO))
1328 col_append_str(pinfo->fd, COL_INFO, "ERROR ");
1331 number_of_causes = 0;
1332 offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1334 length = tvb_get_ntohs(chunk_tvb, offset + CAUSE_LENGTH_OFFSET);
1335 padding_length = nr_of_padding_bytes(length);
1336 total_length = length + padding_length;
1337 /* create a tvb for the chunk including the padding bytes */
1338 cause_tvb = tvb_new_subset(chunk_tvb, offset, total_length, total_length);
1339 dissect_error_cause(cause_tvb, pinfo, chunk_tree);
1340 /* get rid of the handled parameter */
1341 offset += total_length;
1343 } while(tvb_length_remaining(chunk_tvb, offset));
1345 proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1346 number_of_causes, plurality(number_of_causes, "", "s"));
1351 dissect_cookie_echo_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1352 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1354 guint length, cookie_length, padding_length;
1356 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1357 padding_length = nr_of_padding_bytes(length);
1358 cookie_length = length - CHUNK_HEADER_LENGTH;
1360 if (check_col(pinfo->fd, COL_INFO))
1361 col_append_str(pinfo->fd, COL_INFO, "COOKIE_ECHO ");
1364 proto_tree_add_text(chunk_tree, chunk_tvb, COOKIE_ECHO_CHUNK_COOKIE_OFFSET, cookie_length,
1365 "Cookie (%u byte%s)",
1366 cookie_length, plurality(cookie_length, "", "s"));
1367 proto_item_set_text(chunk_item, "COOKIE ECHO chunk containing a cookie of %u byte%s",
1368 cookie_length, plurality(cookie_length, "", "s"));
1370 if (padding_length > 0)
1371 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1372 "Padding: %u byte%s",
1373 padding_length, plurality(padding_length, "", "s"));
1378 dissect_cookie_ack_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1379 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1381 if (check_col(pinfo->fd, COL_INFO))
1382 col_append_str(pinfo->fd, COL_INFO, "COOKIE_ACK ");
1385 proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1390 dissect_ecne_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1391 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1395 if (check_col(pinfo->fd, COL_INFO))
1396 col_append_str(pinfo->fd, COL_INFO, "ECNE ");
1399 lowest_tsn = tvb_get_ntohl(chunk_tvb, ECNE_CHUNK_LOWEST_TSN_OFFSET);
1400 proto_tree_add_uint(chunk_tree, hf_sctp_ecne_chunk_lowest_tsn,
1402 ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1405 proto_item_set_text(chunk_item, "ECNE chunk");
1410 dissect_cwr_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1411 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1415 if (check_col(pinfo->fd, COL_INFO))
1416 col_append_str(pinfo->fd, COL_INFO, "CWR ");
1419 lowest_tsn = tvb_get_ntohl(chunk_tvb, CWR_CHUNK_LOWEST_TSN_OFFSET);
1420 proto_tree_add_uint(chunk_tree, hf_sctp_cwr_chunk_lowest_tsn,
1422 CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1425 proto_item_set_text(chunk_item, "CWR chunk");
1430 dissect_shutdown_complete_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1431 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1435 proto_tree *flag_tree;
1437 if (check_col(pinfo->fd, COL_INFO))
1438 col_append_str(pinfo->fd, COL_INFO, "SHUTDOWN_COMPLETE ");
1441 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1442 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1444 flag_tree = proto_item_add_subtree(flags_item, ett_sctp_data_chunk_flags);
1445 proto_tree_add_boolean(flag_tree, hf_sctp_shutdown_complete_chunk_t_bit, chunk_tvb,
1446 CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH, flags);
1448 proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1453 dissect_unknown_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree,
1454 proto_tree *chunk_tree, proto_item *chunk_item, proto_item *flags_item)
1456 guint length, chunk_value_length, padding_length;
1459 if (check_col(pinfo->fd, COL_INFO))
1460 col_append_str(pinfo->fd, COL_INFO, "UNKNOWN ");
1463 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1464 padding_length = nr_of_padding_bytes(length);
1465 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1467 chunk_value_length = length - CHUNK_HEADER_LENGTH;
1469 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_VALUE_OFFSET, chunk_value_length,
1470 "Chunk value (%u byte%s)",
1471 chunk_value_length, plurality(chunk_value_length, "", "s"));
1473 if (padding_length > 0)
1474 proto_tree_add_text(chunk_tree, chunk_tvb, CHUNK_HEADER_OFFSET + length, padding_length,
1475 "Padding: %u byte%s",
1476 padding_length, plurality(padding_length, "", "s"));
1478 proto_item_set_text(chunk_item, "Chunk of type %u and %u byte%s value",
1479 type, chunk_value_length, plurality(chunk_value_length, "", "s"));
1485 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1490 proto_item *flags_item;
1491 proto_item *chunk_item;
1492 proto_tree *chunk_tree;
1496 /* first extract the chunk header */
1497 type = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1498 flags = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1499 length = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1502 /* create proto_tree stuff */
1503 chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb,
1504 CHUNK_HEADER_OFFSET, tvb_length(chunk_tvb), "Incomplete chunk");
1505 chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk);
1507 /* then insert the chunk header components into the protocol tree */
1508 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_type,
1509 chunk_tvb, CHUNK_TYPE_OFFSET, CHUNK_TYPE_LENGTH,
1511 flags_item = proto_tree_add_uint(chunk_tree, hf_sctp_chunk_flags,
1512 chunk_tvb, CHUNK_FLAGS_OFFSET, CHUNK_FLAGS_LENGTH,
1514 proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length,
1515 chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH,
1523 /* now dissect the chunk value */
1526 case SCTP_DATA_CHUNK_ID:
1527 result = dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1529 case SCTP_INIT_CHUNK_ID:
1530 dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1532 case SCTP_INIT_ACK_CHUNK_ID:
1533 dissect_init_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1535 case SCTP_SACK_CHUNK_ID:
1536 dissect_sack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1538 case SCTP_HEARTBEAT_CHUNK_ID:
1539 dissect_heartbeat_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1541 case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1542 dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1544 case SCTP_ABORT_CHUNK_ID:
1545 dissect_abort_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1547 case SCTP_SHUTDOWN_CHUNK_ID:
1548 dissect_shutdown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1550 case SCTP_SHUTDOWN_ACK_CHUNK_ID:
1551 dissect_shutdown_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1553 case SCTP_ERROR_CHUNK_ID:
1554 dissect_error_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1556 case SCTP_COOKIE_ECHO_CHUNK_ID:
1557 dissect_cookie_echo_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1559 case SCTP_COOKIE_ACK_CHUNK_ID:
1560 dissect_cookie_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1562 case SCTP_ECNE_CHUNK_ID:
1563 dissect_ecne_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1565 case SCTP_CWR_CHUNK_ID:
1566 dissect_cwr_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1568 case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
1569 dissect_shutdown_complete_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1572 dissect_unknown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1579 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1580 proto_item *sctp_item, proto_tree *sctp_tree)
1582 tvbuff_t *chunk_tvb;
1583 guint16 length, padding_length, total_length;
1584 gint last_offset, offset;
1585 gboolean sctp_item_length_set;
1587 /* the common header of the datagram is already handled */
1589 offset = COMMON_HEADER_LENGTH;
1590 sctp_item_length_set = FALSE;
1592 while(tvb_length_remaining(tvb, offset) > 0) {
1593 /* extract the chunk length and compute number of padding bytes */
1594 length = tvb_get_ntohs(tvb, offset + CHUNK_LENGTH_OFFSET);
1595 padding_length = nr_of_padding_bytes(length);
1596 total_length = length + padding_length;
1597 /* create a tvb for the chunk including the padding bytes */
1598 chunk_tvb = tvb_new_subset(tvb, offset, total_length, total_length);
1599 /* call dissect_sctp_chunk for a actual work */
1600 if (dissect_sctp_chunk(chunk_tvb, pinfo, tree, sctp_tree) && (tree)) {
1601 proto_item_set_len(sctp_item, offset - last_offset + DATA_CHUNK_HEADER_LENGTH);
1602 sctp_item_length_set = TRUE;
1603 offset += total_length;
1604 last_offset = offset;
1605 if (tvb_length_remaining(tvb, offset) > 0) {
1606 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, offset, 0, FALSE);
1607 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
1608 sctp_item_length_set = FALSE;
1611 /* get rid of the dissected chunk */
1612 offset += total_length;
1615 if (!sctp_item_length_set && (tree)) {
1616 proto_item_set_len(sctp_item, offset - last_offset);
1620 /* dissect_sctp handles the common header of a SCTP datagram.
1621 * For the handling of the chunks dissect_sctp_chunks is called.
1625 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1627 guint16 source_port, destination_port;
1628 guint32 verification_tag, checksum;
1629 proto_item *sctp_item;
1630 proto_tree *sctp_tree;
1632 /* Extract the common header */
1633 source_port = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
1634 destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
1635 verification_tag = tvb_get_ntohl(tvb, VERIFICATION_TAG_OFFSET);
1636 checksum = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
1638 /* update pi structure */
1639 pinfo->ptype = PT_SCTP;
1640 pinfo->srcport = source_port;
1641 pinfo->destport = destination_port;
1643 /* make entry in the Protocol column on summary display */
1644 if (check_col(pinfo->fd, COL_PROTOCOL))
1645 col_set_str(pinfo->fd, COL_PROTOCOL, "SCTP");
1647 /* Clear entries in Info column on summary display */
1648 if (check_col(pinfo->fd, COL_INFO))
1649 col_add_str(pinfo->fd, COL_INFO, "");
1651 /* In the interest of speed, if "tree" is NULL, don't do any work not
1652 necessary to generate protocol tree items. */
1654 /* create the sctp protocol tree */
1655 sctp_item = proto_tree_add_item(tree, proto_sctp, tvb, 0, 0, FALSE);
1656 sctp_tree = proto_item_add_subtree(sctp_item, ett_sctp);
1658 /* add the components of the common header to the protocol tree */
1659 proto_tree_add_uint(sctp_tree, hf_sctp_source_port,
1660 tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH,
1662 proto_tree_add_uint(sctp_tree, hf_sctp_destination_port,
1663 tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH,
1665 proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag,
1666 tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH,
1668 proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum,
1669 tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, checksum,
1670 "Adler-32 checksum: 0x%08x (%s)",
1671 checksum, sctp_checksum_state(tvb, checksum));
1676 /* add all chunks of the sctp datagram to the protocol tree */
1677 dissect_sctp_chunks(tvb, pinfo, tree, sctp_item, sctp_tree);
1680 /* Register the protocol with Ethereal */
1682 proto_register_sctp(void)
1685 /* Setup list of header fields */
1686 static hf_register_info hf[] = {
1687 { &hf_sctp_source_port,
1688 { "Source port", "sctp.srcport",
1689 FT_UINT16, BASE_DEC, NULL, 0x0,
1692 { &hf_sctp_destination_port,
1693 { "Destination port", "sctp.dstport",
1694 FT_UINT16, BASE_DEC, NULL, 0x0,
1697 { &hf_sctp_verification_tag,
1698 { "Verification tag", "sctp.verfication_tag",
1699 FT_UINT32, BASE_HEX, NULL, 0x0,
1702 { &hf_sctp_checksum,
1703 { "Adler-32 checksum", "sctp.checksum",
1704 FT_UINT32, BASE_HEX, NULL, 0x0,
1707 { &hf_sctp_chunk_type,
1708 { "Identifier", "sctp.chunk_type",
1709 FT_UINT8, BASE_DEC, VALS(sctp_chunk_type_values), 0x0,
1712 { &hf_sctp_chunk_flags,
1713 { "Flags", "sctp.chunk_flags",
1714 FT_UINT8, BASE_BIN, NULL, 0x0,
1717 { &hf_sctp_chunk_length,
1718 { "Length", "sctp.chunk_length",
1719 FT_UINT16, BASE_DEC, NULL, 0x0,
1722 { &hf_sctp_init_chunk_initiate_tag,
1723 { "Initiate tag", "sctp.init.chunk.initiate.tag",
1724 FT_UINT32, BASE_HEX, NULL, 0x0,
1727 { &hf_sctp_init_chunk_adv_rec_window_credit,
1728 { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
1729 FT_UINT32, BASE_DEC, NULL, 0x0,
1732 { &hf_sctp_init_chunk_number_of_outbound_streams,
1733 { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
1734 FT_UINT16, BASE_DEC, NULL, 0x0,
1737 { &hf_sctp_init_chunk_number_of_inbound_streams,
1738 { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
1739 FT_UINT16, BASE_DEC, NULL, 0x0,
1742 {&hf_sctp_init_chunk_initial_tsn,
1743 { "Initial TSN", "sctp.init.chunk.initial.tsn",
1744 FT_UINT32, BASE_DEC, NULL, 0x0,
1747 {&hf_sctp_cumulative_tsn_ack,
1748 { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
1749 FT_UINT32, BASE_DEC, NULL, 0x0,
1752 {&hf_sctp_data_chunk_tsn,
1753 { "TSN", "sctp.tsn",
1754 FT_UINT32, BASE_DEC, NULL, 0x0,
1757 {&hf_sctp_data_chunk_stream_id,
1758 { "Stream Identifier", "sctp.stream_id",
1759 FT_UINT16, BASE_HEX, NULL, 0x0,
1762 {&hf_sctp_data_chunk_stream_seq_number,
1763 { "Stream sequence number", "sctp.stream_seq_number",
1764 FT_UINT16, BASE_DEC, NULL, 0x0,
1767 {&hf_sctp_data_chunk_payload_proto_id,
1768 { "Payload protocol identifier", "sctp.payload_proto_id",
1769 FT_UINT32, BASE_DEC, VALS(sctp_payload_proto_id_values), 0x0,
1772 {&hf_sctp_data_chunk_e_bit,
1773 { "E-Bit", "sctp.data.e_bit",
1774 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,
1777 {&hf_sctp_data_chunk_b_bit,
1778 { "B-Bit", "sctp.data.b_bit",
1779 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,
1782 {&hf_sctp_data_chunk_u_bit,
1783 { "U-Bit", "sctp.data.u.bit",
1784 FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,
1787 {&hf_sctp_sack_chunk_cumulative_tsn_ack,
1788 { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
1789 FT_UINT32, BASE_DEC, NULL, 0x0,
1792 {&hf_sctp_sack_chunk_adv_rec_window_credit,
1793 { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
1794 FT_UINT32, BASE_DEC, NULL, 0x0,
1797 {&hf_sctp_sack_chunk_number_of_gap_blocks,
1798 { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
1799 FT_UINT16, BASE_DEC, NULL, 0x0,
1802 {&hf_sctp_sack_chunk_number_of_dup_tsns,
1803 { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
1804 FT_UINT16, BASE_DEC, NULL, 0x0,
1807 {&hf_sctp_sack_chunk_gap_block_start,
1808 { "Start", "sctp.sack.gap_block_start",
1809 FT_UINT16, BASE_DEC, NULL, 0x0,
1812 {&hf_sctp_sack_chunk_gap_block_end,
1813 { "End", "sctp.sack.gap_block_end",
1814 FT_UINT16, BASE_DEC, NULL, 0x0,
1817 {&hf_sctp_sack_chunk_duplicate_tsn,
1818 { "Duplicate TSN", "sctp.sack.duplicate.tsn",
1819 FT_UINT16, BASE_DEC, NULL, 0x0,
1822 {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1823 { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
1824 FT_UINT32, BASE_DEC, NULL, 0x0,
1827 {&hf_sctp_ecne_chunk_lowest_tsn,
1828 { "Lowest TSN", "sctp.ecne.lowest_tsn",
1829 FT_UINT32, BASE_DEC, NULL, 0x0,
1832 {&hf_sctp_cwr_chunk_lowest_tsn,
1833 { "Lowest TSN", "sctp.cwr.lowest_tsn",
1834 FT_UINT32, BASE_DEC, NULL, 0x0,
1837 {&hf_sctp_shutdown_complete_chunk_t_bit,
1838 { "E-Bit", "sctp.shutdown_complete.t_bit",
1839 FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
1842 {&hf_sctp_chunk_parameter_type,
1843 { "Parameter type", "sctp.parameter.type",
1844 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
1847 {&hf_sctp_chunk_parameter_length,
1848 { "Parameter length", "sctp.parameter.length",
1849 FT_UINT16, BASE_DEC, NULL, 0x0,
1852 {&hf_sctp_parameter_ipv4_address,
1853 { "IP Version 4 address", "sctp.parameter.ipv4_address",
1854 FT_IPv4, BASE_NONE, NULL, 0x0,
1857 {&hf_sctp_parameter_ipv6_address,
1858 { "IP Version 6 address", "sctp.parameter.ipv6_address",
1859 FT_IPv6, BASE_NONE, NULL, 0x0,
1862 {&hf_sctp_parameter_cookie_preservative_increment,
1863 { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
1864 FT_UINT32, BASE_DEC, NULL, 0x0,
1867 {&hf_sctp_parameter_hostname_hostname,
1868 { "Hostname", "sctp.parameter.hostname.hostname",
1869 FT_STRING, BASE_NONE, NULL, 0x0,
1872 {&hf_sctp_supported_address_types_parameter,
1873 { "Supported address type", "sctp.parameter.supported_addres_type",
1874 FT_UINT16, BASE_DEC, NULL, 0x0,
1877 {&hf_sctp_cause_code,
1878 { "Cause code", "sctp.cause.code",
1879 FT_UINT16, BASE_HEX, VALS(sctp_cause_code_values), 0x0,
1882 {&hf_sctp_cause_length,
1883 { "Cause length", "sctp.cause.length",
1884 FT_UINT16, BASE_DEC, NULL, 0x0,
1887 {&hf_sctp_cause_stream_identifier,
1888 { "Stream identifier", "sctp.cause.stream_identifier",
1889 FT_UINT16, BASE_DEC, NULL, 0x0,
1892 {&hf_sctp_cause_number_of_missing_parameters,
1893 { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
1894 FT_UINT32, BASE_DEC, NULL, 0x0,
1897 {&hf_sctp_cause_missing_parameter_type,
1898 { "Missing parameter type", "sctp.cause.missing_parameter_type",
1899 FT_UINT16, BASE_HEX, VALS(sctp_parameter_identifier_values), 0x0,
1902 {&hf_sctp_cause_measure_of_staleness,
1903 { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
1904 FT_UINT32, BASE_DEC, NULL, 0x0,
1907 {&hf_sctp_cause_tsn,
1908 { "TSN", "sctp.cause.tsn",
1909 FT_UINT32, BASE_DEC, NULL, 0x0,
1914 /* Setup protocol subtree array */
1915 static gint *ett[] = {
1918 &ett_sctp_chunk_parameter,
1919 &ett_sctp_chunk_cause,
1920 &ett_sctp_data_chunk_flags,
1921 &ett_sctp_sack_chunk_gap_block,
1922 &ett_sctp_supported_address_types_parameter,
1923 &ett_sctp_unrecognized_parameter_parameter
1926 /* Register the protocol name and description */
1927 proto_sctp = proto_register_protocol("Stream Control Transmission Protocol",
1930 /* Required function calls to register the header fields and subtrees used */
1931 proto_register_field_array(proto_sctp, hf, array_length(hf));
1932 proto_register_subtree_array(ett, array_length(ett));
1934 /* subdissector code */
1935 sctp_port_dissector_table = register_dissector_table("sctp.port");
1936 sctp_ppi_dissector_table = register_dissector_table("sctp.ppi");
1941 proto_reg_handoff_sctp(void)
1943 dissector_add("ip.proto", IP_PROTO_SCTP, dissect_sctp, proto_sctp);