Use "val_to_str()" to translate numerical values to strings, don't
[obnox/wireshark/wip.git] / packet-sctp.c
index 9b7eb3173aacf4a008e4d32686ac5bdddc9e7955..8c32040fbcc1b1f0c401288376a7dd6acf70e1cf 100644 (file)
@@ -2,10 +2,10 @@
  * Routines for Stream Control Transmission Protocol dissection
  * Copyright 2000, Michael Tüxen <Michael.Tuexen@icn.siemens.de>
  *
- * $Id: packet-sctp.c,v 1.12 2001/01/14 08:27:25 guy Exp $
+ * $Id: packet-sctp.c,v 1.19 2001/07/03 04:56:46 guy Exp $
  *
  * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@unicom.net>
+ * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
  *
  * Copied from README.developer
@@ -49,7 +49,7 @@
 #endif
 
 #include "packet.h"
-#include "packet-ip.h"
+#include "ipproto.h"
 
 /* Initialize the protocol and registered fields */
 static int proto_sctp = -1;
@@ -575,12 +575,13 @@ dissect_state_cookie_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tr
 static void
 dissect_unrecognized_parameters_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
 {
-  guint16 length, parameter_value_length;
+  guint16 length, padding_length, parameter_value_length;
   tvbuff_t *unrecognized_parameters_tvb;
 
   length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
-  
-  parameter_value_length = length - PARAMETER_HEADER_LENGTH;
+  padding_length = nr_of_padding_bytes(length);
+
+  parameter_value_length = length - PARAMETER_HEADER_LENGTH + padding_length;
 
   unrecognized_parameters_tvb = tvb_new_subset(parameter_tvb, PARAMETER_VALUE_OFFSET, 
                                               parameter_value_length, parameter_value_length);
@@ -732,7 +733,7 @@ dissect_parameter(tvbuff_t *parameter_tvb, proto_tree *chunk_tree)
     dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
     break;
   };
-  if (padding_length > 0)
+  if ((padding_length > 0) && (type != UNREC_PARA_PARAMETER_ID))
     proto_tree_add_text(parameter_tree, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length,
                        "Padding: %u byte%s",
                        padding_length, plurality(padding_length, "", "s"));
@@ -857,12 +858,13 @@ dissect_invalid_mandatory_parameter_cause(tvbuff_t *cause_tvb, proto_tree *cause
 static void
 dissect_unrecognized_parameters_cause(tvbuff_t *cause_tvb, proto_tree *cause_tree, proto_item *cause_item)
 {
-  guint16 length, cause_info_length;
+  guint16 length, padding_length, cause_info_length;
   tvbuff_t *unrecognized_parameters_tvb;
 
   length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
-  
-  cause_info_length = length - CAUSE_HEADER_LENGTH;
+  padding_length = nr_of_padding_bytes(length);
+
+  cause_info_length = length - CAUSE_HEADER_LENGTH + padding_length;
 
   unrecognized_parameters_tvb = tvb_new_subset(cause_tvb, CAUSE_INFO_OFFSET, 
                                               cause_info_length, cause_info_length);
@@ -921,7 +923,7 @@ dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_t
   length         = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET);
   padding_length = nr_of_padding_bytes(length);
   total_length   = length + padding_length;
-  
+
   cause_item = proto_tree_add_notext(chunk_tree, cause_tvb, CAUSE_HEADER_OFFSET, total_length);
   proto_item_set_text(cause_item, "BAD ERROR CAUSE");
   cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause);
@@ -969,7 +971,7 @@ dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_t
     dissect_unknown_cause(cause_tvb, cause_tree, cause_item);
     break;
   };
-  if (padding_length > 0)
+  if ((padding_length > 0) && (code != UNRECOGNIZED_PARAMETERS))
     proto_tree_add_text(cause_tree, cause_tvb, CAUSE_HEADER_OFFSET + length, padding_length,
                        "Padding: %u byte%s",
                        padding_length, plurality(padding_length, "", "s"));
