2 * Routines for ISDN packet disassembly
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <epan/packet.h>
29 #include <epan/prefs.h>
30 #include <epan/circuit.h>
32 static int proto_isdn
= -1;
33 static int hf_isdn_channel
= -1;
35 static gint ett_isdn
= -1;
38 * Protocol used on the D channel.
40 #define DCHANNEL_LAPD 0 /* LAPD */
41 #define DCHANNEL_DPNSS 1 /* DPNSS link layer */
43 static const enum_val_t dchannel_protocol_options
[] = {
44 { "lapd", "LAPD", DCHANNEL_LAPD
},
45 { "DPNSS", "DPNSS", DCHANNEL_DPNSS
},
49 static int dchannel_protocol
= DCHANNEL_LAPD
;
51 static dissector_handle_t lapd_handle
;
52 static dissector_handle_t dpnss_link_handle
;
53 static dissector_handle_t ppp_hdlc_handle
;
54 static dissector_handle_t v120_handle
;
55 static dissector_handle_t data_handle
;
57 static const value_string channel_vals
[] = {
93 dissect_isdn(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
95 proto_tree
*isdn_tree
;
97 static const guint8 v120_sabme
[3] = { 0x08, 0x01, 0x7F };
98 static const guint8 ppp
[2] = { 0xFF, 0x03 };
101 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ISDN");
103 if (pinfo
->pseudo_header
->isdn
.uton
) {
104 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "Network");
105 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "User");
107 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "User");
108 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "Network");
111 pinfo
->ctype
= CT_ISDN
;
112 pinfo
->circuit_id
= pinfo
->pseudo_header
->isdn
.channel
;
115 ti
= proto_tree_add_item(tree
, proto_isdn
, tvb
, 0, 0, ENC_NA
);
116 isdn_tree
= proto_item_add_subtree(ti
, ett_isdn
);
118 proto_tree_add_uint(isdn_tree
, hf_isdn_channel
, tvb
, 0, 0,
119 pinfo
->pseudo_header
->isdn
.channel
);
123 * Set up a circuit for this channel, and assign it a dissector.
125 circuit
= find_circuit(pinfo
->ctype
, pinfo
->circuit_id
, pinfo
->fd
->num
);
127 circuit
= circuit_new(pinfo
->ctype
, pinfo
->circuit_id
,
130 if (circuit_get_dissector(circuit
) == NULL
) {
132 * We don't yet know the type of traffic on the circuit.
134 switch (pinfo
->pseudo_header
->isdn
.channel
) {
138 * D-channel. Dissect it with whatever protocol
139 * the user specified, or the default of LAPD if
140 * they didn't specify one.
142 switch (dchannel_protocol
) {
145 circuit_set_dissector(circuit
, lapd_handle
);
149 circuit_set_dissector(circuit
,
159 * We don't know yet whether the datastream is
160 * V.120 or not; this heuristic tries to figure
163 * We cannot glean this from the Q.931 SETUP message,
164 * because no commercial V.120 implementation I've
165 * seen actually sets the V.120 protocol discriminator
166 * (that, or I'm misreading the spec badly).
168 * TODO: close the circuit after a close on the B
169 * channel is detected.
171 * -Bert Driehuis (from the i4btrace reader;
172 * this heuristic was moved from there to
175 * XXX - I don't know that one can guarantee that
176 * the SABME will appear in the first frame on
177 * the channels, so we probably can't just say
178 * "it must be PPP" if we don't immediately see
179 * the V.120 SABME frame, so we do so only if
180 * we see the 0xFF 0x03. Unfortunately, that
181 * won't do the right thing if the PPP-over-HDLC
182 * headers aren't being used....
184 if (tvb_memeql(tvb
, 0, v120_sabme
, 3) == 0) {
186 * We assume this is V.120.
188 circuit_set_dissector(circuit
, v120_handle
);
189 } else if (tvb_memeql(tvb
, 0, ppp
, 2) == 0) {
191 * We assume this is PPP.
193 circuit_set_dissector(circuit
, ppp_hdlc_handle
);
199 if (!try_circuit_dissector(pinfo
->ctype
, pinfo
->circuit_id
,
200 pinfo
->fd
->num
, tvb
, pinfo
, tree
, NULL
))
201 call_dissector(data_handle
, tvb
, pinfo
, tree
);
205 proto_register_isdn(void)
207 static hf_register_info hf
[] = {
209 { "Channel", "isdn.channel", FT_UINT8
, BASE_DEC
,
210 VALS(channel_vals
), 0x0, NULL
, HFILL
}},
212 static gint
*ett
[] = {
215 module_t
*isdn_module
;
217 proto_isdn
= proto_register_protocol("ISDN", "ISDN", "isdn");
218 proto_register_field_array(proto_isdn
, hf
, array_length(hf
));
219 proto_register_subtree_array(ett
, array_length(ett
));
221 isdn_module
= prefs_register_protocol(proto_isdn
, NULL
);
223 prefs_register_enum_preference(isdn_module
, "dchannel_protocol",
224 "D-channel protocol",
225 "The protocol running on the D channel",
226 &dchannel_protocol
, dchannel_protocol_options
, FALSE
);
230 proto_reg_handoff_isdn(void)
232 dissector_handle_t isdn_handle
;
235 * Get handles for the LAPD, DPNSS link-layer, PPP, and V.120
238 lapd_handle
= find_dissector("lapd");
239 dpnss_link_handle
= find_dissector("dpnss_link");
240 ppp_hdlc_handle
= find_dissector("ppp_hdlc");
241 v120_handle
= find_dissector("v120");
242 data_handle
= find_dissector("data");
244 isdn_handle
= create_dissector_handle(dissect_isdn
, proto_isdn
);
246 dissector_add_uint("wtap_encap", WTAP_ENCAP_ISDN
, isdn_handle
);