diff options
author | Jaap Keuter <jaap.keuter@xs4all.nl> | 2009-01-15 07:36:50 +0000 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2009-01-15 07:36:50 +0000 |
commit | e33b9d1de3bc3031ae5692d77195236efdb0a109 (patch) | |
tree | d4a04e6e5d2764a6ea0f564a983add9cc6fb73ee /epan/dissectors/packet-itdm.c | |
parent | 6a4f4fdc19029ec92f9b7c0ea4eb62e973ea2ac4 (diff) |
From Dan Gora:
A new protocol dissector for PICMG SFP.0 and SFP.1 I-TDM. This dissector will only dissect
the so-called 125usec modality of I-TDM currently. I-TDM (Internal TDM) is a protocol used to
encapsulate voice traffic into ethernet frames and vise-versa. The protocol is not based upon
IP/UDP/TDP, but is a totally new protocol which uses MPLS.
svn path=/trunk/; revision=27237
Diffstat (limited to 'epan/dissectors/packet-itdm.c')
-rw-r--r-- | epan/dissectors/packet-itdm.c | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/epan/dissectors/packet-itdm.c b/epan/dissectors/packet-itdm.c new file mode 100644 index 0000000000..c90493fd31 --- /dev/null +++ b/epan/dissectors/packet-itdm.c @@ -0,0 +1,299 @@ +/* packet-itdm.c + * Routines for I-TDM (Internal TDM) dissection + * Compliant to PICMG SFP.0 and SFP.1 March 24, 2005 + * + * Copyright 2008, Dan Gora <dg [AT] adax.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <epan/packet.h> +#include "epan/prefs.h" + +/* Initialize the protocol and registered fields */ +static int proto_itdm = -1; +static int hf_itdm_timestamp = -1; +static int hf_itdm_seqnum = -1; +static int hf_itdm_sop_eop = -1; +static int hf_itdm_last_pack = -1; +static int hf_itdm_pktlen = -1; +static int hf_itdm_chksum = -1; +static int hf_itdm_uid = -1; +static int hf_itdm_ack = -1; +static int hf_itdm_act = -1; +static int hf_itdm_chcmd = -1; +static int hf_itdm_chid = -1; +static int hf_itdm_chloc1 = -1; +static int hf_itdm_chloc2 = -1; +static int hf_itdm_pktrate = -1; +static int hf_itdm_cxnsize = -1; + +/* Initialize the subtree pointers */ +static gint ett_itdm = -1; + +/* ZZZZ some magic number.. */ +static guint gbl_ItdmMPLSLabel = 0x99887; + +static dissector_handle_t itdm_handle; +static dissector_handle_t data_handle; + +#define ITDM_CMD_NEW_CHAN 1 +#define ITDM_CMD_CLOSE_CHAN 2 +#define ITDM_CMD_RELOC_CHAN 3 +#define ITDM_CMD_CYCLIC_REAF 4 +#define ITDM_CMD_PACKET_RATE 5 + +#define ITDM_FLOWID_OFFSET 7 +#define ITDM_CHCMD_OFFSET 10 +#define ITDM_CHANID_OFFSET 11 +#define ITDM_CHLOC1_OFFSET 14 +#define ITDM_CHLOC2_OFFSET 16 + +static const value_string sop_eop_vals[] = { + { 0x0, "Middle of Packet" }, + { 0x1, "End of Packet" }, + { 0x2, "Start of Packet" }, + { 0x3, "Complete Packet" }, + { 0, NULL } +}; + +#if 0 +static const value_string ack_vals[] = { + { 0x0, "Normal Command" }, + { 0x1, "Acknowledging a command from remote node" }, + { 0, NULL } +}; +#else +static const true_false_string ack_tfs = { + "Acknowledging a command from remote node", + "Normal Command" +}; +#endif + +static const value_string chcmd_vals[] = { + { 0x0, "Reserved" }, + { 0x1, "New Channel ID" }, + { 0x2, "Close Channel ID" }, + { 0x3, "Relocate Channel ID" }, + { 0x4, "Cyclic Reaffirmation" }, + { 0x5, "Packet Rate Integrity Check" }, + { 0x6, "Reserved" }, + { 0x7, "Reserved" }, + { 0x8, "Reserved" }, + { 0x9, "Reserved" }, + { 0xa, "Reserved" }, + { 0xb, "Reserved" }, + { 0xc, "Reserved" }, + { 0xd, "Reserved" }, + { 0xe, "Reserved" }, + { 0xf, "Reserved" }, + { 0, NULL } +}; + +static void +dissect_itdm_125usec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + tvbuff_t *next_tvb; + proto_item *itdm_item = NULL; + proto_tree *itdm_tree = NULL; + int offset; + guint32 flowid; + guint32 chanid; + guint16 chloc1; + guint16 chloc2; + guint8 chcmd; + guint8 actbit; + guint8 ackbit; + + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ITDM"); + + flowid = tvb_get_ntoh24(tvb, ITDM_FLOWID_OFFSET); + chanid = tvb_get_ntoh24(tvb, ITDM_CHANID_OFFSET); + chcmd = tvb_get_guint8(tvb, ITDM_CHCMD_OFFSET); + chloc1 = tvb_get_ntohs(tvb, ITDM_CHLOC1_OFFSET); + actbit = (chcmd & 0x10) ? 1 : 0; + ackbit = (chcmd & 0x20) ? 1 : 0; + chcmd = chcmd & 0x0f; + + if (check_col(pinfo->cinfo, COL_INFO)) + { + col_add_fstr(pinfo->cinfo, COL_INFO, + "Flow %d Chan %d ACT %d ACK %d %s", + flowid, chanid, actbit, ackbit, + val_to_str(chcmd, chcmd_vals, "Reserved")); + if (chcmd == ITDM_CMD_NEW_CHAN || + chcmd == ITDM_CMD_CLOSE_CHAN || + chcmd == ITDM_CMD_CYCLIC_REAF) + { + col_append_fstr(pinfo->cinfo, COL_INFO, + " Loc1 %d", chloc1); + } + else if (chcmd == ITDM_CMD_RELOC_CHAN) + { + chloc2 = tvb_get_ntohs(tvb, ITDM_CHLOC2_OFFSET); + col_append_fstr(pinfo->cinfo, COL_INFO, + " Loc1 %d Loc2 %d", chloc1, chloc2); + } + } + + offset = 0; + + if (tree) + { + itdm_item = proto_tree_add_item(tree, proto_itdm, tvb, 0, -1, FALSE); + itdm_tree = proto_item_add_subtree(itdm_item, ett_itdm); + + proto_tree_add_item(itdm_tree, hf_itdm_timestamp, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(itdm_tree, hf_itdm_seqnum, tvb, offset, 1, FALSE); + offset += 1; + proto_tree_add_item(itdm_tree, hf_itdm_sop_eop, tvb, offset, 1, FALSE); + proto_tree_add_item(itdm_tree, hf_itdm_last_pack, tvb, offset, 1, FALSE); + proto_tree_add_item(itdm_tree, hf_itdm_pktlen, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(itdm_tree, hf_itdm_chksum, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(itdm_tree, hf_itdm_uid, tvb, offset, 3, FALSE); + offset += 3; + proto_tree_add_item(itdm_tree, hf_itdm_ack, tvb, offset, 1, FALSE); + proto_tree_add_item(itdm_tree, hf_itdm_act, tvb, offset, 1, FALSE); + proto_tree_add_item(itdm_tree, hf_itdm_chcmd, tvb, offset, 1, FALSE); + offset += 1; + proto_tree_add_item(itdm_tree, hf_itdm_chid, tvb, offset, 3, FALSE); + offset += 3; + if (chcmd == ITDM_CMD_PACKET_RATE) + { + proto_tree_add_item(itdm_tree, hf_itdm_pktrate, tvb, offset, 4, FALSE); + offset += 4; + } + else + { + proto_tree_add_item(itdm_tree, hf_itdm_chloc1, tvb, offset, 2, FALSE); + offset += 2; + if (chcmd == ITDM_CMD_CYCLIC_REAF || + chcmd == ITDM_CMD_NEW_CHAN || + chcmd == ITDM_CMD_CLOSE_CHAN) + { + proto_tree_add_item(itdm_tree, hf_itdm_cxnsize, tvb, offset, 2, FALSE); + offset += 2; + } + else + { + proto_tree_add_item(itdm_tree, hf_itdm_chloc2, tvb, offset, 2, FALSE); + offset += 2; + } + } + }; + + next_tvb = tvb_new_subset(tvb, offset, -1 , -1); + call_dissector(data_handle, next_tvb, pinfo, tree); +} + +static void +dissect_itdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + /* ZZZ for now, always 125 usec mode */ + if (tvb_length(tvb) < 18) + return; + + dissect_itdm_125usec(tvb, pinfo, tree); +} + +void +proto_register_itdm(void) +{ + + static hf_register_info hf[] = { + { &hf_itdm_timestamp,{ "Timestamp", "itdm.timestamp", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_itdm_seqnum,{ "Sequence Number", "itdm.seqnum", + FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_itdm_sop_eop,{ "Start/End of Packet", "itdm.sop_eop", + FT_UINT8, BASE_DEC, VALS(sop_eop_vals), 0xc0, NULL, HFILL } }, + { &hf_itdm_last_pack,{ "Last Packet", "itdm.last_pack", + FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x20, NULL, HFILL } }, + { &hf_itdm_pktlen,{ "Packet Length", "itdm.pktlen", + FT_UINT16, BASE_DEC, NULL, 0x07ff, NULL, HFILL } }, + { &hf_itdm_chksum,{ "Checksum", "itdm.chksum", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_itdm_uid,{ "Flow ID", "itdm.uid", + FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_itdm_ack,{ "ACK", "itdm.ack", + FT_BOOLEAN, 8, TFS(&ack_tfs), 0x20, NULL, HFILL } }, + { &hf_itdm_act,{ "Activate", "itdm.act", + FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x10, NULL, HFILL } }, + { &hf_itdm_chcmd,{ "Channel Command", "itdm.chcmd", + FT_UINT8, BASE_DEC, VALS(chcmd_vals), 0x0f, NULL, HFILL } }, + { &hf_itdm_chid,{ "Channel ID", "itdm.chid", + FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_itdm_chloc1,{ "Channel Location 1", "itdm.chloc1", + FT_UINT16, BASE_DEC, NULL, 0x1ff, NULL, HFILL } }, + { &hf_itdm_chloc2,{ "Channel Location 2", "itdm.chloc2", + FT_UINT16, BASE_DEC, NULL, 0x1ff, NULL, HFILL } }, + { &hf_itdm_pktrate,{ "IEEE 754 Packet Rate", "itdm.pktrate", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_itdm_cxnsize, { "Connection Size", "itdm.cxnsize", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } } + }; + + static gint *ett[] = { + &ett_itdm + }; + + module_t *itdm_module; + + proto_itdm = proto_register_protocol("Internal TDM", "ITDM", "itdm"); + register_dissector("itdm", dissect_itdm, proto_itdm); + + proto_register_field_array(proto_itdm, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + itdm_module = prefs_register_protocol(proto_itdm, NULL); + prefs_register_uint_preference(itdm_module, "mpls_label", + "ITDM MPLS label (Flow Bundle ID)", + "The MPLS label (aka Flow Bundle ID) used by ITDM traffic.", + 16, &gbl_ItdmMPLSLabel); +} + +void +proto_reg_handoff_itdm(void) +{ + static gboolean Initialized=FALSE; + static guint ItdmMPLSLabel; + + if (!Initialized) { + itdm_handle = create_dissector_handle(dissect_itdm, proto_itdm); + data_handle = find_dissector("data"); + Initialized=TRUE; + } else { + dissector_delete("mpls.label", ItdmMPLSLabel, itdm_handle); + } + + ItdmMPLSLabel = gbl_ItdmMPLSLabel; + dissector_add("mpls.label", gbl_ItdmMPLSLabel, itdm_handle); +} |