aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-cisco-fp-mim.c228
1 files changed, 118 insertions, 110 deletions
diff --git a/epan/dissectors/packet-cisco-fp-mim.c b/epan/dissectors/packet-cisco-fp-mim.c
index ca9d561e06..83bb477628 100644
--- a/epan/dissectors/packet-cisco-fp-mim.c
+++ b/epan/dissectors/packet-cisco-fp-mim.c
@@ -100,7 +100,8 @@ static dissector_handle_t eth_maybefcs_dissector;
/* 0100.0000.0000 */
#define MAC_MC_BC G_GINT64_CONSTANT(0x010000000000)
-static int dissect_fp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ );
+/* proto */
+static int dissect_fp_common( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int header_size );
/*
* These packets are a bit strange.
@@ -124,11 +125,34 @@ static int dissect_fp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
static gboolean
dissect_fp_heur (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
- if (dissect_fp (tvb, pinfo, tree, NULL) > 0) {
+ guint16 etype = 0;
+ int header_size = 0;
+
+ if ( ! tvb_bytes_exist( tvb, 12, 2 ) )
+ return FALSE;
+
+ etype = tvb_get_ntohs( tvb, 12 );
+
+ switch ( etype ) {
+ case ETHERTYPE_DCE:
+ header_size = FP_HEADER_SIZE;
+ break;
+ case ETHERTYPE_IEEE_802_1AD:
+ case ETHERTYPE_VLAN:
+ if ( tvb_bytes_exist( tvb, 16, 2 ) && tvb_get_ntohs( tvb, 16 ) == ETHERTYPE_DCE ) {
+ header_size = FP_HEADER_WITH_1AD_SIZE;
+ break;
+ }
+ /* fall through */
+ default:
+ return FALSE;
+ }
+
+ if ( dissect_fp_common( tvb, pinfo, tree, header_size ) > 0 ) {
return TRUE;
- } else {
- return FALSE;
}
+
+ return FALSE;
}
static void
@@ -173,14 +197,13 @@ fp_add_hmac (tvbuff_t *tvb, proto_tree *tree, int offset) {
/* FabricPath MiM Dissector */
static int
-dissect_fp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
+dissect_fp_common ( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int header_size)
{
proto_item *ti;
proto_tree *fp_tree;
proto_tree *fp_addr_tree;
tvbuff_t *next_tvb;
int offset = 0;
- int header_size = 0;
guint64 hmac_src;
guint64 hmac_dst;
guint16 sswid = 0;
@@ -193,118 +216,108 @@ dissect_fp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
const guint8 *dst_addr = NULL;
gboolean dest_as_mac = FALSE;
- etype = tvb_get_ntohs (tvb, 12);
-
- if (etype == ETHERTYPE_DCE) {
- header_size = FP_HEADER_SIZE;
- } else if (etype == ETHERTYPE_IEEE_802_1AD && tvb_get_ntohs(tvb, 16) == ETHERTYPE_DCE) {
- header_size = FP_HEADER_WITH_1AD_SIZE;
- } else {
- return 0;
- }
col_set_str( pinfo->cinfo, COL_PROTOCOL, FP_PROTO_COL_NAME );
col_set_str( pinfo->cinfo, COL_INFO, FP_PROTO_COL_INFO );
- if (tree) {
- /*
- * Outer SA:
- * - SwitchID ingress FP switch system ID
- * - SubswitchID is used in some cases of VPC+
- * - LID (Local ID) is specific to the implementation
- * + N7K the LID is generally the port index of the ingress interface
- * + N5K/N6K LID most of the time will be 0
- * + EndnodeID is not currently used
- *
- * Outer DA:
- * - For known SA/DA is taken from MAC table for DMAC
- * - For broadcast and multicast is the same as DMAC
- * - For unknown unicast DA is 010f.ffc1.01c0 (flood to vlan)
- * - For known unicast DA, but unknown SA is 010f.ffc1.02c0 (flood to fabric)
- */
+ /*
+ * Outer SA:
+ * - SwitchID ingress FP switch system ID
+ * - SubswitchID is used in some cases of VPC+
+ * - LID (Local ID) is specific to the implementation
+ * + N7K the LID is generally the port index of the ingress interface
+ * + N5K/N6K LID most of the time will be 0
+ * + EndnodeID is not currently used
+ *
+ * Outer DA:
+ * - For known SA/DA is taken from MAC table for DMAC
+ * - For broadcast and multicast is the same as DMAC
+ * - For unknown unicast DA is 010f.ffc1.01c0 (flood to vlan)
+ * - For known unicast DA, but unknown SA is 010f.ffc1.02c0 (flood to fabric)
+ */
- hmac_dst = tvb_get_ntoh48 (tvb, 0);
- hmac_src = tvb_get_ntoh48 (tvb, 6);
+ hmac_dst = tvb_get_ntoh48 (tvb, 0);
+ hmac_src = tvb_get_ntoh48 (tvb, 6);
- if (hmac_dst & MAC_MC_BC) {
- dest_as_mac = TRUE;
- }
- if (!dest_as_mac) {
- fp_get_hmac_addr (hmac_dst, &dswid, &dsswid, &dlid);
- } else {
- hmac_dst = GUINT64_TO_BE (hmac_dst);
- /* Get pointer to most sig byte of destination address
- in network order
- */
- dst_addr = ((const guint8 *) &hmac_dst) + 2;
- }
- fp_get_hmac_addr (hmac_src, &sswid, &ssswid, &slid);
-
- /* FIXME: Does this make sense??? */
- if (PTREE_DATA(tree)->visible) {
- if (dest_as_mac) {
- address ether_addr;
-
- set_address(&ether_addr, AT_ETHER, 6, dst_addr);
-
- ti = proto_tree_add_protocol_format(tree, proto_fp, tvb, 0, header_size,
- "Cisco FabricPath, Src: %03x.%02x.%04x, Dst: %s",
- sswid, ssswid, slid,
- address_with_resolution_to_str(wmem_packet_scope(), &ether_addr));
- } else {
- ti = proto_tree_add_protocol_format(tree, proto_fp, tvb, 0, header_size,
- "Cisco FabricPath, Src: %03x.%02x.%04x, Dst: %03x.%02x.%04x",
- sswid, ssswid, slid,
- dswid, dsswid, dlid);
- }
- } else {
- ti = proto_tree_add_item( tree, proto_fp, tvb, 0, header_size, ENC_NA );
- }
- fp_tree = proto_item_add_subtree( ti, ett_mim );
+ if (hmac_dst & MAC_MC_BC) {
+ dest_as_mac = TRUE;
+ }
+ if (!dest_as_mac) {
+ fp_get_hmac_addr (hmac_dst, &dswid, &dsswid, &dlid);
+ } else {
+ hmac_dst = GUINT64_TO_BE (hmac_dst);
+ /* Get pointer to most sig byte of destination address
+ in network order
+ */
+ dst_addr = ((const guint8 *) &hmac_dst) + 2;
+ }
+ fp_get_hmac_addr (hmac_src, &sswid, &ssswid, &slid);
- /* Add dest and source heir. mac */
+ /* FIXME: Does this make sense??? */
+ if (tree && PTREE_DATA(tree)->visible) {
if (dest_as_mac) {
- /* MCAST address */
- proto_tree_add_ether( fp_tree, hf_d_hmac_mc, tvb, offset, 6, dst_addr);
+ address ether_addr;
+
+ set_address(&ether_addr, AT_ETHER, 6, dst_addr);
+
+ ti = proto_tree_add_protocol_format(tree, proto_fp, tvb, 0, header_size,
+ "Cisco FabricPath, Src: %03x.%02x.%04x, Dst: %s",
+ sswid, ssswid, slid,
+ address_with_resolution_to_str(wmem_packet_scope(), &ether_addr));
} else {
- /* Unicast */
- ti = proto_tree_add_none_format (fp_tree, hf_d_hmac, tvb, offset, 6, "Destination: %03x.%02x.%04x", dswid, dsswid, dlid);
- fp_addr_tree = proto_item_add_subtree (ti, ett_hmac);
- fp_add_hmac (tvb, fp_addr_tree, offset);
+ ti = proto_tree_add_protocol_format(tree, proto_fp, tvb, 0, header_size,
+ "Cisco FabricPath, Src: %03x.%02x.%04x, Dst: %03x.%02x.%04x",
+ sswid, ssswid, slid,
+ dswid, dsswid, dlid);
}
- offset += FP_HMAC_LEN;
+ } else {
+ ti = proto_tree_add_item( tree, proto_fp, tvb, 0, header_size, ENC_NA );
+ }
+ fp_tree = proto_item_add_subtree( ti, ett_mim );
- ti = proto_tree_add_none_format (fp_tree, hf_s_hmac, tvb, offset, 6,
- "Source: %03x.%02x.%04x", sswid, ssswid, slid);
+ /* Add dest and source heir. mac */
+ if (dest_as_mac) {
+ /* MCAST address */
+ proto_tree_add_ether( fp_tree, hf_d_hmac_mc, tvb, offset, 6, dst_addr);
+ } else {
+ /* Unicast */
+ ti = proto_tree_add_none_format (fp_tree, hf_d_hmac, tvb, offset, 6, "Destination: %03x.%02x.%04x", dswid, dsswid, dlid);
fp_addr_tree = proto_item_add_subtree (ti, ett_hmac);
fp_add_hmac (tvb, fp_addr_tree, offset);
- offset += FP_HMAC_LEN;
-
- etype = tvb_get_ntohs(tvb, offset);
- switch (etype) {
- case ETHERTYPE_DCE:
- proto_tree_add_item(fp_tree, hf_fp_etype, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- break;
- case ETHERTYPE_IEEE_802_1AD:
- proto_tree_add_item(fp_tree, hf_fp_1ad_etype, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- proto_tree_add_item(fp_tree, hf_fp_1ad_priority, tvb, offset, 2, ENC_NA);
- proto_tree_add_item(fp_tree, hf_fp_1ad_cfi, tvb, offset, 2, ENC_NA);
- proto_tree_add_item(fp_tree, hf_fp_1ad_svid, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- proto_tree_add_item(fp_tree, hf_fp_etype, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- break;
- default:
- /* The heuristics should prevent us from getting here */
- DISSECTOR_ASSERT(0);
- }
-
- proto_tree_add_item (fp_tree, hf_ftag, tvb, offset, FP_FTAG_LEN, ENC_BIG_ENDIAN);
- proto_tree_add_item (fp_tree, hf_ttl, tvb, offset, FP_FTAG_LEN, ENC_BIG_ENDIAN);
+ }
+ offset += FP_HMAC_LEN;
+
+ ti = proto_tree_add_none_format (fp_tree, hf_s_hmac, tvb, offset, 6,
+ "Source: %03x.%02x.%04x", sswid, ssswid, slid);
+ fp_addr_tree = proto_item_add_subtree (ti, ett_hmac);
+ fp_add_hmac (tvb, fp_addr_tree, offset);
+ offset += FP_HMAC_LEN;
+
+ etype = tvb_get_ntohs(tvb, offset);
+ switch (etype) {
+ case ETHERTYPE_DCE:
+ proto_tree_add_item(fp_tree, hf_fp_etype, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ break;
+ case ETHERTYPE_IEEE_802_1AD:
+ case ETHERTYPE_VLAN:
+ proto_tree_add_item(fp_tree, hf_fp_1ad_etype, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(fp_tree, hf_fp_1ad_priority, tvb, offset, 2, ENC_NA);
+ proto_tree_add_item(fp_tree, hf_fp_1ad_cfi, tvb, offset, 2, ENC_NA);
+ proto_tree_add_item(fp_tree, hf_fp_1ad_svid, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(fp_tree, hf_fp_etype, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ break;
+ default:
+ /* The heuristics should prevent us from getting here */
+ DISSECTOR_ASSERT(0);
}
+ proto_tree_add_item (fp_tree, hf_ftag, tvb, offset, FP_FTAG_LEN, ENC_BIG_ENDIAN);
+ proto_tree_add_item (fp_tree, hf_ttl, tvb, offset, FP_FTAG_LEN, ENC_BIG_ENDIAN);
+
/* call the eth dissector */
next_tvb = tvb_new_subset_remaining( tvb, header_size );
/*
@@ -340,7 +353,7 @@ proto_register_mim(void)
VALS(etype_vals), 0x0, NULL, HFILL }},
{ &hf_fp_1ad_etype,
- { "1AD Ethertype", "cfp.1ad.etype", FT_UINT16, BASE_HEX,
+ { "IEEE 802.1ad Ethertype", "cfp.1ad.etype", FT_UINT16, BASE_HEX,
VALS(etype_vals), 0x0, NULL, HFILL }},
{ &hf_fp_1ad_priority,
@@ -422,11 +435,6 @@ proto_register_mim(void)
void
proto_reg_handoff_fabricpath(void)
{
- /*
- dissector_handle_t fp_handle;
- fp_handle = create_dissector_handle(dissect_fp, proto_fp);
- dissector_add_uint("ethertype", ETHERTYPE_DCE, fp_handle);
- */
static gboolean prefs_initialized = FALSE;
if (!prefs_initialized) {
@@ -436,7 +444,7 @@ proto_reg_handoff_fabricpath(void)
* get outer source and destination MAC
* before the standard ethernet dissector
*/
- heur_dissector_add ("eth", dissect_fp_heur, "Cisco FabricPath over Ethernet", "fp_eth", proto_fp, HEURISTIC_DISABLE);
+ heur_dissector_add ("eth", dissect_fp_heur, "Cisco FabricPath over Ethernet", "fp_eth", proto_fp, HEURISTIC_ENABLE);
/*
* The FCS in FabricPath frames covers the entire FabricPath frame,