MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-dlsw.c
blobc57620b2fd28427df6bfe0f8125f6af4d15fa23d
1 /* packet-dlsw.c
2 * Routines for DLSw packet dissection (Data Link Switching)
3 * Copyright 2001, Paul Ionescu <paul@acorp.ro>
5 * $Id$
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.
26 /* DLSw dissector ( RFC 1434, RFC 1795, RFC 2166) */
28 #include "config.h"
30 #include <glib.h>
32 #include <epan/packet.h>
33 #include <epan/exceptions.h>
34 #include <epan/expert.h>
36 #include "packet-tcp.h"
38 void proto_register_dlsw(void);
39 void proto_reg_handoff_dlsw(void);
41 static int proto_dlsw = -1;
42 static int hf_dlsw_flow_control_indication = -1;
43 static int hf_dlsw_flow_control_ack = -1;
44 static int hf_dlsw_flow_control_operator = -1;
45 static int hf_dlsw_flags_explorer_msg = -1;
46 /* Generated from convert_proto_tree_add_text.pl */
47 static int hf_dlsw_vector_length = -1;
48 static int hf_dlsw_dlc_header_sa = -1;
49 static int hf_dlsw_dlc_header_fc_byte = -1;
50 static int hf_dlsw_target_transport_id = -1;
51 static int hf_dlsw_error_pointer = -1;
52 static int hf_dlsw_capabilities_length = -1;
53 static int hf_dlsw_multicast_version_number = -1;
54 static int hf_dlsw_frame_direction = -1;
55 static int hf_dlsw_circuit_priority = -1;
56 static int hf_dlsw_origin_dlc_port_id = -1;
57 static int hf_dlsw_protocol_id = -1;
58 static int hf_dlsw_mac_address_list = -1;
59 static int hf_dlsw_origin_link_sap = -1;
60 static int hf_dlsw_header_length = -1;
61 static int hf_dlsw_dlc_header_ctrl = -1;
62 static int hf_dlsw_target_dlc_port_id = -1;
63 static int hf_dlsw_vector_type = -1;
64 static int hf_dlsw_largest_frame_size = -1;
65 static int hf_dlsw_error_cause = -1;
66 static int hf_dlsw_dlc_header_length = -1;
67 static int hf_dlsw_oui = -1;
68 static int hf_dlsw_target_dlc = -1;
69 static int hf_dlsw_dlc_header_ac_byte = -1;
70 static int hf_dlsw_tcp_connections = -1;
71 static int hf_dlsw_initial_pacing_window = -1;
72 static int hf_dlsw_old_message_type = -1;
73 static int hf_dlsw_capex_type = -1;
74 static int hf_dlsw_ssp_flags = -1;
75 static int hf_dlsw_target_mac_address = -1;
76 static int hf_dlsw_origin_mac_address = -1;
77 static int hf_dlsw_dlc_header_rif = -1;
78 static int hf_dlsw_message_type = -1;
79 static int hf_dlsw_header_number = -1;
80 static int hf_dlsw_message_length = -1;
81 static int hf_dlsw_remote_dlc_pid = -1;
82 static int hf_dlsw_vendor_oui = -1;
83 static int hf_dlsw_flow_ctrl_byte = -1;
84 static int hf_dlsw_version_string = -1;
85 static int hf_dlsw_version = -1;
86 static int hf_dlsw_remote_dlc = -1;
87 static int hf_dlsw_origin_dlc = -1;
88 static int hf_dlsw_origin_transport_id = -1;
89 static int hf_dlsw_dlc_header_ssap = -1;
90 static int hf_dlsw_target_link_sap = -1;
91 static int hf_dlsw_dlc_header_da = -1;
92 static int hf_dlsw_netbios_name = -1;
93 static int hf_dlsw_dlc_header_dsap = -1;
95 static gint ett_dlsw = -1;
96 static gint ett_dlsw_header = -1;
97 static gint ett_dlsw_fc = -1;
98 static gint ett_dlsw_sspflags = -1;
99 static gint ett_dlsw_data = -1;
100 static gint ett_dlsw_vector = -1;
102 static expert_field ei_dlsw_dlc_header_length = EI_INIT;
104 #define CANUREACH 0x03
105 #define ICANREACH 0x04
106 #define REACH_ACK 0x05
107 #define DGRMFRAME 0x06
108 #define XIDFRAME 0x07
109 #define CONTACT 0x08
110 #define CONTACTED 0x09
111 #define RESTART_DL 0x10
112 #define DL_RESTARTED 0x11
113 #define ENTER_BUSY 0x0C
114 #define EXIT_BUSY 0x0D
115 #define INFOFRAME 0x0A
116 #define HALT_DL 0x0E
117 #define DL_HALTED 0x0F
118 #define NETBIOS_NQ 0x12
119 #define NETBIOS_NR 0x13
120 #define DATAFRAME 0x14
121 #define HALT_DL_NOACK 0x19
122 #define NETBIOS_ANQ 0x1A
123 #define NETBIOS_ANR 0x1B
124 #define KEEPALIVE 0x1D
125 #define CAP_EXCHANGE 0x20
126 #define IFCM 0x21
127 #define TEST_CIRCUIT_REQ 0x7A
128 #define TEST_CIRCUIT_RSP 0x7B
130 static const value_string dlsw_type_vals[] = {
131 { CANUREACH , "Can U Reach Station-circuit start" },
132 { ICANREACH , "I Can Reach Station-circuit start" },
133 { REACH_ACK , "Reach Acknowledgment" },
134 { DGRMFRAME , "Datagram Frame" },
135 { XIDFRAME , "XID Frame" },
136 { CONTACT , "Contact Remote Station" },
137 { CONTACTED , "Remote Station Contacted" },
138 { RESTART_DL , "Restart Data Link" },
139 { DL_RESTARTED , "Data Link Restarted" },
140 { ENTER_BUSY , "Enter Busy" },
141 { EXIT_BUSY , "Exit Busy" },
142 { INFOFRAME , "Information (I) Frame" },
143 { HALT_DL , "Halt Data Link" },
144 { DL_HALTED , "Data Link Halted" },
145 { NETBIOS_NQ , "NETBIOS Name Query-circuit setup" },
146 { NETBIOS_NR , "NETBIOS Name Recog-circuit setup" },
147 { DATAFRAME , "Data Frame" },
148 { HALT_DL_NOACK , "Halt Data Link with no Ack" },
149 { NETBIOS_ANQ , "NETBIOS Add Name Query" },
150 { NETBIOS_ANR , "NETBIOS Add Name Response" },
151 { KEEPALIVE , "Transport Keepalive Message" },
152 { CAP_EXCHANGE , "Capabilities Exchange" },
153 { IFCM , "Independent Flow Control Message" },
154 { TEST_CIRCUIT_REQ , "Test Circuit Request" },
155 { TEST_CIRCUIT_RSP , "Test Circuit Response" },
156 { 0 , NULL }
158 static const value_string dlsw_version_vals[] = {
159 { 0x31 , "Version 1 (RFC 1795)" },
160 { 0x32 , "Version 2 (RFC 2166)" },
161 { 0x33 , "Vendor Specific" },
162 { 0x34 , "Vendor Specific" },
163 { 0x35 , "Vendor Specific" },
164 { 0x36 , "Vendor Specific" },
165 { 0x37 , "Vendor Specific" },
166 { 0x38 , "Vendor Specific" },
167 { 0x39 , "Vendor Specific" },
168 { 0x3A , "Vendor Specific" },
169 { 0x3B , "Vendor Specific" },
170 { 0x3C , "Vendor Specific" },
171 { 0x3D , "Vendor Specific" },
172 { 0x3E , "Vendor Specific" },
173 { 0x3F , "Vendor Specific" },
174 { 0x4B , "Pre 1 (RFC 1434)" },
175 { 0x00 , NULL }
178 static const value_string dlsw_fc_cmd_vals[] = {
179 { 0x00 , "Repeat Window" },
180 { 0x01 , "Increment Window" },
181 { 0x02 , "Decrement Window" },
182 { 0x03 , "Reset Window" },
183 { 0x04 , "Halve Window" },
184 { 0x00 , NULL }
187 static const value_string dlsw_capex_type_vals[] = {
188 { 0x01 , "Capabilities request" },
189 { 0x02 , "Capabilities response" },
190 { 0x00 , NULL }
193 static const value_string dlsw_frame_direction_vals[] = {
194 { 0x01 , "Origin DLSw to target DLSw" },
195 { 0x02 , "Target DLSw to origin DLSw" },
196 { 0x00 , NULL }
199 static const value_string dlsw_vector_vals[] = {
200 { 0x81 , "Vendor ID Control Vector" },
201 { 0x82 , "DLSw Version Control Vector" },
202 { 0x83 , "Initial Pacing Window Control Vector" },
203 { 0x84 , "Version String Control Vector" },
204 { 0x85 , "Mac Address Exclusivity Control Vector" },
205 { 0x86 , "Supported SAP List Control Vector" },
206 { 0x87 , "TCP Connections Control Vector" },
207 { 0x88 , "NetBIOS Name Exclusivity Control Vector" },
208 { 0x89 , "MAC Address List Control Vector" },
209 { 0x8a , "NetBIOS Name List Control Vector" },
210 { 0x8b , "Vendor Context Control Vector" },
211 { 0x8c , "Multicast Capabilities Control Vector" },
212 { 0x8d , "Reserved for future use" },
213 { 0x8e , "Reserved for future use" },
214 { 0x8f , "Reserved for future use" },
215 { 0x90 , "Reserved for future use" },
216 { 0x91 , " Control Vector" },
217 { 0x92 , " Control Vector" },
218 { 0x93 , " Control Vector" },
219 { 0x94 , " Control Vector" },
220 { 0x95 , " Control Vector" },
221 { 0x96 , " Control Vector" },
222 { 0x00 , NULL }
225 static const value_string dlsw_pri_vals[] = {
226 { 0 , "Unsupported" },
227 { 1 , "Low Priority" },
228 { 2 , "Medium Priority" },
229 { 3 , "High Priority" },
230 { 4 , "Highest Priority" },
231 { 5 , "Reserved" },
232 { 6 , "Reserved" },
233 { 7 , "Reserved" },
234 { 0, NULL }
240 #define DLSW_GDSID_SEND 0x1520
241 #define DLSW_GDSID_ACK 0x1521
242 #define DLSW_GDSID_REF 0x1522
244 static const value_string dlsw_gds_vals[] = {
245 { DLSW_GDSID_SEND , "Request Capabilities GDS" },
246 { DLSW_GDSID_ACK , "Response Capabilities GDS" },
247 { DLSW_GDSID_REF , "Refuse Capabilities GDS" },
248 { 0 , NULL }
251 static const value_string dlsw_refuse_vals[] = {
252 { 0x1 , "invalid GDS length for a DLWs Capabilities Exchange Request"},
253 { 0x2 , "invalid GDS id for a DLSw Capabilities Exchange Request"},
254 { 0x3 , "vendor Id control vector is missing"},
255 { 0x4 , "DLSw Version control vector is missing"},
256 { 0x5 , "initial Pacing Window control vector is missing"},
257 { 0x6 , "length of control vectors doesn't correlate to the length of the GDS variable"},
258 { 0x7 , "invalid control vector id"},
259 { 0x8 , "length of control vector invalid"},
260 { 0x9 , "invalid control vector data value"},
261 { 0xa , "duplicate control vector"},
262 { 0xb , "out-of-sequence control vector"},
263 { 0xc , "DLSw Supported SAP List control vector is missing"},
264 { 0xd , "inconsistent DLSw Version, Multicast Capabilities, and TCP Connections CV received on the inbound Capabilities exchange"},
265 { 0x0 , NULL }
268 #define UDP_PORT_DLSW 2067
269 #define TCP_PORT_DLSW 2065
270 #define DLSW_INFO_HEADER 16
271 #define DLSW_CMD_HEADER 72
273 static void
274 dissect_dlsw_capex(tvbuff_t *tvb, proto_tree *tree, proto_tree *ti);
276 static int
277 dissect_dlsw_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
279 guint version,hlen = 0,mlen = 0,mtype,dlchlen = 0,flags;
280 proto_tree *dlsw_tree = NULL, *dlsw_header_tree = NULL;
281 proto_item *ti,*ti2;
282 proto_tree *dlsw_flags_tree,*dlsw_data_tree;
284 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DLSw");
286 version=tvb_get_guint8(tvb,0);
288 col_add_fstr(pinfo->cinfo, COL_INFO, "DLSw %s",val_to_str_const(version , dlsw_version_vals, "Unknown Version"));
290 if (tree)
292 ti = proto_tree_add_item(tree, proto_dlsw, tvb, 0, -1, ENC_NA);
293 dlsw_tree = proto_item_add_subtree(ti, ett_dlsw);
295 hlen=tvb_get_guint8(tvb,1);
297 ti2 = proto_tree_add_text (dlsw_tree, tvb, 0, hlen,"DLSw header, %s",
298 val_to_str_const(version , dlsw_version_vals, "Unknown Version"));
299 dlsw_header_tree = proto_item_add_subtree(ti2, ett_dlsw_header);
301 proto_tree_add_item(dlsw_header_tree, hf_dlsw_version, tvb, 0, 1, ENC_NA);
302 proto_tree_add_item(dlsw_header_tree, hf_dlsw_header_length, tvb, 1, 1, ENC_NA);
303 mlen=tvb_get_ntohs(tvb,2);
304 proto_tree_add_item(dlsw_header_tree, hf_dlsw_message_length, tvb, 2, 2, ENC_BIG_ENDIAN);
305 proto_tree_add_item(dlsw_header_tree, hf_dlsw_remote_dlc, tvb, 4, 4, ENC_BIG_ENDIAN);
306 proto_tree_add_item(dlsw_header_tree, hf_dlsw_remote_dlc_pid, tvb, 8, 4, ENC_BIG_ENDIAN);
307 proto_tree_add_text (dlsw_header_tree,tvb,12,2,"Reserved") ;
310 mtype=tvb_get_guint8(tvb,14);
311 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",val_to_str_const(mtype , dlsw_type_vals, "Unknown message Type"));
312 if (tree)
314 proto_tree_add_item(dlsw_header_tree, hf_dlsw_message_type, tvb, 14, 1, ENC_NA);
315 if (mtype==CAP_EXCHANGE)
317 proto_tree_add_text (dlsw_header_tree,tvb, 15,1,"Not used for CapEx") ;
319 else
321 flags = tvb_get_guint8(tvb,15);
322 ti2 = proto_tree_add_item(dlsw_header_tree, hf_dlsw_flow_ctrl_byte, tvb, 15, 1, ENC_NA);
323 dlsw_flags_tree = proto_item_add_subtree(ti2, ett_dlsw_fc);
324 proto_tree_add_item(dlsw_flags_tree, hf_dlsw_flow_control_indication, tvb, 15, 1, ENC_BIG_ENDIAN);
325 if (flags & 0x80)
327 proto_tree_add_item(dlsw_flags_tree, hf_dlsw_flow_control_ack, tvb, 15, 1, ENC_BIG_ENDIAN);
328 proto_tree_add_item(dlsw_flags_tree, hf_dlsw_flow_control_operator, tvb, 15, 1, ENC_BIG_ENDIAN);
331 if (hlen != DLSW_INFO_HEADER)
333 if (mtype==CAP_EXCHANGE)
335 proto_tree_add_item(dlsw_header_tree, hf_dlsw_protocol_id, tvb, 16, 1, ENC_NA);
336 proto_tree_add_item(dlsw_header_tree, hf_dlsw_header_number, tvb, 17, 1, ENC_NA);
337 proto_tree_add_text (dlsw_header_tree,tvb, 18,5,"Not used for CapEx") ;
338 proto_tree_add_item(dlsw_header_tree, hf_dlsw_old_message_type, tvb, 23, 1, ENC_NA);
339 proto_tree_add_text (dlsw_header_tree,tvb, 24,14,"Not used for CapEx") ;
340 proto_tree_add_item(dlsw_header_tree, hf_dlsw_capex_type, tvb, 38, 1, ENC_NA);
341 proto_tree_add_text (dlsw_header_tree,tvb, 39,33,"Not used for CapEx") ;
343 else
345 proto_tree_add_item(dlsw_header_tree, hf_dlsw_protocol_id, tvb, 16, 1, ENC_NA);
346 proto_tree_add_item(dlsw_header_tree, hf_dlsw_header_number, tvb, 17, 1, ENC_NA);
347 proto_tree_add_text (dlsw_header_tree,tvb, 18,2,"Reserved") ;
348 proto_tree_add_item(dlsw_header_tree, hf_dlsw_largest_frame_size, tvb, 20, 1, ENC_NA);
349 ti2 = proto_tree_add_item(dlsw_header_tree, hf_dlsw_ssp_flags, tvb, 21, 1, ENC_NA);
350 dlsw_flags_tree = proto_item_add_subtree(ti2, ett_dlsw_sspflags);
351 proto_tree_add_item (dlsw_flags_tree, hf_dlsw_flags_explorer_msg, tvb, 21, 1, ENC_BIG_ENDIAN);
352 proto_tree_add_item(dlsw_header_tree, hf_dlsw_circuit_priority, tvb, 22, 1, ENC_NA);
353 proto_tree_add_item(dlsw_header_tree, hf_dlsw_old_message_type, tvb, 23, 1, ENC_NA);
354 proto_tree_add_item(dlsw_header_tree, hf_dlsw_target_mac_address, tvb, 24, 6, ENC_NA);
355 proto_tree_add_item(dlsw_header_tree, hf_dlsw_origin_mac_address, tvb, 30, 6, ENC_NA);
356 proto_tree_add_item(dlsw_header_tree, hf_dlsw_origin_link_sap, tvb, 36, 1, ENC_NA);
357 proto_tree_add_item(dlsw_header_tree, hf_dlsw_target_link_sap, tvb, 37, 1, ENC_NA);
358 proto_tree_add_item(dlsw_header_tree, hf_dlsw_frame_direction, tvb, 38, 1, ENC_NA);
359 proto_tree_add_text (dlsw_header_tree,tvb, 39,3,"Reserved") ;
360 dlchlen=tvb_get_ntohs(tvb,42);
361 ti = proto_tree_add_item(dlsw_header_tree, hf_dlsw_dlc_header_length, tvb, 42, 2, ENC_BIG_ENDIAN);
362 if ( dlchlen > mlen )
364 expert_add_info_format(pinfo, ti, &ei_dlsw_dlc_header_length,
365 "DLC Header Length = %u (bogus, must be <= message length %u)",dlchlen, mlen) ;
366 return 44;
368 proto_tree_add_item(dlsw_header_tree, hf_dlsw_origin_dlc_port_id, tvb, 44, 4, ENC_BIG_ENDIAN);
369 proto_tree_add_item(dlsw_header_tree, hf_dlsw_origin_dlc, tvb, 48, 4, ENC_BIG_ENDIAN);
370 proto_tree_add_item(dlsw_header_tree, hf_dlsw_origin_transport_id, tvb, 52, 4, ENC_BIG_ENDIAN);
371 proto_tree_add_item(dlsw_header_tree, hf_dlsw_target_dlc_port_id, tvb, 56, 4, ENC_BIG_ENDIAN);
372 proto_tree_add_item(dlsw_header_tree, hf_dlsw_target_dlc, tvb, 60, 4, ENC_BIG_ENDIAN);
373 proto_tree_add_item(dlsw_header_tree, hf_dlsw_target_transport_id, tvb, 64, 4, ENC_BIG_ENDIAN);
374 proto_tree_add_text (dlsw_header_tree,tvb, 68,4,"Reserved") ;
378 /* end of header dissector */
380 ti2 = proto_tree_add_text (dlsw_tree, tvb, hlen, mlen,"DLSw data");
381 dlsw_data_tree = proto_item_add_subtree(ti2, ett_dlsw_data);
383 switch (mtype)
385 case CAP_EXCHANGE:
386 dissect_dlsw_capex(tvb_new_subset(tvb, hlen, mlen, -1), dlsw_data_tree,ti2);
387 break;
388 case IFCM:
389 case INFOFRAME:
390 case KEEPALIVE:
391 proto_tree_add_text (dlsw_data_tree,tvb,hlen,mlen,"Data") ;
392 break;
394 default:
395 if (dlchlen!=0)
397 proto_tree_add_item(dlsw_data_tree, hf_dlsw_dlc_header_ac_byte, tvb, hlen, 1, ENC_NA);
398 proto_tree_add_item(dlsw_data_tree, hf_dlsw_dlc_header_fc_byte, tvb, hlen+1, 1, ENC_NA);
399 proto_tree_add_item(dlsw_data_tree, hf_dlsw_dlc_header_da, tvb, hlen+2, 6, ENC_NA|ENC_ASCII);
400 proto_tree_add_item(dlsw_data_tree, hf_dlsw_dlc_header_sa, tvb, hlen+8, 6, ENC_NA|ENC_ASCII);
401 proto_tree_add_item(dlsw_data_tree, hf_dlsw_dlc_header_rif, tvb, hlen+14, 18, ENC_NA|ENC_ASCII);
402 proto_tree_add_item(dlsw_data_tree, hf_dlsw_dlc_header_dsap, tvb, hlen+32, 1, ENC_NA);
403 proto_tree_add_item(dlsw_data_tree, hf_dlsw_dlc_header_ssap, tvb, hlen+33, 1, ENC_NA);
404 proto_tree_add_item(dlsw_data_tree, hf_dlsw_dlc_header_ctrl, tvb, hlen+34, 1, ENC_NA);
406 proto_tree_add_text (dlsw_data_tree,tvb,hlen+dlchlen,mlen-dlchlen,"Data") ;
411 return tvb_length(tvb);
414 static void
415 dissect_dlsw_capex(tvbuff_t *tvb, proto_tree *tree, proto_tree *ti2)
417 int mlen,vlen,vtype,offset=4,gdsid,sap,i=0;
418 proto_tree *ti,*dlsw_vector_tree;
419 mlen=tvb_get_ntohs(tvb,0);
420 gdsid=tvb_get_ntohs(tvb,2);
421 proto_tree_add_item(tree, hf_dlsw_capabilities_length, tvb, 0, 2, ENC_BIG_ENDIAN);
422 proto_tree_add_text (tree,tvb,2,2,"%s",val_to_str_const( gdsid, dlsw_gds_vals, "Invalid GDS ID"));
423 proto_item_append_text(ti2," - %s",val_to_str_const( gdsid, dlsw_gds_vals, "Invalid GDS ID"));
424 switch (gdsid) {
425 case DLSW_GDSID_ACK:
426 break;
427 case DLSW_GDSID_REF:
428 proto_tree_add_item(tree, hf_dlsw_error_pointer, tvb, 4, 2, ENC_BIG_ENDIAN);
429 proto_tree_add_item(tree, hf_dlsw_error_cause, tvb, 6, 2, ENC_BIG_ENDIAN);
430 break;
431 case DLSW_GDSID_SEND:
432 while (offset < mlen){
433 vlen=tvb_get_guint8(tvb,offset);
434 if (vlen < 3) THROW(ReportedBoundsError);
435 vtype=tvb_get_guint8(tvb,offset+1);
436 ti=proto_tree_add_text (tree,tvb,offset,vlen,"%s",
437 val_to_str_const(vtype,dlsw_vector_vals,"Unknown vector type"));
438 dlsw_vector_tree = proto_item_add_subtree(ti, ett_dlsw_vector);
439 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_vector_length, tvb, offset, 1, ENC_NA);
440 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_vector_type, tvb, offset+1, 1, ENC_NA);
441 switch (vtype){
442 case 0x81:
443 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_oui, tvb, offset+2, vlen-2, ENC_BIG_ENDIAN);
444 break;
445 case 0x82:
446 proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2,
447 "DLSw Version = %d.%d",tvb_get_guint8(tvb,offset+2),tvb_get_guint8(tvb,offset+3));
448 break;
449 case 0x83:
450 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_initial_pacing_window, tvb, offset+2, vlen-2, ENC_BIG_ENDIAN);
451 break;
452 case 0x84:
453 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_version_string, tvb, offset+2, vlen-2, ENC_NA|ENC_ASCII);
454 break;
455 case 0x85:
456 proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2,
457 "MAC Address Exclusivity = %s",tvb_get_guint8(tvb,offset+2)==1?"On":"Off");
458 break;
459 case 0x86:
460 while (i<vlen-2)
462 sap=tvb_get_guint8(tvb,offset+2+i);
463 proto_tree_add_text (dlsw_vector_tree,tvb,offset+2+i,1,
464 "SAP List Support = 0x%x0=%s 0x%x2=%s 0x%x4=%s 0x%x6=%s 0x%x8=%s 0x%xa=%s 0x%xc=%s 0x%xe=%s",
465 i,sap&0x80?"on ":"off",i,sap&0x40?"on ":"off",i,sap&0x20?"on ":"off",i,sap&0x10?"on ":"off",
466 i,sap&0x08?"on ":"off",i,sap&0x04?"on ":"off",i,sap&0x02?"on ":"off",i,sap&0x01?"on ":"off");
467 i++;
469 break;
470 case 0x87:
471 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_tcp_connections, tvb, offset+2, vlen-2, ENC_NA);
472 break;
473 case 0x88:
474 proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2,
475 "NetBIOS Name Exclusivity = %s",tvb_get_guint8(tvb,offset+2)==1?"On":"Off");
476 break;
477 case 0x89:
478 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_mac_address_list, tvb, offset+2, 6, ENC_NA);
479 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_mac_address_list, tvb, offset+8, 6, ENC_NA);
480 break;
481 case 0x8a:
482 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_netbios_name, tvb, offset+2, vlen-2, ENC_NA|ENC_ASCII);
483 break;
484 case 0x8b:
485 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_vendor_oui, tvb, offset+2, vlen-2, ENC_BIG_ENDIAN);
486 break;
487 case 0x8c:
488 proto_tree_add_item(dlsw_vector_tree, hf_dlsw_multicast_version_number, tvb, offset+2, vlen-2, ENC_NA);
489 break;
490 default:
491 proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2,"Vector Data = ???");
493 offset+=vlen;
495 break;
496 default:
497 proto_tree_add_text (tree,tvb,4,mlen - 4,"Unknown data");
502 static int
503 dissect_dlsw_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
505 if (try_val_to_str(tvb_get_guint8(tvb, 0), dlsw_version_vals) == NULL)
507 /* Probably not a DLSw packet. */
508 return 0;
511 return dissect_dlsw_pdu(tvb, pinfo, tree, data);
514 static guint
515 get_dlsw_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
517 guint hlen, mlen;
520 * Get the length of the DLSw header.
522 hlen=tvb_get_guint8(tvb,offset+1);
525 * Get the length of the DLSw message.
527 mlen = tvb_get_ntohs(tvb,offset+2);
530 * The total length is the sum of those.
532 return hlen + mlen;
535 static int
536 dissect_dlsw_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
538 if (try_val_to_str(tvb_get_guint8(tvb, 0), dlsw_version_vals) == NULL)
540 /* Probably not a DLSw packet. */
541 return 0;
544 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 4, get_dlsw_pdu_len, dissect_dlsw_pdu, data);
545 return tvb_length(tvb);
548 void
549 proto_register_dlsw(void)
551 static hf_register_info hf[] = {
552 {&hf_dlsw_flow_control_indication,
553 {"Flow Control Indication", "dlsw.flow_control_indication", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
554 NULL, HFILL}},
555 {&hf_dlsw_flow_control_ack,
556 {"Flow Control Acknowledgment", "dlsw.flow_control_ack", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
557 NULL, HFILL}},
558 {&hf_dlsw_flow_control_operator,
559 {"Flow Control Operator", "dlsw.flow_control_operator", FT_UINT8, BASE_DEC, VALS(dlsw_fc_cmd_vals), 0x07,
560 NULL, HFILL}},
561 {&hf_dlsw_flags_explorer_msg,
562 {"Explorer message", "dlsw.flags.explorer_msg", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
563 NULL, HFILL}},
564 /* Generated from convert_proto_tree_add_text.pl */
565 { &hf_dlsw_version, { "Version", "dlsw.version", FT_UINT8, BASE_DEC, VALS(dlsw_version_vals), 0x0, NULL, HFILL }},
566 { &hf_dlsw_header_length, { "Header Length", "dlsw.header_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
567 { &hf_dlsw_message_length, { "Message Length", "dlsw.message_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
568 { &hf_dlsw_remote_dlc, { "Remote DLC", "dlsw.remote_dlc", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
569 { &hf_dlsw_remote_dlc_pid, { "Remote DLC PID", "dlsw.remote_dlc_pid", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
570 { &hf_dlsw_message_type, { "Message Type", "dlsw.message_type", FT_UINT8, BASE_HEX, VALS(dlsw_type_vals), 0x0, NULL, HFILL }},
571 { &hf_dlsw_flow_ctrl_byte, { "Flow ctrl byte", "dlsw.flow_ctrl_byte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
572 { &hf_dlsw_protocol_id, { "Protocol ID", "dlsw.protocol_id", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
573 { &hf_dlsw_header_number, { "Header Number", "dlsw.header_number", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
574 { &hf_dlsw_old_message_type, { "Old message type", "dlsw.old_message_type", FT_UINT8, BASE_HEX, VALS(dlsw_type_vals), 0x0, NULL, HFILL }},
575 { &hf_dlsw_capex_type, { "Capability exchange type", "dlsw.capex_type", FT_UINT8, BASE_HEX, VALS(dlsw_capex_type_vals), 0x0, NULL, HFILL }},
576 { &hf_dlsw_largest_frame_size, { "Largest Frame size", "dlsw.largest_frame_size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
577 { &hf_dlsw_ssp_flags, { "SSP Flags", "dlsw.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
578 { &hf_dlsw_circuit_priority, { "Circuit priority", "dlsw.circuit_priority", FT_UINT8, BASE_DEC, VALS(dlsw_pri_vals), 0x7, NULL, HFILL }},
579 { &hf_dlsw_target_mac_address, { "Target MAC Address", "dlsw.target_mac_address", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }},
580 { &hf_dlsw_origin_mac_address, { "Origin MAC Address", "dlsw.origin_mac_address", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }},
581 { &hf_dlsw_origin_link_sap, { "Origin Link SAP", "dlsw.origin_link_sap", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
582 { &hf_dlsw_target_link_sap, { "Target Link SAP", "dlsw.target_link_sap", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
583 { &hf_dlsw_frame_direction, { "Frame direction", "dlsw.frame_direction", FT_UINT8, BASE_HEX, VALS(dlsw_frame_direction_vals), 0x0, NULL, HFILL }},
584 { &hf_dlsw_dlc_header_length, { "DLC Header Length", "dlsw.dlc_header_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
585 { &hf_dlsw_origin_dlc_port_id, { "Origin DLC Port ID", "dlsw.origin_dlc_port_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
586 { &hf_dlsw_origin_dlc, { "Origin DLC", "dlsw.origin_dlc", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
587 { &hf_dlsw_origin_transport_id, { "Origin Transport ID", "dlsw.origin_transport_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
588 { &hf_dlsw_target_dlc_port_id, { "Target DLC Port ID", "dlsw.target_dlc_port_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
589 { &hf_dlsw_target_dlc, { "Target DLC", "dlsw.target_dlc", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
590 { &hf_dlsw_target_transport_id, { "Target Transport ID", "dlsw.target_transport_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
591 { &hf_dlsw_dlc_header_ac_byte, { "DLC Header - AC byte", "dlsw.dlc_header.ac_byte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
592 { &hf_dlsw_dlc_header_fc_byte, { "DLC Header - FC byte", "dlsw.dlc_header.fc_byte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
593 { &hf_dlsw_dlc_header_da, { "DLC Header - DA", "dlsw.dlc_header.da", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
594 { &hf_dlsw_dlc_header_sa, { "DLC Header - SA", "dlsw.dlc_header.sa", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
595 { &hf_dlsw_dlc_header_rif, { "DLC Header - RIF", "dlsw.dlc_header.rif", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
596 { &hf_dlsw_dlc_header_dsap, { "DLC Header - DSAP", "dlsw.dlc_header.dsap", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
597 { &hf_dlsw_dlc_header_ssap, { "DLC Header - SSAP", "dlsw.dlc_header.ssap", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
598 { &hf_dlsw_dlc_header_ctrl, { "DLC Header - Ctrl", "dlsw.dlc_header.ctrl", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
599 { &hf_dlsw_capabilities_length, { "Capabilities Length", "dlsw.capabilities_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
600 { &hf_dlsw_error_pointer, { "Error pointer", "dlsw.error_pointer", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
601 { &hf_dlsw_error_cause, { "Error cause", "dlsw.error_cause", FT_UINT16, BASE_HEX, VALS(dlsw_refuse_vals), 0x0, NULL, HFILL }},
602 { &hf_dlsw_vector_length, { "Vector Length", "dlsw.vector_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
603 { &hf_dlsw_vector_type, { "Vector Type", "dlsw.vector_type", FT_UINT8, BASE_HEX, VALS(dlsw_vector_vals), 0x0, NULL, HFILL }},
604 { &hf_dlsw_oui, { "OUI", "dlsw.oui", FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
605 { &hf_dlsw_initial_pacing_window, { "Initial Pacing Window", "dlsw.initial_pacing_window", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
606 { &hf_dlsw_version_string, { "Version String", "dlsw.version_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
607 { &hf_dlsw_tcp_connections, { "TCP connections", "dlsw.tcp_connections", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
608 { &hf_dlsw_mac_address_list, { "MAC Address List", "dlsw.mac_address_list", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }},
609 { &hf_dlsw_netbios_name, { "NetBIOS name", "dlsw.netbios_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
610 { &hf_dlsw_vendor_oui, { "Vendor OUI", "dlsw.vendor_oui", FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
611 { &hf_dlsw_multicast_version_number, { "Multicast Version Number", "dlsw.multicast_version_number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
614 static gint *ett[] = {
615 &ett_dlsw,
616 &ett_dlsw_header,
617 &ett_dlsw_fc,
618 &ett_dlsw_sspflags,
619 &ett_dlsw_data,
620 &ett_dlsw_vector,
623 static ei_register_info ei[] = {
624 { &ei_dlsw_dlc_header_length, { "dlsw.dlc_header_length.bogus", PI_PROTOCOL, PI_WARN, "DLC Header Length bogus", EXPFILL }},
627 expert_module_t* expert_dlsw;
629 proto_dlsw = proto_register_protocol("Data Link SWitching", "DLSw", "dlsw");
630 proto_register_field_array(proto_dlsw, hf, array_length(hf));
631 proto_register_subtree_array(ett, array_length(ett));
632 expert_dlsw = expert_register_protocol(proto_dlsw);
633 expert_register_field_array(expert_dlsw, ei, array_length(ei));
637 void
638 proto_reg_handoff_dlsw(void)
640 dissector_handle_t dlsw_udp_handle, dlsw_tcp_handle;
642 dlsw_udp_handle = new_create_dissector_handle(dissect_dlsw_udp, proto_dlsw);
643 dissector_add_uint("udp.port", UDP_PORT_DLSW, dlsw_udp_handle);
645 dlsw_tcp_handle = new_create_dissector_handle(dissect_dlsw_tcp, proto_dlsw);
646 dissector_add_uint("tcp.port", TCP_PORT_DLSW, dlsw_tcp_handle);