* - RFC 2960, for basic SCTP support
* - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-addip-sctp-03.txt for the add-IP extension
* - http://www.sctp.org/draft-ietf-tsvwg-usctp-01.txt for the 'Limited Retransmission' extension
- * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpcsum-01.txt
+ * - http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpcsum-03.txt
* Copyright 2000, 2001, 2002, Michael Tuexen <Michael.Tuexen@icn.siemens.de>
* Still to do (so stay tuned)
* - support for reassembly
* - code cleanup
*
- * $Id: packet-sctp.c,v 1.29 2002/01/20 22:28:50 guy Exp $
+ * $Id: packet-sctp.c,v 1.33 2002/03/03 22:42:08 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
#endif
#include "prefs.h"
-#include "packet.h"
+#include <epan/packet.h>
#include "ipproto.h"
/* Initialize the protocol and registered fields */
static int proto_sctp = -1;
+static int hf_sctp_port = -1;
static int hf_sctp_source_port = -1;
static int hf_sctp_destination_port = -1;
static int hf_sctp_verification_tag = -1;
static int hf_sctp_checksum = -1;
-static int hf_sctp_checksum_correct = -1;
+static int hf_sctp_checksum_bad = -1;
static int hf_sctp_chunk_type = -1;
static int hf_sctp_chunk_flags = -1;
{
unsigned int i;
unsigned long crc32 = ~0L;
-
+ unsigned long result;
+ unsigned char byte0,byte1,byte2,byte3;
+
for (i = 0; i < SOURCE_PORT_LENGTH + DESTINATION_PORT_LENGTH + VERIFICATION_TAG_LENGTH; i++)
{
CRC32C(crc32, buf[i]);
{
CRC32C(crc32, buf[i]);
}
- return crc32;
+ result = ~crc32;
+
+ byte0 = result & 0xff;
+ byte1 = (result>>8) & 0xff;
+ byte2 = (result>>16) & 0xff;
+ byte3 = (result>>24) & 0xff;
+ crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
+ return ( crc32 );
}
static guint
static void
dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
{
- guint16 length, padding_length, parameter_value_length;
+ guint16 length, padding_length, parameter_value_length, unrecognized_parameter_type;
tvbuff_t *unrecognized_parameters_tvb;
length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET,
parameter_value_length, parameter_value_length);
+ unrecognized_parameter_type = tvb_get_ntohs(unrecognized_parameters_tvb, PARAMETER_TYPE_OFFSET);
dissect_tlv_parameter_list(unrecognized_parameters_tvb, pinfo, parameter_tree);
- proto_item_set_text(parameter_item, "Unrecognized parameter of type");
+ proto_item_set_text(parameter_item, "Unrecognized parameter of type %s (0x%x)",
+ val_to_str(unrecognized_parameter_type, sctp_parameter_identifier_values, "unknown"), unrecognized_parameter_type);
}
static void
proto_tree_add_uint(sctp_tree, hf_sctp_source_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
proto_tree_add_uint(sctp_tree, hf_sctp_destination_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
proto_tree_add_uint(sctp_tree, hf_sctp_verification_tag, tvb, VERIFICATION_TAG_OFFSET, VERIFICATION_TAG_LENGTH, verification_tag);
-
+ proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, SOURCE_PORT_OFFSET, SOURCE_PORT_LENGTH, source_port);
+ proto_tree_add_uint_hidden(sctp_tree, hf_sctp_port, tvb, DESTINATION_PORT_OFFSET, DESTINATION_PORT_LENGTH, destination_port);
+
length = tvb_length(tvb);
switch(sctp_checksum) {
case SCTP_CHECKSUM_NONE:
else
proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
checksum, "Checksum: 0x%08x (incorrect Adler32, should be 0x%08x)", checksum, calculated_adler32);
- proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_correct, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, adler32_correct);
+ proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(adler32_correct));
break;
case SCTP_CHECKSUM_CRC32C:
calculated_crc32c = sctp_crc32c(tvb_get_ptr(tvb, 0, length), length);
else
proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
checksum, "Checksum: 0x%08x (incorrect CRC32C, should be 0x%08x)", checksum, calculated_crc32c);
- proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_correct, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, crc32c_correct);
+ proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct));
break;
case SCTP_CHECKSUM_AUTOMATIC:
calculated_adler32 = sctp_adler32(tvb_get_ptr(tvb, 0, length), length);
proto_tree_add_uint_format(sctp_tree, hf_sctp_checksum, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH,
checksum, "Checksum: 0x%08x (incorrect, should be 0x%08x (Adler32) or 0x%08x (CRC32C))",
checksum, calculated_adler32, calculated_crc32c);
- proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_correct, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, (crc32c_correct || adler32_correct));
+ proto_tree_add_boolean_hidden(sctp_tree, hf_sctp_checksum_bad, tvb, CHECKSUM_OFFSET, CHECKSUM_LENGTH, !(crc32c_correct || adler32_correct));
break;
}
} else {
FT_UINT16, BASE_DEC, NULL, 0x0,
"", HFILL }
},
+ { &hf_sctp_port,
+ { "Port", "sctp.port",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
{ &hf_sctp_verification_tag,
{ "Verification tag", "sctp.verfication_tag",
FT_UINT32, BASE_HEX, NULL, 0x0,
FT_UINT32, BASE_HEX, NULL, 0x0,
"", HFILL }
},
- { &hf_sctp_checksum_correct,
- { "Checksum correct", "sctp.checksum_correct",
+ { &hf_sctp_checksum_bad,
+ { "Bad checksum", "sctp.checksum_bad",
FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"", HFILL }
},