diff options
author | Michael Tüxen <tuexen@fh-muenster.de> | 2005-01-14 22:26:18 +0000 |
---|---|---|
committer | Michael Tüxen <tuexen@fh-muenster.de> | 2005-01-14 22:26:18 +0000 |
commit | 8d5801b10d8f1b021374427947730b9a2bc96c10 (patch) | |
tree | 9c110366586228f7676fe9a8975133e384521e98 /epan/dissectors | |
parent | fd6f84b46dcad8664f180830b9951f72a255f41e (diff) |
Add support for extended sequence numbers as specified in Annex A of Q.703.
svn path=/trunk/; revision=13042
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-mtp2.c | 192 |
1 files changed, 132 insertions, 60 deletions
diff --git a/epan/dissectors/packet-mtp2.c b/epan/dissectors/packet-mtp2.c index 9dfc559b6c..e643f60dfa 100644 --- a/epan/dissectors/packet-mtp2.c +++ b/epan/dissectors/packet-mtp2.c @@ -1,9 +1,9 @@ /* packet-mtp2.c * Routines for MTP2 dissection * It is hopefully (needs testing) compliant to - * ITU-T Q.703 + * ITU-T Q.703 and Q.703 Annex A. * - * Copyright 2001, Michael Tuexen <tuexen [AT] fh-muenster.de> + * Copyright 2001, 2004 Michael Tuexen <tuexen [AT] fh-muenster.de> * * $Id$ * @@ -34,53 +34,91 @@ #include <glib.h> #include <epan/packet.h> +#include "epan/prefs.h" #define LITTLE_ENDIAN_BYTE_ORDER TRUE /* Initialize the protocol and registered fields */ -static int proto_mtp2 = -1; -static int hf_mtp2_bsn = -1; -static int hf_mtp2_bib = -1; -static int hf_mtp2_fsn = -1; -static int hf_mtp2_fib = -1; -static int hf_mtp2_li = -1; -static int hf_mtp2_spare = -1; -static int hf_mtp2_sf = -1; -static int hf_mtp2_long_sf = -1; +static int proto_mtp2 = -1; +static int hf_mtp2_bsn = -1; +static int hf_mtp2_ext_bsn = -1; +static int hf_mtp2_ext_res = -1; +static int hf_mtp2_bib = -1; +static int hf_mtp2_ext_bib = -1; +static int hf_mtp2_fsn = -1; +static int hf_mtp2_ext_fsn = -1; +static int hf_mtp2_fib = -1; +static int hf_mtp2_ext_fib = -1; +static int hf_mtp2_li = -1; +static int hf_mtp2_ext_li = -1; +static int hf_mtp2_spare = -1; +static int hf_mtp2_ext_spare = -1; +static int hf_mtp2_sf = -1; +static int hf_mtp2_long_sf = -1; /* Initialize the subtree pointers */ static gint ett_mtp2 = -1; static dissector_handle_t mtp3_handle; static int mtp3_proto_id; - -#define BSN_BIB_LENGTH 1 -#define FSN_FIB_LENGTH 1 -#define LI_LENGTH 1 -#define HEADER_LENGTH (BSN_BIB_LENGTH + FSN_FIB_LENGTH + LI_LENGTH) - -#define BSN_BIB_OFFSET 0 -#define FSN_FIB_OFFSET (BSN_BIB_OFFSET + BSN_BIB_LENGTH) -#define LI_OFFSET (FSN_FIB_OFFSET + FSN_FIB_LENGTH) -#define SIO_OFFSET (LI_OFFSET + LI_LENGTH) - -#define BSN_MASK 0x7f -#define BIB_MASK 0x80 -#define FSN_MASK 0x7f -#define FIB_MASK 0x80 -#define LI_MASK 0x3f -#define SPARE_MASK 0xc0 +static gboolean use_extended_sequence_numbers = FALSE; + +#define BSN_BIB_LENGTH 1 +#define FSN_FIB_LENGTH 1 +#define LI_LENGTH 1 +#define HEADER_LENGTH (BSN_BIB_LENGTH + FSN_FIB_LENGTH + LI_LENGTH) + +#define EXTENDED_BSN_BIB_LENGTH 2 +#define EXTENDED_FSN_FIB_LENGTH 2 +#define EXTENDED_LI_LENGTH 2 +#define EXTENDED_HEADER_LENGTH (EXTENDED_BSN_BIB_LENGTH + EXTENDED_FSN_FIB_LENGTH + EXTENDED_LI_LENGTH) + +#define BSN_BIB_OFFSET 0 +#define FSN_FIB_OFFSET (BSN_BIB_OFFSET + BSN_BIB_LENGTH) +#define LI_OFFSET (FSN_FIB_OFFSET + FSN_FIB_LENGTH) +#define SIO_OFFSET (LI_OFFSET + LI_LENGTH) + +#define EXTENDED_BSN_BIB_OFFSET 0 +#define EXTENDED_FSN_FIB_OFFSET (EXTENDED_BSN_BIB_OFFSET + EXTENDED_BSN_BIB_LENGTH) +#define EXTENDED_LI_OFFSET (EXTENDED_FSN_FIB_OFFSET + EXTENDED_FSN_FIB_LENGTH) +#define EXTENDED_SIO_OFFSET (EXTENDED_LI_OFFSET + EXTENDED_LI_LENGTH) + +#define BSN_MASK 0x7f +#define BIB_MASK 0x80 +#define FSN_MASK 0x7f +#define FIB_MASK 0x80 +#define LI_MASK 0x3f +#define SPARE_MASK 0xc0 + +#define EXTENDED_BSN_MASK 0x0fff +#define EXTENDED_RES_MASK 0x7000 +#define EXTENDED_BIB_MASK 0x8000 +#define EXTENDED_FSN_MASK 0x0fff +#define EXTENDED_FIB_MASK 0x8000 +#define EXTENDED_LI_MASK 0x01ff +#define EXTENDED_SPARE_MASK 0xfe00 static void dissect_mtp2_header(tvbuff_t *su_tvb, proto_item *mtp2_tree) { if (mtp2_tree) { - proto_tree_add_item(mtp2_tree, hf_mtp2_bsn, su_tvb, BSN_BIB_OFFSET, BSN_BIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); - proto_tree_add_item(mtp2_tree, hf_mtp2_bib, su_tvb, BSN_BIB_OFFSET, BSN_BIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); - proto_tree_add_item(mtp2_tree, hf_mtp2_fsn, su_tvb, FSN_FIB_OFFSET, FSN_FIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); - proto_tree_add_item(mtp2_tree, hf_mtp2_fib, su_tvb, FSN_FIB_OFFSET, FSN_FIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); - proto_tree_add_item(mtp2_tree, hf_mtp2_li, su_tvb, LI_OFFSET, LI_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); - proto_tree_add_item(mtp2_tree, hf_mtp2_spare, su_tvb, LI_OFFSET, LI_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + if (use_extended_sequence_numbers) { + proto_tree_add_item(mtp2_tree, hf_mtp2_ext_bsn, su_tvb, EXTENDED_BSN_BIB_OFFSET, EXTENDED_BSN_BIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_ext_res, su_tvb, EXTENDED_BSN_BIB_OFFSET, EXTENDED_BSN_BIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_ext_bib, su_tvb, EXTENDED_BSN_BIB_OFFSET, EXTENDED_BSN_BIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_ext_fsn, su_tvb, EXTENDED_FSN_FIB_OFFSET, EXTENDED_FSN_FIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_ext_res, su_tvb, EXTENDED_BSN_BIB_OFFSET, EXTENDED_BSN_BIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_ext_fib, su_tvb, EXTENDED_FSN_FIB_OFFSET, EXTENDED_FSN_FIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_ext_li, su_tvb, EXTENDED_LI_OFFSET, EXTENDED_LI_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_ext_spare, su_tvb, EXTENDED_LI_OFFSET, EXTENDED_LI_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + } else { + proto_tree_add_item(mtp2_tree, hf_mtp2_bsn, su_tvb, BSN_BIB_OFFSET, BSN_BIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_bib, su_tvb, BSN_BIB_OFFSET, BSN_BIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_fsn, su_tvb, FSN_FIB_OFFSET, FSN_FIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_fib, su_tvb, FSN_FIB_OFFSET, FSN_FIB_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_li, su_tvb, LI_OFFSET, LI_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + proto_tree_add_item(mtp2_tree, hf_mtp2_spare, su_tvb, LI_OFFSET, LI_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + } } } @@ -101,24 +139,30 @@ static const value_string status_field_vals[] = { { 0, NULL} }; -#define SF_OFFSET (LI_OFFSET + LI_LENGTH) -#define SF_LENGTH 1 -#define LONG_SF_LENGTH 2 +#define SF_OFFSET (LI_OFFSET + LI_LENGTH) +#define EXTENDED_SF_OFFSET (EXTENDED_LI_OFFSET + EXTENDED_LI_LENGTH) + +#define SF_LENGTH 1 +#define LONG_SF_LENGTH 2 static void dissect_mtp2_lssu(tvbuff_t *su_tvb, packet_info *pinfo, proto_item *mtp2_tree) { - guint8 li; - if (check_col(pinfo->cinfo, COL_INFO)) col_set_str(pinfo->cinfo, COL_INFO, "LSSU "); if (mtp2_tree) { - li = tvb_get_guint8(su_tvb, LI_OFFSET); - if ((li & LI_MASK) == 1) - proto_tree_add_item(mtp2_tree, hf_mtp2_sf, su_tvb, SF_OFFSET, SF_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); - else - proto_tree_add_item(mtp2_tree, hf_mtp2_long_sf, su_tvb, SF_OFFSET, LONG_SF_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + if (use_extended_sequence_numbers) { + if ((tvb_get_letohs(su_tvb, EXTENDED_LI_OFFSET) & EXTENDED_LI_MASK) == 1) + proto_tree_add_item(mtp2_tree, hf_mtp2_sf, su_tvb, EXTENDED_SF_OFFSET, SF_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + else + proto_tree_add_item(mtp2_tree, hf_mtp2_long_sf, su_tvb, EXTENDED_SF_OFFSET, LONG_SF_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + } else { + if ((tvb_get_guint8(su_tvb, LI_OFFSET) & LI_MASK) == 1) + proto_tree_add_item(mtp2_tree, hf_mtp2_sf, su_tvb, SF_OFFSET, SF_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + else + proto_tree_add_item(mtp2_tree, hf_mtp2_long_sf, su_tvb, SF_OFFSET, LONG_SF_LENGTH, LITTLE_ENDIAN_BYTE_ORDER); + } } } @@ -131,23 +175,34 @@ dissect_mtp2_msu(tvbuff_t *su_tvb, packet_info *pinfo, proto_item *mtp2_item, pr if (check_col(pinfo->cinfo, COL_INFO)) col_set_str(pinfo->cinfo, COL_INFO, "MSU "); - sif_sio_length = tvb_length(su_tvb) - HEADER_LENGTH; - sif_sio_tvb = tvb_new_subset(su_tvb, SIO_OFFSET, sif_sio_length, sif_sio_length); + if (use_extended_sequence_numbers) { + sif_sio_length = tvb_length(su_tvb) - EXTENDED_HEADER_LENGTH; + sif_sio_tvb = tvb_new_subset(su_tvb, EXTENDED_SIO_OFFSET, sif_sio_length, sif_sio_length); + } else { + sif_sio_length = tvb_length(su_tvb) - HEADER_LENGTH; + sif_sio_tvb = tvb_new_subset(su_tvb, SIO_OFFSET, sif_sio_length, sif_sio_length); + } call_dissector(mtp3_handle, sif_sio_tvb, pinfo, tree); - if (tree) - proto_item_set_len(mtp2_item, HEADER_LENGTH); - + if (tree) { + if (use_extended_sequence_numbers) + proto_item_set_len(mtp2_item, EXTENDED_HEADER_LENGTH); + else + proto_item_set_len(mtp2_item, HEADER_LENGTH); + } } static void dissect_mtp2_su(tvbuff_t *su_tvb, packet_info *pinfo, proto_item *mtp2_item, proto_item *mtp2_tree, proto_tree *tree) { - guint8 li; + guint16 li; dissect_mtp2_header(su_tvb, mtp2_tree); - li = tvb_get_guint8(su_tvb, LI_OFFSET); - switch(li & LI_MASK) { + if (use_extended_sequence_numbers) + li = tvb_get_letohs(su_tvb, EXTENDED_LI_OFFSET) & EXTENDED_LI_MASK; + else + li = tvb_get_guint8(su_tvb, LI_OFFSET) & LI_MASK; + switch(li) { case 0: dissect_mtp2_fisu(pinfo); break; @@ -183,25 +238,42 @@ proto_register_mtp2(void) { static hf_register_info hf[] = { - { &hf_mtp2_bsn, { "Backward sequence number", "mtp2.bsn", FT_UINT8, BASE_DEC, NULL, BSN_MASK, "", HFILL } }, - { &hf_mtp2_bib, { "Backward indicator bit", "mtp2.bib", FT_UINT8, BASE_DEC, NULL, BIB_MASK, "", HFILL } }, - { &hf_mtp2_fsn, { "Forward sequence number", "mtp2.fsn", FT_UINT8, BASE_DEC, NULL, FSN_MASK, "", HFILL } }, - { &hf_mtp2_fib, { "Forward indicator bit", "mtp2.fib", FT_UINT8, BASE_DEC, NULL, FIB_MASK, "", HFILL } }, - { &hf_mtp2_li, { "Length Indicator", "mtp2.li", FT_UINT8, BASE_DEC, NULL, LI_MASK, "", HFILL } }, - { &hf_mtp2_spare, { "Spare", "mtp2.spare", FT_UINT8, BASE_DEC, NULL, SPARE_MASK, "", HFILL } }, - { &hf_mtp2_sf, { "Status field", "mtp2.sf", FT_UINT8, BASE_DEC, VALS(status_field_vals), 0x0, "", HFILL } }, - { &hf_mtp2_long_sf, { "Status field", "mtp2.sf", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } } + { &hf_mtp2_bsn, { "Backward sequence number", "mtp2.bsn", FT_UINT8, BASE_DEC, NULL, BSN_MASK, "", HFILL } }, + { &hf_mtp2_ext_bsn, { "Backward sequence number", "mtp2.bsn", FT_UINT16, BASE_DEC, NULL, EXTENDED_BSN_MASK, "", HFILL } }, + { &hf_mtp2_ext_res, { "Reserved", "mtp2.res", FT_UINT16, BASE_DEC, NULL, EXTENDED_RES_MASK, "", HFILL } }, + { &hf_mtp2_bib, { "Backward indicator bit", "mtp2.bib", FT_UINT8, BASE_DEC, NULL, BIB_MASK, "", HFILL } }, + { &hf_mtp2_ext_bib, { "Backward indicator bit", "mtp2.bib", FT_UINT16, BASE_DEC, NULL, EXTENDED_BIB_MASK, "", HFILL } }, + { &hf_mtp2_fsn, { "Forward sequence number", "mtp2.fsn", FT_UINT8, BASE_DEC, NULL, FSN_MASK, "", HFILL } }, + { &hf_mtp2_ext_fsn, { "Forward sequence number", "mtp2.fsn", FT_UINT16, BASE_DEC, NULL, EXTENDED_FSN_MASK, "", HFILL } }, + { &hf_mtp2_fib, { "Forward indicator bit", "mtp2.fib", FT_UINT8, BASE_DEC, NULL, FIB_MASK, "", HFILL } }, + { &hf_mtp2_ext_fib, { "Forward indicator bit", "mtp2.fib", FT_UINT16, BASE_DEC, NULL, EXTENDED_FIB_MASK, "", HFILL } }, + { &hf_mtp2_li, { "Length Indicator", "mtp2.li", FT_UINT8, BASE_DEC, NULL, LI_MASK, "", HFILL } }, + { &hf_mtp2_ext_li, { "Length Indicator", "mtp2.li", FT_UINT16, BASE_DEC, NULL, EXTENDED_LI_MASK, "", HFILL } }, + { &hf_mtp2_spare, { "Spare", "mtp2.spare", FT_UINT8, BASE_DEC, NULL, SPARE_MASK, "", HFILL } }, + { &hf_mtp2_ext_spare, { "Spare", "mtp2.spare", FT_UINT16, BASE_DEC, NULL, EXTENDED_SPARE_MASK, "", HFILL } }, + { &hf_mtp2_sf, { "Status field", "mtp2.sf", FT_UINT8, BASE_DEC, VALS(status_field_vals), 0x0, "", HFILL } }, + { &hf_mtp2_long_sf, { "Status field", "mtp2.sf", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } } }; static gint *ett[] = { &ett_mtp2 }; + module_t *mtp2_module; + proto_mtp2 = proto_register_protocol("Message Transfer Part Level 2", "MTP2", "mtp2"); register_dissector("mtp2", dissect_mtp2, proto_mtp2); proto_register_field_array(proto_mtp2, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); + + mtp2_module = prefs_register_protocol(proto_mtp2, NULL); + prefs_register_bool_preference(mtp2_module, + "use_extended_sequence_numbers", + "Use extended sequence numbers", + "Whether the MTP2 dissector should use extended sequence numbers as described in Q.703, Annex A", + &use_extended_sequence_numbers); + } |