From Michael Lum:
GSM A facility element decoding; make TCAP dissector export routines for use by various GSM dissectors; make GSM MAP dissector use exported TCAP routines/defines; GSM Supplementary Services support. svn path=/trunk/; revision=10409
This commit is contained in:
parent
e39c338b07
commit
11340a8122
1
AUTHORS
1
AUTHORS
|
@ -1836,6 +1836,7 @@ Michael Lum <mlum [AT] telostech.com> {
|
|||
GSM SMS (3GPP TS 24.011) support
|
||||
GSM SS (3GPP TS 24.080) support
|
||||
GSM SMS TPDU (3GPP TS 23.040) support
|
||||
GSM Supplementary Services support
|
||||
GSM MAP fixes and parameter separation
|
||||
Taps for ANSI A-interface statistics
|
||||
Support for SS7 point codes as address types
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# a) common to both files and
|
||||
# b) portable between both files
|
||||
#
|
||||
# $Id: Makefile.common,v 1.29 2004/03/18 08:25:09 guy Exp $
|
||||
# $Id: Makefile.common,v 1.30 2004/03/19 07:54:57 guy Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -94,6 +94,7 @@ DISSECTOR_INCLUDES = \
|
|||
packet-gnutella.h \
|
||||
packet-gsm_a.h \
|
||||
packet-gsm_map.h \
|
||||
packet-gsm_ss.h \
|
||||
packet-gssapi.h \
|
||||
packet-gtp.h \
|
||||
packet-h225.h \
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# a) common to both files and
|
||||
# b) portable between both files
|
||||
#
|
||||
# $Id: Makefile.common,v 1.8 2004/03/18 08:25:09 guy Exp $
|
||||
# $Id: Makefile.common,v 1.9 2004/03/19 07:54:58 guy Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -198,6 +198,7 @@ DISSECTOR_SRC = \
|
|||
../packet-gsm_map.c \
|
||||
../packet-gsm_sms.c \
|
||||
../packet-gsm_sms_ud.c \
|
||||
../packet-gsm_ss.c \
|
||||
../packet-gssapi.c \
|
||||
../packet-gtp.c \
|
||||
../packet-gvrp.c \
|
||||
|
|
502
packet-gsm_a.c
502
packet-gsm_a.c
|
@ -38,7 +38,7 @@
|
|||
* Formats and coding
|
||||
* (3GPP TS 24.080 version 4.3.0 Release 4)
|
||||
*
|
||||
* $Id: packet-gsm_a.c,v 1.11 2004/02/20 10:50:13 guy Exp $
|
||||
* $Id: packet-gsm_a.c,v 1.12 2004/03/19 07:54:57 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -71,8 +71,11 @@
|
|||
#include "epan/packet.h"
|
||||
#include "prefs.h"
|
||||
#include "tap.h"
|
||||
#include "asn1.h"
|
||||
|
||||
#include "packet-tcap.h"
|
||||
#include "packet-bssap.h"
|
||||
#include "packet-gsm_ss.h"
|
||||
#include "packet-gsm_a.h"
|
||||
|
||||
/* PROTOTYPES/FORWARDS */
|
||||
|
@ -684,6 +687,8 @@ static int hf_gsm_a_cell_lac = -1;
|
|||
static int hf_gsm_a_dlci_cc = -1;
|
||||
static int hf_gsm_a_dlci_spare = -1;
|
||||
static int hf_gsm_a_dlci_sapi = -1;
|
||||
static int hf_gsm_a_bssmap_cause = -1;
|
||||
static int hf_gsm_a_dtap_cause = -1;
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static gint ett_bssmap_msg = -1;
|
||||
|
@ -711,6 +716,14 @@ static gint ett_bc_oct_6f = -1;
|
|||
static gint ett_bc_oct_6g = -1;
|
||||
static gint ett_bc_oct_7 = -1;
|
||||
|
||||
static gint ett_tc_component = -1;
|
||||
static gint ett_tc_invoke_id = -1;
|
||||
static gint ett_tc_linked_id = -1;
|
||||
static gint ett_tc_opr_code = -1;
|
||||
static gint ett_tc_err_code = -1;
|
||||
static gint ett_tc_prob_code = -1;
|
||||
static gint ett_tc_sequence = -1;
|
||||
|
||||
static char a_bigbuf[1024];
|
||||
static gchar a_add_string[1024];
|
||||
|
||||
|
@ -1214,8 +1227,8 @@ be_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_
|
|||
}
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
proto_tree_add_uint_format(tree, hf_gsm_a_bssmap_cause,
|
||||
tvb, curr_offset, 1, oct & 0x7f,
|
||||
"%s : Cause: (%u) %s",
|
||||
a_bigbuf,
|
||||
oct & 0x7f,
|
||||
|
@ -5907,8 +5920,8 @@ de_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_
|
|||
}
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
proto_tree_add_uint_format(tree, hf_gsm_a_dtap_cause,
|
||||
tvb, curr_offset, 1, cause,
|
||||
"%s : Cause: (%u) %s",
|
||||
a_bigbuf,
|
||||
cause,
|
||||
|
@ -5931,6 +5944,332 @@ de_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_
|
|||
return(curr_offset - offset);
|
||||
}
|
||||
|
||||
|
||||
#define GSM_A_TC_START_SUBTREE(_Gtree, _Gsaved_offset, _Gtag, _Gstr1, _Gett, _Gdef_len_p, _Glen_p, _Gsubtree_p) \
|
||||
{ \
|
||||
guint _len_offset; \
|
||||
proto_item *_item; \
|
||||
\
|
||||
_len_offset = asn1->offset; \
|
||||
asn1_length_decode(asn1, _Gdef_len_p, _Glen_p); \
|
||||
\
|
||||
_item = \
|
||||
proto_tree_add_text(_Gtree, asn1->tvb, _Gsaved_offset, -1, _Gstr1); \
|
||||
\
|
||||
_Gsubtree_p = proto_item_add_subtree(_item, _Gett); \
|
||||
\
|
||||
proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
|
||||
_Gsaved_offset, _len_offset - _Gsaved_offset, "Tag: 0x%02x", _Gtag); \
|
||||
\
|
||||
if (*_Gdef_len_p) \
|
||||
{ \
|
||||
proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
|
||||
_len_offset, asn1->offset - _len_offset, "Length: %d", *_Glen_p); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
|
||||
_len_offset, asn1->offset - _len_offset, "Length: Indefinite"); \
|
||||
\
|
||||
*_Glen_p = tcap_find_eoc(asn1); \
|
||||
} \
|
||||
\
|
||||
proto_item_set_len(_item, (asn1->offset - _Gsaved_offset) + *_Glen_p + \
|
||||
(*_Gdef_len_p ? 0 : TCAP_EOC_LEN)); \
|
||||
}
|
||||
|
||||
/*
|
||||
* [6] 3.6
|
||||
*/
|
||||
static guint8
|
||||
de_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
|
||||
{
|
||||
ASN1_SCK asn1_real, *asn1;
|
||||
proto_item *item;
|
||||
proto_tree *subtree, *temp_subtree, *seq_subtree;
|
||||
guint saved_offset, comp_saved_offset, comp_len_offset, comp_data_offset;
|
||||
guint comp_len, temp_len;
|
||||
gboolean def_len[3];
|
||||
guint comp_tag, tag;
|
||||
gchar *str;
|
||||
gint32 int_val;
|
||||
|
||||
add_string = add_string;
|
||||
|
||||
asn1 = &asn1_real;
|
||||
asn1_open(asn1, tvb, offset);
|
||||
|
||||
/* call next dissector for EACH component */
|
||||
|
||||
while ((len - (asn1->offset - offset)) > 0)
|
||||
{
|
||||
comp_saved_offset = asn1->offset;
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &comp_tag);
|
||||
|
||||
comp_len_offset = asn1->offset;
|
||||
comp_len = 0;
|
||||
def_len[0] = FALSE;
|
||||
asn1_length_decode(asn1, &def_len[0], &comp_len);
|
||||
comp_data_offset = asn1->offset;
|
||||
|
||||
if (def_len[0])
|
||||
{
|
||||
temp_len = comp_len + (asn1->offset - saved_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
comp_len = tcap_find_eoc(asn1);
|
||||
temp_len = comp_len + (asn1->offset - saved_offset) + TCAP_EOC_LEN;
|
||||
}
|
||||
|
||||
item =
|
||||
proto_tree_add_text(tree, asn1->tvb, comp_saved_offset, temp_len, "Component");
|
||||
|
||||
subtree = proto_item_add_subtree(item, ett_tc_component);
|
||||
|
||||
str = match_strval((guint32) comp_tag, tcap_component_type_str);
|
||||
|
||||
if (str == NULL)
|
||||
{
|
||||
proto_tree_add_text(subtree, asn1->tvb, comp_saved_offset, temp_len,
|
||||
"Unknown component type tag, ignoring component");
|
||||
|
||||
asn1->offset = comp_saved_offset + temp_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb, comp_saved_offset,
|
||||
comp_len_offset - comp_saved_offset,
|
||||
"%s Type Tag: 0x%02x", str, comp_tag);
|
||||
|
||||
if (def_len[0])
|
||||
{
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
comp_len_offset, asn1->offset - comp_len_offset, "Length: %d", comp_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
comp_len_offset, asn1->offset - comp_len_offset, "Length: Indefinite");
|
||||
}
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Invoke ID",
|
||||
ett_tc_invoke_id, &def_len[1], &temp_len, temp_subtree);
|
||||
|
||||
if (temp_len > 0)
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_int32_value_decode(asn1, temp_len, &int_val);
|
||||
|
||||
proto_tree_add_text(temp_subtree, asn1->tvb,
|
||||
saved_offset, temp_len, "Invoke ID: %d", int_val);
|
||||
}
|
||||
|
||||
if (!def_len[1])
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
|
||||
switch (comp_tag)
|
||||
{
|
||||
case TCAP_COMP_INVOKE:
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
if (tag == TCAP_LINKED_ID_TAG)
|
||||
{
|
||||
GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Linked ID",
|
||||
ett_tc_linked_id, &def_len[1], &temp_len, temp_subtree);
|
||||
|
||||
if (temp_len > 0)
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_int32_value_decode(asn1, temp_len, &int_val);
|
||||
|
||||
proto_tree_add_text(temp_subtree, asn1->tvb,
|
||||
saved_offset, temp_len, "Linked ID: %d", int_val);
|
||||
}
|
||||
|
||||
if (!def_len[1])
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
}
|
||||
|
||||
GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Operation Code",
|
||||
ett_tc_opr_code, &def_len[1], &temp_len, temp_subtree);
|
||||
|
||||
if (temp_len > 0)
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_int32_value_decode(asn1, temp_len, &int_val);
|
||||
|
||||
str = match_strval(int_val, gsm_ss_opr_code_strings);
|
||||
|
||||
proto_tree_add_text(temp_subtree, asn1->tvb,
|
||||
saved_offset, temp_len, "Operation Code: %s (%d)",
|
||||
(str == NULL) ? "Unknown Operation Code" : str,
|
||||
int_val);
|
||||
}
|
||||
|
||||
if (!def_len[1])
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
|
||||
if ((comp_len - (asn1->offset - comp_data_offset)) > 0)
|
||||
{
|
||||
gsm_ss_dissect(asn1, subtree,
|
||||
comp_len - (asn1->offset - comp_data_offset), int_val, comp_tag);
|
||||
}
|
||||
break;
|
||||
|
||||
case TCAP_COMP_RRL:
|
||||
if ((len - (asn1->offset - offset)) > 0)
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Sequence",
|
||||
ett_tc_sequence, &def_len[1], &temp_len, seq_subtree);
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
GSM_A_TC_START_SUBTREE(seq_subtree, saved_offset, tag, "Operation Code",
|
||||
ett_tc_opr_code, &def_len[2], &temp_len, temp_subtree);
|
||||
|
||||
if (temp_len > 0)
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_int32_value_decode(asn1, temp_len, &int_val);
|
||||
|
||||
str = match_strval(int_val, gsm_ss_opr_code_strings);
|
||||
|
||||
proto_tree_add_text(temp_subtree, asn1->tvb,
|
||||
saved_offset, temp_len, "Operation Code: %s (%d)",
|
||||
(str == NULL) ? "Unknown Operation Code" : str,
|
||||
int_val);
|
||||
}
|
||||
|
||||
if (!def_len[2])
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
|
||||
if ((comp_len - (asn1->offset - comp_data_offset)) > 0)
|
||||
{
|
||||
gsm_ss_dissect(asn1, seq_subtree,
|
||||
comp_len - (asn1->offset - comp_data_offset), int_val, comp_tag);
|
||||
}
|
||||
|
||||
if (!def_len[1])
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TCAP_COMP_RE:
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Error Code",
|
||||
ett_tc_err_code, &def_len[1], &temp_len, temp_subtree);
|
||||
|
||||
if (temp_len > 0)
|
||||
{
|
||||
proto_tree_add_text(temp_subtree, asn1->tvb,
|
||||
asn1->offset, temp_len, "Error Code");
|
||||
|
||||
asn1->offset += temp_len;
|
||||
}
|
||||
|
||||
if (!def_len[1])
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
|
||||
if ((comp_len - (asn1->offset - comp_data_offset)) > 0)
|
||||
{
|
||||
/*
|
||||
* XXX need conversations to determine 'opr_code'
|
||||
*/
|
||||
gsm_ss_dissect(asn1, subtree,
|
||||
comp_len - (asn1->offset - comp_data_offset), 0, comp_tag);
|
||||
}
|
||||
break;
|
||||
|
||||
case TCAP_COMP_REJECT:
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
GSM_A_TC_START_SUBTREE(subtree, saved_offset, tag, "Problem Code",
|
||||
ett_tc_prob_code, &def_len[1], &temp_len, temp_subtree);
|
||||
|
||||
if (temp_len > 0)
|
||||
{
|
||||
proto_tree_add_text(temp_subtree, asn1->tvb,
|
||||
asn1->offset, temp_len, "Problem Code");
|
||||
|
||||
asn1->offset += temp_len;
|
||||
}
|
||||
|
||||
if (!def_len[1])
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!def_len[0])
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
}
|
||||
|
||||
return(len);
|
||||
}
|
||||
|
||||
/*
|
||||
* [3] 10.5.4.17
|
||||
*/
|
||||
|
@ -5939,7 +6278,6 @@ de_keypad_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, g
|
|||
{
|
||||
guint8 oct;
|
||||
guint32 curr_offset;
|
||||
gchar *str;
|
||||
|
||||
len = len;
|
||||
curr_offset = offset;
|
||||
|
@ -5952,16 +6290,6 @@ de_keypad_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, g
|
|||
"%s : Spare",
|
||||
a_bigbuf);
|
||||
|
||||
switch ((oct & 0x60) >> 5)
|
||||
{
|
||||
case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
|
||||
case 1: str = "Reserved for other international standards"; break;
|
||||
case 2: str = "National standard"; break;
|
||||
default:
|
||||
str = "Standard defined for the GSM PLMNS";
|
||||
break;
|
||||
}
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
|
@ -5978,6 +6306,113 @@ de_keypad_facility(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, g
|
|||
return(curr_offset - offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* [3] 10.5.4.21
|
||||
*/
|
||||
static guint8
|
||||
de_prog_ind(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
|
||||
{
|
||||
guint8 oct;
|
||||
guint32 curr_offset;
|
||||
gchar *str;
|
||||
|
||||
len = len;
|
||||
curr_offset = offset;
|
||||
|
||||
oct = tvb_get_guint8(tvb, curr_offset);
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
"%s : Extension: %s",
|
||||
a_bigbuf,
|
||||
(oct & 0x80) ? "extended" : "not extended");
|
||||
|
||||
switch ((oct & 0x60) >> 5)
|
||||
{
|
||||
case 0: str = "Coding as specified in ITU-T Rec. Q.931"; break;
|
||||
case 1: str = "Reserved for other international standards"; break;
|
||||
case 2: str = "National standard"; break;
|
||||
default:
|
||||
str = "Standard defined for the GSM PLMNS";
|
||||
break;
|
||||
}
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
"%s : Coding standard: %s",
|
||||
a_bigbuf,
|
||||
str);
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
"%s : Spare",
|
||||
a_bigbuf);
|
||||
|
||||
switch (oct & 0x0f)
|
||||
{
|
||||
case 0: str = "User"; break;
|
||||
case 1: str = "Private network serving the local user"; break;
|
||||
case 2: str = "Public network serving the local user"; break;
|
||||
case 4: str = "Public network serving the remote user"; break;
|
||||
case 5: str = "Private network serving the remote user"; break;
|
||||
case 10: str = "Network beyond interworking point"; break;
|
||||
default:
|
||||
str = "Reserved";
|
||||
break;
|
||||
}
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
"%s : Location: %s",
|
||||
a_bigbuf,
|
||||
str);
|
||||
|
||||
curr_offset++;
|
||||
|
||||
oct = tvb_get_guint8(tvb, curr_offset);
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
"%s : Extension: %s",
|
||||
a_bigbuf,
|
||||
(oct & 0x80) ? "extended" : "not extended");
|
||||
|
||||
switch (oct & 0x7f)
|
||||
{
|
||||
case 1: str = "Call is not end-to-end PLMN/ISDN, further call progress information may be available in-band"; break;
|
||||
case 2: str = "Destination address in non-PLMN/ISDN"; break;
|
||||
case 3: str = "Origination address in non-PLMN/ISDN"; break;
|
||||
case 4: str = "Call has returned to the PLMN/ISDN"; break;
|
||||
case 8: str = "In-band information or appropriate pattern now available"; break;
|
||||
case 32: str = "Call is end-to-end PLMN/ISDN"; break;
|
||||
case 64: str = "Queueing"; break;
|
||||
default:
|
||||
str = "Unspecific";
|
||||
break;
|
||||
}
|
||||
|
||||
other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
|
||||
proto_tree_add_text(tree,
|
||||
tvb, curr_offset, 1,
|
||||
"%s : Progress Description: %s (%d)",
|
||||
a_bigbuf,
|
||||
str,
|
||||
oct & 0x7f);
|
||||
|
||||
sprintf(add_string, " - %d", oct & 0x7f);
|
||||
|
||||
curr_offset++;
|
||||
|
||||
EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
|
||||
|
||||
return(curr_offset - offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* [3] 10.5.4.22
|
||||
*/
|
||||
|
@ -6409,13 +6844,13 @@ static guint8 (*dtap_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset
|
|||
NULL /* handled inline */, /* Congestion Level */
|
||||
NULL, /* Connected Number */
|
||||
NULL, /* Connected Subaddress */
|
||||
NULL, /* Facility */
|
||||
de_facility, /* Facility */
|
||||
NULL, /* High Layer Compatibility */
|
||||
de_keypad_facility, /* Keypad Facility */
|
||||
NULL, /* Low Layer Compatibility */
|
||||
NULL, /* More Data */
|
||||
NULL, /* Notification Indicator */
|
||||
NULL, /* Progress Indicator */
|
||||
de_prog_ind, /* Progress Indicator */
|
||||
NULL, /* Recall type $(CCBS)$ */
|
||||
NULL, /* Redirecting Party BCD Number */
|
||||
NULL, /* Redirecting Party Subaddress */
|
||||
|
@ -10723,19 +11158,32 @@ proto_register_gsm_a(void)
|
|||
{ &hf_gsm_a_dlci_cc,
|
||||
{ "Control Channel", "bssap.dlci.cc",
|
||||
FT_UINT8, BASE_HEX, VALS(bssap_cc_values), 0xc0,
|
||||
"", HFILL}},
|
||||
"", HFILL}
|
||||
},
|
||||
{ &hf_gsm_a_dlci_spare,
|
||||
{ "Spare", "bssap.dlci.spare",
|
||||
FT_UINT8, BASE_HEX, NULL, 0x38,
|
||||
"", HFILL}},
|
||||
"", HFILL}
|
||||
},
|
||||
{ &hf_gsm_a_dlci_sapi,
|
||||
{ "SAPI", "bssap.dlci.sapi",
|
||||
FT_UINT8, BASE_HEX, VALS(bssap_sapi_values), 0x07,
|
||||
"", HFILL}},
|
||||
"", HFILL}
|
||||
},
|
||||
{ &hf_gsm_a_bssmap_cause,
|
||||
{ "BSSMAP Cause", "gsm_a_bssmap.cause",
|
||||
FT_UINT8, BASE_HEX, 0, 0x0,
|
||||
"", HFILL }
|
||||
},
|
||||
{ &hf_gsm_a_dtap_cause,
|
||||
{ "DTAP Cause", "gsm_a_dtap.cause",
|
||||
FT_UINT8, BASE_HEX, 0, 0x0,
|
||||
"", HFILL }
|
||||
},
|
||||
};
|
||||
|
||||
/* Setup protocol subtree array */
|
||||
#define NUM_INDIVIDUAL_ELEMS 24
|
||||
#define NUM_INDIVIDUAL_ELEMS 33
|
||||
static gint *ett[NUM_INDIVIDUAL_ELEMS + NUM_GSM_BSSMAP_MSG +
|
||||
NUM_GSM_DTAP_MSG_MM + NUM_GSM_DTAP_MSG_RR + NUM_GSM_DTAP_MSG_CC +
|
||||
NUM_GSM_DTAP_MSG_GMM + NUM_GSM_DTAP_MSG_SMS +
|
||||
|
@ -10769,6 +11217,16 @@ proto_register_gsm_a(void)
|
|||
ett[22] = &ett_bc_oct_6g;
|
||||
ett[23] = &ett_bc_oct_7;
|
||||
|
||||
ett[24] = &ett_tc_component;
|
||||
ett[25] = &ett_tc_invoke_id;
|
||||
ett[26] = &ett_tc_linked_id;
|
||||
ett[27] = &ett_tc_opr_code;
|
||||
ett[28] = &ett_tc_err_code;
|
||||
ett[29] = &ett_tc_prob_code;
|
||||
ett[30] = &ett_tc_sequence;
|
||||
ett[31] = &gsm_ss_ett_sequence;
|
||||
ett[32] = &gsm_ss_ett_param;
|
||||
|
||||
last_offset = NUM_INDIVIDUAL_ELEMS;
|
||||
|
||||
for (i=0; i < NUM_GSM_BSSMAP_MSG; i++, last_offset++)
|
||||
|
|
683
packet-gsm_map.c
683
packet-gsm_map.c
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,810 @@
|
|||
/* packet-gsm_ss.c
|
||||
* Routines for GSM Supplementary Services dissection
|
||||
*
|
||||
* NOTE:
|
||||
* Routines are shared by GSM MAP/GSM A dissectors.
|
||||
* This file provides SHARED routines and is NOT a
|
||||
* standalone dissector.
|
||||
*
|
||||
* Copyright 2004, Michael Lum <mlum [AT] telostech.com>
|
||||
* In association with Telos Technology Inc.
|
||||
*
|
||||
* Title 3GPP Other
|
||||
*
|
||||
* Reference [1]
|
||||
* Mobile radio Layer 3 supplementary service specification;
|
||||
* Formats and coding
|
||||
* (3GPP TS 24.080 version 4.3.0 Release 4)
|
||||
*
|
||||
* Michael Lum <mlum [AT] telostech.com>,
|
||||
* Created (2004).
|
||||
*
|
||||
* $Id: packet-gsm_ss.c,v 1.1 2004/03/19 07:54:57 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* Copied from packet-gsm_map.c (where "WHATEVER_FILE_YOU_USED"
|
||||
* is a dissector file; if you just copied this from README.developer,
|
||||
* don't bother with the "Copied from" - you don't even need to put
|
||||
* in a "Copied from" if you copied an existing dissector, especially
|
||||
* if the bulk of the code in the new dissector is your code)
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "epan/packet.h"
|
||||
#include "tap.h"
|
||||
#include "asn1.h"
|
||||
|
||||
#include "packet-tcap.h"
|
||||
#include "packet-gsm_ss.h"
|
||||
|
||||
|
||||
const value_string gsm_ss_opr_code_strings[] = {
|
||||
{ 10, "RegisterSS" },
|
||||
{ 11, "EraseSS" },
|
||||
{ 12, "ActivateSS" },
|
||||
{ 13, "DeactivateSS" },
|
||||
{ 14, "InterrogateSS" },
|
||||
{ 16, "NotifySS" },
|
||||
{ 17, "RegisterPassword" },
|
||||
{ 18, "GetPassword" },
|
||||
{ 19, "ProcessUnstructuredSS-Data" },
|
||||
{ 38, "ForwardCheckSS-Indication" },
|
||||
{ 59, "ProcessUnstructuredSS-Request" },
|
||||
{ 60, "UnstructuredSS-Request" },
|
||||
{ 61, "UnstructuredSS-Notify" },
|
||||
{ 77, "EraseCC-Entry" },
|
||||
{ 119, "AccessRegisterCCEntry" },
|
||||
{ 120, "ForwardCUG-Info" },
|
||||
{ 121, "SplitMPTY" },
|
||||
{ 122, "RetrieveMPTY" },
|
||||
{ 123, "HoldMPTY" },
|
||||
{ 124, "BuildMPTY" },
|
||||
{ 125, "ForwardChargeAdvice" },
|
||||
{ 126, "ExplicitCT" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
/* never initialize in field array */
|
||||
static int hf_null = -1;
|
||||
#define HF_NULL &hf_null
|
||||
|
||||
gint gsm_ss_ett_sequence = -1;
|
||||
gint gsm_ss_ett_param = -1;
|
||||
|
||||
|
||||
/* GENERIC HELPER FUNCTIONS */
|
||||
|
||||
static gchar *
|
||||
my_match_strval(guint32 val, const value_string *vs, gint *idx)
|
||||
{
|
||||
gint i = 0;
|
||||
|
||||
while (vs[i].strptr) {
|
||||
if (vs[i].value == val)
|
||||
{
|
||||
*idx = i;
|
||||
return(vs[i].strptr);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
*idx = -1;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* PARAMETER dissection */
|
||||
|
||||
static void
|
||||
param_ssCode(ASN1_SCK *asn1, proto_tree *tree, guint len, int hf_field)
|
||||
{
|
||||
guint saved_offset;
|
||||
gint32 value;
|
||||
gchar *str = NULL;
|
||||
|
||||
hf_field = hf_field;
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_int32_value_decode(asn1, len, &value);
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case 0x00:
|
||||
str = "allSS - all SS";
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
str = "allLineIdentificationSS - all line identification SS";
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
str = "clip - calling line identification presentation";
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
str = "clir - calling line identification restriction";
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
str = "colp - connected line identification presentation";
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
str = "colr - connected line identification restriction";
|
||||
break;
|
||||
|
||||
case 0x15:
|
||||
str = "mci - malicious call identification";
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
str = "allNameIdentificationSS - all name indentification SS";
|
||||
break;
|
||||
|
||||
case 0x19:
|
||||
str = "cnap - calling name presentation";
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
str = "allForwardingSS - all forwarding SS";
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
str = "cfu - call forwarding unconditional";
|
||||
break;
|
||||
|
||||
case 0x28:
|
||||
str = "allCondForwardingSS - all conditional forwarding SS";
|
||||
break;
|
||||
|
||||
case 0x29:
|
||||
str = "cfb - call forwarding busy";
|
||||
break;
|
||||
|
||||
case 0x2a:
|
||||
str = "cfnry - call forwarding on no reply";
|
||||
break;
|
||||
|
||||
case 0x2b:
|
||||
str = "cfnrc - call forwarding on mobile subscriber not reachable";
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
str = "cd - call deflection";
|
||||
break;
|
||||
|
||||
case 0x30:
|
||||
str = "allCallOfferingSS - all call offering SS includes also all forwarding SS";
|
||||
break;
|
||||
|
||||
case 0x31:
|
||||
str = "ect - explicit call transfer";
|
||||
break;
|
||||
|
||||
case 0x32:
|
||||
str = "mah - mobile access hunting";
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
str = "allCallCompletionSS - all Call completion SS";
|
||||
break;
|
||||
|
||||
case 0x41:
|
||||
str = "cw - call waiting";
|
||||
break;
|
||||
|
||||
case 0x42:
|
||||
str = "hold - call hold";
|
||||
break;
|
||||
|
||||
case 0x43:
|
||||
str = "ccbs-A - completion of call to busy subscribers, originating side";
|
||||
break;
|
||||
|
||||
case 0x44:
|
||||
str = "ccbs-B - completion of call to busy subscribers, destination side";
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
str = "mc - multicall";
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
str = "allMultiPartySS - all multiparty SS";
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
str = "multiPTY - multiparty";
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
str = "allCommunityOfInterestSS - all community of interest SS";
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
str = "cug - closed user group";
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
str = "allChargingSS - all charging SS";
|
||||
break;
|
||||
|
||||
case 0x71:
|
||||
str = "aoci - advice of charge information";
|
||||
break;
|
||||
|
||||
case 0x72:
|
||||
str = "aocc - advice of charge charging";
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
str = "allAdditionalInfoTransferSS - all additional information transfer SS";
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
str = "uus1 - UUS1 user-to-user signalling";
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
str = "uus2 - UUS2 user-to-user signalling";
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
str = "uus3 - UUS3 user-to-user signalling";
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
str = "allBarringSS - all barring SS";
|
||||
break;
|
||||
|
||||
case 0x91:
|
||||
str = "barringOfOutgoingCalls";
|
||||
break;
|
||||
|
||||
case 0x92:
|
||||
str = "baoc - barring of all outgoing calls";
|
||||
break;
|
||||
|
||||
case 0x93:
|
||||
str = "boic - barring of outgoing international calls";
|
||||
break;
|
||||
|
||||
case 0x94:
|
||||
str = "boicExHC - barring of outgoing international calls except those directed to the home PLMN";
|
||||
break;
|
||||
|
||||
case 0x99:
|
||||
str = "barringOfIncomingCalls";
|
||||
break;
|
||||
|
||||
case 0x9a:
|
||||
str = "baic - barring of all incoming calls";
|
||||
break;
|
||||
|
||||
case 0x9b:
|
||||
str = "bicRoam - barring of incoming calls when roaming outside home PLMN Country";
|
||||
break;
|
||||
|
||||
case 0xf0:
|
||||
str = "allPLMN-specificSS";
|
||||
break;
|
||||
|
||||
case 0xa0:
|
||||
str = "allCallPrioritySS - all call priority SS";
|
||||
break;
|
||||
|
||||
case 0xa1:
|
||||
str = "emlpp - enhanced Multilevel Precedence Pre-emption (EMLPP) service";
|
||||
break;
|
||||
|
||||
case 0xb0:
|
||||
str = "allLCSPrivacyException - all LCS Privacy Exception Classes";
|
||||
break;
|
||||
|
||||
case 0xb1:
|
||||
str = "universal - allow location by any LCS client";
|
||||
break;
|
||||
|
||||
case 0xb2:
|
||||
str = "callrelated - allow location by any value added LCS client to which a call is established from the target MS";
|
||||
break;
|
||||
|
||||
case 0xb3:
|
||||
str = "callunrelated - allow location by designated external value added LCS clients";
|
||||
break;
|
||||
|
||||
case 0xb4:
|
||||
str = "plmnoperator - allow location by designated PLMN operator LCS clients";
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
str = "allMOLR-SS - all Mobile Originating Location Request Classes";
|
||||
break;
|
||||
|
||||
case 0xc1:
|
||||
str = "basicSelfLocation - allow an MS to request its own location";
|
||||
break;
|
||||
|
||||
case 0xc2:
|
||||
str = "autonomousSelfLocation - allow an MS to perform self location without interaction with the PLMN for a predetermined period of time";
|
||||
break;
|
||||
|
||||
case 0xc3:
|
||||
str = "transferToThirdParty - allow an MS to request transfer of its location to another LCS client";
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* XXX
|
||||
*/
|
||||
str = "reserved for future use";
|
||||
break;
|
||||
}
|
||||
|
||||
proto_tree_add_text(tree, asn1->tvb, saved_offset, len, str);
|
||||
}
|
||||
|
||||
/*
|
||||
* See GSM 03.11
|
||||
*/
|
||||
static void
|
||||
param_ssStatus(ASN1_SCK *asn1, proto_tree *tree, guint len, int hf_field)
|
||||
{
|
||||
guint saved_offset;
|
||||
gint32 value;
|
||||
char bigbuf[1024];
|
||||
|
||||
hf_field = hf_field;
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_int32_value_decode(asn1, len, &value);
|
||||
|
||||
other_decode_bitfield_value(bigbuf, value, 0xf0, 8);
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
saved_offset, 1,
|
||||
"%s : Unused",
|
||||
bigbuf);
|
||||
|
||||
/*
|
||||
* Q bit is valid only if A bit is "Active"
|
||||
*/
|
||||
other_decode_bitfield_value(bigbuf, value, 0x08, 8);
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
saved_offset, 1,
|
||||
"%s : Q bit: %s",
|
||||
bigbuf,
|
||||
(value & 0x01) ?
|
||||
((value & 0x08) ? "Quiescent" : "Operative") : "N/A");
|
||||
|
||||
other_decode_bitfield_value(bigbuf, value, 0x04, 8);
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
saved_offset, 1,
|
||||
"%s : P bit: %sProvisioned",
|
||||
bigbuf,
|
||||
(value & 0x04) ? "" : "Not ");
|
||||
|
||||
other_decode_bitfield_value(bigbuf, value, 0x02, 8);
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
saved_offset, 1,
|
||||
"%s : R bit: %sRegistered",
|
||||
bigbuf,
|
||||
(value & 0x02) ? "" : "Not ");
|
||||
|
||||
other_decode_bitfield_value(bigbuf, value, 0x01, 8);
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
saved_offset, 1,
|
||||
"%s : A bit: %sActive",
|
||||
bigbuf,
|
||||
(value & 0x01) ? "" : "Not ");
|
||||
}
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSM_SS_P_SS_CODE, /* SS-Code */
|
||||
GSM_SS_P_SS_STATUS, /* SS-Status */
|
||||
GSM_SS_P_NONE /* NONE */
|
||||
}
|
||||
param_idx_t;
|
||||
|
||||
#define NUM_PARAM_1 (GSM_SS_P_NONE+1)
|
||||
static gint ett_param_1[NUM_PARAM_1];
|
||||
static void (*param_1_fcn[])(ASN1_SCK *asn1, proto_tree *tree, guint len, int hf_field) = {
|
||||
param_ssCode, /* SS-Code */
|
||||
param_ssStatus, /* SS-Status */
|
||||
NULL /* NONE */
|
||||
};
|
||||
|
||||
static int *param_1_hf[] = {
|
||||
HF_NULL, /* SS-Code */
|
||||
HF_NULL, /* SS-Status */
|
||||
NULL /* NONE */
|
||||
};
|
||||
|
||||
#define GSM_SS_START_SUBTREE(_Gtree, _Gsaved_offset, _Gtag, _Gstr1, _Gett, _Gdef_len_p, _Glen_p, _Gsubtree_p) \
|
||||
{ \
|
||||
guint _len_offset; \
|
||||
proto_item *_item; \
|
||||
\
|
||||
_len_offset = asn1->offset; \
|
||||
asn1_length_decode(asn1, _Gdef_len_p, _Glen_p); \
|
||||
\
|
||||
_item = \
|
||||
proto_tree_add_text(_Gtree, asn1->tvb, _Gsaved_offset, -1, _Gstr1); \
|
||||
\
|
||||
_Gsubtree_p = proto_item_add_subtree(_item, _Gett); \
|
||||
\
|
||||
proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
|
||||
_Gsaved_offset, _len_offset - _Gsaved_offset, "Tag: 0x%02x", _Gtag); \
|
||||
\
|
||||
if (*_Gdef_len_p) \
|
||||
{ \
|
||||
proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
|
||||
_len_offset, asn1->offset - _len_offset, "Length: %d", *_Glen_p); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
proto_tree_add_text(_Gsubtree_p, asn1->tvb, \
|
||||
_len_offset, asn1->offset - _len_offset, "Length: Indefinite"); \
|
||||
\
|
||||
*_Glen_p = tcap_find_eoc(asn1); \
|
||||
} \
|
||||
\
|
||||
proto_item_set_len(_item, (asn1->offset - _Gsaved_offset) + *_Glen_p + \
|
||||
(*_Gdef_len_p ? 0 : TCAP_EOC_LEN)); \
|
||||
}
|
||||
|
||||
|
||||
#define GSM_SS_PARAM_DISPLAY(Gtree, Goffset, Gtag, Ga1, Ga2) \
|
||||
{ \
|
||||
gint _ett_param_idx; \
|
||||
guint _len; \
|
||||
void (*_param_fcn)(ASN1_SCK *asn1, proto_tree *tree, guint len, int hf_field) = NULL; \
|
||||
int *_param_hf = NULL; \
|
||||
proto_tree *_subtree; \
|
||||
gboolean _def_len; \
|
||||
\
|
||||
if (Ga1 == GSM_SS_P_NONE) \
|
||||
{ \
|
||||
_ett_param_idx = gsm_ss_ett_param; \
|
||||
_param_fcn = NULL; \
|
||||
_param_hf = HF_NULL; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_ett_param_idx = ett_param_1[Ga1]; \
|
||||
_param_fcn = param_1_fcn[Ga1]; \
|
||||
_param_hf = param_1_hf[Ga1]; \
|
||||
} \
|
||||
\
|
||||
GSM_SS_START_SUBTREE(Gtree, Goffset, Gtag, Ga2, _ett_param_idx, &_def_len, &_len, _subtree); \
|
||||
\
|
||||
if (_len > 0) \
|
||||
{ \
|
||||
if (Ga1 == GSM_SS_P_NONE || _param_fcn == NULL) \
|
||||
{ \
|
||||
proto_tree_add_text(_subtree, asn1->tvb, \
|
||||
asn1->offset, _len, "Parameter Data"); \
|
||||
\
|
||||
asn1->offset += _len; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(*_param_fcn)(asn1, _subtree, _len, *_param_hf); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (!_def_len) \
|
||||
{ \
|
||||
guint _saved_offset; \
|
||||
\
|
||||
_saved_offset = asn1->offset; \
|
||||
asn1_eoc_decode(asn1, -1); \
|
||||
\
|
||||
proto_tree_add_text(Gtree, asn1->tvb, \
|
||||
_saved_offset, asn1->offset - _saved_offset, "End of Contents"); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
op_generic_ss(ASN1_SCK *asn1, proto_tree *tree, guint exp_len)
|
||||
{
|
||||
guint orig_offset, saved_offset, len_offset;
|
||||
guint tag, len;
|
||||
gboolean def_len = FALSE;
|
||||
proto_item *item;
|
||||
proto_tree *subtree;
|
||||
|
||||
orig_offset = asn1->offset;
|
||||
|
||||
while ((tvb_length_remaining(asn1->tvb, asn1->offset) > 0) &&
|
||||
(!tcap_check_tag(asn1, 0)))
|
||||
{
|
||||
if ((exp_len != 0) &&
|
||||
((asn1->offset - orig_offset) >= exp_len))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
if (TCAP_CONSTRUCTOR(tag))
|
||||
{
|
||||
GSM_SS_START_SUBTREE(tree, saved_offset, tag, "Sequence",
|
||||
gsm_ss_ett_sequence,
|
||||
&def_len, &len, subtree);
|
||||
|
||||
op_generic_ss(asn1, subtree, len);
|
||||
|
||||
if (!def_len)
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
len_offset = asn1->offset;
|
||||
asn1_length_decode(asn1, &def_len, &len);
|
||||
|
||||
if (!def_len)
|
||||
{
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
saved_offset, len_offset - saved_offset,
|
||||
"Tag: 0x%02x", tag);
|
||||
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
len_offset, asn1->offset - len_offset, "Length: Indefinite");
|
||||
|
||||
len = tcap_find_eoc(asn1);
|
||||
|
||||
op_generic_ss(asn1, tree, len);
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
continue;
|
||||
}
|
||||
|
||||
item =
|
||||
proto_tree_add_text(tree, asn1->tvb,
|
||||
saved_offset, (asn1->offset - saved_offset) + len, "Parameter");
|
||||
|
||||
subtree = proto_item_add_subtree(item, gsm_ss_ett_param);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, len_offset - saved_offset,
|
||||
"Tag: 0x%02x", tag);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
len_offset, asn1->offset - len_offset, "Length: %d", len);
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
asn1->offset, len, "Parameter Data");
|
||||
|
||||
asn1->offset += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
op_interrogate_ss(ASN1_SCK *asn1, proto_tree *tree, guint exp_len)
|
||||
{
|
||||
guint saved_offset, start_offset;
|
||||
guint tag, len;
|
||||
gboolean def_len = FALSE;
|
||||
proto_tree *subtree;
|
||||
|
||||
exp_len = exp_len;
|
||||
|
||||
if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0) return;
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
if (TCAP_CONSTRUCTOR(tag) == FALSE)
|
||||
{
|
||||
/*
|
||||
* Hmmm, unexpected
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
GSM_SS_START_SUBTREE(tree, saved_offset, tag, "Sequence",
|
||||
gsm_ss_ett_sequence,
|
||||
&def_len, &len, subtree);
|
||||
|
||||
start_offset = asn1->offset;
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
GSM_SS_PARAM_DISPLAY(subtree, saved_offset, tag, GSM_SS_P_SS_CODE, "SS-Code");
|
||||
|
||||
op_generic_ss(asn1, subtree, len - (asn1->offset - start_offset));
|
||||
|
||||
if (!def_len)
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
|
||||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
saved_offset, asn1->offset - saved_offset, "End of Contents");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
op_interrogate_ss_rr(ASN1_SCK *asn1, proto_tree *tree, guint exp_len)
|
||||
{
|
||||
guint saved_offset;
|
||||
guint tag;
|
||||
|
||||
exp_len = exp_len;
|
||||
|
||||
if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0) return;
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case 0x80: /* SS-Status */
|
||||
GSM_SS_PARAM_DISPLAY(tree, saved_offset, tag, GSM_SS_P_SS_STATUS, "SS-Status");
|
||||
return;
|
||||
|
||||
case 0x82: /* BasicServiceGroupList */
|
||||
/* FALLTHRU */
|
||||
case 0x83: /* ForwardingFeatureList */
|
||||
/* FALLTHRU */
|
||||
|
||||
case 0x84: /* GenericServiceInfo */
|
||||
/*
|
||||
* XXX
|
||||
* needs implementing, let "generic" parameter dissector handle it for now
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
/* do nothing - unexpected tag */
|
||||
break;
|
||||
}
|
||||
|
||||
op_generic_ss(asn1, tree, 0);
|
||||
}
|
||||
|
||||
#define GSM_SS_NUM_OP (sizeof(gsm_ss_opr_code_strings)/sizeof(value_string))
|
||||
static void (*op_fcn[])(ASN1_SCK *asn1, proto_tree *tree, guint exp_len) = {
|
||||
NULL, /* RegisterSS */
|
||||
NULL, /* EraseSS */
|
||||
NULL, /* ActivateSS */
|
||||
NULL, /* DeactivateSS */
|
||||
op_interrogate_ss, /* InterrogateSS */
|
||||
NULL, /* NotifySS */
|
||||
NULL, /* RegisterPassword */
|
||||
NULL, /* GetPassword */
|
||||
NULL, /* ProcessUnstructuredSS-Data */
|
||||
NULL, /* ForwardCheckSS-Indication */
|
||||
NULL, /* ProcessUnstructuredSS-Request */
|
||||
NULL, /* UnstructuredSS-Request */
|
||||
NULL, /* UnstructuredSS-Notify */
|
||||
NULL, /* EraseCC-Entry */
|
||||
NULL, /* AccessRegisterCCEntry */
|
||||
NULL, /* ForwardCUG-Info */
|
||||
NULL, /* SplitMPTY */
|
||||
NULL, /* RetrieveMPTY */
|
||||
NULL, /* HoldMPTY */
|
||||
NULL, /* BuildMPTY */
|
||||
NULL, /* ForwardChargeAdvice */
|
||||
NULL, /* ExplicitCT */
|
||||
|
||||
NULL /* NONE */
|
||||
};
|
||||
|
||||
static void (*op_fcn_rr[])(ASN1_SCK *asn1, proto_tree *tree, guint exp_len) = {
|
||||
NULL, /* RegisterSS */
|
||||
NULL, /* EraseSS */
|
||||
NULL, /* ActivateSS */
|
||||
NULL, /* DeactivateSS */
|
||||
op_interrogate_ss_rr, /* InterrogateSS */
|
||||
NULL, /* NotifySS */
|
||||
NULL, /* RegisterPassword */
|
||||
NULL, /* GetPassword */
|
||||
NULL, /* ProcessUnstructuredSS-Data */
|
||||
NULL, /* ForwardCheckSS-Indication */
|
||||
NULL, /* ProcessUnstructuredSS-Request */
|
||||
NULL, /* UnstructuredSS-Request */
|
||||
NULL, /* UnstructuredSS-Notify */
|
||||
NULL, /* EraseCC-Entry */
|
||||
NULL, /* AccessRegisterCCEntry */
|
||||
NULL, /* ForwardCUG-Info */
|
||||
NULL, /* SplitMPTY */
|
||||
NULL, /* RetrieveMPTY */
|
||||
NULL, /* HoldMPTY */
|
||||
NULL, /* BuildMPTY */
|
||||
NULL, /* ForwardChargeAdvice */
|
||||
NULL, /* ExplicitCT */
|
||||
|
||||
NULL /* NONE */
|
||||
};
|
||||
|
||||
void
|
||||
gsm_ss_dissect(ASN1_SCK *asn1, proto_tree *tree, guint exp_len,
|
||||
guint opr_code, guint comp_type_tag)
|
||||
{
|
||||
void (*dissect_fcn)(ASN1_SCK *asn1, proto_tree *tree, guint exp_len);
|
||||
gchar *str;
|
||||
gint op_idx;
|
||||
|
||||
|
||||
dissect_fcn = NULL;
|
||||
|
||||
str = my_match_strval(opr_code, gsm_ss_opr_code_strings, &op_idx);
|
||||
|
||||
if (str != NULL)
|
||||
{
|
||||
switch (comp_type_tag)
|
||||
{
|
||||
case TCAP_COMP_INVOKE:
|
||||
dissect_fcn = op_fcn[op_idx];
|
||||
break;
|
||||
|
||||
case TCAP_COMP_RRL:
|
||||
dissect_fcn = op_fcn_rr[op_idx];
|
||||
break;
|
||||
|
||||
case TCAP_COMP_RE:
|
||||
/* XXX */
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* no parameters should be present in the component types
|
||||
* ignore
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (dissect_fcn == NULL)
|
||||
{
|
||||
op_generic_ss(asn1, tree, exp_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*dissect_fcn)(asn1, tree, exp_len);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* packet-gsm_ss.h
|
||||
*
|
||||
* $Id: packet-gsm_ss.h,v 1.1 2004/03/19 07:54:57 guy Exp $
|
||||
*
|
||||
* Copyright 2004, Michael Lum <mlum [AT] telostech.com>,
|
||||
* In association with Telos Technology Inc.
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
extern gint gsm_ss_ett_sequence;
|
||||
extern gint gsm_ss_ett_param;
|
||||
|
||||
extern const value_string gsm_ss_opr_code_strings[];
|
||||
|
||||
extern void gsm_ss_dissect(ASN1_SCK *asn1, proto_tree *tree, guint exp_len, guint opr_code, guint comp_type_tag);
|
157
packet-tcap.c
157
packet-tcap.c
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
* (append your name here for newer version)
|
||||
*
|
||||
* $Id: packet-tcap.c,v 1.8 2004/03/05 10:05:03 guy Exp $
|
||||
* $Id: packet-tcap.c,v 1.9 2004/03/19 07:54:57 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -61,8 +61,8 @@
|
|||
|
||||
#include <epan/packet.h>
|
||||
#include "prefs.h"
|
||||
#include "packet-tcap.h"
|
||||
#include "asn1.h"
|
||||
#include "packet-tcap.h"
|
||||
|
||||
Tcap_Standard_Type tcap_standard = ITU_TCAP_STANDARD;
|
||||
|
||||
|
@ -107,11 +107,6 @@ static dissector_table_t tcap_itu_ssn_dissector_table; /* map use ssn in sccp */
|
|||
static dissector_table_t tcap_ansi_ssn_dissector_table; /* map use ssn in sccp */
|
||||
static gboolean lock_info_col = TRUE;
|
||||
|
||||
#define TC_SEQ_TAG 0x30
|
||||
#define TC_SET_TAG 0x31
|
||||
|
||||
#define TC_EOC_LEN 2 /* 0x00 0x00 */
|
||||
|
||||
/* TCAP transaction message type definition - Samuel */
|
||||
#define ST_MSG_TYP_UNI 0x61 /*0b01100001*/
|
||||
#define ST_MSG_TYP_BGN 0x62 /*0b01100010*/
|
||||
|
@ -176,27 +171,20 @@ static const value_string dlg_type_strings[] = {
|
|||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/* TCAP component type */
|
||||
#define TC_INVOKE 0xa1
|
||||
#define TC_RRL 0xa2
|
||||
#define TC_RE 0xa3
|
||||
#define TC_REJECT 0xa4
|
||||
#define TC_RRN 0xa7
|
||||
|
||||
/* ANSI TCAP component type */
|
||||
#define ANSI_TC_INVOKE_L 0xe9
|
||||
#define ANSI_TC_RRL 0xea
|
||||
#define ANSI_TC_RE 0xeb
|
||||
#define ANSI_TC_REJECT 0xec
|
||||
#define ANSI_TC_INVOKE_N 0xed
|
||||
#define ANSI_TC_RRN 0xee
|
||||
const value_string tcap_component_type_str[] = {
|
||||
{ TCAP_COMP_INVOKE, "Invoke" },
|
||||
{ TCAP_COMP_RRL, "Return Result(L)" },
|
||||
{ TCAP_COMP_RE, "Return Error" },
|
||||
{ TCAP_COMP_REJECT, "Reject" },
|
||||
{ TCAP_COMP_RRN, "Return Result(NL)" },
|
||||
{ 0, NULL } };
|
||||
|
||||
#define TC_DS_OK 1
|
||||
#define TC_DS_FAIL 0
|
||||
|
||||
|
||||
static int
|
||||
find_eoc(ASN1_SCK *asn1)
|
||||
int
|
||||
tcap_find_eoc(ASN1_SCK *asn1)
|
||||
{
|
||||
guint saved_offset;
|
||||
guint tag;
|
||||
|
@ -216,7 +204,7 @@ find_eoc(ASN1_SCK *asn1)
|
|||
}
|
||||
else
|
||||
{
|
||||
asn1->offset += find_eoc(asn1);
|
||||
asn1->offset += tcap_find_eoc(asn1);
|
||||
asn1_eoc_decode(asn1, -1);
|
||||
}
|
||||
}
|
||||
|
@ -227,7 +215,23 @@ find_eoc(ASN1_SCK *asn1)
|
|||
return(len);
|
||||
}
|
||||
|
||||
/* dissect length */
|
||||
gboolean
|
||||
tcap_check_tag(ASN1_SCK *asn1, guint tag)
|
||||
{
|
||||
guint saved_offset, real_tag;
|
||||
|
||||
if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
|
||||
{
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &real_tag);
|
||||
asn1->offset = saved_offset;
|
||||
return (tag == real_tag);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dissect_tcap_len(ASN1_SCK *asn1, proto_tree *tree, gboolean *def_len, guint *len)
|
||||
{
|
||||
|
@ -320,22 +324,6 @@ dissect_tcap_integer(ASN1_SCK *asn1, proto_tree *tree, guint len, gchar * str)
|
|||
return TC_DS_OK;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_tcap_tag(ASN1_SCK *asn1, guint tag)
|
||||
{
|
||||
guint saved_offset, real_tag;
|
||||
|
||||
if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
|
||||
{
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &real_tag);
|
||||
asn1->offset = saved_offset;
|
||||
return (tag == real_tag);
|
||||
}
|
||||
|
||||
/* dissect tid */
|
||||
static int
|
||||
dissect_tcap_tid(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti, int type)
|
||||
|
@ -424,7 +412,7 @@ dissect_tcap_invokeId(ASN1_SCK *asn1, proto_tree *tree)
|
|||
gboolean def_len;
|
||||
|
||||
#define INVOKE_ID_TAG 0x2
|
||||
if (check_tcap_tag(asn1, INVOKE_ID_TAG))
|
||||
if (tcap_check_tag(asn1, INVOKE_ID_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Invoke ID Tag");
|
||||
|
@ -442,8 +430,7 @@ dissect_tcap_lnkId(ASN1_SCK *asn1, proto_tree *tree)
|
|||
guint tag;
|
||||
gboolean def_len;
|
||||
|
||||
#define LINK_ID_TAG 0x80
|
||||
if (check_tcap_tag(asn1, LINK_ID_TAG))
|
||||
if (tcap_check_tag(asn1, TCAP_LINKED_ID_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Linked ID Tag");
|
||||
|
@ -463,14 +450,14 @@ dissect_tcap_opr_code(ASN1_SCK *asn1, proto_tree *tree)
|
|||
gboolean def_len;
|
||||
|
||||
#define TCAP_LOC_OPR_CODE_TAG 0x02
|
||||
if (check_tcap_tag(asn1, TCAP_LOC_OPR_CODE_TAG))
|
||||
if (tcap_check_tag(asn1, TCAP_LOC_OPR_CODE_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Local Operation Code Tag");
|
||||
got_it = TRUE;
|
||||
}
|
||||
#define TCAP_GLB_OPR_CODE_TAG 0x06
|
||||
else if (check_tcap_tag(asn1, TCAP_GLB_OPR_CODE_TAG))
|
||||
else if (tcap_check_tag(asn1, TCAP_GLB_OPR_CODE_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Global Operation Code Tag");
|
||||
|
@ -500,7 +487,7 @@ dissect_tcap_param(ASN1_SCK *asn1, proto_tree *tree, guint exp_len)
|
|||
|
||||
#define TC_INVALID_TAG 0
|
||||
while ((tvb_length_remaining(asn1->tvb, asn1->offset) > 0) &&
|
||||
(!check_tcap_tag(asn1, 0)))
|
||||
(!tcap_check_tag(asn1, 0)))
|
||||
{
|
||||
if ((exp_len != 0) &&
|
||||
((asn1->offset - orig_offset) >= exp_len))
|
||||
|
@ -513,7 +500,7 @@ dissect_tcap_param(ASN1_SCK *asn1, proto_tree *tree, guint exp_len)
|
|||
len_offset = asn1->offset;
|
||||
asn1_length_decode(asn1, &def_len, &len);
|
||||
|
||||
if (tag == TC_SEQ_TAG)
|
||||
if (TCAP_CONSTRUCTOR(tag))
|
||||
{
|
||||
item =
|
||||
proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Sequence");
|
||||
|
@ -533,12 +520,12 @@ dissect_tcap_param(ASN1_SCK *asn1, proto_tree *tree, guint exp_len)
|
|||
proto_tree_add_text(subtree, asn1->tvb,
|
||||
len_offset, asn1->offset - len_offset, "Length: Indefinite");
|
||||
|
||||
len = find_eoc(asn1);
|
||||
len = tcap_find_eoc(asn1);
|
||||
}
|
||||
|
||||
proto_item_set_len(item,
|
||||
(asn1->offset - saved_offset) + len +
|
||||
(def_len ? 0 : TC_EOC_LEN));
|
||||
(def_len ? 0 : TCAP_EOC_LEN));
|
||||
|
||||
dissect_tcap_param(asn1, subtree, len);
|
||||
|
||||
|
@ -557,7 +544,7 @@ dissect_tcap_param(ASN1_SCK *asn1, proto_tree *tree, guint exp_len)
|
|||
proto_tree_add_text(tree, asn1->tvb,
|
||||
len_offset, asn1->offset - len_offset, "Length: Indefinite");
|
||||
|
||||
len = find_eoc(asn1);
|
||||
len = tcap_find_eoc(asn1);
|
||||
|
||||
dissect_tcap_param(asn1, tree, len);
|
||||
|
||||
|
@ -643,11 +630,11 @@ dissect_tcap_problem(ASN1_SCK *asn1, proto_tree *tree)
|
|||
|
||||
if (!def_len)
|
||||
{
|
||||
len = find_eoc(asn1);
|
||||
len = tcap_find_eoc(asn1);
|
||||
}
|
||||
|
||||
proto_item_set_len(item, (asn1->offset - saved_offset) + len +
|
||||
(def_len ? 0 : TC_EOC_LEN));
|
||||
(def_len ? 0 : TCAP_EOC_LEN));
|
||||
|
||||
if (len != 1)
|
||||
{
|
||||
|
@ -761,14 +748,14 @@ dissect_ansi_opr_code(ASN1_SCK *asn1, proto_tree *tree)
|
|||
gboolean def_len;
|
||||
|
||||
#define TCAP_NAT_OPR_CODE_TAG 0xd0
|
||||
if (check_tcap_tag(asn1, TCAP_NAT_OPR_CODE_TAG))
|
||||
if (tcap_check_tag(asn1, TCAP_NAT_OPR_CODE_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "National TCAP Operation Code Identifier");
|
||||
got_it = TRUE;
|
||||
}
|
||||
#define TCAP_PRIV_OPR_CODE_TAG 0xd1
|
||||
else if (check_tcap_tag(asn1, TCAP_PRIV_OPR_CODE_TAG))
|
||||
else if (tcap_check_tag(asn1, TCAP_PRIV_OPR_CODE_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Private TCAP Operation Code Identifier");
|
||||
|
@ -800,7 +787,7 @@ dissect_ansi_problem(ASN1_SCK *asn1, proto_tree *tree)
|
|||
|
||||
|
||||
#define TCAP_PROB_CODE_TAG 0xd5
|
||||
if (check_tcap_tag(asn1, TCAP_PROB_CODE_TAG))
|
||||
if (tcap_check_tag(asn1, TCAP_PROB_CODE_TAG))
|
||||
{
|
||||
str = "Problem Code Identifier";
|
||||
}
|
||||
|
@ -941,12 +928,12 @@ dissect_ansi_error(ASN1_SCK *asn1, proto_tree *tree)
|
|||
|
||||
|
||||
#define TCAP_NAT_ERR_CODE_TAG 0xd3
|
||||
if (check_tcap_tag(asn1, TCAP_NAT_ERR_CODE_TAG))
|
||||
if (tcap_check_tag(asn1, TCAP_NAT_ERR_CODE_TAG))
|
||||
{
|
||||
str = "National TCAP Error Code Identifier";
|
||||
}
|
||||
#define TCAP_PRIV_ERR_CODE_TAG 0xd4
|
||||
else if (check_tcap_tag(asn1, TCAP_PRIV_ERR_CODE_TAG))
|
||||
else if (tcap_check_tag(asn1, TCAP_PRIV_ERR_CODE_TAG))
|
||||
{
|
||||
str = "Private TCAP Error Code Identifier";
|
||||
}
|
||||
|
@ -986,14 +973,14 @@ dissect_ansi_param(ASN1_SCK *asn1, proto_tree *tree)
|
|||
gboolean def_len;
|
||||
|
||||
#define TCAP_PARAM_SET_TAG 0xf2
|
||||
if (check_tcap_tag(asn1, TCAP_PARAM_SET_TAG))
|
||||
if (tcap_check_tag(asn1, TCAP_PARAM_SET_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Parameter Set Identifier");
|
||||
got_it = TRUE;
|
||||
}
|
||||
#define TCAP_PARAM_SEQ_TAG 0x30
|
||||
else if (check_tcap_tag(asn1, TCAP_PARAM_SEQ_TAG))
|
||||
else if (tcap_check_tag(asn1, TCAP_PARAM_SEQ_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Parameter Sequence Identifier");
|
||||
|
@ -1017,7 +1004,7 @@ dissect_ansi_tcap_reject(ASN1_SCK *asn1, proto_tree *tree)
|
|||
proto_tree *subtree;
|
||||
|
||||
#define COMPONENT_ID_TAG 0xcf
|
||||
if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
|
||||
if (tcap_check_tag(asn1, COMPONENT_ID_TAG))
|
||||
{
|
||||
subtree = dissect_tcap_component(asn1, tree, &len);
|
||||
|
||||
|
@ -1041,7 +1028,7 @@ dissect_ansi_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
|
|||
proto_tree *subtree;
|
||||
|
||||
#define COMPONENT_ID_TAG 0xcf
|
||||
if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
|
||||
if (tcap_check_tag(asn1, COMPONENT_ID_TAG))
|
||||
{
|
||||
subtree = dissect_tcap_component(asn1, tree, &len);
|
||||
|
||||
|
@ -1065,7 +1052,7 @@ dissect_ansi_tcap_rr(ASN1_SCK *asn1, proto_tree *tree)
|
|||
proto_tree *subtree;
|
||||
|
||||
#define COMPONENT_ID_TAG 0xcf
|
||||
if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
|
||||
if (tcap_check_tag(asn1, COMPONENT_ID_TAG))
|
||||
{
|
||||
subtree = dissect_tcap_component(asn1, tree, &len);
|
||||
|
||||
|
@ -1087,7 +1074,7 @@ dissect_ansi_tcap_invoke(ASN1_SCK *asn1, proto_tree *tree)
|
|||
proto_tree *subtree;
|
||||
|
||||
#define COMPONENT_ID_TAG 0xcf
|
||||
if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
|
||||
if (tcap_check_tag(asn1, COMPONENT_ID_TAG))
|
||||
{
|
||||
subtree = dissect_tcap_component(asn1, tree, &len);
|
||||
|
||||
|
@ -1148,7 +1135,7 @@ dissect_tcap_invoke(ASN1_SCK *asn1, proto_tree *tree)
|
|||
}
|
||||
else
|
||||
{
|
||||
len = find_eoc(asn1);
|
||||
len = tcap_find_eoc(asn1);
|
||||
}
|
||||
|
||||
dissect_tcap_param(asn1, subtree, len);
|
||||
|
@ -1202,7 +1189,7 @@ dissect_tcap_rr(ASN1_SCK *asn1, proto_tree *tree, gchar *str)
|
|||
tag = -1;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
||||
if (tag == TC_SEQ_TAG)
|
||||
if (TCAP_CONSTRUCTOR(tag))
|
||||
{
|
||||
len_offset = asn1->offset;
|
||||
asn1_length_decode(asn1, &def_len, &len);
|
||||
|
@ -1225,12 +1212,12 @@ dissect_tcap_rr(ASN1_SCK *asn1, proto_tree *tree, gchar *str)
|
|||
proto_tree_add_text(seq_subtree, asn1->tvb,
|
||||
len_offset, asn1->offset - len_offset, "Length: Indefinite");
|
||||
|
||||
len = find_eoc(asn1);
|
||||
len = tcap_find_eoc(asn1);
|
||||
}
|
||||
|
||||
proto_item_set_len(seq_item,
|
||||
(asn1->offset - saved_offset) + len +
|
||||
(def_len ? 0 : TC_EOC_LEN));
|
||||
(def_len ? 0 : TCAP_EOC_LEN));
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
|
||||
|
@ -1281,7 +1268,7 @@ dissect_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
|
|||
|
||||
if (!comp_def_len)
|
||||
{
|
||||
comp_len = find_eoc(asn1);
|
||||
comp_len = tcap_find_eoc(asn1);
|
||||
}
|
||||
|
||||
saved_offset = asn1->offset;
|
||||
|
@ -1290,12 +1277,12 @@ dissect_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
|
|||
|
||||
#define TC_LOCAL_ERR_CODE_TAG 0x2
|
||||
#define TC_GBL_ERR_CODE_TAG 0x6
|
||||
if (check_tcap_tag(asn1, TC_LOCAL_ERR_CODE_TAG))
|
||||
if (tcap_check_tag(asn1, TC_LOCAL_ERR_CODE_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, subtree, &tag, "Local Error Code Tag");
|
||||
}
|
||||
else if (check_tcap_tag(asn1, TC_GBL_ERR_CODE_TAG))
|
||||
else if (tcap_check_tag(asn1, TC_GBL_ERR_CODE_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, subtree, &tag, "Global Error Code Tag");
|
||||
|
@ -1529,8 +1516,8 @@ dissect_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
|
|||
/* call next dissector for EACH component */
|
||||
|
||||
keep_len =
|
||||
(comps_def_len ? 0 : TC_EOC_LEN) +
|
||||
(g_tcap_ends_def_len ? 0 : TC_EOC_LEN);
|
||||
(comps_def_len ? 0 : TCAP_EOC_LEN) +
|
||||
(g_tcap_ends_def_len ? 0 : TCAP_EOC_LEN);
|
||||
|
||||
while (tvb_length_remaining(asn1->tvb, asn1->offset) > keep_len)
|
||||
{
|
||||
|
@ -1548,7 +1535,7 @@ dissect_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
|
|||
}
|
||||
else
|
||||
{
|
||||
comp_len = (asn1->offset - saved_offset) + find_eoc(asn1) + TC_EOC_LEN;
|
||||
comp_len = (asn1->offset - saved_offset) + tcap_find_eoc(asn1) + TCAP_EOC_LEN;
|
||||
}
|
||||
|
||||
next_tvb = tvb_new_subset(asn1->tvb, saved_offset, comp_len, comp_len);
|
||||
|
@ -1565,19 +1552,19 @@ dissect_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
|
|||
{
|
||||
switch (tag)
|
||||
{
|
||||
case TC_INVOKE :
|
||||
case TCAP_COMP_INVOKE :
|
||||
dissect_tcap_invoke(asn1, subtree);
|
||||
break;
|
||||
case TC_RRL :
|
||||
case TCAP_COMP_RRL :
|
||||
dissect_tcap_rr(asn1, subtree, "Return Result(Last) Type Tag");
|
||||
break;
|
||||
case TC_RE :
|
||||
case TCAP_COMP_RE :
|
||||
dissect_tcap_re(asn1, subtree);
|
||||
break;
|
||||
case TC_REJECT :
|
||||
case TCAP_COMP_REJECT :
|
||||
dissect_tcap_reject(asn1, subtree);
|
||||
break;
|
||||
case TC_RRN :
|
||||
case TCAP_COMP_RRN :
|
||||
/* same definition as RRL */
|
||||
dissect_tcap_rr(asn1, subtree, "Return Result(Not Last) Type Tag");
|
||||
break;
|
||||
|
@ -1610,7 +1597,7 @@ dissect_tcap_dlg_protocol_version(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_i
|
|||
gboolean def_len;
|
||||
|
||||
#define TC_DLG_PROTO_VER_TAG 0x80
|
||||
if (check_tcap_tag(asn1, TC_DLG_PROTO_VER_TAG))
|
||||
if (tcap_check_tag(asn1, TC_DLG_PROTO_VER_TAG))
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
ret = asn1_id_decode1(asn1, &tag);
|
||||
|
@ -1721,13 +1708,13 @@ dissect_tcap_dlg_result_src_diag(ASN1_SCK *asn1, proto_tree *tree)
|
|||
|
||||
#define TC_DIAG_SERV_USER_TAG 0xa1
|
||||
#define TC_DIAG_SERV_PROV_TAG 0xa2
|
||||
if (check_tcap_tag(asn1, TC_DIAG_SERV_USER_TAG))
|
||||
if (tcap_check_tag(asn1, TC_DIAG_SERV_USER_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Dialogue Service User Tag");
|
||||
user = TRUE;
|
||||
}
|
||||
else if (check_tcap_tag(asn1, TC_DIAG_SERV_PROV_TAG))
|
||||
else if (tcap_check_tag(asn1, TC_DIAG_SERV_PROV_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "Dialogue Service Provider Tag");
|
||||
|
@ -1800,14 +1787,14 @@ dissect_tcap_dlg_user_info(ASN1_SCK *asn1, proto_tree *tree)
|
|||
gboolean user_info_def_len;
|
||||
|
||||
#define TC_USR_INFO_TAG 0xbe
|
||||
if (check_tcap_tag(asn1, TC_USR_INFO_TAG))
|
||||
if (tcap_check_tag(asn1, TC_USR_INFO_TAG))
|
||||
{
|
||||
tag = -1;
|
||||
dissect_tcap_tag(asn1, tree, &tag, "User Info Tag");
|
||||
dissect_tcap_len(asn1, tree, &user_info_def_len, &len);
|
||||
|
||||
#define TC_EXT_TAG 0x28
|
||||
if (check_tcap_tag(asn1, TC_EXT_TAG))
|
||||
if (tcap_check_tag(asn1, TC_EXT_TAG))
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
asn1_id_decode1(asn1, &tag);
|
||||
|
@ -2114,7 +2101,7 @@ dissect_tcap_abort_reason(ASN1_SCK *asn1, proto_tree *tcap_tree)
|
|||
|
||||
#define TC_PABRT_REASON_TAG 0x4a
|
||||
tag = TC_PABRT_REASON_TAG;
|
||||
if (check_tcap_tag(asn1, tag))
|
||||
if (tcap_check_tag(asn1, tag))
|
||||
{
|
||||
saved_offset = asn1->offset;
|
||||
item =
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* packet-tcap.h
|
||||
*
|
||||
* $Id: packet-tcap.h,v 1.2 2003/12/21 04:31:57 jmayer Exp $
|
||||
* $Id: packet-tcap.h,v 1.3 2004/03/19 07:54:58 guy Exp $
|
||||
*
|
||||
* Copyright 2003, Michael Lum <mlum [AT] telostech.com>,
|
||||
* In association with Telos Technology Inc.
|
||||
|
@ -27,8 +27,38 @@
|
|||
*/
|
||||
|
||||
typedef enum {
|
||||
ITU_TCAP_STANDARD = 1,
|
||||
ANSI_TCAP_STANDARD = 2
|
||||
ITU_TCAP_STANDARD = 1,
|
||||
ANSI_TCAP_STANDARD = 2
|
||||
} Tcap_Standard_Type;
|
||||
|
||||
extern Tcap_Standard_Type tcap_standard;
|
||||
|
||||
extern const value_string tcap_component_type_str[];
|
||||
|
||||
/* TCAP component type */
|
||||
#define TCAP_COMP_INVOKE 0xa1
|
||||
#define TCAP_COMP_RRL 0xa2
|
||||
#define TCAP_COMP_RE 0xa3
|
||||
#define TCAP_COMP_REJECT 0xa4
|
||||
#define TCAP_COMP_RRN 0xa7
|
||||
|
||||
/* ANSI TCAP component type */
|
||||
#define ANSI_TC_INVOKE_L 0xe9
|
||||
#define ANSI_TC_RRL 0xea
|
||||
#define ANSI_TC_RE 0xeb
|
||||
#define ANSI_TC_REJECT 0xec
|
||||
#define ANSI_TC_INVOKE_N 0xed
|
||||
#define ANSI_TC_RRN 0xee
|
||||
|
||||
#define TCAP_SEQ_TAG 0x30
|
||||
#define TCAP_SET_TAG 0x31
|
||||
|
||||
#define TCAP_INVOKE_ID_TAG 0x02
|
||||
#define TCAP_LINKED_ID_TAG 0x80
|
||||
|
||||
#define TCAP_EOC_LEN 2 /* 0x00 0x00 */
|
||||
|
||||
#define TCAP_CONSTRUCTOR(TCtag) (TCtag & 0x20)
|
||||
|
||||
extern int tcap_find_eoc(ASN1_SCK *asn1);
|
||||
extern gboolean tcap_check_tag(ASN1_SCK *asn1, guint tag);
|
||||
|
|
Loading…
Reference in New Issue