diff options
author | Harald Welte <laforge@gnumonks.org> | 2017-05-26 21:44:08 +0200 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2017-05-27 12:21:06 +0000 |
commit | 9097d1b07c2f03badf9c39f8b338b1dcbb55f18e (patch) | |
tree | 86f06b2e6b0d9066c9059e71add86b71476f8280 /epan | |
parent | 2023f419f45c6285232e4df8fcce9f99043be1f1 (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.am | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-gsmtap.c | 16 | ||||
-rw-r--r-- | epan/dissectors/packet-lapdm.c | 59 | ||||
-rw-r--r-- | epan/dissectors/packet-lapdm.h | 38 |
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 |