diff options
author | Jaap Keuter <jaap.keuter@xs4all.nl> | 2009-08-23 19:16:35 +0000 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2009-08-23 19:16:35 +0000 |
commit | 58dedc38728be4dbe797b47de7cbe950fd72054e (patch) | |
tree | e93d7365632dd03db540fcd08de97a2dcbf1b8ea | |
parent | 60a30e223e6aeb8da051ff70c1ef4a9b9857e0aa (diff) | |
download | wireshark-58dedc38728be4dbe797b47de7cbe950fd72054e.tar.gz wireshark-58dedc38728be4dbe797b47de7cbe950fd72054e.tar.bz2 wireshark-58dedc38728be4dbe797b47de7cbe950fd72054e.zip |
From kahou:
Add Fibre Channel Delimiter Dissector for Fibre Channel FC2.
svn path=/trunk/; revision=29531
-rw-r--r-- | epan/dissectors/packet-fc.c | 196 | ||||
-rw-r--r-- | wiretap/pcap-common.c | 2 | ||||
-rw-r--r-- | wiretap/wtap.c | 7 | ||||
-rw-r--r-- | wiretap/wtap.h | 1 |
4 files changed, 202 insertions, 4 deletions
diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c index 88ed326998..96c867cef0 100644 --- a/epan/dissectors/packet-fc.c +++ b/epan/dissectors/packet-fc.c @@ -55,6 +55,8 @@ #include "packet-fcbls.h" #include <epan/tap.h> #include <epan/emem.h> +#include <epan/crc32.h> +#include <epan/expert.h> #define FC_HEADER_SIZE 24 #define FC_RCTL_VFT 0x50 @@ -133,6 +135,17 @@ static int hf_fc_bls_rjtcode = -1; static int hf_fc_bls_rjtdetail = -1; static int hf_fc_bls_vendor = -1; +/* For FC SOF */ +static int proto_fcsof = -1; + +static int hf_fcsof = -1; +static int hf_fceof = -1; +static int hf_fccrc = -1; + +static int ett_fcsof = -1; +static int ett_fceof = -1; +static int ett_fccrc = -1; + /* Initialize the subtree pointers */ static gint ett_fc = -1; @@ -141,7 +154,7 @@ static gint ett_fcbls = -1; static gint ett_fc_vft = -1; static dissector_table_t fcftype_dissector_table; -static dissector_handle_t data_handle; +static dissector_handle_t data_handle, fc_handle; static int fc_tap = -1; @@ -269,6 +282,72 @@ static const value_string fc_iu_val[] = { }; +/* For FC SOF */ +typedef enum { + FC_SOFC1 = 0xBCB51717, + FC_SOFI1 = 0xBCB55757, + FC_SOFN1 = 0xBCB53737, + FC_SOFI2 = 0xBCB55555, + FC_SOFN2 = 0xBCB53535, + FC_SOFI3 = 0xBCB55656, + FC_SOFN3 = 0xBCB53636, + FC_SOFC4 = 0xBCB51919, + FC_SOFI4 = 0xBCB55959, + FC_SOFN4 = 0xBCB53939, + FC_SOFF = 0xBCB55858 +} fc_sof_t; + +typedef enum { + EOFT_NEG = 0xBC957575, + EOFT_POS = 0xBCB57575, + EOFDT_NEG = 0xBC959595, + EOFDT_POS = 0xBCB59595, + EOFA_NEG = 0xBC95F5F5, + EOFA_POS = 0xBCB5F5F5, + EOFNI_NEG = 0xBC8AD5D5, + EOFNI_POS = 0xBCAAD5D5, + EOFDTI_NEG = 0xBC8A9595, + EOFDTI_POS = 0xBCAA9595, + EOFRI_NEG = 0xBC959999, + EOFRI_POS = 0xBCB59999, + EOFRTI_NEG = 0xBC8A9999, + EOFRTI_POS = 0xBCAA9999 +} fc_eof_t; + +static const value_string fc_sof_vals[] = { + {FC_SOFC1, "SOFc1 - SOF Connect Class 1 (Obsolete)" }, + {FC_SOFI1, "SOFi1 - SOF Initiate Class 1 (Obsolete)" }, + {FC_SOFN1, "SOFn1 - SOF Normal Class 1 (Obsolete)" }, + {FC_SOFI2, "SOFi2 - SOF Initiate Class 2" }, + {FC_SOFN2, "SOFn2 - SOF Normal Class 2" }, + {FC_SOFI3, "SOFi3 - SOF Initiate Class 3" }, + {FC_SOFN3, "SOFn3 - SOF Normal Class 3" }, + {FC_SOFC4, "SOFc4 - SOF Activate Class 4 (Obsolete)" }, + {FC_SOFI4, "SOFi4 - SOF Initiate Class 4 (Obsolete)" }, + {FC_SOFN4, "SOFn4 - SOF Normal Class 4 (Obsolete)" }, + {FC_SOFF, "SOFf - SOF Fabric" }, + {0, NULL} +}; + +static const value_string fc_eof_vals[] = { + {EOFT_NEG, "EOFt- - EOF Terminate" }, + {EOFT_POS, "EOFT+ - EOF Terminate" }, + {EOFDT_NEG, "EOFdt- - EOF Disconnect-Terminate-Class 1 (Obsolete)" }, + {EOFDT_POS, "EOFdt+ - EOF Disconnect-Terminate-Class 1 (Obsolete)" }, + {EOFA_NEG, "EOFa- - EOF Abort" }, + {EOFA_POS, "EOFa+ - EOF Abort" }, + {EOFNI_NEG, "EOFn- - EOF Normal" }, + {EOFNI_POS, "EOFn+ - EOF Normal" }, + {EOFDTI_NEG, "EOFni- - EOF Normal Invalid" }, + {EOFDTI_POS, "EOFni+ - EOF Normal Invalid" }, + {EOFRI_NEG, "EOFdti- - EOF Disconnect-Terminate-Invalid Class 1 (Obsolete)" }, + {EOFRI_POS, "EOFdti+ - EOF Disconnect-Terminate-Invalid Class 1 (Obsolete)" }, + {EOFRTI_NEG, "EOFrti- - EOF Remove-Terminate Invalid Class 4 (Obsolete)" }, + {EOFRTI_POS, "EOFrti+ - EOF Remove-Terminate Invalid Class 4 (Obsolete)" }, + {0, NULL} +}; + + static void fc_defragment_init(void) { fragment_table_init (&fc_fragment_table); @@ -1191,6 +1270,87 @@ dissect_fc_ifcp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) dissect_fc_helper (tvb, pinfo, tree, TRUE); } +static void +dissect_fcsof(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + + proto_item *it = NULL; + proto_tree *fcsof_tree = NULL; + gint bytes_remaining; + tvbuff_t *next_tvb; + guint32 sof = 0; + guint32 crc = 0; + guint32 crc_computed = 0; + guint32 eof = 0; + gint crc_offset = 0; + gint eof_offset = 0; + gint sof_offset = 0; + const gint FCSOF_TRAILER_LEN = 8; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "FC"); + + crc_offset = tvb_reported_length_remaining(tvb, 0) - FCSOF_TRAILER_LEN; + eof_offset = crc_offset + 4; + sof_offset = 0; + + /* Get SOF */ + sof = tvb_get_ntohl(tvb, 0); + + /* GET CRC */ + crc = tvb_get_ntohl(tvb, crc_offset); + + /* GET Computed CRC */ + crc_computed = crc32_802_tvb(tvb, tvb_length(tvb) - 4); + + /* Get EOF */ + eof = tvb_get_ntohl(tvb, eof_offset); + + it = proto_tree_add_protocol_format(tree, proto_fcsof, tvb, 0, + 4, "Fibre Channel Delimiter: SOF: %s EOF: %s", + val_to_str(sof, fc_sof_vals, "0x%x"), + val_to_str(eof, fc_eof_vals, "0x%x")); + + fcsof_tree = proto_item_add_subtree(it, ett_fcsof); + + proto_tree_add_uint(fcsof_tree, hf_fcsof, tvb, sof_offset, 4, sof); + + if (crc == crc_computed) { + proto_tree_add_uint_format(fcsof_tree, hf_fccrc, tvb, + crc_offset, 4, crc, + "CRC: %8.8x [valid]", crc); + } else { + it = proto_tree_add_uint_format(fcsof_tree, hf_fccrc, tvb, + crc_offset, 4, crc, + "CRC: %8.8x " + "[error: should be %8.8x]", + crc, crc_computed); + + expert_add_info_format(pinfo, it, PI_CHECKSUM, PI_ERROR, + "Bad FC CRC %8.8x %8.x", + crc, crc_computed); + } + + proto_tree_add_uint(fcsof_tree, hf_fceof, tvb, eof_offset, 4, eof); + + bytes_remaining = tvb_length_remaining(tvb, 4); + next_tvb = tvb_new_subset(tvb, 4, bytes_remaining, -1); + + pinfo->sof_eof = 0; + if (sof == FC_SOFI2 || sof == FC_SOFI3) { + pinfo->sof_eof = PINFO_SOF_FIRST_FRAME; + } else if (sof == FC_SOFF) { + pinfo->sof_eof = PINFO_SOF_SOFF; + } + + if (eof == EOFT_POS || eof == EOFT_NEG) { + pinfo->sof_eof |= PINFO_EOF_LAST_FRAME; + } else if (eof == EOFDTI_NEG || eof == EOFDTI_POS) { + pinfo->sof_eof |= PINFO_EOF_INVALID; + } + + /* Call FC dissector */ + call_dissector(fc_handle, next_tvb, pinfo, tree); +} + /* Register the protocol with Wireshark */ /* this format is require because a script is used to build the C function @@ -1364,6 +1524,26 @@ proto_register_fc(void) module_t *fc_module; + /* FC SOF */ + + static hf_register_info sof_hf[] = { + { &hf_fcsof, + { "SOF", "fc.sof", FT_UINT32, BASE_HEX, VALS(fc_sof_vals), 0, + NULL, HFILL }}, + { &hf_fceof, + { "EOF", "fc.eof", FT_UINT32, BASE_HEX, VALS(fc_eof_vals), 0, + NULL, HFILL }}, + { &hf_fccrc, + { "CRC", "fc.crc", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + }; + + static gint *sof_ett[] = { + &ett_fcsof, + &ett_fceof, + &ett_fccrc + }; + + /* Register the protocol name and description */ proto_fc = proto_register_protocol ("Fibre Channel", "FC", "fc"); register_dissector ("fc", dissect_fc, proto_fc); @@ -1397,6 +1577,15 @@ proto_register_fc(void) register_init_routine(fc_defragment_init); register_init_routine (fc_exchange_init_protocol); + + + /* Register FC SOF/EOF */ + proto_fcsof = proto_register_protocol("Fibre Channel Delimiters", "FCSoF", "fcsof"); + + proto_register_field_array(proto_fcsof, sof_hf, array_length(sof_hf)); + proto_register_subtree_array(sof_ett, array_length(sof_ett)); + + register_dissector("fcsof", dissect_fcsof, proto_fcsof); } @@ -1407,10 +1596,13 @@ proto_register_fc(void) void proto_reg_handoff_fc (void) { - dissector_handle_t fc_handle; + dissector_handle_t fcsof_handle; fc_handle = find_dissector("fc"); dissector_add("wtap_encap", WTAP_ENCAP_FIBRE_CHANNEL_FC2, fc_handle); + fcsof_handle = find_dissector("fcsof"); + dissector_add("wtap_encap", WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS, fcsof_handle); + data_handle = find_dissector("data"); } diff --git a/wiretap/pcap-common.c b/wiretap/pcap-common.c index 3d62004833..e872745b44 100644 --- a/wiretap/pcap-common.c +++ b/wiretap/pcap-common.c @@ -351,6 +351,8 @@ static const struct { { 220, WTAP_ENCAP_USB_LINUX_MMAPPED }, /* Fibre Channel FC-2 frame */ { 224, WTAP_ENCAP_FIBRE_CHANNEL_FC2 }, + /* Fibre Channel FC-2 frame with Delimiter */ + { 225, WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS }, /* * To repeat: diff --git a/wiretap/wtap.c b/wiretap/wtap.c index ca46f58ca7..f968c5c3cf 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -447,8 +447,11 @@ static struct encap_type_info encap_table_base[] = { /* WTAP_ENCAP_NSTRACE_2_0 */ { "NetScaler Encapsulation 2.0 of Ethernet", "nstrace20" }, - /* WTAP_ENCAP_FIBRE_CHANNEL_FC2 */ - { "Fibre Channel FC-2", "fc2" }, + /* WTAP_ENCAP_FIBRE_CHANNEL_FC2 */ + { "Fibre Channel FC-2", "fc2" }, + + /* WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS */ + { "Fibre Channel FC-2 With Frame Delimiter", "fc2sof"} }; diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 8c110ae3b8..452a6bd4f4 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -212,6 +212,7 @@ extern "C" { #define WTAP_ENCAP_NSTRACE_1_0 119 #define WTAP_ENCAP_NSTRACE_2_0 120 #define WTAP_ENCAP_FIBRE_CHANNEL_FC2 121 +#define WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS 122 #define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types() |