Add basic dissector for Ericsson Packet A-bis TFP Protocol

This dissector currently onl dissects the TFP header, treating the
payload (TRAU) as opaque data.  Still, it is an improvement to see the
header information like timeslot, sequence number, delay and frame type.

The new TFP dissector is called from packet-ehdlc.c, which in turn is
used inside Ericsson-specific L2TP.

Change-Id: I8835c07e259ec9a324ec92aac39abbef2c902af3
Reviewed-on: https://code.wireshark.org/review/16509
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Harald Welte 2016-07-16 18:34:34 +02:00 committed by Michael Mann
parent 051f5cb18a
commit e878525f5f
5 changed files with 226 additions and 1 deletions

View File

@ -120,6 +120,7 @@ Real Time Location System (RTLS)
Network-Based IP Flow Mobility (NBIFOM)
IEEE 802.1BR E-Tag
Nordic BLE Sniffer
Ericsson A-bis TFP (Traffic Forwarding Protocol)
--sort-and-group--
=== Updated Protocol Support

View File

@ -636,6 +636,7 @@ set(DISSECTOR_SRC
packet-gsm_a_rr.c
packet-gsm_abis_om2000.c
packet-gsm_abis_oml.c
packet-gsm_abis_tfp.c
packet-gsm_bsslap.c
packet-gsm_bssmap_le.c
packet-gsm_cbch.c

View File

@ -665,6 +665,7 @@ DISSECTOR_SRC = \
packet-gsm_a_rr.c \
packet-gsm_abis_om2000.c \
packet-gsm_abis_oml.c \
packet-gsm_abis_tfp.c \
packet-gsm_bsslap.c \
packet-gsm_bssmap_le.c \
packet-gsm_cbch.c \

View File

@ -98,6 +98,7 @@ static gint ett_ehdlc_control = -1;
enum {
SUB_RSL,
SUB_OML,
SUB_TFP,
SUB_DATA,
SUB_MAX
@ -199,7 +200,7 @@ dissect_ehdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U
if (sapi == 10 || sapi == 11) {
/* Voice TRAU */
next_tvb = tvb_new_subset_length(tvb, offset+2, len-2);
call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree);
call_dissector(sub_handles[SUB_TFP], next_tvb, pinfo, tree);
offset += len;
continue;
} else if (sapi == 12) {
@ -384,6 +385,7 @@ proto_reg_handoff_ehdlc(void)
{
sub_handles[SUB_RSL] = find_dissector_add_dependency("gsm_abis_rsl", proto_ehdlc);
sub_handles[SUB_OML] = find_dissector_add_dependency("gsm_abis_oml", proto_ehdlc);
sub_handles[SUB_TFP] = find_dissector_add_dependency("gsm_abis_tfp", proto_ehdlc);
sub_handles[SUB_DATA] = find_dissector("data");
dissector_add_uint("l2tp.pw_type", L2TPv3_PROTOCOL_ERICSSON, ehdlc_handle);

View File

@ -0,0 +1,220 @@
/* packet-gsm_abis_tfp.c
* Routines for packet dissection of Ericsson GSM A-bis TFP
* (Traffic Forwarding Protocol)
* Copyright 2010-2016 by Harald Welte <laforge@gnumonks.org>
*
* TFP is an Ericsson-specific packetized version of replacing TRAU
* frames on 8k/16k E1 sub-slots with a paketized frame format which
* can be transported over LAPD on a SuperChannel (E1 timeslot bundle)
* or L2TP.
*
* 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.
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/prefs.h>
enum {
SUB_DATA,
SUB_MAX
};
static dissector_handle_t sub_handles[SUB_MAX];
/* initialize the protocol and registered fields */
static int proto_abis_tfp = -1;
/* TFP header */
static int hf_tfp_hdr_atsr = -1;
static int hf_tfp_hdr_slot_rate = -1;
static int hf_tfp_hdr_seq_nr = -1;
static int hf_tfp_hdr_delay_info = -1;
static int hf_tfp_hdr_p = -1;
static int hf_tfp_hdr_s = -1;
static int hf_tfp_hdr_m = -1;
static int hf_tfp_hdr_frame_type = -1;
/* initialize the subtree pointers */
static int ett_tfp = -1;
static const value_string tfp_slot_rate_vals[] = {
{ 0, "Full Rate (16kbps)" },
{ 1, "Sub-Channel 0 (8kbps)" },
{ 2, "Sub-Channel 1 (8kbps)" },
{ 3, "Reserved" },
{ 0, NULL }
};
#define TFP_PACKED_NONE 0
#define TFP_PACKED_SCHEME_1 1
static const value_string tfp_packed_vals[] = {
{ 0, "Not Packed" },
{ 1, "Packing Scheme 1" },
{ 0, NULL }
};
static const value_string tfp_frame_type_vals[] = {
/* 8k */
{ 0, "TFP-AMR-IND" },
{ 1, "TFP-SCCE-AMR-IND" },
{ 2, "TFP-HR-IND" },
/* 16k */
{ 0x80, "TFP-AMR-IND" },
{ 0x81, "TFP-SCCE-AMR-IND" },
{ 0x82, "TFP-FR-IND" },
{ 0x83, "TFP-EFR-IND" },
{ 0x84, "TFP-SCCE-EFR-IND" },
{ 0, NULL }
};
static int
dissect_abis_tfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
proto_item *ti;
proto_tree *tfp_tree;
int offset = 0;
guint32 slot_rate, frame_bits, hdr2, atsr, seq_nr;
guint8 ftype;
tvbuff_t *next_tvb;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TFP");
ti = proto_tree_add_item(tree, proto_abis_tfp, tvb, 0, -1, ENC_NA);
tfp_tree = proto_item_add_subtree(ti, ett_tfp);
proto_tree_add_item_ret_uint(tfp_tree, hf_tfp_hdr_atsr, tvb, offset, 2, ENC_BIG_ENDIAN, &hdr2);
proto_tree_add_item(tfp_tree, hf_tfp_hdr_slot_rate, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(tfp_tree, hf_tfp_hdr_seq_nr, tvb, offset, 2, ENC_BIG_ENDIAN);
atsr = hdr2 >> 13;
slot_rate = (hdr2 >> 11) & 3;
seq_nr = (hdr2 >> 6) & 0x1f;
proto_tree_add_item(tfp_tree, hf_tfp_hdr_delay_info, tvb, offset+1, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(tfp_tree, hf_tfp_hdr_p, tvb, offset+1, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(tfp_tree, hf_tfp_hdr_s, tvb, offset+2, 1, ENC_NA);
proto_tree_add_item(tfp_tree, hf_tfp_hdr_m, tvb, offset+2, 1, ENC_NA);
/* Frame Type depends on Slot Rate */
ftype = tvb_get_guint8(tvb, offset+2);
if (slot_rate == 0)
ftype |= 0x80;
proto_tree_add_uint_format_value(tfp_tree, hf_tfp_hdr_frame_type, tvb, offset+2, 1, ftype, "%s",
val_to_str(ftype, tfp_frame_type_vals, "Unknown (%u)"));
offset += 2;
col_append_fstr(pinfo->cinfo, COL_INFO, "TS=%u, Seq=%u, %s, %s ", atsr, seq_nr,
val_to_str(slot_rate, tfp_slot_rate_vals, "Unknown (%u)"),
val_to_str(ftype, tfp_frame_type_vals, "Unknown (%u)"));
/* check for Tail bit == 1, iterate over further octests */
while ((tvb_get_guint8(tvb, offset) & 0x01) == 0)
offset++;
offset++;
/* FIXME: implement packed frame support */
if (slot_rate == 0)
frame_bits = 320;
else
frame_bits = 160;
next_tvb = tvb_new_subset_length(tvb, offset, frame_bits/8);
call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree);
return offset;
}
void
proto_register_abis_tfp(void)
{
static hf_register_info hf[] = {
{ &hf_tfp_hdr_atsr,
{ "Air Timeslot Resource", "gsm_abis_tfp.atsr",
FT_UINT16, BASE_DEC, NULL, 0xe000,
NULL, HFILL }
},
{ &hf_tfp_hdr_slot_rate,
{ "Slot Rate", "gsm_abis_tfp.slot_rate",
FT_UINT16, BASE_DEC, VALS(tfp_slot_rate_vals), 0x1800,
NULL, HFILL }
},
{ &hf_tfp_hdr_seq_nr,
{ "Sequence Number", "gsm_abis_tfp.seq_nr",
FT_UINT16, BASE_DEC, NULL, 0x07c0,
NULL, HFILL }
},
{ &hf_tfp_hdr_delay_info,
{ "Delay Information (ms)", "gsm_abis_tfp.delay_info",
FT_UINT16, BASE_DEC, NULL, 0x003e,
NULL, HFILL }
},
{ &hf_tfp_hdr_p,
{ "Packing Scheme", "gsm_abis_tfp.packing_scheme",
FT_UINT16, BASE_DEC, VALS(tfp_packed_vals), 0x0180,
NULL, HFILL }
},
{ &hf_tfp_hdr_s,
{ "Silence Indicator", "gsm_abis_tfp.silence_ind",
FT_BOOLEAN, 8, NULL, 0x40,
NULL, HFILL }
},
{ &hf_tfp_hdr_m,
{ "Marker bit", "gsm_abis_tfp.marker",
FT_BOOLEAN, 8, NULL, 0x20,
NULL, HFILL }
},
{ &hf_tfp_hdr_frame_type,
{ "Frame Type", "gsm_abis_tfp.frame_type",
FT_UINT8, BASE_DEC, VALS(tfp_frame_type_vals), 0,
NULL, HFILL }
},
};
static gint *ett[] = {
&ett_tfp,
};
/* assign our custom match functions */
proto_abis_tfp = proto_register_protocol("GSM A-bis TFP", "Ericsson GSM A-bis TFP",
"gsm_abis_tfp");
proto_register_field_array(proto_abis_tfp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("gsm_abis_tfp", dissect_abis_tfp, proto_abis_tfp);
}
/* This function is called once at startup and every time the user hits
* 'apply' in the preferences dialogue */
void
proto_reg_handoff_abis_tfp(void)
{
sub_handles[SUB_DATA] = find_dissector("data");
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/