remove incorrect bound check. the check can fail on legal packet, at the
[obnox/wireshark/wip.git] / packet-sctp.c
1 /* packet-sctp.c
2  * Routines for Stream Control Transmission Protocol dissection
3  * Copyright 2000, Michael Tüxen <Michael.Tuexen@icn.siemens.de>
4  *
5  * $Id: packet-sctp.c,v 1.7 2000/11/19 08:54:05 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@unicom.net>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from README.developer
12  * 
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.
17  * 
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.
22  * 
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.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <stdio.h>
33 #include <stdlib.h>
34
35
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
38 #endif
39
40 #ifdef HAVE_NETINET_IN_H
41 # include <netinet/in.h>
42 #endif
43
44 #include <string.h>
45 #include <glib.h>
46
47 #ifdef NEED_SNPRINTF_H
48 # include "snprintf.h"
49 #endif
50
51 #include "packet.h"
52 #include "packet-ip.h"
53
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;
60
61 static int hf_sctp_chunk_type       = -1;
62 static int hf_sctp_chunk_flags      = -1;
63 static int hf_sctp_chunk_length     = -1;
64
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;
70
71 static int hf_sctp_cumulative_tsn_ack = -1;
72
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;
77
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;
81
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;
89
90 static int hf_sctp_shutdown_chunk_cumulative_tsn_ack = -1;
91
92 static int hf_sctp_cwr_chunk_lowest_tsn = -1;
93
94 static int hf_sctp_ecne_chunk_lowest_tsn = -1;
95
96 static int hf_sctp_shutdown_complete_chunk_t_bit = -1;
97
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;
105
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;
109
110 static int hf_sctp_cause_number_of_missing_parameters = -1;
111 static int hf_sctp_cause_missing_parameter_type = -1;
112
113 static int hf_sctp_cause_measure_of_staleness = -1;
114
115 static int hf_sctp_cause_tsn = -1;
116
117 static dissector_table_t sctp_dissector_table;
118
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;
128
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
145
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" },
163   { 0,                               NULL } };
164
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
174
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" },
185   { 0,                                    NULL } };
186
187 #define PARAMETER_TYPE_LENGTH            2
188 #define PARAMETER_LENGTH_LENGTH          2
189 #define PARAMETER_HEADER_LENGTH          (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
190
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)
195
196 #define HEARTBEAT_INFO_PARAMETER_INFO_OFFSET PARAMETER_VALUE_OFFSET
197 #define HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH PARAMETER_HEADER_LENGTH
198
199 #define IPV4_ADDRESS_LENGTH              4
200 #define IPV6_ADDRESS_LENGTH              16
201
202 #define STATE_COOKIE_PARAMETER_HEADER_LENGTH   PARAMETER_HEADER_LENGTH
203 #define STATE_COOKIE_PARAMETER_COOKIE_OFFSET   PARAMETER_VALUE_OFFSET
204
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
208
209 #define CAUSE_CODE_LENGTH            2
210 #define CAUSE_LENGTH_LENGTH          2
211 #define CAUSE_HEADER_LENGTH          (CAUSE_CODE_LENGTH + CAUSE_LENGTH_LENGTH)
212
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)
217
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)
222
223 #define CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH 4
224 #define CAUSE_MISSING_PARAMETER_TYPE_LENGTH       2
225
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 )
229
230 #define CAUSE_MEASURE_OF_STALENESS_LENGTH 4
231 #define CAUSE_MEASURE_OF_STALENESS_OFFSET CAUSE_INFO_OFFSET
232
233 #define CAUSE_TSN_LENGTH 4
234 #define CAUSE_TSN_OFFSET CAUSE_INFO_OFFSET
235
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
246
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" },
258   { 0,                           NULL } };
259
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 + \
268                                  CHECKSUM_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)
273
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 + \
280                                        CHUNK_LENGTH_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)
286
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
292
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)
301
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)
307
308 #define SCTP_DATA_CHUNK_E_BIT 0x01
309 #define SCTP_DATA_CHUNK_B_BIT 0x02
310 #define SCTP_DATA_CHUNK_U_BIT 0x04
311
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
317
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 )
329
330
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
339
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)
349
350 #define HEARTBEAT_CHUNK_INFO_OFFSET CHUNK_VALUE_OFFSET
351
352 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET CHUNK_VALUE_OFFSET
353 #define SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
354                 
355 #define ABORT_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4     
356 #define ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET 4     
357
358 #define COOKIE_ECHO_CHUNK_COOKIE_OFFSET CHUNK_VALUE_OFFSET
359
360 #define ECNE_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
361 #define ECNE_CHUNK_LOWEST_TSN_LENGTH 4
362
363 #define CWR_CHUNK_LOWEST_TSN_OFFSET CHUNK_VALUE_OFFSET
364 #define CWR_CHUNK_LOWEST_TSN_LENGTH 4
365                      
366 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT 0x01
367
368 static const true_false_string sctp_data_chunk_e_bit_value = {
369   "Last segment",
370   "Not the last segment"
371 };
372
373 static const true_false_string sctp_data_chunk_b_bit_value = {
374   "First segment",
375   "Subsequent segment"
376 };
377
378 static const true_false_string sctp_data_chunk_u_bit_value = {
379   "Unordered delivery",
380   "Ordered deliviery"
381 };
382
383 static const true_false_string sctp_shutdown_complete_chunk_t_bit_value = {
384   "No TCB destroyed",
385   "TCB destroyed"
386 };
387
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/
392  *
393  * It was modified for the use in this dissector.
394  */
395
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 */
399
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);
405
406 unsigned int sctp_adler_32(const unsigned char* buf,
407                                  unsigned int len)
408 {
409     unsigned int s1 = 1L;
410     unsigned int s2 = 0L;
411     int k;
412     
413     /* handle the first 8 bytes of the datagram */
414     DO8(buf,0);
415     buf += SOURCE_PORT_LENGTH + 
416            DESTINATION_PORT_LENGTH + 
417            VERIFICATION_TAG_LENGTH;
418     
419     /* handle four 0 bytes as checksum */
420     s2  += CHECKSUM_LENGTH * s1;
421     buf += CHECKSUM_LENGTH;
422
423     /* now we have 12 bytes handled */
424     len -= COMMON_HEADER_LENGTH;
425
426     /* handle the rest of the datagram */
427     while (len > 0) {
428         k = len < NMAX ? len : NMAX;
429         len -= k;
430         while (k >= 16) {
431             DO16(buf);
432             buf += 16;
433             k -= 16;
434         }
435         if (k != 0) do {
436             s1 += *buf++;
437             s2 += s1;
438         } while (--k);
439         s1 %= BASE;
440         s2 %= BASE;
441     }
442     return (s2 << 16) | s1;
443 }
444
445 static char *sctp_checksum_state(tvbuff_t *tvb, guint orig_checksum)
446 {
447   guint length;
448   
449   length = tvb_length(tvb);
450   if (orig_checksum == sctp_adler_32(tvb_get_ptr(tvb, 0, length), length))
451     return "correct";
452   else
453     return "incorrect";
454 }
455
456 guint 
457 nr_of_padding_bytes (guint length)
458 {
459   guint remainder;
460
461   remainder = length % 4;
462
463   if (remainder == 0)
464     return 0;
465   else
466     return 4 - remainder;
467 }
468
469 /* 
470  * TLV parameter stuff for INIT and INIT-ACK chunks
471  */
472
473 void
474 dissect_parameter(tvbuff_t *, proto_tree *);
475
476 void
477 dissect_sctp_chunk(tvbuff_t *, packet_info *, proto_tree *, proto_tree *);
478
479 void dissect_tlv_parameter_list(tvbuff_t *parameter_list_tvb, proto_tree *tree)
480 {
481   guint offset, length, padding_length, total_length;
482   tvbuff_t *parameter_tvb;
483
484   offset = 0;
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;
494   }
495 }
496
497 void
498 dissect_heartbeat_info_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
499 {
500   guint16 length, heartbeat_info_length;
501   
502   length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
503   
504   heartbeat_info_length = length - HEARTBEAT_INFO_PARAMETER_HEADER_LENGTH;
505
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"));
509
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"));
512 }
513
514 void
515 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
516 {
517   guint32 ipv4_address;
518
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,
522                       ipv4_address);  
523   proto_item_set_text(parameter_item, "IPV4 address parameter");
524 }
525
526 void
527 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
528 {
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));
532   
533   proto_item_set_text(parameter_item, "IPV6 address parameter");
534 }
535
536 void
537 dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
538 {
539   guint16 length, state_cookie_length;
540   
541   length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
542   
543   state_cookie_length = length - STATE_COOKIE_PARAMETER_HEADER_LENGTH;
544
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"));
548
549   proto_item_set_text(parameter_item, "State Cookie Parameter with %u byte%s cookie",
550                       state_cookie_length, plurality(state_cookie_length, "", "s"));
551 }
552
553 void
554 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
555 {
556   guint16 length, parameter_value_length;
557   tvbuff_t *unrecognized_parameters_tvb;
558
559   length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
560   
561   parameter_value_length = length - PARAMETER_HEADER_LENGTH;
562
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);
566    
567   proto_item_set_text(parameter_item, "Unrecognized parameter of type");
568 }
569
570 void
571 dissect_cookie_preservative_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
572 {
573   guint32 increment;
574
575   increment =  tvb_get_ntohl(parameter_tvb, COOKIE_PRESERVATIVE_PARAMETER_INCR_OFFSET);
576   
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,
580                       increment);
581   
582   proto_item_set_text(parameter_item, "Cookie preservative parameter requesting for a %u msec increment",
583                       increment);
584 }
585
586 void
587 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
588 {
589   guint16  length, hostname_length;
590   char *hostname;
591
592   length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
593   
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,
598                         hostname);
599
600   proto_item_set_text(parameter_item, "Hostname parameter");
601 }
602
603 void
604 dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
605 {
606   guint16 length, address_type, number_of_address_types, address_type_number, list_of_address_types_length ;
607   guint offset;
608   proto_item *address_list_item;
609   proto_tree *address_list_tree;
610
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;
614
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);
619  
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;
628   };
629
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"));
632 }
633
634 void
635 dissect_ecn_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
636 {
637    proto_item_set_text(parameter_item, "ECN parameter");
638 }
639
640 void
641 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
642 {
643   guint16 type, length, parameter_value_length;
644   
645   type   = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
646   length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
647   
648   parameter_value_length = length - PARAMETER_HEADER_LENGTH;
649
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"));
653
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"));
656 }
657
658 void
659 dissect_parameter(tvbuff_t *parameter_tvb, proto_tree *chunk_tree)
660 {
661   guint16 type, length, padding_length, total_length;
662   proto_item *parameter_item;
663   proto_tree *parameter_tree;
664
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;
669    
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);
672  
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,
679                       length);
680  
681   switch(type) {
682   case HEARTBEAT_INFO_PARAMETER_ID:
683     dissect_heartbeat_info_parameter(parameter_tvb, parameter_tree, parameter_item);
684     break;
685   case IPV4ADDRESS_PARAMETER_ID:
686     dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
687     break;
688   case IPV6ADDRESS_PARAMETER_ID:
689     dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
690     break;
691   case STATE_COOKIE_PARAMETER_ID:
692     dissect_state_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
693     break;
694   case UNREC_PARA_PARAMETER_ID:
695     dissect_unrecognized_parameters_parameter(parameter_tvb, parameter_tree, parameter_item);
696     break;
697   case COOKIE_PRESERVATIVE_PARAMETER_ID:
698     dissect_cookie_preservative_parameter(parameter_tvb, parameter_tree, parameter_item);
699     break;
700   case HOSTNAME_ADDRESS_PARAMETER_ID:
701     dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item);
702     break;
703   case SUPPORTED_ADDRESS_TYPES_PARAMETER_ID:
704     dissect_supported_address_types_parameter(parameter_tvb, parameter_tree, parameter_item);
705     break;
706   case ECN_PARAMETER_ID:
707     dissect_ecn_parameter(parameter_tvb, parameter_tree, parameter_item);
708     break;
709   default:
710     dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
711     break;
712   };
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"));
717 }
718
719 /*
720  * Code to handle error causes for ABORT and ERROR chunks
721  */
722 void
723 dissect_invalid_stream_identifier_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
724 {
725   guint16 stream_identifier;
726
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,
730                       stream_identifier);
731   proto_tree_add_text(cause_tree, cause_tvb, CAUSE_RESERVED_OFFSET, CAUSE_RESERVED_LENGTH,
732                       "Reserved (2 bytes)");
733
734   proto_item_set_text(cause_item, "Error cause reporting invalid stream identifier %u",
735                       stream_identifier);
736 }
737
738 void
739 dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
740 {
741   guint32 number_of_missing_parameters, missing_parameter_number;
742   guint16 parameter_type;
743   guint   offset;
744
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)",
755                                parameter_type, 
756                                val_to_str(parameter_type, sctp_parameter_identifier_values, "unknown"));
757     offset +=  CAUSE_MISSING_PARAMETER_TYPE_LENGTH;
758   };
759
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") );
762 }
763
764 void
765 dissect_stale_cookie_error_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
766 {
767   guint32 measure_of_staleness;
768
769   measure_of_staleness =  tvb_get_ntohl(cause_tvb, CAUSE_MEASURE_OF_STALENESS_OFFSET);
770   
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);
775   
776   proto_item_set_text(cause_item, "Error cause reporting a measure of staleness of %u usec",
777                       measure_of_staleness);
778 }
779
780 void
781 dissect_out_of_resource_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
782 {
783   proto_item_set_text(cause_item, "Error cause reporting lack of resources");
784 }
785
786 void
787 dissect_unresolvable_address_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
788 {
789   guint16 code, length, parameter_length, parameter_type;
790   tvbuff_t *parameter_tvb;
791
792   code   = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
793   length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
794   
795   parameter_length = length - CAUSE_HEADER_LENGTH;
796   parameter_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, 
797                                  parameter_length, parameter_length);
798
799   dissect_parameter(parameter_tvb, cause_tree);
800   parameter_type = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
801  
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") );
804 }
805
806 void
807 dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb,  packet_info *pinfo, 
808                                       proto_tree *cause_tree, proto_item *cause_item)
809 {
810   guint16 length, chunk_length;
811   guint8 unrecognized_type;
812   tvbuff_t *unrecognized_chunk_tvb;
813
814   length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
815   
816   chunk_length = length - CAUSE_HEADER_LENGTH;
817
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);
821
822   unrecognized_type   = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET);
823  
824   proto_item_set_text(cause_item, "Error cause reporting unrecognized chunk of type %u (%s)",
825                       unrecognized_type,
826                       val_to_str(unrecognized_type, sctp_chunk_type_values, "unknown"));
827 }
828
829 void
830 dissect_invalid_mandatory_parameter_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
831 {
832   proto_item_set_text(cause_item, "Error cause reporting an invalid mandatory parameter");
833 }
834
835 void
836 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
837 {
838   guint16 length, cause_info_length;
839   tvbuff_t *unrecognized_parameters_tvb;
840
841   length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
842   
843   cause_info_length = length - CAUSE_HEADER_LENGTH;
844
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);
848  
849   proto_item_set_text(cause_item, "Error cause reporting unrecognized parameters");
850 }
851
852 void
853 dissect_no_user_data_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
854 {
855   guint32 tsn;
856
857   tsn = tvb_get_ntohl(cause_tvb, CAUSE_TSN_OFFSET);
858   proto_tree_add_uint(cause_tree, hf_sctp_cause_tsn, cause_tvb, 
859                       CAUSE_TSN_OFFSET, 
860                       CAUSE_TSN_LENGTH,
861                       tsn);
862
863   proto_item_set_text(cause_item, "Error cause reporting data chunk with TSN %u contains no data",
864                       tsn);
865 }
866
867 void
868 dissect_cookie_received_while_shutting_down_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
869 {
870   proto_item_set_text(cause_item, "Error cause reporting cookie reception while shutting down");
871 }
872
873 void
874 dissect_unknown_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
875 {
876   guint16 code, length, cause_info_length;
877
878   code   = tvb_get_ntohs(cause_tvb, CAUSE_CODE_OFFSET);
879   length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
880   
881   cause_info_length = length - CAUSE_HEADER_LENGTH;
882
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"));
886
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"));
889 }
890
891 void
892 dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_tree)
893 {
894   guint16 code, length, padding_length, total_length;
895   proto_item *cause_item;
896   proto_tree *cause_tree;
897
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;
902   
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);
906  
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,
913                       length);
914  
915   switch(code) {
916   case INVALID_STREAM_IDENTIFIER:
917     dissect_invalid_stream_identifier_cause(cause_tvb, cause_tree, cause_item);
918     break;
919   case MISSING_MANDATORY_PARAMETERS:
920     dissect_missing_mandatory_parameters_cause(cause_tvb, cause_tree, cause_item);
921     break;
922   case STALE_COOKIE_ERROR:
923     dissect_stale_cookie_error_cause(cause_tvb, cause_tree, cause_item);
924     break;
925   case OUT_OF_RESOURCE:
926     dissect_out_of_resource_cause(cause_tvb, cause_tree, cause_item);
927     break;
928   case UNRESOLVABLE_ADDRESS:
929     dissect_unresolvable_address_cause(cause_tvb, cause_tree, cause_item);
930     break;
931   case UNRECOGNIZED_CHUNK_TYPE:
932     dissect_unrecognized_chunk_type_cause(cause_tvb, pinfo, cause_tree, cause_item);
933     break;
934   case INVALID_MANDATORY_PARAMETER:
935     dissect_invalid_mandatory_parameter_cause(cause_tvb, cause_tree, cause_item);
936     break;
937   case UNRECOGNIZED_PARAMETERS:
938     dissect_unrecognized_parameters_cause(cause_tvb, cause_tree, cause_item);
939     break;
940   case NO_USER_DATA:
941     dissect_no_user_data_cause(cause_tvb, cause_tree, cause_item);
942     break;
943   case COOKIE_RECEIVED_WHILE_SHUTTING_DOWN:
944     dissect_cookie_received_while_shutting_down_cause(cause_tvb, cause_tree, cause_item);
945     break;
946   default:
947     dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
948     break;
949   };
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"));
954 }
955
956 /*
957  * Code to actually dissect the packets 
958 */
959
960 static void
961 dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
962                 proto_tree *chunk_tree, guint16 payload_length, guint16 padding_length)
963 {
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))
967     return;
968   else {
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"));
976   }
977 }
978
979
980
981
982
983 static void
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)
986
987   guint8  flags;
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;
992
993   flags             = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
994   length            = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
995    
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);
1003
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);
1008   
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);
1014    
1015   proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_tsn, 
1016                       chunk_tvb,
1017                       DATA_CHUNK_TSN_OFFSET, DATA_CHUNK_TSN_LENGTH,
1018                       tsn);
1019   proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_id, 
1020                       chunk_tvb, 
1021                       DATA_CHUNK_STREAM_ID_OFFSET, DATA_CHUNK_STREAM_ID_LENGTH,
1022                       stream_id);
1023   proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_stream_seq_number, 
1024                       chunk_tvb, 
1025                       DATA_CHUNK_STREAM_SEQ_NUMBER_OFFSET, DATA_CHUNK_STREAM_SEQ_NUMBER_LENGTH,
1026                       stream_seq_number);
1027   proto_tree_add_uint(chunk_tree, hf_sctp_data_chunk_payload_proto_id, 
1028                       chunk_tvb,
1029                       DATA_CHUNK_PAYLOAD_PROTOCOL_ID_OFFSET, DATA_CHUNK_PAYLOAD_PROTOCOL_ID_LENGTH,
1030                       payload_proto_id);
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"));
1034
1035   dissect_payload(payload_tvb, pinfo, tree, chunk_tree, payload_length, padding_length);
1036
1037
1038 void
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)
1041
1042   guint32 initiate_tag, adv_rec_window_credit, initial_tsn;
1043   guint16 number_of_inbound_streams, number_of_outbound_streams;
1044   guint8  type;
1045   tvbuff_t *parameter_list_tvb;
1046
1047   type                       = tvb_get_guint8(chunk_tvb, CHUNK_TYPE_OFFSET);
1048  
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);
1054
1055   /* handle fixed parameters */
1056   proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_initiate_tag, 
1057                       chunk_tvb,
1058                       INIT_CHUNK_INITIATE_TAG_OFFSET, INIT_CHUNK_INITIATE_TAG_LENGTH,
1059                       initiate_tag);
1060   proto_tree_add_uint(chunk_tree, hf_sctp_init_chunk_adv_rec_window_credit, 
1061                       chunk_tvb,
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, 
1065                       chunk_tvb,
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, 
1069                       chunk_tvb,
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, 
1073                       chunk_tvb,
1074                       INIT_CHUNK_INITIAL_TSN_OFFSET, INIT_CHUNK_INITIAL_TSN_LENGTH,
1075                       initial_tsn);
1076   
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);
1080
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"));
1086
1087
1088 void
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)
1091
1092   dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1093
1094
1095 void
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)
1098
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;
1105
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);
1110   
1111   proto_tree_add_uint(chunk_tree, hf_sctp_sack_chunk_cumulative_tsn_ack, 
1112                       chunk_tvb,
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, 
1116                       chunk_tvb,
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, 
1120                       chunk_tvb,
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, 
1124                       chunk_tvb,
1125                       SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET, SACK_CHUNK_NUMBER_OF_DUP_TSNS_LENGTH,
1126                       number_of_dup_tsns);
1127   
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, 
1139                         chunk_tvb,
1140                         gap_block_offset, SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1141                         start);
1142     proto_tree_add_uint(block_tree, hf_sctp_sack_chunk_gap_block_end, 
1143                         chunk_tvb,
1144                         gap_block_offset + SACK_CHUNK_GAP_BLOCK_START_LENGTH,
1145                         SACK_CHUNK_GAP_BLOCK_END_LENGTH,
1146                         end);
1147     gap_block_offset += SACK_CHUNK_GAP_BLOCK_LENGTH;
1148   };
1149   
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, 
1155                         chunk_tvb,
1156                         dup_tsn, SACK_CHUNK_DUP_TSN_LENGTH,
1157                         dup_tsn);
1158     dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH;
1159   };
1160
1161   proto_item_set_text(chunk_item, 
1162                       "SACK chunk acknowledging TSN %u and reporting %u gap%s and %u duplicate TSN%s",
1163                       cumulative_tsn_ack,
1164                       number_of_gap_blocks, plurality(number_of_gap_blocks, "", "s"),
1165                       number_of_dup_tsns, plurality(number_of_dup_tsns, "", "s"));
1166
1167
1168 void
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)
1171 {
1172   tvbuff_t   *parameter_tvb;
1173   guint chunk_length, info_length, padding_length, total_length;
1174
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);
1180     
1181   dissect_parameter(parameter_tvb, chunk_tree);
1182
1183   proto_item_set_text(chunk_item, "HEARTBEAT chunk");
1184 }
1185  
1186 void
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)
1189 {  
1190   tvbuff_t   *parameter_tvb;
1191   guint chunk_length, info_length, padding_length, total_length;
1192
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;
1197
1198   parameter_tvb  = tvb_new_subset(chunk_tvb, HEARTBEAT_CHUNK_INFO_OFFSET, total_length, total_length);
1199     
1200   dissect_parameter(parameter_tvb, chunk_tree);
1201
1202   proto_item_set_text(chunk_item, "HEARTBEAT ACK chunk");
1203
1204
1205 void
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)
1208 {
1209   guint offset, number_of_causes;
1210   guint16 length, padding_length, total_length;
1211   tvbuff_t *cause_tvb;
1212
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;
1224     number_of_causes++;
1225   };
1226
1227   proto_item_set_text(chunk_item, "Abort chunk with %u cause%s",
1228                       number_of_causes, plurality(number_of_causes, "", "s"));
1229
1230
1231 void
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)
1234
1235   guint32 cumulative_tsn_ack;
1236
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, 
1239                       chunk_tvb,
1240                       SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_OFFSET,
1241                       SHUTDOWN_CHUNK_CUMULATIVE_TSN_ACK_LENGTH,
1242                       cumulative_tsn_ack);
1243
1244   proto_item_set_text(chunk_item, "SHUTDOWN chunk acknowledging up to TSN %u",
1245                       cumulative_tsn_ack);
1246
1247
1248 void
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)
1251
1252   proto_item_set_text(chunk_item, "SHUTDOWN ACK chunk");
1253
1254
1255 void
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)
1258
1259   guint offset, number_of_causes;
1260   guint16 length, padding_length, total_length;
1261   tvbuff_t *cause_tvb;
1262   
1263   number_of_causes = 0;
1264   offset = ERROR_CHUNK_FIRST_ERROR_CAUSE_OFFSET;
1265   do {
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;
1274     number_of_causes++;
1275   } while(tvb_length_remaining(chunk_tvb, offset));
1276
1277   proto_item_set_text(chunk_item, "Error chunk with %u cause%s",
1278                       number_of_causes, plurality(number_of_causes, "", "s"));
1279
1280
1281 void
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)
1284
1285   guint length, cookie_length, padding_length;
1286
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;
1290   
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"));
1296
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"));
1301
1302
1303 void
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)
1306
1307   proto_item_set_text(chunk_item, "COOKIE ACK chunk");
1308
1309
1310 void
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)
1313
1314   guint32 lowest_tsn;
1315
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, 
1318                       chunk_tvb,
1319                       ECNE_CHUNK_LOWEST_TSN_OFFSET, ECNE_CHUNK_LOWEST_TSN_LENGTH,
1320                       lowest_tsn);
1321
1322   proto_item_set_text(chunk_item, "ECNE chunk");
1323
1324
1325 void
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)
1328
1329   guint32 lowest_tsn;
1330
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, 
1333                       chunk_tvb,
1334                       CWR_CHUNK_LOWEST_TSN_OFFSET, CWR_CHUNK_LOWEST_TSN_LENGTH,
1335                       lowest_tsn);
1336
1337   proto_item_set_text(chunk_item, "CWR chunk");
1338
1339
1340 void
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)
1343
1344   guint8  flags;
1345   guint16 length;
1346   proto_tree *flag_tree;
1347
1348   flags             = tvb_get_guint8(chunk_tvb, CHUNK_FLAGS_OFFSET);
1349   length            = tvb_get_ntohs(chunk_tvb, CHUNK_LENGTH_OFFSET);
1350
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);
1354
1355   proto_item_set_text(chunk_item, "SHUTDOWN COMPLETE chunk");
1356
1357
1358 void
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)
1361
1362   guint length, chunk_value_length, padding_length;
1363   guint8 type;
1364
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);
1368  
1369   chunk_value_length = length - CHUNK_HEADER_LENGTH;
1370   
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"));
1374   
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"));
1379    
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"));
1382
1383  
1384
1385
1386
1387 void
1388 dissect_sctp_chunk(tvbuff_t *chunk_tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1389 {  
1390   guint8 type, flags;
1391   guint16 length;
1392   proto_item *flags_item;
1393   proto_item *chunk_item;
1394   proto_tree *chunk_tree;
1395
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);
1400
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);
1405   
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,
1413                       flags);
1414   proto_tree_add_uint(chunk_tree, hf_sctp_chunk_length, 
1415                       chunk_tvb, CHUNK_LENGTH_OFFSET, CHUNK_LENGTH_LENGTH,
1416                       length);
1417   
1418   /* now dissect the chunk value */
1419   switch(type) {
1420   case SCTP_DATA_CHUNK_ID:
1421     dissect_data_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1422     break;
1423   case SCTP_INIT_CHUNK_ID:
1424     dissect_init_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1425     break;
1426   case SCTP_INIT_ACK_CHUNK_ID:
1427     dissect_init_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1428     break;
1429   case SCTP_SACK_CHUNK_ID:
1430     dissect_sack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1431     break; 
1432   case SCTP_HEARTBEAT_CHUNK_ID:
1433     dissect_heartbeat_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1434     break;
1435   case SCTP_HEARTBEAT_ACK_CHUNK_ID:
1436     dissect_heartbeat_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1437     break;
1438   case SCTP_ABORT_CHUNK_ID:
1439     dissect_abort_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1440     break;
1441   case SCTP_SHUTDOWN_CHUNK_ID:
1442     dissect_shutdown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1443     break;
1444   case SCTP_SHUTDOWN_ACK_CHUNK_ID:
1445     dissect_shutdown_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1446     break;
1447   case SCTP_ERROR_CHUNK_ID:
1448     dissect_error_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1449     break;
1450   case SCTP_COOKIE_ECHO_CHUNK_ID:
1451     dissect_cookie_echo_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1452     break;
1453   case SCTP_COOKIE_ACK_CHUNK_ID:
1454     dissect_cookie_ack_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1455     break;
1456   case SCTP_ECNE_CHUNK_ID:
1457     dissect_ecne_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1458     break;
1459   case SCTP_CWR_CHUNK_ID:
1460     dissect_cwr_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1461     break;
1462   case SCTP_SHUTDOWN_COMPLETE_CHUNK_ID:
1463     dissect_shutdown_complete_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1464     break;
1465   default:
1466     dissect_unknown_chunk(chunk_tvb, pinfo, tree, chunk_tree, chunk_item, flags_item);
1467     break;
1468   }  
1469 }
1470
1471 void
1472 dissect_sctp_chunks(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sctp_tree)
1473
1474   tvbuff_t *chunk_tvb;
1475   guint16 length, padding_length, total_length;
1476   gint offset;
1477   
1478   /* the common header of the datagram is already handled */
1479   offset = COMMON_HEADER_LENGTH;
1480
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;
1492   }
1493 }
1494
1495
1496
1497 /* dissect_sctp handles the common header of a SCTP datagram.
1498  * For the handling of the chunks dissect_sctp_chunks is called.
1499  */
1500
1501 static void
1502 dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1503 {
1504   guint16 source_port, destination_port;
1505   guint32 verification_tag, checksum;
1506   proto_item *ti;
1507   proto_tree *sctp_tree;
1508
1509   CHECK_DISPLAY_AS_DATA(proto_sctp, tvb, pinfo, tree);
1510
1511   pinfo->current_proto = "SCTP";
1512
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);
1518
1519   /* update pi structure */
1520   pi.ptype = PT_SCTP;
1521   pi.srcport = source_port;
1522   pi.destport = destination_port;
1523
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");
1527
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);
1532   
1533   /* In the interest of speed, if "tree" is NULL, don't do any work not
1534      necessary to generate protocol tree items. */
1535   if (tree) {
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);
1540
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,
1544                         source_port);
1545     proto_tree_add_uint(sctp_tree, hf_sctp_destination_port,
1546                         tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH,
1547                         destination_port);
1548     proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag,
1549                         tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH,
1550                         verification_tag);
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));
1555     
1556     /* add all chunks of the sctp datagram to the protocol tree */
1557     dissect_sctp_chunks(tvb, pinfo, tree, sctp_tree);
1558   };
1559 }
1560
1561 /* Register the protocol with Ethereal */
1562 void
1563 proto_register_sctp(void)
1564 {                 
1565
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,          
1571         ""}
1572     },
1573     { &hf_sctp_destination_port,
1574       { "Destination port", "sctp.dstport",
1575         FT_UINT16, BASE_DEC, NULL, 0x0,          
1576         ""}
1577     }, 
1578     { &hf_sctp_verification_tag,
1579       { "Verification tag", "sctp.verfication_tag",
1580         FT_UINT32, BASE_HEX, NULL, 0x0,          
1581         ""}
1582     },
1583     { &hf_sctp_checksum,
1584       { "Adler-32 checksum", "sctp.checksum",
1585         FT_UINT32, BASE_HEX, NULL, 0x0,          
1586         ""}
1587     },
1588     { &hf_sctp_chunk_type,
1589       { "Identifier", "sctp.chunk_type",
1590         FT_UINT8, BASE_DEC, NULL, 0x0,          
1591         ""}
1592     },
1593     { &hf_sctp_chunk_flags,
1594       { "Flags", "sctp.chunk_flags",
1595         FT_UINT8, BASE_BIN, NULL, 0x0,          
1596         ""}
1597     },
1598     { &hf_sctp_chunk_length,
1599       { "Length", "sctp.chunk_length",
1600         FT_UINT16, BASE_DEC, NULL, 0x0,          
1601         ""}
1602     },
1603     { &hf_sctp_init_chunk_initiate_tag,
1604       { "Initiate tag", "sctp.init.chunk.initiate.tag",
1605         FT_UINT32, BASE_HEX, NULL, 0x0,          
1606         ""}
1607     },
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,          
1611         ""}
1612     },
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,          
1616         ""}
1617     },
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,          
1621         ""}
1622     },
1623     {&hf_sctp_init_chunk_initial_tsn,
1624       { "Initial TSN", "sctp.init.chunk.initial.tsn",
1625         FT_UINT32, BASE_DEC, NULL, 0x0,          
1626         ""}
1627     }, 
1628     {&hf_sctp_cumulative_tsn_ack,
1629      { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
1630         FT_UINT32, BASE_DEC, NULL, 0x0,          
1631         ""}
1632     },
1633     {&hf_sctp_data_chunk_tsn,
1634      { "TSN", "sctp.tsn",
1635        FT_UINT32, BASE_DEC, NULL, 0x0,          
1636         ""}
1637     },
1638     {&hf_sctp_data_chunk_stream_id,
1639      { "Stream Identifier", "sctp.stream_id",
1640         FT_UINT16, BASE_HEX, NULL, 0x0,          
1641         ""}
1642     },
1643     {&hf_sctp_data_chunk_stream_seq_number,
1644      { "Stream sequence number", "sctp.stream_seq_number",
1645        FT_UINT16, BASE_DEC, NULL, 0x0,          
1646        ""}
1647     },
1648     {&hf_sctp_data_chunk_payload_proto_id,
1649      { "Payload Protocol identifier", "sctp.payload_proto_id",
1650         FT_UINT32, BASE_HEX, NULL, 0x0,          
1651         ""}
1652     },
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,          
1656        ""}
1657     },
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,          
1661        ""}
1662     },
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,          
1666        ""}
1667     },
1668     {&hf_sctp_sack_chunk_cumulative_tsn_ack,
1669      { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
1670        FT_UINT32, BASE_DEC, NULL, 0x0,          
1671        ""}
1672     }, 
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,          
1676        ""}
1677     },
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,          
1681        ""}
1682     }, 
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,          
1686        ""}
1687     },
1688     {&hf_sctp_sack_chunk_gap_block_start,
1689      { "Start", "sctp.sack.gap_block_start",
1690        FT_UINT16, BASE_DEC, NULL, 0x0,          
1691        ""}
1692     },
1693     {&hf_sctp_sack_chunk_gap_block_end,
1694      { "End", "sctp.sack.gap_block_end",
1695        FT_UINT16, BASE_DEC, NULL, 0x0,          
1696        ""}
1697     },
1698     {&hf_sctp_sack_chunk_duplicate_tsn,
1699      { "Duplicate TSN", "sctp.sack.duplicate.tsn",
1700        FT_UINT16, BASE_DEC, NULL, 0x0,          
1701        ""}
1702     },  
1703     {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
1704      { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
1705         FT_UINT32, BASE_DEC, NULL, 0x0,          
1706         ""}
1707     },
1708     {&hf_sctp_ecne_chunk_lowest_tsn,
1709      { "Lowest TSN", "sctp.ecne.lowest_tsn",
1710        FT_UINT32, BASE_DEC, NULL, 0x0,          
1711        ""}
1712     }, 
1713     {&hf_sctp_cwr_chunk_lowest_tsn,
1714      { "Lowest TSN", "sctp.cwr.lowest_tsn",
1715        FT_UINT32, BASE_DEC, NULL, 0x0,          
1716        ""}
1717     }, 
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,
1721        ""}
1722     },
1723     {&hf_sctp_chunk_parameter_type,
1724      { "Parameter type", "sctp.parameter.type",
1725        FT_UINT16, BASE_HEX, NULL, 0x0,          
1726        ""}
1727     },
1728     {&hf_sctp_chunk_parameter_length,
1729      { "Parameter length", "sctp.parameter.length",
1730        FT_UINT16, BASE_DEC, NULL, 0x0,          
1731        ""}
1732     },
1733     {&hf_sctp_parameter_ipv4_address,
1734      { "IP Version 4 address", "sctp.parameter.ipv4_address",
1735        FT_IPv4, BASE_NONE, NULL, 0x0,
1736        ""}
1737     },
1738     {&hf_sctp_parameter_ipv6_address,
1739      { "IP Version 6 address", "sctp.parameter.ipv6_address",
1740        FT_IPv6, BASE_NONE, NULL, 0x0,
1741        ""}
1742     },
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,          
1746        ""}
1747     },
1748     {&hf_sctp_parameter_hostname_hostname,
1749      { "Hostname", "sctp.parameter.hostname.hostname",
1750        FT_STRING, BASE_NONE, NULL, 0x0,          
1751        ""}
1752     }, 
1753     {&hf_sctp_supported_address_types_parameter,
1754      { "Supported address type", "sctp.parameter.supported_addres_type",
1755        FT_UINT16, BASE_DEC, NULL, 0x0,          
1756        ""}
1757     }, 
1758     {&hf_sctp_cause_code,
1759      { "Cause code", "sctp.cause.code",
1760        FT_UINT16, BASE_DEC, NULL, 0x0,          
1761        ""}
1762     },
1763     {&hf_sctp_cause_length,
1764      { "Cause length", "sctp.cause.length",
1765        FT_UINT16, BASE_DEC, NULL, 0x0,          
1766        ""}
1767     }, 
1768     {&hf_sctp_cause_stream_identifier,
1769      { "Stream identifier", "sctp.cause.stream_identifier",
1770        FT_UINT16, BASE_DEC, NULL, 0x0,          
1771        ""}
1772     },
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,          
1776        ""}
1777     }, 
1778     {&hf_sctp_cause_missing_parameter_type,
1779      { "Missing parameters type", "sctp.cause.missing_parameter_type",
1780        FT_UINT16, BASE_DEC, NULL, 0x0,          
1781        ""}
1782     },
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,          
1786        ""}
1787     },
1788     {&hf_sctp_cause_tsn,
1789      { "TSN", "sctp.cause.tsn",
1790        FT_UINT32, BASE_DEC, NULL, 0x0,          
1791        ""}
1792     },
1793   };
1794   
1795   /* Setup protocol subtree array */
1796   static gint *ett[] = {
1797     &ett_sctp,
1798     &ett_sctp_chunk,
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
1805   };
1806   
1807   /* Register the protocol name and description */
1808   proto_sctp = proto_register_protocol("Stream Control Transmission Protcol",
1809                                        "sctp");
1810   
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));
1814
1815   /* subdissector code */
1816   sctp_dissector_table = register_dissector_table("sctp.port");
1817
1818 };
1819
1820 void
1821 proto_reg_handoff_sctp(void)
1822 {
1823         dissector_add("ip.proto", IP_PROTO_SCTP, dissect_sctp);
1824 }