2 * Routines for GSM L2RCOP (3GPP TS 27.002) dissection
3 * (C) 2023 Harald Welte <laforge@osmocom.org>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
17 void proto_register_gsm_l2rcop(void);
19 static int proto_l2rcop
;
21 static int hf_l2rcop_sa
;
22 static int hf_l2rcop_sb
;
23 static int hf_l2rcop_x
;
24 static int hf_l2rcop_addr
;
25 static int hf_l2rcop_break
;
26 static int hf_l2rcop_break_ack
;
28 static int ett_l2rcop
;
30 static const value_string addr_vals
[] = {
31 { 31, "last status change, remainder empty" },
32 { 30, "last status change, remainder full of characters" },
33 { 29, "destructive break signal, remainder empty" },
34 { 28, "destructive break acknowledge, remainder empty" },
35 { 27, "extended address in ext octet" },
40 add_characters(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, unsigned offset
, unsigned len
)
42 tvbuff_t
*next_tvb
= tvb_new_subset_length(tvb
, offset
, len
);
43 call_data_dissector(next_tvb
, pinfo
, tree
);
46 /* Dissect a L2RCOP message as described in 3GPP TS 27.002 */
48 dissect_l2rcop(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
50 int reported_len
= tvb_reported_length(tvb
);
53 /* we currently support RLP v0 + v1 (first octet is always status octet) */
55 for (cur
= 0; cur
< (unsigned)reported_len
; ) {
56 uint8_t oct
= tvb_get_uint8(tvb
, cur
);
57 uint8_t addr
= oct
& 0x1f;
58 proto_tree
*l2rcop_tree
;
60 const char *addr_str
= val_to_str(addr
, addr_vals
, "%u characters");
62 ti
= proto_tree_add_protocol_format(tree
, proto_l2rcop
, tvb
, 0, reported_len
,
63 "GSM L2RCOP Chunk Status=0x%02x (Addr: %s)", oct
, addr_str
);
64 l2rcop_tree
= proto_item_add_subtree(ti
, ett_l2rcop
);
66 proto_tree_add_item(l2rcop_tree
, hf_l2rcop_sa
, tvb
, cur
, 1, ENC_BIG_ENDIAN
);
67 proto_tree_add_item(l2rcop_tree
, hf_l2rcop_sb
, tvb
, cur
, 1, ENC_BIG_ENDIAN
);
68 proto_tree_add_item(l2rcop_tree
, hf_l2rcop_x
, tvb
, cur
, 1, ENC_BIG_ENDIAN
);
69 proto_tree_add_item(l2rcop_tree
, hf_l2rcop_addr
, tvb
, cur
, 1, ENC_BIG_ENDIAN
);
72 case 31: /* last status change, remainder empty */
74 case 30: /* last status change, remainder full of characters */
75 add_characters(l2rcop_tree
, pinfo
, tvb
, cur
+1, reported_len
-cur
-1);
77 case 29: /* destructive break signal, remainder empty */
78 proto_tree_add_item(l2rcop_tree
, hf_l2rcop_break
, tvb
, cur
, 1, ENC_BIG_ENDIAN
);
80 case 28: /* destructive break acknowledge, remainder empty */
81 proto_tree_add_item(l2rcop_tree
, hf_l2rcop_break_ack
, tvb
, cur
, 1, ENC_BIG_ENDIAN
);
83 case 27: /* extended address in ext octet */
85 addr
= tvb_get_uint8(tvb
, cur
) & 0x3f;
86 /* This "cannot happen"; let's abort processing right now. */
89 proto_tree_add_uint(l2rcop_tree
, hf_l2rcop_addr
, tvb
, cur
, 1, addr
);
90 add_characters(l2rcop_tree
, pinfo
, tvb
, cur
+1, addr
);
94 /* This "cannot happen"; let's abort processing right now. */
97 /* This "cannot happen"; let's abort processing right now. */
100 add_characters(l2rcop_tree
, pinfo
, tvb
, cur
+1, addr
);
109 static const true_false_string x_vals
= {
110 "flow control ACTIVE", "flow control inactive"
115 proto_register_gsm_l2rcop(void)
117 static hf_register_info hf
[] = {
119 { "SA", "gsm_l2rcop.sa", FT_BOOLEAN
, 8, TFS(&tfs_off_on
), 0x80,
122 { "SB", "gsm_l2rcop.sb", FT_BOOLEAN
, 8, TFS(&tfs_off_on
), 0x40,
125 { "X", "gsm_l2rcop.x", FT_BOOLEAN
, 8, TFS(&x_vals
), 0x20,
128 { "Address", "gsm_l2rcop.addr", FT_UINT8
, BASE_DEC
|BASE_SPECIAL_VALS
, VALS(addr_vals
), 0x1f,
131 { "Break", "gsm_l2rcop.break", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
133 { &hf_l2rcop_break_ack
,
134 { "Break Ack", "gsm_l2rcop.break_ack", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
137 static int *ett
[] = {
141 proto_l2rcop
= proto_register_protocol("GSM L2R Character Oriented Protocol (L2RCOP)", "GSM-L2RCOP",
143 proto_register_field_array(proto_l2rcop
, hf
, array_length(hf
));
144 proto_register_subtree_array(ett
, array_length(ett
));
145 register_dissector("gsm_l2rcop", dissect_l2rcop
, proto_l2rcop
);
150 * Editor modelines - https://www.wireshark.org/tools/modelines.html
155 * indent-tabs-mode: nil
158 * vi: set shiftwidth=4 tabstop=8 expandtab:
159 * :indentSize=4:tabSize=8:noTabs=true: