diff options
-rw-r--r-- | epan/dissectors/CMakeLists.txt | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-dect-aastra.c | 15 | ||||
-rw-r--r-- | epan/dissectors/packet-dect-dlc.c | 292 |
3 files changed, 306 insertions, 2 deletions
diff --git a/epan/dissectors/CMakeLists.txt b/epan/dissectors/CMakeLists.txt index f2345a8c64..a5c38bb02e 100644 --- a/epan/dissectors/CMakeLists.txt +++ b/epan/dissectors/CMakeLists.txt @@ -897,6 +897,7 @@ set(DISSECTOR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/packet-dec-dnart.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-dect.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-dect-aastra.c + ${CMAKE_CURRENT_SOURCE_DIR}/packet-dect-dlc.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-devicenet.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-dhcp.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-dhcp-failover.c diff --git a/epan/dissectors/packet-dect-aastra.c b/epan/dissectors/packet-dect-aastra.c index 974848f4e6..b126a92446 100644 --- a/epan/dissectors/packet-dect-aastra.c +++ b/epan/dissectors/packet-dect-aastra.c @@ -28,6 +28,7 @@ static gint hf_xdlc_subfield = -1; static gint ett_aamide = -1; static dissector_handle_t data_handle; +static dissector_handle_t dlc_handle; #define AAMIDE_ETH_T_XDLC 0xA000 #define AAMIDE_ETH_T_DOWNLOAD 0xA002 @@ -150,10 +151,14 @@ static int dissect_aamide_xdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr col_append_fstr(pinfo->cinfo, COL_INFO, "MCEI=%02x ", mcei); proto_tree_add_item(tree, hf_xdlc_mcei, tvb, offset+4, 1, ENC_NA); break; + case AAMIDE_P_LC_DTR_IND: + mcei = tvb_get_guint8(tvb, offset+4); + col_append_fstr(pinfo->cinfo, COL_INFO, "MCEI=%02x ", mcei); + proto_tree_add_item(tree, hf_xdlc_mcei, tvb, offset+4, 1, ENC_NA); + proto_tree_add_item(tree, hf_xdlc_subfield, tvb, offset+5, 1, ENC_NA); + break; case AAMIDE_P_LC_DATA_REQ: case AAMIDE_P_LC_DATA_IND: - case AAMIDE_P_LC_DTR_IND: - default: mcei = tvb_get_guint8(tvb, offset+4); col_append_fstr(pinfo->cinfo, COL_INFO, "MCEI=%02x ", mcei); proto_tree_add_item(tree, hf_xdlc_mcei, tvb, offset+4, 1, ENC_NA); @@ -161,6 +166,11 @@ static int dissect_aamide_xdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr payload_len = tvb_get_guint8(tvb, offset+6); payload_len = tvb_get_guint8(tvb, offset+6); payload_tvb = tvb_new_subset_length(tvb, offset+7, payload_len); + if (payload_tvb) + call_dissector(dlc_handle, payload_tvb, pinfo, tree); + payload_tvb = NULL; + break; + default: break; } @@ -225,6 +235,7 @@ void proto_reg_handoff_dect_aastra(void) dissector_add_uint("ethertype", AAMIDE_ETH_T_XDLC, xdlc_handle); data_handle = find_dissector("data"); + dlc_handle = find_dissector("dect_dlc"); } /* diff --git a/epan/dissectors/packet-dect-dlc.c b/epan/dissectors/packet-dect-dlc.c new file mode 100644 index 0000000000..c021cdb6ad --- /dev/null +++ b/epan/dissectors/packet-dect-dlc.c @@ -0,0 +1,292 @@ +/* packet-dect-dlc.c + * + * Dissector for the DECT (Digital Enhanced Cordless Telecommunications) + * DLC protocol layer as described in ETSI EN 300 175-4 V2.7.1 (2017-11) + * + * DLC is sometimes also called LAPC, which is a derivative of LAPDm (GSM), + * which is a derivative of LAPD (ISDN). + * + * Copyright 2018 by Harald Welte <laforge@gnumonks.org> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" +#include <epan/packet.h> +#include <epan/prefs.h> +#include <epan/xdlc.h> + +static int proto_dect_dlc = -1; + +static gint hf_dlc_address = -1; +static gint hf_dlc_nlf = -1; +static gint hf_dlc_lln = -1; +static gint hf_dlc_sapi = -1; +static gint hf_dlc_cr = -1; + +static int hf_dlc_control = -1; +static int hf_dlc_n_r = -1; +static int hf_dlc_n_s = -1; +static int hf_dlc_p = -1; +static int hf_dlc_f = -1; +static int hf_dlc_s_ftype = -1; +static int hf_dlc_u_modifier_cmd = -1; +static int hf_dlc_u_modifier_resp = -1; +static int hf_dlc_ftype_i = -1; +static int hf_dlc_ftype_s_u = -1; + +static int hf_dlc_length = -1; +static int hf_dlc_el = -1; +static int hf_dlc_m = -1; +static int hf_dlc_len = -1; + +static gint ett_dect_dlc = -1; +static gint ett_dect_dlc_address = -1; +static gint ett_dect_dlc_control = -1; +static gint ett_dect_dlc_length = -1; + +static dissector_handle_t data_handle; + +static dissector_table_t dlc_sapi_dissector_table; + + +static const xdlc_cf_items dlc_cf_items = { + &hf_dlc_n_r, + &hf_dlc_n_s, + &hf_dlc_p, + &hf_dlc_f, + &hf_dlc_s_ftype, + &hf_dlc_u_modifier_cmd, + &hf_dlc_u_modifier_resp, + &hf_dlc_ftype_i, + &hf_dlc_ftype_s_u +}; + +static const value_string dlc_sapi_vals[] = { + { 0, "Connection oriented signalling" }, + { 3, "Connectionless signalling" }, + { 0, NULL } +}; + +static const value_string dlc_lln_vals[] = { + { 0, "U0" }, + { 1, "A1" }, + { 2, "B2" }, + { 3, "B3" }, + { 4, "B4" }, + { 5, "B5" }, + { 6, "B6" }, + { 7, "unassigned" }, + { 0, NULL } +}; + +static const value_string dlc_m_vals[] = { + { 0, "Last segment" }, + { 1, "More segments" }, + { 0, NULL } +}; + +static const value_string dlc_el_vals[] = { + { 0, "More octets" }, + { 1, "Final octet" }, + { 0, NULL } +}; + + +static int dissect_dect_dlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void _U_ *data) +{ + proto_tree *dlc_tree, *addr_tree, *length_tree; + proto_item *dlc_ti, *addr_ti, *length_ti; + gboolean is_response = FALSE; + int available_length; + tvbuff_t *payload; + guint8 cr, sapi, length, len; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "DECT-DLC"); + + cr = tvb_get_guint8(tvb, 0) & 0x02; + if (pinfo->p2p_dir == P2P_DIR_RECV) + is_response = cr ? FALSE : TRUE; + else if (pinfo->p2p_dir == P2P_DIR_SENT) + is_response = cr ? TRUE : FALSE; + + dlc_ti = proto_tree_add_item(tree, proto_dect_dlc, tvb, 0, 3, ENC_NA); + dlc_tree = proto_item_add_subtree(dlc_ti, ett_dect_dlc); + + addr_ti = proto_tree_add_item(dlc_tree, hf_dlc_address, tvb, 0, 1, ENC_NA); + addr_tree = proto_item_add_subtree(addr_ti, ett_dect_dlc_address); + + sapi = (tvb_get_guint8(tvb, 0) & 0x0C) >> 2; + proto_tree_add_item(addr_tree, hf_dlc_nlf, tvb, 0, 1, ENC_NA); + proto_tree_add_item(addr_tree, hf_dlc_lln, tvb, 0, 1, ENC_NA); + proto_tree_add_item(addr_tree, hf_dlc_sapi, tvb, 0, 1, ENC_NA); + proto_tree_add_item(addr_tree, hf_dlc_cr, tvb, 0, 1, ENC_NA); + + dissect_xdlc_control(tvb, 1, pinfo, dlc_tree, hf_dlc_control, + ett_dect_dlc_control, &dlc_cf_items, NULL, NULL, NULL, + is_response, FALSE, FALSE); + + length_ti = proto_tree_add_item(dlc_tree, hf_dlc_length, tvb, 2, 1, ENC_NA); + length_tree = proto_item_add_subtree(length_ti, ett_dect_dlc_length); + length = tvb_get_guint8(tvb, 2); + proto_tree_add_uint(length_tree, hf_dlc_len, tvb, 2, 1, length); + proto_tree_add_uint(length_tree, hf_dlc_m, tvb, 2, 1, length); + proto_tree_add_uint(length_tree, hf_dlc_el, tvb, 2, 1, length); + len = length >> 2; + + available_length = tvb_captured_length(tvb) - 3; + payload = tvb_new_subset_length_caplen(tvb, 3, MIN(len, available_length), len); + + /* FIXME: fragment reassembly like in packet-lapdm.c */ + + if (!dissector_try_uint(dlc_sapi_dissector_table, sapi, payload, pinfo, tree)) + call_data_dissector(payload, pinfo, tree); + + return tvb_captured_length(tvb); +} + +void proto_register_dect_dlc(void) +{ + static hf_register_info hf[] = + { + { &hf_dlc_address, + { "Address Field", "dect_dlc.address_field", FT_UINT8, BASE_HEX, + NULL, 0x0, NULL, HFILL + } + }, + { &hf_dlc_nlf, + { "NLF", "dect_dlc.nlf", FT_UINT8, BASE_DEC, + NULL, 0x80, "New Link Flag", HFILL + } + }, + { &hf_dlc_lln, + { "LLN", "dect_dlc.lln", FT_UINT8, BASE_DEC, + VALS(dlc_lln_vals), 0x70, "Logical Link Number", HFILL + } + }, + { &hf_dlc_sapi, + { "SAPI", "dect_dlc.sapi", FT_UINT8, BASE_DEC, + VALS(dlc_sapi_vals), 0x0C, "Service Access Point Identifier", HFILL + } + }, + { &hf_dlc_cr, + { "C/R", "dect_dlc.cr", FT_UINT8, BASE_DEC, + NULL, 0x02, "Command/Response field bit", HFILL + } + }, + { &hf_dlc_control, + { "Control Field", "dect_dlc.control_field", FT_UINT8, BASE_HEX, + NULL, 0x0, NULL, HFILL + } + }, + { &hf_dlc_n_r, + { "N(R)", "dect_dlc.control.n_r", FT_UINT8, BASE_DEC, + NULL, 0xE0, NULL, HFILL + } + }, + { &hf_dlc_n_s, + { "N(S)", "dect_dlc.control.n_s", FT_UINT8, BASE_DEC, + NULL, 0x0E, NULL, HFILL + } + }, + { &hf_dlc_p, + { "Poll", "dect_dlc.control.p", FT_BOOLEAN, 8, + TFS(&tfs_true_false), 0x10, NULL, HFILL + } + }, + { &hf_dlc_f, + { "Final", "dect_dlc.control.f", FT_BOOLEAN, 8, + TFS(&tfs_true_false), 0x10, NULL, HFILL + } + }, + { &hf_dlc_s_ftype, + { "Supervisory frame type", "dect_dlc.control.s_ftype", FT_UINT8, BASE_HEX, + VALS(stype_vals), XDLC_S_FTYPE_MASK, NULL, HFILL + } + }, + { &hf_dlc_u_modifier_cmd, + { "Command", "dect_dlc.control.u_modifier_cmd", FT_UINT8, BASE_HEX, + VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, NULL, HFILL + } + }, + { &hf_dlc_u_modifier_resp, + { "Response", "dect_dlc.control.u_modifier_resp", FT_UINT8, BASE_HEX, + VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, NULL, HFILL + } + }, + { &hf_dlc_ftype_i, + { "Frame type", "dect_dlc.control.ftype", FT_UINT8, BASE_HEX, + VALS(ftype_vals), XDLC_I_MASK, NULL, HFILL + } + }, + { &hf_dlc_ftype_s_u, + { "Frame type", "dect_dlc.control.ftype", FT_UINT8, BASE_HEX, + VALS(ftype_vals), XDLC_S_U_MASK, NULL, HFILL + } + }, + { &hf_dlc_length, + { "Length Field", "dect_dlc.length_field", FT_UINT8, BASE_HEX, + NULL, 0x0, NULL, HFILL + } + }, + { &hf_dlc_el, + { "EL", "dect_dlc.el", FT_UINT8, BASE_DEC, + VALS(dlc_el_vals), 0x01, "Length indicator field extension bit", HFILL + } + }, + { &hf_dlc_m, + { "M", "dect_dlc.m", FT_UINT8, BASE_DEC, + VALS(dlc_m_vals), 0x02, "More data bit", HFILL + } + }, + { &hf_dlc_len, + { "Length", "dect_dlc.length", FT_UINT8, BASE_DEC, + NULL, 0xFC, "LEngth indicator", HFILL + } + }, + + }; + + static gint *ett[] = { + &ett_dect_dlc, + &ett_dect_dlc_address, + &ett_dect_dlc_control, + &ett_dect_dlc_length, + }; + + /* Register protocol */ + proto_dect_dlc = proto_register_protocol("DECT DLC (LAPC)", "DECT-DLC", "dect_dlc"); + + proto_register_subtree_array(ett, array_length(ett)); + proto_register_field_array(proto_dect_dlc, hf, array_length(hf)); + + register_dissector("dect_dlc", dissect_dect_dlc, proto_dect_dlc); + + dlc_sapi_dissector_table = register_dissector_table("dect_dlc.sapi", "DECT DLC SAPI", proto_dect_dlc, FT_UINT8, BASE_DEC); + + data_handle = find_dissector("data"); +} + +#if 0 +void proto_reg_handoff_dect_aastra(void) +{ + dissector_handle_t dlc_handle = create_dissector_handle(dissect_aamide_xdlc, proto_dect_dlc); +} +#endif + +/* + * 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: + */ |