summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-bssgp.c103
1 files changed, 85 insertions, 18 deletions
diff --git a/epan/dissectors/packet-bssgp.c b/epan/dissectors/packet-bssgp.c
index 875516dd19..9fe4678eeb 100644
--- a/epan/dissectors/packet-bssgp.c
+++ b/epan/dissectors/packet-bssgp.c
@@ -41,6 +41,7 @@
#include <math.h>
#include <glib.h>
#include <epan/packet.h>
+#include <prefs.h>
/*#define BSSGP_DEBUG*/
#define BSSGP_LITTLE_ENDIAN FALSE
@@ -55,12 +56,16 @@
#define BSSGP_SEP ", "
#define BSSGP_NOT_DECODED "< Not decoded yet >"
#define BSSGP_UNKNOWN -1
+static int bssgp_decode_nri = 0;
+static int bssgp_nri_length = 4;
static dissector_handle_t bssgp_handle;
static dissector_handle_t llc_handle;
static dissector_handle_t rrlp_handle;
static dissector_handle_t data_handle;
+module_t *bssgp_module;
+void proto_reg_handoff_bssgp(void);
/* Initialize the protocol and registered fields */
static int proto_bssgp = -1;
@@ -71,6 +76,7 @@ static int hf_bssgp_mnc = -1;
static int hf_bssgp_lac = -1;
static int hf_bssgp_rac = -1;
static int hf_bssgp_ci = -1;
+static int hf_bssgp_nri = -1;
static int hf_bssgp_imsi = -1;
static int hf_bssgp_imei = -1;
static int hf_bssgp_imeisv = -1;
@@ -410,6 +416,42 @@ get_masked_guint8(guint8 value, guint8 mask) {
return (value & mask) >> i;
}
+static guint16
+get_masked_guint16(guint16 value, guint16 mask) {
+ const guint16 MASK_BIT_1 = 0x01;
+ guint8 i = 0;
+
+ while (!((mask >> i) & MASK_BIT_1)) {
+ i++;
+ if (i > 15) return 0;
+ }
+ return (value & mask) >> i;
+}
+
+static gint32
+make_mask32(guint8 num_bits, guint8 shift_value) {
+ const guint32 LEFT_MOST_1 = 0x80000000;
+ int i;
+ guint32 mask = LEFT_MOST_1;
+
+ for (i = 0; i < (num_bits - 1); i++) {
+ mask = (mask >> 1) | LEFT_MOST_1;
+ }
+ return mask >> shift_value;
+}
+
+static guint32
+get_masked_guint32(guint32 value, guint32 mask) {
+ const guint16 MASK_BIT_1 = 0x01;
+ guint8 i = 0;
+
+ while (!((mask >> i) & MASK_BIT_1)) {
+ i++;
+ if (i > 31) return 0;
+ }
+ return (value & mask) >> i;
+}
+
static guint8
tvb_get_masked_guint8(tvbuff_t *tvb, int offset, guint8 mask) {
guint8 value = tvb_get_guint8(tvb, offset);
@@ -1189,6 +1231,27 @@ bssgp_proto_handoff(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset, disse
}
}
+static void
+decode_nri(proto_tree *tf, build_info_t *bi, guint32 tmsi_tlli) {
+ const guint32 LOCAL_TLLI_MASK = 0xc0000000;
+ const guint32 FOREIGN_TLLI_MASK = 0x80000000;
+ guint16 nri;
+
+ if (bssgp_decode_nri && (bssgp_nri_length > 0) &&
+ (((tmsi_tlli & LOCAL_TLLI_MASK) == LOCAL_TLLI_MASK) ||
+ ((tmsi_tlli & FOREIGN_TLLI_MASK) == FOREIGN_TLLI_MASK))) {
+ nri = get_masked_guint32(tmsi_tlli, make_mask32(bssgp_nri_length, 8));
+ if (tf) {
+ proto_tree_add_uint_hidden(tf, hf_bssgp_nri, bi->tvb, bi->offset, 4,
+ nri);
+ }
+ if (check_col(bi->pinfo->cinfo, COL_INFO)) {
+ col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
+ "NRI %u", nri);
+ }
+ }
+}
+
static void
decode_mobile_identity(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
#define MAX_NUM_IMSI_DIGITS 15
@@ -1296,18 +1359,18 @@ decode_mobile_identity(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
break;
case BSSGP_MOBILE_IDENTITY_TYPE_TMSI_PTMSI:
tmsi = tvb_get_ntohl(bi->tvb, bi->offset);
+ if (check_col(bi->pinfo->cinfo, COL_INFO)) {
+ col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
+ "TMSI/P-TMSI %0x04x", tmsi);
+ }
if (bi->bssgp_tree) {
proto_tree_add_item(tf, hf_bssgp_tmsi_ptmsi, bi->tvb, bi->offset, 4,
BSSGP_LITTLE_ENDIAN);
proto_item_append_text(ti, ": %#04x", tmsi);
}
+ decode_nri(tf, bi, tmsi);
bi->offset += 4;
-
- if (check_col(bi->pinfo->cinfo, COL_INFO)) {
- col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
- "TMSI/P-TMSI %0x04x", tmsi);
- }
- return;
+ break;
default:
;
};
@@ -2743,6 +2806,7 @@ decode_iei_tlli(bssgp_ie_t *ie, build_info_t *bi, int ie_start_offset) {
col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, BSSGP_SEP,
"TLLI %#4x", tlli);
}
+ decode_nri(bi->bssgp_tree, bi, tlli);
}
static void
@@ -5673,6 +5737,11 @@ proto_register_bssgp(void)
FT_STRING, BASE_NONE, NULL, 0x0,
"", HFILL }
},
+ { &hf_bssgp_nri,
+ { "NRI", "bssgp.nri",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
};
/* Setup protocol subtree array */
@@ -5726,6 +5795,16 @@ proto_register_bssgp(void)
proto_register_field_array(proto_bssgp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("bssgp", dissect_bssgp, proto_bssgp);
+
+ /* Register configuration options */
+ bssgp_module = prefs_register_protocol(proto_bssgp, proto_reg_handoff_bssgp);
+ prefs_register_bool_preference(bssgp_module, "decode_nri",
+ "Decode NRI",
+ "Decode NRI (for use with SGSN in Pool)",
+ &bssgp_decode_nri);
+ prefs_register_uint_preference(bssgp_module, "nri_length", "NRI length",
+ "NRI length, in bits",
+ 10, &bssgp_nri_length);
}
/* If this dissector uses sub-dissector registration add a registration routine.
@@ -5738,15 +5817,3 @@ proto_reg_handoff_bssgp(void)
rrlp_handle = find_dissector("rrlp");
data_handle = find_dissector("data");
}
-
-
-
-
-
-
-
-
-
-
-
-