aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-05-26 21:44:08 +0200
committerMichael Mann <mmann78@netscape.net>2017-05-27 12:21:06 +0000
commit9097d1b07c2f03badf9c39f8b338b1dcbb55f18e (patch)
tree86f06b2e6b0d9066c9059e71add86b71476f8280 /epan
parent2023f419f45c6285232e4df8fcce9f99043be1f1 (diff)
LAPDm: Support the LAPDm B4 Frame Format
The B4 Frame Format is used on the downlink SACCH and has no length field. While the comment on top of packet-lapdm.c claimed ever since its introduction in 2009 that B4 was a supported format, in fact it was not supported yet. This patch makes handling the length field conditional to a frame format that has a length field, and introduces lapdm_data_t that can be passed using call_dissector_with_data(). The GSMTAP dissector is updated to use this mechanism to specify the frame format based on the channel type. Change-Id: I52cb1cedbc8c7baf65e70d3e050e8932573647aa Reviewed-on: https://code.wireshark.org/review/21767 Reviewed-by: Jaap Keuter <jaap.keuter@xs4all.nl> Petri-Dish: Jaap Keuter <jaap.keuter@xs4all.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/Makefile.am1
-rw-r--r--epan/dissectors/packet-gsmtap.c16
-rw-r--r--epan/dissectors/packet-lapdm.c59
-rw-r--r--epan/dissectors/packet-lapdm.h38
4 files changed, 102 insertions, 12 deletions
diff --git a/epan/dissectors/Makefile.am b/epan/dissectors/Makefile.am
index b5df4cdda3..5f49065059 100644
--- a/epan/dissectors/Makefile.am
+++ b/epan/dissectors/Makefile.am
@@ -1621,6 +1621,7 @@ DISSECTOR_INCLUDES = \
packet-kerberos.h \
packet-klm.h \
packet-l2tp.h \
+ packet-lapdm.h \
packet-lbm.h \
packet-lbtrm.h \
packet-lbtru.h \
diff --git a/epan/dissectors/packet-gsmtap.c b/epan/dissectors/packet-gsmtap.c
index c5ddd0539a..6494caf78e 100644
--- a/epan/dissectors/packet-gsmtap.c
+++ b/epan/dissectors/packet-gsmtap.c
@@ -43,6 +43,7 @@
#include <epan/packet.h>
#include "packet-gsmtap.h"
+#include "packet-lapdm.h"
#include "packet-tetra.h"
void proto_register_gsmtap(void);
@@ -318,6 +319,17 @@ dissect_sacch_l1h(tvbuff_t *tvb, proto_tree *tree)
proto_tree_add_item(l1h_tree, hf_sacch_l1h_ta, tvb, 1, 1, ENC_BIG_ENDIAN);
}
+static void
+handle_lapdm(guint8 sub_type, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ lapdm_data_t ld;
+
+ ld.hdr_type = LAPDM_HDR_FMT_B;
+ /* only downlink SACCH frames use B4 header format */
+ if (sub_type & GSMTAP_CHANNEL_ACCH && pinfo->p2p_dir == P2P_DIR_RECV)
+ ld.hdr_type = LAPDM_HDR_FMT_B4;
+ call_dissector_with_data(sub_handles[GSMTAP_SUB_UM_LAPDM], tvb, pinfo, tree, &ld);
+}
static void
handle_tetra(int channel _U_, tvbuff_t *payload_tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_)
@@ -489,8 +501,8 @@ dissect_gsmtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _
case GSMTAP_CHANNEL_SDCCH8:
case GSMTAP_CHANNEL_TCH_F:
case GSMTAP_CHANNEL_TCH_H:
- sub_handle = GSMTAP_SUB_UM_LAPDM;
- break;
+ handle_lapdm(sub_type, payload_tvb, pinfo, tree);
+ return tvb_captured_length(tvb);
case GSMTAP_CHANNEL_PACCH:
if (pinfo->p2p_dir == P2P_DIR_SENT) {
sub_handle = GSMTAP_SUB_UM_RLC_MAC_UL;
diff --git a/epan/dissectors/packet-lapdm.c b/epan/dissectors/packet-lapdm.c
index 3135a1166f..d351edd76e 100644
--- a/epan/dissectors/packet-lapdm.c
+++ b/epan/dissectors/packet-lapdm.c
@@ -50,6 +50,7 @@
*/
#include "config.h"
+#include "packet-lapdm.h"
#include <epan/packet.h>
#include <epan/prefs.h>
@@ -130,6 +131,7 @@ static gboolean reassemble_lapdm = TRUE;
#define LAPDM_LEN_SHIFT 2
#define LAPDM_HEADER_LEN 3
+#define LAPDM_HEADER_LEN_B4 2
#define LAPDM_SAPI_RR_CC_MM 0
#define LAPDM_SAPI_SMS 3
@@ -201,27 +203,57 @@ static const fragment_items lapdm_frag_items = {
"fragments"
};
+static gboolean hdr_has_length(enum lapdm_hdr_type hdr_type)
+{
+ switch (hdr_type) {
+ case LAPDM_HDR_FMT_A:
+ case LAPDM_HDR_FMT_B:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
static int
-dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
proto_tree *lapdm_tree, *addr_tree, *length_tree;
proto_item *lapdm_ti, *addr_ti, *length_ti;
- guint8 addr, length, cr, sapi, len, n_s;
+ guint8 addr, length, header_len, cr, sapi, len, n_s;
int control;
gboolean m;
tvbuff_t *payload;
int available_length;
gboolean is_response = FALSE;
+ enum lapdm_hdr_type hdr_type = LAPDM_HDR_FMT_B;
+
+ if (data) {
+ lapdm_data_t *ld = (lapdm_data_t *) data;
+ hdr_type = ld->hdr_type;
+ }
+
+ switch (hdr_type) {
+ case LAPDM_HDR_FMT_A:
+ case LAPDM_HDR_FMT_B:
+ length = tvb_get_guint8(tvb, 2);
+ header_len = LAPDM_HEADER_LEN;
+ break;
+ case LAPDM_HDR_FMT_B4:
+ length = 0;
+ header_len = LAPDM_HEADER_LEN_B4;
+ break;
+ default:
+ return 0;
+ }
/* Check that there's enough data */
- if (tvb_captured_length(tvb) < LAPDM_HEADER_LEN)
+ if (tvb_captured_length(tvb) < header_len)
return 0;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "LAPDm");
addr = tvb_get_guint8(tvb, 0);
- length = tvb_get_guint8(tvb, 2);
cr = addr & LAPDM_CR;
if (pinfo->p2p_dir == P2P_DIR_RECV) {
@@ -232,7 +264,7 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U
}
if (tree) {
- lapdm_ti = proto_tree_add_item(tree, proto_lapdm, tvb, 0, LAPDM_HEADER_LEN, ENC_NA);
+ lapdm_ti = proto_tree_add_item(tree, proto_lapdm, tvb, 0, header_len, ENC_NA);
lapdm_tree = proto_item_add_subtree(lapdm_ti, ett_lapdm);
addr_ti = proto_tree_add_uint(lapdm_tree, hf_lapdm_address, tvb, 0, 1, addr);
@@ -252,7 +284,8 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U
ett_lapdm_control, &lapdm_cf_items, NULL /* LAPDm doesn't support extended */, NULL, NULL,
is_response, FALSE, FALSE);
- if (tree) {
+ /* dissect length field (if present) */
+ if (tree && hdr_has_length(hdr_type)) {
length_ti = proto_tree_add_uint(lapdm_tree, hf_lapdm_length, tvb,
2, 1, length);
length_tree = proto_item_add_subtree(length_ti, ett_lapdm_length);
@@ -262,18 +295,24 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U
proto_tree_add_uint(length_tree, hf_lapdm_el, tvb, 2, 1, length);
}
+ if (hdr_has_length(hdr_type)) {
+ len = (length & LAPDM_LEN) >> LAPDM_LEN_SHIFT;
+ m = (length & LAPDM_M) >> LAPDM_M_SHIFT;
+ } else {
+ len = tvb_captured_length(tvb) - header_len;
+ m = 0;
+ }
+
sapi = (addr & LAPDM_SAPI) >> LAPDM_SAPI_SHIFT;
- len = (length & LAPDM_LEN) >> LAPDM_LEN_SHIFT;
n_s = (control & XDLC_N_S_MASK) >> XDLC_N_S_SHIFT;
- m = (length & LAPDM_M) >> LAPDM_M_SHIFT;
- available_length = tvb_captured_length(tvb) - LAPDM_HEADER_LEN;
+ available_length = tvb_captured_length(tvb) - header_len;
/* No point in doing anything if no payload
*/
if( !MIN(len, available_length) )
return 2;
- payload = tvb_new_subset_length_caplen(tvb, LAPDM_HEADER_LEN, MIN(len,available_length), len);
+ payload = tvb_new_subset_length_caplen(tvb, header_len, MIN(len,available_length), len);
/* Potentially segmented I frame
*/
diff --git a/epan/dissectors/packet-lapdm.h b/epan/dissectors/packet-lapdm.h
new file mode 100644
index 0000000000..7b399fd334
--- /dev/null
+++ b/epan/dissectors/packet-lapdm.h
@@ -0,0 +1,38 @@
+/* packet-lapdm.h
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __PACKET_BTL2CAP_H__
+#define __PACKET_BTL2CAP_H__
+
+/* See GSM TS 04.06 */
+enum lapdm_hdr_type {
+ LAPDM_HDR_FMT_A,
+ LAPDM_HDR_FMT_B,
+ LAPDM_HDR_FMT_Bter,
+ LAPDM_HDR_FMT_B4,
+ LAPDM_HDR_FMT_C,
+};
+
+typedef struct _lapdm_data_t {
+ enum lapdm_hdr_type hdr_type;
+} lapdm_data_t;
+
+#endif