2 * Routines for TDM over Ethernet packet disassembly
3 * Copyright 2010, Haakon Nessjoen <haakon.nessjoen@gmail.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 #include <epan/packet.h>
31 #include <epan/etypes.h>
32 #include <epan/prefs.h>
34 /* Bitmasks for the flags in the fourth byte of the packet */
35 #define TDMOE_YELLOW_ALARM_BITMASK 0x01
36 #define TDMOE_SIGBITS_BITMASK 0x02
38 /* protocols and header fields */
39 static int proto_tdmoe
= -1;
41 static int hf_tdmoe_subaddress
= -1;
42 static int hf_tdmoe_samples
= -1;
43 static int hf_tdmoe_flags
= -1;
44 static int hf_tdmoe_yellow_alarm
= -1;
45 static int hf_tdmoe_sig_bits_present
= -1;
46 static int hf_tdmoe_packet_counter
= -1;
47 static int hf_tdmoe_channels
= -1;
48 static int hf_tdmoe_sig_bits
= -1;
50 static gint ett_tdmoe
= -1;
51 static gint ett_tdmoe_flags
= -1;
53 static dissector_handle_t lapd_handle
;
54 static dissector_handle_t data_handle
;
56 static gint pref_tdmoe_d_channel
= 24;
58 void proto_reg_handoff_tdmoe(void);
61 dissect_tdmoe(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
64 proto_tree
*tdmoe_tree
;
65 tvbuff_t
*next_client
;
69 static const gint
*flags
[] = { &hf_tdmoe_yellow_alarm
, &hf_tdmoe_sig_bits_present
, NULL
};
72 /* Check that there's enough data */
73 if (tvb_length(tvb
) < 8)
76 subaddress
= tvb_get_ntohs(tvb
, 0);
77 channels
= tvb_get_ntohs(tvb
, 6);
79 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "TDMoE");
80 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Subaddress: %d Channels: %d %s",
83 (tvb_get_guint8(tvb
, 3) & TDMOE_YELLOW_ALARM_BITMASK
? "[YELLOW ALARM]" : "")
87 /* create display subtree for the protocol */
88 ti
= proto_tree_add_item(tree
, proto_tdmoe
, tvb
, 0, -1, ENC_NA
);
89 tdmoe_tree
= proto_item_add_subtree(ti
, ett_tdmoe
);
92 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_subaddress
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
95 /* Samples (1 byte) */
96 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_samples
, tvb
, offset
, 1, ENC_NA
);
99 /* Yellow alarm & "Sig bits present" bits (1 byte) */
100 proto_tree_add_bitmask(tdmoe_tree
, tvb
, offset
, hf_tdmoe_flags
, ett_tdmoe_flags
, flags
, ENC_BIG_ENDIAN
);
103 /* Packet counter (2 bytes) */
104 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_packet_counter
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
107 /* Number of channels in packet (2 bytes) */
108 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_channels
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
111 if (tvb_get_guint8(tvb
, 3) & TDMOE_SIGBITS_BITMASK
) {
112 /* 4 sigbits per channel. Might be different on other sub-protocols? */
113 guint16 length
= (channels
>> 1) + ((channels
& 0x01) ? 1 : 0);
115 proto_tree_add_item(tdmoe_tree
, hf_tdmoe_sig_bits
, tvb
, offset
, length
, ENC_NA
);
119 /* The rest is SAMPLES * CHANNELS bytes of channel data */
120 for (chan
= 1; chan
<= channels
; chan
++) {
121 next_client
= tvb_new_subset_length(tvb
, offset
+ ((chan
- 1) * 8), 8);
122 if (chan
== pref_tdmoe_d_channel
) {
123 call_dissector(lapd_handle
, next_client
, pinfo
, tree
);
125 call_dissector(data_handle
, next_client
, pinfo
, tree
);
132 proto_register_tdmoe(void)
134 static hf_register_info hf
[] = {
136 { &hf_tdmoe_subaddress
,
137 { "Subaddress", "tdmoe.subaddress", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
140 { "Samples", "tdmoe.samples", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
141 "Samples per channel", HFILL
}},
143 { "Flags", "tdmoe.flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
145 { &hf_tdmoe_yellow_alarm
,
146 { "Yellow Alarm", "tdmoe.yellowalarm", FT_BOOLEAN
, 8, NULL
, TDMOE_YELLOW_ALARM_BITMASK
,
148 { &hf_tdmoe_sig_bits_present
,
149 { "Sig bits present", "tdmoe.sig_bits_present", FT_BOOLEAN
, 8, NULL
, TDMOE_SIGBITS_BITMASK
,
151 { &hf_tdmoe_packet_counter
,
152 { "Counter", "tdmoe.counter", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
153 "Packet number", HFILL
}},
154 { &hf_tdmoe_channels
,
155 { "Channels", "tdmoe.channels", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
157 { &hf_tdmoe_sig_bits
,
158 { "Sig bits", "tdmoe.sig_bits", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
161 static gint
*ett
[] = {
165 module_t
*tdmoe_module
;
167 proto_tdmoe
= proto_register_protocol("Digium TDMoE Protocol", "TDMoE", "tdmoe");
168 proto_register_field_array(proto_tdmoe
, hf
, array_length(hf
));
169 proto_register_subtree_array(ett
, array_length(ett
));
170 tdmoe_module
= prefs_register_protocol(proto_tdmoe
, proto_reg_handoff_tdmoe
);
171 prefs_register_uint_preference(tdmoe_module
, "d_channel",
173 "The TDMoE channel that contains the D-Channel.",
174 10, &pref_tdmoe_d_channel
);
178 proto_reg_handoff_tdmoe(void)
180 dissector_handle_t tdmoe_handle
;
182 tdmoe_handle
= new_create_dissector_handle(dissect_tdmoe
, proto_tdmoe
);
183 dissector_add_uint("ethertype", ETHERTYPE_TDMOE
, tdmoe_handle
);
185 lapd_handle
= find_dissector("lapd-bitstream");
186 data_handle
= find_dissector("data");