2 * Routines for TDM over Ethernet packet disassembly
3 * Copyright 2010, Haakon Nessjoen <haakon.nessjoen@gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/etypes.h>
16 #include <epan/prefs.h>
18 /* Bitmasks for the flags in the fourth byte of the packet */
19 #define TDMOE_YELLOW_ALARM_BITMASK 0x01
20 #define TDMOE_SIGBITS_BITMASK 0x02
22 void proto_reg_handoff_tdmoe(void);
23 void proto_register_tdmoe(void);
25 static dissector_handle_t tdmoe_handle
;
27 /* protocols and header fields */
28 static int proto_tdmoe
;
30 static int hf_tdmoe_subaddress
;
31 static int hf_tdmoe_samples
;
32 static int hf_tdmoe_flags
;
33 static int hf_tdmoe_yellow_alarm
;
34 static int hf_tdmoe_sig_bits_present
;
35 static int hf_tdmoe_packet_counter
;
36 static int hf_tdmoe_channels
;
37 static int hf_tdmoe_sig_bits
;
40 static int ett_tdmoe_flags
;
42 static dissector_handle_t lapd_handle
;
44 static int pref_tdmoe_d_channel
= 24;
47 dissect_tdmoe(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
50 proto_tree
*tdmoe_tree
;
51 tvbuff_t
*next_client
;
55 static int * const flags
[] = { &hf_tdmoe_yellow_alarm
, &hf_tdmoe_sig_bits_present
, NULL
};
58 /* Check that there's enough data */
59 if (tvb_captured_length(tvb
) < 8)
62 subaddress
= tvb_get_ntohs(tvb
, 0);
63 channels
= tvb_get_ntohs(tvb
, 6);
65 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "TDMoE");
66 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Subaddress: %d Channels: %d %s",
69 (tvb_get_uint8(tvb
, 3) & TDMOE_YELLOW_ALARM_BITMASK
? "[YELLOW ALARM]" : "")
73 /* create display subtree for the protocol */
74 ti
= proto_tree_add_item(tree
, proto_tdmoe
, tvb
, 0, -1, ENC_NA
);
75 tdmoe_tree
= proto_item_add_subtree(ti
, ett_tdmoe
);
78 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_subaddress
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
81 /* Samples (1 byte) */
82 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_samples
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
85 /* Yellow alarm & "Sig bits present" bits (1 byte) */
86 proto_tree_add_bitmask(tdmoe_tree
, tvb
, offset
, hf_tdmoe_flags
, ett_tdmoe_flags
, flags
, ENC_BIG_ENDIAN
);
89 /* Packet counter (2 bytes) */
90 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_packet_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
93 /* Number of channels in packet (2 bytes) */
94 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_channels
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
97 if (tvb_get_uint8(tvb
, 3) & TDMOE_SIGBITS_BITMASK
) {
98 /* 4 sigbits per channel. Might be different on other sub-protocols? */
99 uint16_t length
= (channels
>> 1) + ((channels
& 0x01) ? 1 : 0);
101 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_sig_bits
, tvb
, offset
, length
, ENC_NA
);
105 /* The rest is SAMPLES * CHANNELS bytes of channel data */
106 for (chan
= 1; chan
<= channels
; chan
++) {
107 next_client
= tvb_new_subset_length(tvb
, offset
+ ((chan
- 1) * 8), 8);
108 if (chan
== pref_tdmoe_d_channel
) {
109 call_dissector(lapd_handle
, next_client
, pinfo
, tree
);
111 call_data_dissector(next_client
, pinfo
, tree
);
118 proto_register_tdmoe(void)
120 static hf_register_info hf
[] = {
122 { &hf_tdmoe_subaddress
,
123 { "Subaddress", "tdmoe.subaddress", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
126 { "Samples", "tdmoe.samples", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
127 "Samples per channel", HFILL
}},
129 { "Flags", "tdmoe.flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
131 { &hf_tdmoe_yellow_alarm
,
132 { "Yellow Alarm", "tdmoe.yellowalarm", FT_BOOLEAN
, 8, NULL
, TDMOE_YELLOW_ALARM_BITMASK
,
134 { &hf_tdmoe_sig_bits_present
,
135 { "Sig bits present", "tdmoe.sig_bits_present", FT_BOOLEAN
, 8, NULL
, TDMOE_SIGBITS_BITMASK
,
137 { &hf_tdmoe_packet_counter
,
138 { "Counter", "tdmoe.counter", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
139 "Packet number", HFILL
}},
140 { &hf_tdmoe_channels
,
141 { "Channels", "tdmoe.channels", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
143 { &hf_tdmoe_sig_bits
,
144 { "Sig bits", "tdmoe.sig_bits", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
147 static int *ett
[] = {
151 module_t
*tdmoe_module
;
153 proto_tdmoe
= proto_register_protocol("Digium TDMoE Protocol", "TDMoE", "tdmoe");
154 proto_register_field_array(proto_tdmoe
, hf
, array_length(hf
));
155 proto_register_subtree_array(ett
, array_length(ett
));
156 tdmoe_handle
= register_dissector("tdmoe", dissect_tdmoe
, proto_tdmoe
);
157 tdmoe_module
= prefs_register_protocol(proto_tdmoe
, NULL
);
158 prefs_register_uint_preference(tdmoe_module
, "d_channel",
160 "The TDMoE channel that contains the D-Channel.",
161 10, &pref_tdmoe_d_channel
);
165 proto_reg_handoff_tdmoe(void)
167 dissector_add_uint("ethertype", ETHERTYPE_TDMOE
, tdmoe_handle
);
169 lapd_handle
= find_dissector_add_dependency("lapd-bitstream", proto_tdmoe
);
173 * Editor modelines - https://www.wireshark.org/tools/modelines.html
178 * indent-tabs-mode: t
181 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
182 * :indentSize=8:tabSize=8:noTabs=false: