Some minor bugfixes for netlogon
[obnox/wireshark/wip.git] / packet-sctp.c
index 01264453c52369467377d2e78c098ac7ef7c0983..4cafeb605cc3784a52cfc322f646c6e589127db4 100644 (file)
@@ -4,13 +4,13 @@
  * - 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;
@@ -603,7 +604,9 @@ sctp_crc32c(const unsigned char* buf, unsigned int len)
 {
   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]); 
@@ -616,7 +619,14 @@ sctp_crc32c(const unsigned char* buf, unsigned int len)
   { 
     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 
@@ -723,7 +733,7 @@ dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tr
 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);
@@ -733,9 +743,11 @@ dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, packet_info *
 
   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
@@ -2109,7 +2121,9 @@ dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     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:
@@ -2124,7 +2138,7 @@ dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       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);
@@ -2135,7 +2149,7 @@ dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       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);
@@ -2155,7 +2169,7 @@ dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         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 {
@@ -2183,6 +2197,11 @@ proto_register_sctp(void)
               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,          
@@ -2193,8 +2212,8 @@ proto_register_sctp(void)
              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 }
     },