@@ -985,8 +987,8 @@ dissect_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree,
 {
   /* do lookup with the subdissector table */
   if (dissector_try_port (sctp_ppi_dissector_table, ppi,  payload_tvb, pinfo, tree) ||
-      dissector_try_port(sctp_port_dissector_table, pi.srcport,  payload_tvb, pinfo, tree) ||
-      dissector_try_port(sctp_port_dissector_table, pi.destport, payload_tvb, pinfo, tree)){
+      dissector_try_port(sctp_port_dissector_table, pinfo->srcport,  payload_tvb, pinfo, tree) ||
+      dissector_try_port(sctp_port_dissector_table, pinfo->destport, payload_tvb, pinfo, tree)){
     return TRUE;
   }
   else {
@@ -1630,10 +1632,6 @@ dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   proto_item *sctp_item;
   proto_tree *sctp_tree;
 
-  CHECK_DISPLAY_AS_DATA(proto_sctp, tvb, pinfo, tree);
-
-  pinfo->current_proto = "SCTP";
-
   /* Extract the common header */
   source_port      = tvb_get_ntohs(tvb, SOURCE_PORT_OFFSET);
   destination_port = tvb_get_ntohs(tvb, DESTINATION_PORT_OFFSET);
@@ -1641,9 +1639,9 @@ dissect_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   checksum         = tvb_get_ntohl(tvb, CHECKSUM_OFFSET);
 
   /* update pi structure */
-  pi.ptype    = PT_SCTP;
-  pi.srcport  = source_port;
-  pi.destport = destination_port;
+  pinfo->ptype    = PT_SCTP;
+  pinfo->srcport  = source_port;
+  pinfo->destport = destination_port;
 
   /* make entry in the Protocol column on summary display */
   if (check_col(pinfo->fd, COL_PROTOCOL)) 
@@ -1692,227 +1690,227 @@ proto_register_sctp(void)
     { &hf_sctp_source_port,
       { "Source port", "sctp.srcport",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_destination_port,
       { "Destination port", "sctp.dstport",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     { &hf_sctp_verification_tag,
       { "Verification tag", "sctp.verfication_tag",
        FT_UINT32, BASE_HEX, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_checksum,
       { "Adler-32 checksum", "sctp.checksum",
        FT_UINT32, BASE_HEX, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_chunk_type,
       { "Identifier", "sctp.chunk_type",
        FT_UINT8, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_chunk_flags,
       { "Flags", "sctp.chunk_flags",
        FT_UINT8, BASE_BIN, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_chunk_length,
       { "Length", "sctp.chunk_length",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_init_chunk_initiate_tag,
       { "Initiate tag", "sctp.init.chunk.initiate.tag",
        FT_UINT32, BASE_HEX, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_init_chunk_adv_rec_window_credit,
       { "Advertised reciever window credit (a_rwnd)", "sctp.init.chunk.credit",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_init_chunk_number_of_outbound_streams,
       { "Number of outbound streams", "sctp.init.chunk.nr.out.streams",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     { &hf_sctp_init_chunk_number_of_inbound_streams,
       { "Number of inbound streams", "sctp.init.chunk.nr.in.streams",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_init_chunk_initial_tsn,
       { "Initial TSN", "sctp.init.chunk.initial.tsn",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_cumulative_tsn_ack,
      { "Cumulative TSN Ack", "sctp.cumulative.tsn.ack",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_data_chunk_tsn,
      { "TSN", "sctp.tsn",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_data_chunk_stream_id,
      { "Stream Identifier", "sctp.stream_id",
        FT_UINT16, BASE_HEX, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_data_chunk_stream_seq_number,
      { "Stream sequence number", "sctp.stream_seq_number",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_data_chunk_payload_proto_id,
      { "Payload Protocol identifier", "sctp.payload_proto_id",
        FT_UINT32, BASE_HEX, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_data_chunk_e_bit,
      { "E-Bit", "sctp.data.e_bit",
        FT_BOOLEAN, 8, TFS(&sctp_data_chunk_e_bit_value), SCTP_DATA_CHUNK_E_BIT,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_data_chunk_b_bit,
      { "B-Bit", "sctp.data.b_bit",
        FT_BOOLEAN, 8, TFS(&sctp_data_chunk_b_bit_value), SCTP_DATA_CHUNK_B_BIT,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_data_chunk_u_bit,
      { "U-Bit", "sctp.data.u.bit",
        FT_BOOLEAN, 8, TFS(&sctp_data_chunk_u_bit_value), SCTP_DATA_CHUNK_U_BIT,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_sack_chunk_cumulative_tsn_ack,
      { "Cumulative TSN ACK", "sctp.sack.cumulative_tsn_ack",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_sack_chunk_adv_rec_window_credit,
      { "Advertised receiver window credit (a_rwnd)", "sctp.sack.a_rwnd",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_sack_chunk_number_of_gap_blocks,
      { "Number of gap acknowldgement blocks ", "sctp.sack.number_of_gap_blocks",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_sack_chunk_number_of_dup_tsns,
      { "Number of duplicated TSNs", "sctp.sack.number_of_duplicated_tsns",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_sack_chunk_gap_block_start,
      { "Start", "sctp.sack.gap_block_start",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_sack_chunk_gap_block_end,
      { "End", "sctp.sack.gap_block_end",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_sack_chunk_duplicate_tsn,
      { "Duplicate TSN", "sctp.sack.duplicate.tsn",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },  
     {&hf_sctp_shutdown_chunk_cumulative_tsn_ack,
      { "Cumulative TSN Ack", "sctp.shutdown.cumulative_tsn_ack",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_ecne_chunk_lowest_tsn,
      { "Lowest TSN", "sctp.ecne.lowest_tsn",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_cwr_chunk_lowest_tsn,
      { "Lowest TSN", "sctp.cwr.lowest_tsn",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_shutdown_complete_chunk_t_bit,
      { "E-Bit", "sctp.shutdown_complete.t_bit",
        FT_BOOLEAN, 8, TFS(&sctp_shutdown_complete_chunk_t_bit_value), SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT,
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_chunk_parameter_type,
      { "Parameter type", "sctp.parameter.type",
        FT_UINT16, BASE_HEX, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_chunk_parameter_length,
      { "Parameter length", "sctp.parameter.length",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_parameter_ipv4_address,
      { "IP Version 4 address", "sctp.parameter.ipv4_address",
        FT_IPv4, BASE_NONE, NULL, 0x0,
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_parameter_ipv6_address,
      { "IP Version 6 address", "sctp.parameter.ipv6_address",
        FT_IPv6, BASE_NONE, NULL, 0x0,
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_parameter_cookie_preservative_increment,
      { "Suggested Cookie life-span increment (msec)", "sctp.parameter.cookie_preservative_incr",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_parameter_hostname_hostname,
      { "Hostname", "sctp.parameter.hostname.hostname",
        FT_STRING, BASE_NONE, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_supported_address_types_parameter,
      { "Supported address type", "sctp.parameter.supported_addres_type",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_cause_code,
      { "Cause code", "sctp.cause.code",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_cause_length,
      { "Cause length", "sctp.cause.length",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_cause_stream_identifier,
      { "Stream identifier", "sctp.cause.stream_identifier",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_cause_number_of_missing_parameters,
      { "Number of missing parameters", "sctp.cause.nr_of_missing_parameters",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     }, 
     {&hf_sctp_cause_missing_parameter_type,
      { "Missing parameters type", "sctp.cause.missing_parameter_type",
        FT_UINT16, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_cause_measure_of_staleness,
      { "Measure of staleness in usec", "sctp.cause.measure_of_staleness",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
     {&hf_sctp_cause_tsn,
      { "TSN", "sctp.cause.tsn",
        FT_UINT32, BASE_DEC, NULL, 0x0,          
-       ""}
+       "", HFILL }
     },
   };
   
@@ -1929,7 +1927,7 @@ proto_register_sctp(void)
   };
   
   /* Register the protocol name and description */
-  proto_sctp = proto_register_protocol("Stream Control Transmission Protcol",
+  proto_sctp = proto_register_protocol("Stream Control Transmission Protocol",
                                       "SCTP", "sctp");
   
   /* Required function calls to register the header fields and subtrees used */