2 * Routines for ISDN packet disassembly
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include <epan/packet.h>
14 #include <epan/prefs.h>
16 #include <wsutil/array.h>
17 #include <wiretap/wtap.h>
18 #include <epan/conversation.h>
20 void proto_register_isdn(void);
21 void proto_reg_handoff_isdn(void);
23 static int proto_isdn
;
24 static int hf_isdn_direction
;
25 static int hf_isdn_channel
;
29 static dissector_handle_t isdn_handle
;
32 * Protocol used on the D channel.
34 #define DCHANNEL_LAPD 0 /* LAPD */
35 #define DCHANNEL_DPNSS 1 /* DPNSS link layer */
37 static const enum_val_t dchannel_protocol_options
[] = {
38 { "lapd", "LAPD", DCHANNEL_LAPD
},
39 { "DPNSS", "DPNSS", DCHANNEL_DPNSS
},
43 static int dchannel_protocol
= DCHANNEL_LAPD
;
45 static dissector_handle_t lapd_phdr_handle
;
46 static dissector_handle_t dpnss_link_handle
;
47 static dissector_handle_t ppp_hdlc_handle
;
48 static dissector_handle_t v120_handle
;
50 static const true_false_string isdn_direction_tfs
= {
55 static const value_string channel_vals
[] = {
91 dissect_isdn(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
93 struct isdn_phdr
*isdn
= (struct isdn_phdr
*)data
;
94 proto_tree
*isdn_tree
;
96 static const uint8_t v120_sabme
[3] = { 0x08, 0x01, 0x7F };
97 static const uint8_t ppp
[2] = { 0xFF, 0x03 };
100 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ISDN");
103 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "Network");
104 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "User");
105 pinfo
->p2p_dir
= P2P_DIR_SENT
;
107 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "User");
108 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "Network");
109 pinfo
->p2p_dir
= P2P_DIR_RECV
;
113 ti
= proto_tree_add_item(tree
, proto_isdn
, tvb
, 0, 0, ENC_NA
);
114 isdn_tree
= proto_item_add_subtree(ti
, ett_isdn
);
116 proto_tree_add_boolean(isdn_tree
, hf_isdn_direction
, tvb
, 0, 0,
119 proto_tree_add_uint(isdn_tree
, hf_isdn_channel
, tvb
, 0, 0,
124 * Set up a circuit for this channel, and assign it a dissector.
126 conv
= find_or_create_conversation_by_id(pinfo
, CONVERSATION_ISDN
,
129 if (conversation_get_dissector(conv
, 0) == NULL
) {
131 * We don't yet know the type of traffic on the circuit.
133 switch (isdn
->channel
) {
137 * D-channel. Dissect it with whatever protocol
138 * the user specified, or the default of LAPD if
139 * they didn't specify one.
141 switch (dchannel_protocol
) {
144 conversation_set_dissector(conv
, lapd_phdr_handle
);
148 conversation_set_dissector(conv
,
158 * We don't know yet whether the datastream is
159 * V.120 or not; this heuristic tries to figure
162 * We cannot glean this from the Q.931 SETUP message,
163 * because no commercial V.120 implementation I've
164 * seen actually sets the V.120 protocol discriminator
165 * (that, or I'm misreading the spec badly).
167 * TODO: close the circuit after a close on the B
168 * channel is detected.
170 * -Bert Driehuis (from the i4btrace reader;
171 * this heuristic was moved from there to
174 * XXX - I don't know that one can guarantee that
175 * the SABME will appear in the first frame on
176 * the channels, so we probably can't just say
177 * "it must be PPP" if we don't immediately see
178 * the V.120 SABME frame, so we do so only if
179 * we see the 0xFF 0x03. Unfortunately, that
180 * won't do the right thing if the PPP-over-HDLC
181 * headers aren't being used....
183 if (tvb_memeql(tvb
, 0, v120_sabme
, 3) == 0) {
185 * We assume this is V.120.
187 conversation_set_dissector(conv
, v120_handle
);
188 } else if (tvb_memeql(tvb
, 0, ppp
, 2) == 0) {
190 * We assume this is PPP.
192 conversation_set_dissector(conv
, ppp_hdlc_handle
);
198 if (!try_conversation_dissector_by_id(CONVERSATION_ISDN
, isdn
->channel
,
199 tvb
, pinfo
, tree
, data
))
200 call_data_dissector(tvb
, pinfo
, tree
);
202 return tvb_captured_length(tvb
);
206 proto_register_isdn(void)
208 static hf_register_info hf
[] = {
209 { &hf_isdn_direction
,
210 { "Direction", "isdn.direction", FT_BOOLEAN
, BASE_NONE
,
211 TFS(&isdn_direction_tfs
), 0x0, NULL
, HFILL
}},
214 { "Channel", "isdn.channel", FT_UINT8
, BASE_DEC
,
215 VALS(channel_vals
), 0x0, NULL
, HFILL
}},
217 static int *ett
[] = {
220 module_t
*isdn_module
;
222 proto_isdn
= proto_register_protocol("ISDN", "ISDN", "isdn");
223 proto_register_field_array(proto_isdn
, hf
, array_length(hf
));
224 proto_register_subtree_array(ett
, array_length(ett
));
226 isdn_module
= prefs_register_protocol(proto_isdn
, NULL
);
228 prefs_register_enum_preference(isdn_module
, "dchannel_protocol",
229 "D-channel protocol",
230 "The protocol running on the D channel",
231 &dchannel_protocol
, dchannel_protocol_options
, false);
233 isdn_handle
= register_dissector("isdn", dissect_isdn
, proto_isdn
);
237 proto_reg_handoff_isdn(void)
240 * Get handles for the LAPD-with-pseudoheader, DPNSS link-layer,
241 * PPP, and V.120 dissectors.
243 lapd_phdr_handle
= find_dissector("lapd-phdr");
244 dpnss_link_handle
= find_dissector("dpnss_link");
245 ppp_hdlc_handle
= find_dissector("ppp_hdlc");
246 v120_handle
= find_dissector("v120");
248 dissector_add_uint("wtap_encap", WTAP_ENCAP_ISDN
, isdn_handle
);
252 * Editor modelines - https://www.wireshark.org/tools/modelines.html
257 * indent-tabs-mode: t
260 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
261 * :indentSize=8:tabSize=8:noTabs=false: