Boolean fields are just like other fields - if you use the field name
[obnox/wireshark/wip.git] / packet-clnp.c
index 118271db3dd5df564464688a20f1dd01397bcf88..8e385813505c1c2f8a334ac95ac17844ccfb181b 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-clnp.c
  * Routines for ISO/OSI network and transport protocol packet disassembly
  *
- * $Id: packet-clnp.c,v 1.15 2000/11/19 04:14:26 guy Exp $
+ * $Id: packet-clnp.c,v 1.24 2001/01/22 08:03:44 guy Exp $
  * Laurent Deniel <deniel@worldnet.fr>
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
@@ -50,6 +50,8 @@
 
 static int  proto_clnp         = -1;
 static gint ett_clnp           = -1;
+static gint ett_clnp_type      = -1;
+static gint ett_clnp_disc_pdu  = -1;
 static int  proto_cotp         = -1;
 static gint ett_cotp           = -1;
 static int  proto_cltp         = -1;
@@ -98,7 +100,7 @@ static int hf_clnp_src         = -1;
 #define ERQ_NPDU               0x1E
 #define ERP_NPDU               0x1F
 
-static const value_string npdu_type_vals[] = {
+static const value_string npdu_type_abbrev_vals[] = {
   { DT_NPDU,   "DT" },
   { MD_NPDU,   "MD" },
   { ER_NPDU,   "ER" },
@@ -107,6 +109,15 @@ static const value_string npdu_type_vals[] = {
   { 0,         NULL }
 };
 
+static const value_string npdu_type_vals[] = {
+  { DT_NPDU,   "Data" },
+  { MD_NPDU,   "Multicast Data" },
+  { ER_NPDU,   "Error Report" },
+  { ERQ_NPDU,  "Echo Request" },
+  { ERP_NPDU,  "Echo Response" },
+  { 0,         NULL }
+};
+
 /* field position */
 
 #define P_CLNP_PROTO_ID                0
@@ -1516,7 +1527,7 @@ static gboolean dissect_ositp_internal(tvbuff_t *tvb, packet_info *pinfo,
       /* Well, we found at least one valid COTP or CLTP PDU, so I guess this
          is either COTP or CLTP. */
       if (!subdissector_found && check_col(pinfo->fd, COL_PROTOCOL))
-        col_add_str(pinfo->fd, COL_PROTOCOL, is_cltp ? "CLTP" : "COTP");
+        col_set_str(pinfo->fd, COL_PROTOCOL, is_cltp ? "CLTP" : "COTP");
       found_ositp = TRUE;
     }
 
@@ -1548,6 +1559,7 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   guint8      cnf_type;
   char        flag_string[6+1];
   char       *pdu_type_string;
+  proto_tree *type_tree;
   guint16     segment_length;
   guint16     segment_offset = 0;
   guint16     cnf_cksum;
@@ -1555,19 +1567,19 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   u_char      src_len, dst_len, nsel, opt_len = 0;
   guint8     *dst_addr, *src_addr;
   guint       len;
+  guint       next_length;
+  proto_tree *discpdu_tree;
   tvbuff_t   *next_tvb;
 
-  CHECK_DISPLAY_AS_DATA(proto_clnp, tvb, pinfo, tree);
-
-  pinfo->current_proto = "CLNP";
-
   if (check_col(pinfo->fd, COL_PROTOCOL))
-    col_add_str(pinfo->fd, COL_PROTOCOL, "CLNP");
+    col_set_str(pinfo->fd, COL_PROTOCOL, "CLNP");
+  if (check_col(pinfo->fd, COL_INFO))
+    col_clear(pinfo->fd, COL_INFO);
 
   cnf_proto_id = tvb_get_guint8(tvb, P_CLNP_PROTO_ID);
   if (cnf_proto_id == NLPID_NULL) {
     if (check_col(pinfo->fd, COL_INFO))
-      col_add_str(pinfo->fd, COL_INFO, "Inactive subset");
+      col_set_str(pinfo->fd, COL_INFO, "Inactive subset");
     if (tree) {
       ti = proto_tree_add_item(tree, proto_clnp, tvb, P_CLNP_PROTO_ID, 1, FALSE);
       clnp_tree = proto_item_add_subtree(ti, ett_clnp);
@@ -1603,12 +1615,12 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     cnf_ttl = tvb_get_guint8(tvb, P_CLNP_TTL);
     proto_tree_add_uint_format(clnp_tree, hf_clnp_ttl, tvb, P_CLNP_TTL, 1, 
                               cnf_ttl,
-                              "Holding Time : %u (%u secs)", 
-                              cnf_ttl, cnf_ttl / 2);
+                              "Holding Time : %u (%u.%u secs)", 
+                              cnf_ttl, cnf_ttl / 2, (cnf_ttl % 2) * 5);
   }
 
   cnf_type = tvb_get_guint8(tvb, P_CLNP_TYPE);
-  pdu_type_string = val_to_str(cnf_type & CNF_TYPE, npdu_type_vals,
+  pdu_type_string = val_to_str(cnf_type & CNF_TYPE, npdu_type_abbrev_vals,
                                "Unknown (0x%02x)");
   flag_string[0] = '\0';
   if (cnf_type & CNF_SEG_OK)
@@ -1618,12 +1630,28 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   if (cnf_type & CNF_ERR_OK)
     strcat(flag_string, "E ");
   if (tree) {
-    proto_tree_add_uint_format(clnp_tree, hf_clnp_type, tvb, P_CLNP_TYPE, 1,
+    ti = proto_tree_add_uint_format(clnp_tree, hf_clnp_type, tvb, P_CLNP_TYPE, 1,
                               cnf_type,
                               "PDU Type     : 0x%02x (%s%s)",
                               cnf_type,
                               flag_string,
                               pdu_type_string);
+    type_tree = proto_item_add_subtree(ti, ett_clnp_type);
+    proto_tree_add_text(type_tree, tvb, P_CLNP_TYPE, 1, "%s",
+                       decode_boolean_bitfield(cnf_type, CNF_SEG_OK, 8,
+                                     "Segmentation permitted",
+                                     "Segmentation not permitted"));
+    proto_tree_add_text(type_tree, tvb, P_CLNP_TYPE, 1, "%s",
+                       decode_boolean_bitfield(cnf_type, CNF_MORE_SEGS, 8,
+                                     "More segments",
+                                     "Last segment"));
+    proto_tree_add_text(type_tree, tvb, P_CLNP_TYPE, 1, "%s",
+                       decode_boolean_bitfield(cnf_type, CNF_ERR_OK, 8,
+                                     "Report error if PDU discarded",
+                                     "Don't report error if PDU discarded"));
+    proto_tree_add_text(type_tree, tvb, P_CLNP_TYPE, 1, "%s",
+                       decode_enumerated_bitfield(cnf_type, CNF_TYPE, 8,
+                                     npdu_type_vals, "%s"));
   }
 
   /* If we don't have the full header - i.e., not enough to see the
@@ -1765,9 +1793,23 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     case ER_NPDU:
       /* The payload is the header and "none, some, or all of the data
          part of the discarded PDU", i.e. it's like an ICMP error;
-        just as we don't yet trust ourselves to be able to dissect
-        the payload of an ICMP error packet, we don't yet trust
-        ourselves to dissect the payload of a CLNP ER packet. */
+        dissect it as a CLNP PDU. */
+      if (tree) {
+        next_length = tvb_length_remaining(tvb, offset);
+        if (next_length != 0) {
+          /* We have payload; dissect it.
+             Make the columns non-writable, so the packet isn't shown
+             in the summary based on what the discarded PDU's contents
+             are. */
+          col_set_writable(pinfo->fd, FALSE);
+          ti = proto_tree_add_text(clnp_tree, tvb, offset, next_length,
+            "Discarded PDU");
+          discpdu_tree = proto_item_add_subtree(ti, ett_clnp_disc_pdu);
+          next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+          dissect_clnp(next_tvb, pinfo, discpdu_tree);
+          offset += next_length;
+        }
+      }
       break;
 
     case ERQ_NPDU:
@@ -1823,15 +1865,17 @@ void proto_register_clnp(void)
   };
   static gint *ett[] = {
     &ett_clnp,
+    &ett_clnp_type,
+    &ett_clnp_disc_pdu,
   };
 
   module_t *clnp_module;
 
-  proto_clnp = proto_register_protocol(PROTO_STRING_CLNP, "clnp");
+  proto_clnp = proto_register_protocol(PROTO_STRING_CLNP, "CLNP", "clnp");
   proto_register_field_array(proto_clnp, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
 
-  clnp_module = prefs_register_module("clnp", "CLNP", NULL);
+  clnp_module = prefs_register_protocol(proto_clnp, NULL);
   prefs_register_uint_preference(clnp_module, "tp_nsap_selector",
        "NSAP selector for Transport Protocol (last byte in hexa)",
        "NSAP selector for Transport Protocol (last byte in hexa)",
@@ -1853,14 +1897,15 @@ void proto_register_cotp(void)
                &ett_cotp,
        };
 
-        proto_cotp = proto_register_protocol(PROTO_STRING_COTP, "cotp");
+        proto_cotp = proto_register_protocol(PROTO_STRING_COTP, "COTP", "cotp");
  /*       proto_register_field_array(proto_cotp, hf, array_length(hf));*/
        proto_register_subtree_array(ett, array_length(ett));
 
 /* subdissector code */
        register_heur_dissector_list("cotp_is", &cotp_is_heur_subdissector_list);
 
-       register_dissector("ositp", dissect_ositp);
+       /* XXX - what about CLTP? */
+       register_dissector("ositp", dissect_ositp, proto_cotp);
 }
 
 void proto_register_cltp(void)
@@ -1873,7 +1918,7 @@ void proto_register_cltp(void)
                &ett_cltp,
        };
 
-        proto_cltp = proto_register_protocol(PROTO_STRING_CLTP, "cltp");
+        proto_cltp = proto_register_protocol(PROTO_STRING_CLTP, "CLTP", "cltp");
  /*       proto_register_field_array(proto_cotp, hf, array_length(hf));*/
        proto_register_subtree_array(ett, array_length(ett));
 }
@@ -1881,6 +1926,10 @@ void proto_register_cltp(void)
 void
 proto_reg_handoff_clnp(void)
 {
-       dissector_add("osinl", NLPID_ISO8473_CLNP, dissect_clnp);
-       dissector_add("osinl", NLPID_NULL, dissect_clnp);       /* Inactive subset */
+       dissector_add("osinl", NLPID_ISO8473_CLNP, dissect_clnp,
+           proto_clnp);
+       dissector_add("osinl", NLPID_NULL, dissect_clnp,
+           proto_clnp);        /* Inactive subset */
+       dissector_add("fr.ietf", NLPID_ISO8473_CLNP, dissect_clnp,
+           proto_clnp);        /* Inactive subset */
 }