/* 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>
*
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;
#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" },
{ 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
/* 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;
}
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;
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);
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)
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
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:
};
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)",
&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)
&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));
}
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 */
}