From Kai Blin:
[obnox/wireshark/wip.git] / epan / dissectors / packet-dplay.c
1 /* packet-dplay.c
2  * This is a dissector for the DirectPlay protocol.
3  * Copyright 2006 - 2008 by Kai Blin
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
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.
15  *
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.
20  *
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,
24  * USA.59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  *
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <epan/packet.h>
33 #include <epan/prefs.h>
34 #include <epan/emem.h>
35 #include <string.h>
36
37 /* function declarations */
38 void proto_reg_handoff_dplay(void);
39 static gboolean heur_dissect_dplay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
40 static void dissect_dplay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
41 static gint dissect_type1a_message(proto_tree *tree, tvbuff_t *tvb, gint offset);
42 static gint dissect_type2e_message(proto_tree *tree, tvbuff_t *tvb, gint offset);
43
44 static int proto_dplay = -1;
45 static dissector_handle_t dplay_handle;
46
47 /* Common data fields */
48 static int hf_dplay_size = -1;              /* Size of the whole data */
49 static int hf_dplay_token = -1;
50 static int hf_dplay_saddr_af = -1;          /* AF_INET, as this dissector does not handle IPX yet */
51 static int hf_dplay_saddr_port = -1;        /* port to use for the reply to this packet */
52 static int hf_dplay_saddr_ip = -1;          /* IP to use for the reply to this packet, or 0.0.0.0,
53                                                then use the same IP as this packet used. */
54 static int hf_dplay_saddr_padding = -1;     /* null padding used in s_addr_in structures */
55 static int hf_dplay_play_str = -1;          /* always "play" without a null terminator */
56 static int hf_dplay_command = -1;           /* the dplay command this message contains*/
57 static int hf_dplay_proto_dialect = -1;     /* 0x0b00 for dplay7, 0x0e00 for dplay9 */
58 static int hf_dplay_play_str_2 = -1;        /* packet type 0x0015 encapsulates another packet */
59 static int hf_dplay_command_2 = -1;         /* that also has a "play" string, a command and a */
60 static int hf_dplay_proto_dialect_2 = -1;   /* protocol dialect, same as above */
61 static const int DPLAY_HEADER_OFFSET = 28;  /* The dplay header is 28 bytes in size */
62
63 /* The following fields are not part of the header, but hopefully have the same
64  * meaning for all packets they show up in. */
65
66 static int hf_dplay_sess_desc_flags = -1; /* This is a 32bit field with some sort of a flag */
67 static int hf_dplay_flags_no_create_players = -1;
68 static int hf_dplay_flags_0002 = -1;
69 static int hf_dplay_flags_migrate_host = -1;
70 static int hf_dplay_flags_short_player_msg = -1;
71 static int hf_dplay_flags_ignored = -1;
72 static int hf_dplay_flags_can_join = -1;
73 static int hf_dplay_flags_use_ping = -1;
74 static int hf_dplay_flags_no_player_updates = -1;
75 static int hf_dplay_flags_use_auth = -1;
76 static int hf_dplay_flags_private_session = -1;
77 static int hf_dplay_flags_password_req = -1;
78 static int hf_dplay_flags_route = -1;
79 static int hf_dplay_flags_server_player_only = -1;
80 static int hf_dplay_flags_reliable = -1;
81 static int hf_dplay_flags_preserve_order = -1;
82 static int hf_dplay_flags_optimize_latency = -1;
83 static int hf_dplay_flags_acqire_voice = -1;
84 static int hf_dplay_flags_no_sess_desc_changes = -1;
85
86 #define DPLAY_FLAG_NO_CREATE_PLAYERS 0x0001
87 #define DPLAY_FLAG_0002 0x0002
88 #define DPLAY_FLAG_MIGRATE_HOST 0x0004
89 #define DPLAY_FLAG_SHORT_PLAYER_MSG 0x0008
90 #define DPLAY_FLAG_IGNORED 0x0010
91 #define DPLAY_FLAG_CAN_JOIN 0x0020
92 #define DPLAY_FLAG_USE_PING 0x0040
93 #define DPLAY_FLAG_NO_P_UPD 0x0080
94 #define DPLAY_FLAG_USE_AUTH 0x0100
95 #define DPLAY_FLAG_PRIV_SESS 0x0200
96 #define DPLAY_FLAG_PASS_REQ 0x0400
97 #define DPLAY_FLAG_ROUTE 0x0800
98 #define DPLAY_FLAG_SRV_ONLY 0x1000
99 #define DPLAY_FLAG_RELIABLE 0x2000
100 #define DPLAY_FLAG_ORDER 0x4000
101 #define DPLAY_FLAG_OPT_LAT 0x8000
102 #define DPLAY_FLAG_ACQ_VOICE 0x10000
103 #define DPLAY_FLAG_NO_SESS_DESC_CHANGES 0x20000
104
105 /* special fields, to be phased out in favour for more detailed information */
106 static int hf_dplay_data_type_0f = -1;
107 static int hf_dplay_data_type_1a = -1;
108
109 /* Session description structure fields */
110 static int hf_dplay_sess_desc_length = -1;
111 static int hf_dplay_game_guid = -1;
112 static int hf_dplay_instance_guid = -1;
113 static int hf_dplay_max_players = -1;
114 static int hf_dplay_curr_players = -1;
115 static int hf_dplay_sess_name_ptr = -1;
116 static int hf_dplay_passwd_ptr = -1;
117 static int hf_dplay_sess_desc_reserved_1 = -1;
118 static int hf_dplay_sess_desc_reserved_2 = -1;
119 static int hf_dplay_sess_desc_user_1 = -1;
120 static int hf_dplay_sess_desc_user_2 = -1;
121 static int hf_dplay_sess_desc_user_3 = -1;
122 static int hf_dplay_sess_desc_user_4 = -1;
123
124 /* SuperPackedPlayer structure fields */
125 static int hf_dplay_spp_size = -1;
126 static int hf_dplay_spp_flags = -1;
127 static int hf_dplay_spp_flags_sysplayer = -1;
128 static int hf_dplay_spp_flags_nameserver = -1;
129 static int hf_dplay_spp_flags_in_group = -1;
130 static int hf_dplay_spp_flags_sending = -1;
131 static int hf_dplay_spp_id = -1;
132 static int hf_dplay_spp_player_info_mask = -1;
133 static int hf_dplay_spp_have_short_name = -1;
134 static int hf_dplay_spp_have_long_name = -1;
135 static int hf_dplay_spp_sp_length_type = -1;
136 static int hf_dplay_spp_pd_length_type = -1;
137 static int hf_dplay_spp_player_count_type = -1;
138 static int hf_dplay_spp_have_parent_id = -1;
139 static int hf_dplay_spp_shortcut_count_type = -1;
140 static int hf_dplay_spp_dialect = -1;
141 static int hf_dplay_spp_sys_player_id = -1;
142 static int hf_dplay_spp_short_name = -1;
143 static int hf_dplay_spp_long_name = -1;
144 static int hf_dplay_spp_player_data_length = -1;
145 static int hf_dplay_spp_player_data = -1;
146 static int hf_dplay_spp_sp_data_length = -1;
147 static int hf_dplay_spp_sp_data = -1;
148 static int hf_dplay_spp_player_count = -1;
149 static int hf_dplay_spp_player_id = -1;
150 static int hf_dplay_spp_parent_id = -1;
151 static int hf_dplay_spp_shortcut_count = -1;
152 static int hf_dplay_spp_shortcut_id = -1;
153 #define DPLAY_SPP_FLAG_SYSPLAYER 0x01
154 #define DPLAY_SPP_FLAG_NAMESERVER 0x02
155 #define DPLAY_SPP_FLAG_IN_GROUP 0x04
156 #define DPLAY_SPP_FLAG_SENDING 0x08
157
158 /* SecurityDesc structure fields */
159 static int hf_dplay_sd_size = -1;
160 static int hf_dplay_sd_flags = -1;
161 static int hf_dplay_sd_sspi = -1;
162 static int hf_dplay_sd_capi = -1;
163 static int hf_dplay_sd_capi_type = -1;
164 static int hf_dplay_sd_enc_alg = -1;
165
166 /* Message Type 0x0001 data fields */
167 static int hf_dplay_type_01_name_offset = -1;
168 static int hf_dplay_type_01_game_name = -1;
169
170 /* Message Type 0x0002 data fields */
171 static int hf_dplay_type_02_game_guid = -1;
172 static int hf_dplay_type_02_password_offset = -1;
173 static int hf_dplay_type_02_flags = -1;
174 static int hf_dplay_type_02_password = -1;
175 static int hf_enum_sess_flag_join = -1;
176 static int hf_enum_sess_flag_all = -1;
177 static int hf_enum_sess_flag_passwd = -1;
178 #define DPLAY_ENUM_SESS_FLAG_JOIN 0x0001
179 #define DPLAY_ENUM_SESS_FLAG_ALL 0x0002
180 #define DPLAY_ENUM_SESS_FLAG_PASSWD 0x0040
181
182 /* Message Type 0x0005 data fields */
183 static int hf_dplay_type_05_flags = -1;
184 static int hf_dplay_type_05_system_player = -1;
185 static int hf_dplay_type_05_name_server = -1;
186 static int hf_dplay_type_05_local = -1;
187 static int hf_dplay_type_05_unknown = -1; /* unknown, but always set */
188 static int hf_dplay_type_05_secure = -1;
189 #define DPLAY_TYPE05_FLAG_SYSPLAYER 0x001
190 #define DPLAY_TYPE05_FLAG_NAMESERVER 0x002
191 #define DPLAY_TYPE05_FLAG_LOCAL 0x004
192 #define DPLAY_TYPE05_FLAG_UNKNOWN 0x008
193 #define DPLAY_TYPE05_FLAG_SECURE 0x200
194
195 /* Message Type 0x0007 data fields */
196 static int hf_dplay_type_07_dpid = -1;
197 static int hf_dplay_type_07_sspi_offset = -1;
198 static int hf_dplay_type_07_capi_offset = -1;
199 static int hf_dplay_type_07_hresult = -1;
200 static int hf_dplay_type_07_sspi = -1;
201 static int hf_dplay_type_07_capi = -1;
202
203 /* Message Type 0x0008 data fields */
204 static int hf_dplay_type_08_padding_1 = -1;     /* 4 bytes */
205 static int hf_dplay_type_08_dpid_1 = -1;        /* 4 bytes */
206 static int hf_dplay_type_08_unknown_1 = -1;     /*20 bytes */
207 static int hf_dplay_type_08_dpid_2 = -1;        /* 4 bytes */
208 static int hf_dplay_type_08_string_1_len = -1;
209 static int hf_dplay_type_08_string_2_len = -1;
210 static int hf_dplay_type_08_unknown_2 = -1;     /*20 bytes */
211 static int hf_dplay_type_08_dpid_3 = -1;        /* 4 bytes */
212 static int hf_dplay_type_08_unknown_3 = -1;     /*12 bytes */
213 static int hf_dplay_type_08_string_1 = -1;
214 static int hf_dplay_type_08_string_2 = -1;
215 static int hf_dplay_type_08_saddr_af_1 = -1;    /* 2 bytes */
216 static int hf_dplay_type_08_saddr_port_1 = -1;  /* 2 bytes */
217 static int hf_dplay_type_08_saddr_ip_1 = -1;    /* 4 bytes */
218 static int hf_dplay_type_08_saddr_padd_1 = -1;  /* 8 bytes */
219 static int hf_dplay_type_08_saddr_af_2 = -1;    /* 2 bytes */
220 static int hf_dplay_type_08_saddr_port_2 = -1;  /* 2 bytes */
221 static int hf_dplay_type_08_saddr_ip_2 = -1;    /* 4 bytes */
222 static int hf_dplay_type_08_saddr_padd_2 = -1;  /* 8 bytes */
223 static int hf_dplay_type_08_padding_2 = -1;     /* 2 bytes */
224
225 /* Message Type 0x000b data fields */
226 static int hf_dplay_type_0b_padding_1 = -1;
227 static int hf_dplay_type_0b_dpid = -1;
228 static int hf_dplay_type_0b_padding_2 = -1;
229
230 /* Message Type 0x000d data fields */
231 static int hf_dplay_type_0d_padding_1 = -1;     /* 4 bytes */
232 static int hf_dplay_type_0d_dpid_1 = -1;        /* 4 bytes */
233 static int hf_dplay_type_0d_dpid_2 = -1;        /* 4 bytes */
234 static int hf_dplay_type_0d_padding_2 = -1;     /* 8 bytes */
235
236 /* Message Type 0x000e data fields */
237 static int hf_dplay_type_0e_padding_1 = -1;     /* 4 bytes */
238 static int hf_dplay_type_0e_dpid_1 = -1;        /* 4 bytes */
239 static int hf_dplay_type_0e_dpid_2 = -1;        /* 4 bytes */
240 static int hf_dplay_type_0e_padding_2 = -1;     /* 8 bytes */
241
242 /* Message Type 0x0013 data fields */
243 static int hf_dplay_type_13_padding_1 = -1;     /* 4 bytes */
244 static int hf_dplay_type_13_dpid_1 = -1;        /* 4 bytes */
245 static int hf_dplay_type_13_unknown_1 = -1;     /*20 bytes */
246 static int hf_dplay_type_13_dpid_2 = -1;        /* 4 bytes */
247 static int hf_dplay_type_13_unknown_2 = -1;     /*20 bytes */
248 static int hf_dplay_type_13_dpid_3 = -1;        /* 4 bytes */
249 static int hf_dplay_type_13_unknown_3 = -1;     /*12 bytes */
250 static int hf_dplay_type_13_saddr_af_1 = -1;    /* 2 bytes */
251 static int hf_dplay_type_13_saddr_port_1 = -1;  /* 2 bytes */
252 static int hf_dplay_type_13_saddr_ip_1 = -1;    /* 4 bytes */
253 static int hf_dplay_type_13_saddr_padd_1 = -1;  /* 8 bytes */
254 static int hf_dplay_type_13_saddr_af_2 = -1;    /* 2 bytes */
255 static int hf_dplay_type_13_saddr_port_2 = -1;  /* 2 bytes */
256 static int hf_dplay_type_13_saddr_ip_2 = -1;    /* 4 bytes */
257 static int hf_dplay_type_13_saddr_padd_2 = -1;  /* 8 bytes */
258 static int hf_dplay_type_13_padding_2 = -1;     /* 2 bytes */
259 static int hf_dplay_type_13_dpid_4 = -1;        /* 4 bytes */
260
261 /* Message Type 0x0015 data fields */
262 static int hf_dplay_container_guid = -1;
263 static int hf_dplay_type_15_padding_1 = -1;
264 static int hf_dplay_type_15_size_1 = -1;
265 static int hf_dplay_type_15_padding_2 = -1;
266 static int hf_dplay_type_15_unknown_1 = -1;
267 static int hf_dplay_type_15_size_2 = -1;
268 static int hf_dplay_type_15_padding_3 = -1;
269
270 /* Message Type 0x0016 data field */
271 static int hf_dplay_type_16_data = -1;
272
273 /* Message Type 0x0017 data field */
274 static int hf_dplay_type_17_data = -1;
275
276 /* Message Type 0x0029 data fields */
277 static int hf_dplay_type_29_player_count = -1;
278 static int hf_dplay_type_29_group_count = -1;
279 static int hf_dplay_type_29_packed_offset = -1;
280 static int hf_dplay_type_29_shortcut_count = -1;
281 static int hf_dplay_type_29_description_offset = -1;
282 static int hf_dplay_type_29_name_offset = -1;
283 static int hf_dplay_type_29_password_offset = -1;
284 static int hf_dplay_type_29_game_name = -1;
285 static int hf_dplay_type_29_password = -1;
286
287 /* Message Type 0x002e data fields */
288 static int hf_dplay_type_2e_padding_1 = -1;
289 static int hf_dplay_type_2e_dpid_1 = -1;
290 static int hf_dplay_type_2e_unknown_1 = -1;
291 static int hf_dplay_type_2e_dpid_2 = -1;
292 static int hf_dplay_type_2e_string_1_len = -1;
293 static int hf_dplay_type_2e_string_2_len = -1;
294 static int hf_dplay_type_2e_unknown_2 = -1;
295 static int hf_dplay_type_2e_dpid_3 = -1;
296 static int hf_dplay_type_2e_unknown_3 = -1;
297 static int hf_dplay_type_2e_string_1 = -1;
298 static int hf_dplay_type_2e_string_2 = -1;
299 static int hf_dplay_type_2e_saddr_af_1 = -1;
300 static int hf_dplay_type_2e_saddr_port_1 = -1;
301 static int hf_dplay_type_2e_saddr_ip_1 = -1;
302 static int hf_dplay_type_2e_saddr_padd_1 = -1;
303 static int hf_dplay_type_2e_saddr_af_2 = -1;
304 static int hf_dplay_type_2e_saddr_port_2 = -1;
305 static int hf_dplay_type_2e_saddr_ip_2 = -1;
306 static int hf_dplay_type_2e_saddr_padd_2 = -1;
307
308 /* Message Type 0x002f data fields */
309 static int hf_dplay_type_2f_dpid = -1;
310
311 /* Message Type 0x0038 data fields */
312 static int hf_dplay_type_38_padding_1 = -1;     /* 4 bytes */
313 static int hf_dplay_type_38_dpid_1 = -1;        /* 4 bytes */
314 static int hf_dplay_type_38_unknown_1 = -1;     /*20 bytes */
315 static int hf_dplay_type_38_dpid_2 = -1;        /* 4 bytes */
316 static int hf_dplay_type_38_string_1_len = -1;
317 static int hf_dplay_type_38_string_2_len = -1;
318 static int hf_dplay_type_38_unknown_2 = -1;     /*20 bytes */
319 static int hf_dplay_type_38_dpid_3 = -1;        /* 4 bytes */
320 static int hf_dplay_type_38_unknown_3 = -1;     /*12 bytes */
321 static int hf_dplay_type_38_string_1 = -1;
322 static int hf_dplay_type_38_string_2 = -1;
323 static int hf_dplay_type_38_saddr_af_1 = -1;    /* 2 bytes */
324 static int hf_dplay_type_38_saddr_port_1 = -1;  /* 2 bytes */
325 static int hf_dplay_type_38_saddr_ip_1 = -1;    /* 4 bytes */
326 static int hf_dplay_type_38_saddr_padd_1 = -1;  /* 8 bytes */
327 static int hf_dplay_type_38_saddr_af_2 = -1;    /* 2 bytes */
328 static int hf_dplay_type_38_saddr_port_2 = -1;  /* 2 bytes */
329 static int hf_dplay_type_38_saddr_ip_2 = -1;    /* 4 bytes */
330 static int hf_dplay_type_38_saddr_padd_2 = -1;  /* 8 bytes */
331
332 /* various */
333 static gint ett_dplay = -1;
334 static gint ett_dplay_header = -1;
335 static gint ett_dplay_sockaddr = -1;
336 static gint ett_dplay_data = -1;
337 static gint ett_dplay_enc_packet = -1;
338 static gint ett_dplay_flags = -1;
339 static gint ett_dplay_sess_desc_flags = -1;
340 static gint ett_dplay_spp_flags = -1;
341 static gint ett_dplay_spp_info_mask = -1;
342 static gint ett_dplay_type02_flags = -1;
343 static gint ett_dplay_type05_flags = -1;
344 static gint ett_dplay_type08_saddr1 = -1;
345 static gint ett_dplay_type08_saddr2 = -1;
346 static gint ett_dplay_type13_saddr1 = -1;
347 static gint ett_dplay_type13_saddr2 = -1;
348 static gint ett_dplay_type29_spp = -1;
349 static gint ett_dplay_type2e_saddr1 = -1;
350 static gint ett_dplay_type2e_saddr2 = -1;
351 static gint ett_dplay_type38_saddr1 = -1;
352 static gint ett_dplay_type38_saddr2 = -1;
353
354 static const value_string dplay_command_val[] = {
355     { 0x0001, "Enum Sessions Reply" },
356     { 0x0002, "Enum Sessions" },
357     { 0x0003, "Enum Players Reply" },
358     { 0x0004, "Enum Players" },
359     { 0x0005, "Request Player ID" },
360     { 0x0006, "Request Group ID" },
361     { 0x0007, "Request Player Reply" },
362     { 0x0008, "Create Player" },
363     { 0x0009, "Create Group" },
364     { 0x000a, "Player Message" },
365     { 0x000b, "Delete Player" },
366     { 0x000c, "Delete Group" },
367     { 0x000d, "Add Player To Group" },
368     { 0x000e, "Delete Player From Group" },
369     { 0x000f, "Player Data Changed" },
370     { 0x0010, "Player Name Changed" },
371     { 0x0011, "Group Data Changed" },
372     { 0x0012, "Group Name Changed" },
373     { 0x0013, "Add Forward Request" },
374     /* There is no command 0x0014 */
375     { 0x0015, "Packet" },
376     { 0x0016, "Ping" },
377     { 0x0017, "Pong" },
378     { 0x0018, "You Are Dead" },
379     { 0x0019, "Player Wrapper" },
380     { 0x001a, "Session Desc Changed" },
381     { 0x001c, "Challenge" },
382     { 0x001d, "Access Granted" },
383     { 0x001e, "Logon Denied" },
384     { 0x001f, "Auth Error" },
385     { 0x0020, "Negotiate" },
386     { 0x0021, "Challenge Response" },
387     { 0x0022, "Signed"},
388     /* There is no command 0x0023 */
389     { 0x0024, "Add Forward Reply" },
390     { 0x0025, "Ask For Multicast" },
391     { 0x0026, "Ask For Multicast Guaranteed" },
392     { 0x0027, "Add Shortcut To Group" },
393     { 0x0028, "Delete Group From Group" },
394     { 0x0029, "Super Enum Players Reply" },
395     /* There is no command 0x002a */
396     { 0x002b, "Key Exchange" },
397     { 0x002c, "Key Exchange Reply" },
398     { 0x002d, "Chat" },
399     { 0x002e, "Add Forward" },
400     { 0x002f, "Add Forward ACK" },
401     { 0x0030, "Packet2 Data" },
402     { 0x0031, "Packet2 ACK" },
403     /* No commands 0x0032, 0x0033, 0x0034 */
404     { 0x0035, "I Am Nameserver" },
405     { 0x0036, "Voice" },
406     { 0x0037, "Multicast Delivery" },
407     { 0x0038, "Create Players Verify"},
408     { 0     , NULL },
409 };
410
411 static const value_string dplay_af_val[] = {
412     { 0x0002, "AF_INET" },
413     { 0x0006, "AF_IPX" },
414     { 0     , NULL},
415 };
416
417 static const value_string dplay_proto_dialect_val[] = {
418     { 0x0009, "dplay 6" },
419     { 0x000a, "dplay 6.1" },
420     { 0x000b, "dplay 6.1a" },
421     { 0x000c, "dplay 7.1" },
422     { 0x000d, "dplay 8" },
423     { 0x000e, "dplay 9"},
424     { 0     , NULL},
425 };
426
427 static const value_string dplay_token_val[] = {
428     { 0xfab, "Remote Message" },
429     { 0xcab, "Forwarded Message" },
430     { 0xbab, "Server Message" },
431     { 0    , NULL },
432 };
433
434 static const value_string dplay_spp_length_val[] = {
435     { 0x0, "Not present" },
436     { 0x1, "One byte" },
437     { 0x2, "Two bytes" },
438     { 0x3, "Four bytes" },
439     { 0  , NULL},
440 };
441
442 static const value_string dplay_enc_alg_val[] = {
443     { 0x0000, "Default" },
444     { 0x6611, "AES" },
445     { 0x6603, "3DES" },
446     { 0x6601, "DES" },
447     { 0x6602, "RC2" },
448     { 0x6801, "RC4" },
449     { 0     , NULL },
450 };
451
452 static const value_string yes_no_val[] = {
453     { 0x0, "No" },
454     { 0x1, "Yes" },
455     { 0  , NULL },
456 };
457
458 static const true_false_string tfs_dplay_flag = {
459     "present",
460     "absent"
461 };
462
463 /* borrowed from epan/dissectors/packets-smb-common.c */
464 static gint display_unicode_string(proto_tree *tree, gint hf_index, tvbuff_t *tvb, gint offset)
465 {
466     char *str, *p;
467     gint len;
468     gint charoffset;
469     guint16 character;
470
471     /* display a unicode string from the tree and return new offset */
472
473     /*
474      * Get the length of the string.
475      * XXX - is it a bug or a feature that this will throw an exception
476      * if we don't find the '\0'?  I think it's a feature.
477      */
478     len = 0;
479     while ((character = tvb_get_letohs(tvb, offset + len)) != '\0')
480         len += 2;
481     len += 2;   /* count the '\0' too */
482
483     /*
484      * Allocate a buffer for the string; "len" is the length in
485      * bytes, not the length in characters.
486      */
487     str = ep_alloc(len/2);
488
489     /*
490      * XXX - this assumes the string is just ISO 8859-1; we need
491      * to better handle multiple character sets in Wireshark,
492      * including Unicode/ISO 10646, and multiple encodings of
493      * that character set (UCS-2, UTF-8, etc.).
494      */
495     charoffset = offset;
496     p = str;
497     while ((character = tvb_get_letohs(tvb, charoffset)) != '\0') {
498         *p++ = (char) character;
499         charoffset += 2;
500     }
501     *p = '\0';
502
503     proto_tree_add_string(tree, hf_index, tvb, offset, len, str);
504
505     return  offset+len;
506 }
507
508 static gint dissect_sockaddr_in(proto_tree *tree, tvbuff_t *tvb, gint offset)
509 {
510     proto_item *sa_item = NULL;
511     proto_tree *sa_tree = NULL;
512
513     sa_item = proto_tree_add_text(tree, tvb, offset, 16,
514             "DirectPlay sockaddr_in structure");
515     sa_tree = proto_item_add_subtree(sa_item, ett_dplay_sockaddr);
516     proto_tree_add_item(sa_tree, hf_dplay_saddr_af, tvb, offset, 2, TRUE); offset += 2;
517     proto_tree_add_item(sa_tree, hf_dplay_saddr_port, tvb, offset, 2, FALSE); offset += 2;
518     proto_tree_add_item(sa_tree, hf_dplay_saddr_ip, tvb, offset, 4, FALSE); offset += 4;
519     proto_tree_add_item(sa_tree, hf_dplay_saddr_padding, tvb, offset, 8, FALSE); offset += 8;
520     return offset;
521 }
522
523 static gint dissect_session_desc(proto_tree *tree, tvbuff_t *tvb, gint offset)
524 {
525     gint data_len;
526     guint32 flags;
527     proto_item *flags_item = NULL;
528     proto_tree *flags_tree = NULL;
529
530     data_len = tvb_get_letohl(tvb, offset);
531     flags = tvb_get_letohl(tvb, offset+4);
532
533     proto_tree_add_item(tree, hf_dplay_sess_desc_length, tvb, offset, 4, TRUE); offset += 4;
534     flags_item = proto_tree_add_item(tree, hf_dplay_sess_desc_flags, tvb, offset, 4, TRUE);
535     flags_tree = proto_item_add_subtree(flags_item, ett_dplay_sess_desc_flags);
536     proto_tree_add_boolean(flags_tree, hf_dplay_flags_no_sess_desc_changes, tvb, offset, 4, flags);
537     proto_tree_add_boolean(flags_tree, hf_dplay_flags_acqire_voice, tvb, offset, 4, flags);
538     proto_tree_add_boolean(flags_tree, hf_dplay_flags_optimize_latency, tvb, offset, 4, flags);
539     proto_tree_add_boolean(flags_tree, hf_dplay_flags_preserve_order, tvb, offset, 4, flags);
540     proto_tree_add_boolean(flags_tree, hf_dplay_flags_reliable, tvb, offset, 4, flags);
541     proto_tree_add_boolean(flags_tree, hf_dplay_flags_server_player_only, tvb, offset, 4, flags);
542     proto_tree_add_boolean(flags_tree, hf_dplay_flags_route, tvb, offset, 4, flags);
543     proto_tree_add_boolean(flags_tree, hf_dplay_flags_password_req, tvb, offset, 4, flags);
544     proto_tree_add_boolean(flags_tree, hf_dplay_flags_private_session, tvb, offset, 4, flags);
545     proto_tree_add_boolean(flags_tree, hf_dplay_flags_use_auth, tvb, offset, 4, flags);
546     proto_tree_add_boolean(flags_tree, hf_dplay_flags_no_player_updates, tvb, offset, 4, flags);
547     proto_tree_add_boolean(flags_tree, hf_dplay_flags_use_ping, tvb, offset, 4, flags);
548     proto_tree_add_boolean(flags_tree, hf_dplay_flags_can_join, tvb, offset, 4, flags);
549     proto_tree_add_boolean(flags_tree, hf_dplay_flags_ignored, tvb, offset, 4, flags);
550     proto_tree_add_boolean(flags_tree, hf_dplay_flags_short_player_msg, tvb, offset, 4, flags);
551     proto_tree_add_boolean(flags_tree, hf_dplay_flags_migrate_host, tvb, offset, 4, flags);
552     proto_tree_add_boolean(flags_tree, hf_dplay_flags_0002, tvb, offset, 4, flags);
553     proto_tree_add_boolean(flags_tree, hf_dplay_flags_no_create_players, tvb, offset, 4, flags);
554     offset += 4;
555
556     proto_tree_add_item(tree, hf_dplay_instance_guid, tvb, offset, 16, FALSE); offset += 16;
557     proto_tree_add_item(tree, hf_dplay_game_guid, tvb, offset, 16, FALSE); offset += 16;
558     proto_tree_add_item(tree, hf_dplay_max_players, tvb, offset, 4, TRUE); offset += 4;
559     proto_tree_add_item(tree, hf_dplay_curr_players, tvb, offset, 4, TRUE); offset += 4;
560     proto_tree_add_item(tree, hf_dplay_sess_name_ptr, tvb, offset, 4, FALSE); offset += 4;
561     proto_tree_add_item(tree, hf_dplay_passwd_ptr, tvb, offset, 4, FALSE); offset += 4;
562     proto_tree_add_item(tree, hf_dplay_sess_desc_reserved_1, tvb, offset, 4, FALSE); offset += 4;
563     proto_tree_add_item(tree, hf_dplay_sess_desc_reserved_2, tvb, offset, 4, FALSE); offset += 4;
564     proto_tree_add_item(tree, hf_dplay_sess_desc_user_1, tvb, offset, 4, FALSE); offset += 4;
565     proto_tree_add_item(tree, hf_dplay_sess_desc_user_2, tvb, offset, 4, FALSE); offset += 4;
566     proto_tree_add_item(tree, hf_dplay_sess_desc_user_3, tvb, offset, 4, FALSE); offset += 4;
567     proto_tree_add_item(tree, hf_dplay_sess_desc_user_4, tvb, offset, 4, FALSE); offset += 4;
568
569     return offset;
570 }
571
572 static gint spp_get_value(guint32 length_type, tvbuff_t *tvb, gint offset, guint32 *value)
573 {
574     gint len = 0;
575
576     *value = 0;
577
578     switch (length_type) {
579         case 1:
580             len = 1;
581             *value = tvb_get_guint8(tvb, offset);
582             break;
583         case 2:
584             len = 2;
585             *value = tvb_get_letohs(tvb, offset);
586             break;
587         case 3:
588             len = 4;
589             *value = tvb_get_letohl(tvb, offset);
590             break;
591     }
592
593     return len;
594 }
595
596 static gint dissect_dplay_super_packed_player(proto_tree *tree, tvbuff_t *tvb, gint offset)
597 {
598     guint32 flags, is_sysplayer, info_mask;
599     guint32 have_short_name, have_long_name, sp_length_type, pd_length_type;
600     guint32 player_count_type, have_parent_id, shortcut_count_type;
601     guint32 player_data_length, sp_data_length, player_count, shortcut_count;
602     proto_item *flags_item = NULL, *im_item = NULL;
603     proto_tree *flags_tree = NULL, *im_tree = NULL;
604     gint len;
605
606     proto_tree_add_item(tree, hf_dplay_spp_size, tvb, offset, 4, TRUE); offset += 4;
607
608     flags = tvb_get_letohl(tvb, offset);
609     is_sysplayer = flags & 0x00000001;
610     flags_item = proto_tree_add_item(tree, hf_dplay_spp_flags, tvb, offset, 4, TRUE);
611     flags_tree = proto_item_add_subtree(flags_item, ett_dplay_spp_flags);
612     proto_tree_add_boolean(flags_tree, hf_dplay_spp_flags_sending, tvb, offset, 4, flags);
613     proto_tree_add_boolean(flags_tree, hf_dplay_spp_flags_in_group, tvb, offset, 4, flags);
614     proto_tree_add_boolean(flags_tree, hf_dplay_spp_flags_nameserver, tvb, offset, 4, flags);
615     proto_tree_add_boolean(flags_tree, hf_dplay_spp_flags_sysplayer, tvb, offset, 4, flags);
616     offset += 4;
617     proto_tree_add_item(tree, hf_dplay_spp_id, tvb, offset, 4, TRUE); offset += 4;
618
619     info_mask = tvb_get_letohl(tvb, offset);
620
621     have_short_name     =  info_mask & 0x00000001;
622     have_long_name      = (info_mask & 0x00000002) >> 1;
623     sp_length_type      = (info_mask & 0x0000000c) >> 2;
624     pd_length_type      = (info_mask & 0x00000030) >> 4;
625     player_count_type   = (info_mask & 0x000000c0) >> 6;
626     have_parent_id      = (info_mask & 0x00000100) >> 8;
627     shortcut_count_type = (info_mask & 0x00000600) >> 9;
628
629     im_item = proto_tree_add_item(tree, hf_dplay_spp_player_info_mask, tvb, offset, 4, TRUE);
630
631     im_tree = proto_item_add_subtree(im_item, ett_dplay_spp_info_mask);
632     proto_tree_add_uint(im_tree, hf_dplay_spp_have_short_name, tvb, offset, 4, have_short_name);
633     proto_tree_add_uint(im_tree, hf_dplay_spp_have_long_name, tvb, offset, 4, have_long_name);
634     proto_tree_add_uint(im_tree, hf_dplay_spp_sp_length_type, tvb, offset, 4, sp_length_type);
635     proto_tree_add_uint(im_tree, hf_dplay_spp_pd_length_type, tvb, offset, 4, pd_length_type);
636     proto_tree_add_uint(im_tree, hf_dplay_spp_player_count_type, tvb, offset, 4, player_count_type);
637     proto_tree_add_uint(im_tree, hf_dplay_spp_have_parent_id, tvb, offset, 4, have_parent_id);
638     proto_tree_add_uint(im_tree, hf_dplay_spp_shortcut_count_type, tvb, offset, 4, shortcut_count_type);
639     offset+=4;
640
641     if (is_sysplayer) {
642         proto_tree_add_item(tree, hf_dplay_spp_dialect, tvb, offset, 4, TRUE);
643     } else {
644         proto_tree_add_item(tree, hf_dplay_spp_sys_player_id, tvb, offset, 4, FALSE);
645     }
646     offset += 4;
647
648     if (have_short_name) {
649         offset = display_unicode_string(tree, hf_dplay_spp_short_name, tvb, offset);
650     }
651
652     if (have_long_name) {
653         offset = display_unicode_string(tree, hf_dplay_spp_long_name, tvb, offset);
654     }
655
656     if (pd_length_type) {
657         len = spp_get_value(pd_length_type, tvb, offset, &player_data_length);
658         proto_tree_add_item(tree, hf_dplay_spp_player_data_length, tvb, offset, len, TRUE);
659         offset += len;
660         proto_tree_add_item(tree, hf_dplay_spp_player_data, tvb, offset, player_data_length, FALSE);
661         offset += player_data_length;
662     }
663
664     if (sp_length_type) {
665         len = spp_get_value(sp_length_type, tvb, offset, &sp_data_length);
666         proto_tree_add_item(tree, hf_dplay_spp_sp_data_length, tvb, offset, len, TRUE);
667         offset += len;
668         proto_tree_add_item(tree, hf_dplay_spp_sp_data, tvb, offset, sp_data_length, FALSE);
669         offset += sp_data_length;
670     }
671
672     if (player_count_type) {
673         guint32 i;
674
675         len = spp_get_value(player_count_type, tvb, offset, &player_count);
676         proto_tree_add_item(tree, hf_dplay_spp_player_count, tvb, offset, len, TRUE);
677         offset += len;
678         for (i=0; i < player_count; ++i) {
679             proto_tree_add_item(tree, hf_dplay_spp_player_id, tvb, offset, 4, FALSE); offset += 4;
680         }
681     }
682
683     if (have_parent_id) {
684         proto_tree_add_item(tree, hf_dplay_spp_parent_id, tvb, offset, 4, FALSE); offset += 4;
685     }
686
687     if (shortcut_count_type) {
688         guint32 i;
689
690         len = spp_get_value(shortcut_count_type, tvb, offset, &shortcut_count);
691         proto_tree_add_item(tree, hf_dplay_spp_shortcut_count, tvb, offset, len, TRUE);
692         offset += len;
693         for (i=0; i < shortcut_count; ++i) {
694             proto_tree_add_item(tree, hf_dplay_spp_shortcut_id, tvb, offset, 4, FALSE); offset += 4;
695         }
696     }
697
698     return offset;
699 }
700
701 static gint dissect_security_desc(proto_tree *tree, tvbuff_t *tvb, gint offset)
702 {
703     proto_tree_add_item(tree, hf_dplay_sd_size, tvb, offset, 4, TRUE); offset += 4;
704     proto_tree_add_item(tree, hf_dplay_sd_flags, tvb, offset, 4, TRUE); offset += 4;
705     proto_tree_add_item(tree, hf_dplay_sd_sspi, tvb, offset, 4, TRUE); offset += 4;
706     proto_tree_add_item(tree, hf_dplay_sd_capi, tvb, offset, 4, TRUE); offset += 4;
707     proto_tree_add_item(tree, hf_dplay_sd_capi_type, tvb, offset, 4, TRUE); offset += 4;
708     proto_tree_add_item(tree, hf_dplay_sd_enc_alg, tvb, offset, 4, TRUE); offset += 4;
709     return offset;
710 }
711
712 static gint dissect_dplay_header(proto_tree *tree, tvbuff_t *tvb, gint offset)
713 {
714     guint32 mixed, size, token;
715
716     mixed = tvb_get_letohl(tvb, offset);
717     size = mixed & 0x000FFFFF;
718     token = (mixed & 0xFFF00000) >> 20;
719
720     proto_tree_add_uint(tree, hf_dplay_size, tvb, offset, 4, size);
721     proto_tree_add_uint(tree, hf_dplay_token, tvb, offset, 4, token);
722     offset += 4;
723     offset = dissect_sockaddr_in(tree, tvb, offset);
724     proto_tree_add_item(tree, hf_dplay_play_str, tvb, offset, 4, TRUE); offset += 4;
725     proto_tree_add_item(tree, hf_dplay_command, tvb, offset, 2, TRUE); offset += 2;
726     proto_tree_add_item(tree, hf_dplay_proto_dialect, tvb, offset, 2, TRUE); offset += 2;
727     return offset;
728 }
729
730 static gint dissect_type01_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
731 {
732     guint32 name_offset;
733
734     offset = dissect_session_desc(tree, tvb, offset);
735     name_offset = tvb_get_letohl(tvb, offset);
736     proto_tree_add_item(tree, hf_dplay_type_01_name_offset, tvb, offset, 4, TRUE); offset += 4;
737
738     if (name_offset != 0) {
739         offset = display_unicode_string(tree, hf_dplay_type_01_game_name, tvb, offset);
740     }
741     return offset;
742 }
743
744 static gint dissect_type02_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
745 {
746     guint32 passwd_offset;
747     guint32 flags;
748     proto_item *flags_item = NULL;
749     proto_tree *flags_tree = NULL;
750
751     passwd_offset = tvb_get_letohl(tvb, offset + 16);
752     flags = tvb_get_letohl(tvb, offset + 20);
753
754     proto_tree_add_item(tree, hf_dplay_type_02_game_guid, tvb, offset, 16, FALSE); offset += 16;
755     proto_tree_add_item(tree, hf_dplay_type_02_password_offset, tvb, offset, 4, TRUE); offset += 4;
756
757     flags_item = proto_tree_add_item(tree, hf_dplay_type_02_flags, tvb, offset, 4, TRUE);
758     flags_tree = proto_item_add_subtree(flags_item, ett_dplay_type02_flags);
759     proto_tree_add_boolean(flags_tree, hf_enum_sess_flag_passwd, tvb, offset, 4, flags);
760     proto_tree_add_boolean(flags_tree, hf_enum_sess_flag_all, tvb, offset, 4, flags);
761     proto_tree_add_boolean(flags_tree, hf_enum_sess_flag_join, tvb, offset, 4, flags);
762     offset += 4;
763
764     if (passwd_offset != 0) {
765         offset = display_unicode_string(tree, hf_dplay_type_02_password, tvb, offset);
766     }
767     return offset;
768 }
769
770 static gint dissect_type05_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
771 {
772     proto_item *flag_item;
773     proto_item *flag_tree;
774     guint32 flags;
775
776     flags = tvb_get_letohl(tvb, offset);
777     flag_item = proto_tree_add_item(tree, hf_dplay_type_05_flags, tvb, offset, 4, TRUE);
778     flag_tree = proto_item_add_subtree(flag_item, ett_dplay_type05_flags);
779     proto_tree_add_boolean(flag_tree, hf_dplay_type_05_secure, tvb, offset, 4, flags);
780     proto_tree_add_boolean(flag_tree, hf_dplay_type_05_unknown, tvb, offset, 4, flags);
781     proto_tree_add_boolean(flag_tree, hf_dplay_type_05_local, tvb, offset, 4, flags);
782     proto_tree_add_boolean(flag_tree, hf_dplay_type_05_name_server, tvb, offset, 4, flags);
783     proto_tree_add_boolean(flag_tree, hf_dplay_type_05_system_player, tvb, offset, 4, flags);
784     offset += 4;
785     return offset;
786 }
787
788 static gint dissect_type07_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
789 {
790     guint32 sspi_offset, capi_offset;
791
792     proto_tree_add_item(tree, hf_dplay_type_07_dpid, tvb, offset, 4, FALSE); offset += 4;
793     offset = dissect_security_desc(tree, tvb, offset);
794
795     sspi_offset = tvb_get_letohl(tvb, offset);
796     proto_tree_add_item(tree, hf_dplay_type_07_sspi_offset, tvb, offset, 4, TRUE); offset += 4;
797
798     capi_offset = tvb_get_letohl(tvb, offset);
799     proto_tree_add_item(tree, hf_dplay_type_07_capi_offset, tvb, offset, 4, TRUE); offset += 4;
800
801     proto_tree_add_item(tree, hf_dplay_type_07_hresult, tvb, offset, 4, TRUE); offset += 4;
802
803     if (sspi_offset) {
804         offset = display_unicode_string(tree, hf_dplay_type_07_sspi, tvb, offset);
805     }
806
807     if (capi_offset) {
808         offset = display_unicode_string(tree, hf_dplay_type_07_capi, tvb, offset);
809     }
810     return offset;
811 }
812
813 static gint dissect_type08_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
814 {
815     proto_item *first_saddr_item = NULL, *second_saddr_item = NULL;
816     proto_tree *first_saddr_tree = NULL, *second_saddr_tree = NULL;
817     gint string_1_len, string_2_len;
818
819     proto_tree_add_item(tree, hf_dplay_type_08_padding_1, tvb, offset, 4, FALSE); offset += 4;
820     proto_tree_add_item(tree, hf_dplay_type_08_dpid_1, tvb, offset, 4, FALSE); offset += 4;
821     proto_tree_add_item(tree, hf_dplay_type_08_unknown_1, tvb, offset, 20, FALSE); offset += 20;
822     proto_tree_add_item(tree, hf_dplay_type_08_dpid_2, tvb, offset, 4, FALSE); offset += 4;
823     string_1_len = tvb_get_letohl(tvb, offset);
824     proto_tree_add_item(tree, hf_dplay_type_08_string_1_len, tvb, offset, 4, TRUE); offset += 4;
825     string_2_len = tvb_get_letohl(tvb, offset);
826     proto_tree_add_item(tree, hf_dplay_type_08_string_2_len, tvb, offset, 4, TRUE); offset += 4;
827     proto_tree_add_item(tree, hf_dplay_type_08_unknown_2, tvb, offset, 12, FALSE); offset += 12;
828     proto_tree_add_item(tree, hf_dplay_type_08_dpid_3, tvb, offset, 4, FALSE); offset += 4;
829     proto_tree_add_item(tree, hf_dplay_type_08_unknown_3, tvb, offset, 12, FALSE); offset += 12;
830
831     if(string_1_len > 0)
832         offset = display_unicode_string(tree, hf_dplay_type_08_string_1, tvb, offset);
833     if(string_2_len > 0)
834         offset = display_unicode_string(tree, hf_dplay_type_08_string_2, tvb, offset);
835
836     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
837             "DirectPlay message type 0x0008 s_addr_in structure 1");
838     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type08_saddr1);
839
840     proto_tree_add_item(first_saddr_tree, hf_dplay_type_08_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
841     proto_tree_add_item(first_saddr_tree, hf_dplay_type_08_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
842     proto_tree_add_item(first_saddr_tree, hf_dplay_type_08_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
843     proto_tree_add_item(first_saddr_tree, hf_dplay_type_08_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
844
845     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
846             "DirectPlay message type 0x0008 s_addr_in structure 2");
847     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type08_saddr2);
848
849     proto_tree_add_item(second_saddr_tree, hf_dplay_type_08_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
850     proto_tree_add_item(second_saddr_tree, hf_dplay_type_08_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
851     proto_tree_add_item(second_saddr_tree, hf_dplay_type_08_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
852     proto_tree_add_item(second_saddr_tree, hf_dplay_type_08_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
853
854     proto_tree_add_item(tree, hf_dplay_type_08_padding_2, tvb, offset, 6, FALSE); offset += 6;
855
856     return offset;
857 }
858
859 static gint dissect_type0b_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
860 {
861     proto_tree_add_item(tree, hf_dplay_type_0b_padding_1, tvb, offset, 4, FALSE); offset += 4;
862     proto_tree_add_item(tree, hf_dplay_type_0b_dpid, tvb, offset, 4, FALSE); offset += 4;
863     proto_tree_add_item(tree, hf_dplay_type_0b_padding_2, tvb, offset, 12, FALSE); offset += 12;
864     return offset;
865 }
866
867 static gint dissect_type0d_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
868 {
869     proto_tree_add_item(tree, hf_dplay_type_0d_padding_1, tvb, offset, 4, FALSE); offset += 4;
870     proto_tree_add_item(tree, hf_dplay_type_0d_dpid_1, tvb, offset, 4, FALSE); offset += 4;
871     proto_tree_add_item(tree, hf_dplay_type_0d_dpid_2, tvb, offset, 4, FALSE); offset += 4;
872     proto_tree_add_item(tree, hf_dplay_type_0d_padding_2, tvb, offset, 8, FALSE); offset += 8;
873     return offset;
874 }
875
876 static gint dissect_type0e_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
877 {
878     proto_tree_add_item(tree, hf_dplay_type_0e_padding_1, tvb, offset, 4, FALSE); offset += 4;
879     proto_tree_add_item(tree, hf_dplay_type_0e_dpid_1, tvb, offset, 4, FALSE); offset += 4;
880     proto_tree_add_item(tree, hf_dplay_type_0e_dpid_2, tvb, offset, 4, FALSE); offset += 4;
881     proto_tree_add_item(tree, hf_dplay_type_0e_padding_2, tvb, offset, 8, FALSE); offset += 8;
882     return offset;
883 }
884
885 static gint dissect_type0f_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
886 {
887     proto_tree_add_item(tree, hf_dplay_data_type_0f, tvb, offset, -1, FALSE);
888     return offset;
889 }
890
891 static gint dissect_type13_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
892 {
893     proto_item *first_saddr_item = NULL, *second_saddr_item = NULL;
894     proto_tree *first_saddr_tree = NULL, *second_saddr_tree = NULL;
895
896     proto_tree_add_item(tree, hf_dplay_type_13_padding_1, tvb, offset, 4, FALSE); offset += 4;
897     proto_tree_add_item(tree, hf_dplay_type_13_dpid_1, tvb, offset, 4, FALSE); offset += 4;
898     proto_tree_add_item(tree, hf_dplay_type_13_unknown_1, tvb, offset, 20, FALSE); offset += 20;
899     proto_tree_add_item(tree, hf_dplay_type_13_dpid_2, tvb, offset, 4, FALSE); offset += 4;
900     proto_tree_add_item(tree, hf_dplay_type_13_unknown_2, tvb, offset, 20, FALSE); offset += 20;
901     proto_tree_add_item(tree, hf_dplay_type_13_dpid_3, tvb, offset, 4, FALSE); offset += 4;
902     proto_tree_add_item(tree, hf_dplay_type_13_unknown_3, tvb, offset, 12, FALSE); offset += 12;
903
904     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
905             "DirectPlay message type 0x0013 s_addr_in structure 1");
906     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type13_saddr1);
907
908     proto_tree_add_item(first_saddr_tree, hf_dplay_type_13_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
909     proto_tree_add_item(first_saddr_tree, hf_dplay_type_13_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
910     proto_tree_add_item(first_saddr_tree, hf_dplay_type_13_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
911     proto_tree_add_item(first_saddr_tree, hf_dplay_type_13_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
912
913     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
914             "DirectPlay message type 0x0013 s_addr_in structure 2");
915     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type13_saddr2);
916
917     proto_tree_add_item(second_saddr_tree, hf_dplay_type_13_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
918     proto_tree_add_item(second_saddr_tree, hf_dplay_type_13_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
919     proto_tree_add_item(second_saddr_tree, hf_dplay_type_13_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
920     proto_tree_add_item(second_saddr_tree, hf_dplay_type_13_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
921
922     proto_tree_add_item(tree, hf_dplay_type_13_padding_2, tvb, offset, 2, FALSE); offset += 2;
923     proto_tree_add_item(tree, hf_dplay_type_13_dpid_4, tvb, offset, 4, FALSE); offset += 4;
924
925     return offset;
926 }
927
928 static gint dissect_type15_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
929 {
930     guint16 second_message_type;
931     proto_item *enc_item = NULL;
932     proto_tree *enc_tree = NULL;
933     second_message_type = tvb_get_letohs(tvb, 72);
934
935     proto_tree_add_item(tree, hf_dplay_container_guid, tvb, offset, 16, FALSE); offset += 16;
936     proto_tree_add_item(tree, hf_dplay_type_15_padding_1, tvb, offset, 4, FALSE); offset += 4;
937     proto_tree_add_item(tree, hf_dplay_type_15_size_1, tvb, offset, 4, TRUE); offset += 4;
938     proto_tree_add_item(tree, hf_dplay_type_15_padding_2, tvb, offset, 4, FALSE); offset += 4;
939     proto_tree_add_item(tree, hf_dplay_type_15_unknown_1, tvb, offset, 4, TRUE); offset += 4;
940     proto_tree_add_item(tree, hf_dplay_type_15_size_2, tvb, offset, 4, TRUE); offset += 4;
941     proto_tree_add_item(tree, hf_dplay_type_15_padding_3, tvb, offset, 4, FALSE); offset += 4;
942
943     enc_item = proto_tree_add_text(tree, tvb, offset, -1, "DirectPlay encapsulated packet");
944     enc_tree = proto_item_add_subtree(enc_item, ett_dplay_enc_packet);
945
946     proto_tree_add_item(enc_tree, hf_dplay_play_str_2, tvb, offset, 4, FALSE); offset += 4;
947     proto_tree_add_item(enc_tree, hf_dplay_command_2, tvb, offset, 2, TRUE); offset += 2;
948     proto_tree_add_item(enc_tree, hf_dplay_proto_dialect_2, tvb, offset, 2, TRUE); offset += 2;
949
950     switch(second_message_type)
951     {
952         case 0x0005:
953             offset = dissect_type05_message(enc_tree, tvb, offset);
954             break;
955         case 0x0007:
956             offset = dissect_type05_message(enc_tree, tvb, offset);
957             break;
958         case 0x0008:
959             offset = dissect_type08_message(enc_tree, tvb, offset);
960             break;
961         case 0x000b:
962             offset = dissect_type0b_message(enc_tree, tvb, offset);
963             break;
964         case 0x0013:
965             offset = dissect_type13_message(enc_tree, tvb, offset);
966             break;
967         case 0x001a:
968             offset = dissect_type1a_message(enc_tree, tvb, offset);
969             break;
970         case 0x002e:
971             offset = dissect_type2e_message(enc_tree, tvb, offset);
972             break;
973     }
974
975     return offset;
976 }
977
978 static gint dissect_type16_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
979 {
980     proto_tree_add_item(tree, hf_dplay_type_16_data, tvb, offset, -1, FALSE);
981     return offset;
982 }
983
984 static gint dissect_type17_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
985 {
986     proto_tree_add_item(tree, hf_dplay_type_17_data, tvb, offset, -1, FALSE);
987     return offset;
988 }
989
990 static gint dissect_type1a_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
991 {
992     proto_tree_add_item(tree, hf_dplay_data_type_1a, tvb, offset, -1, FALSE);
993     return offset;
994 }
995
996 static gint dissect_type29_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
997 {
998     guint32 password_offset = tvb_get_letohl(tvb, offset + 24);
999     gint player_count, group_count, shortcut_count;
1000     gint i;
1001
1002     player_count = tvb_get_letohl(tvb, offset);
1003     proto_tree_add_item(tree, hf_dplay_type_29_player_count, tvb, offset, 4, TRUE); offset += 4;
1004     group_count = tvb_get_letohl(tvb, offset);
1005     proto_tree_add_item(tree, hf_dplay_type_29_group_count, tvb, offset, 4, TRUE); offset += 4;
1006     proto_tree_add_item(tree, hf_dplay_type_29_packed_offset, tvb, offset, 4, TRUE); offset += 4;
1007     shortcut_count = tvb_get_letohl(tvb, offset);
1008     proto_tree_add_item(tree, hf_dplay_type_29_shortcut_count, tvb, offset, 4, TRUE); offset += 4;
1009     proto_tree_add_item(tree, hf_dplay_type_29_description_offset, tvb, offset, 4, TRUE); offset += 4;
1010     proto_tree_add_item(tree, hf_dplay_type_29_name_offset, tvb, offset, 4, TRUE); offset += 4;
1011     proto_tree_add_item(tree, hf_dplay_type_29_password_offset, tvb, offset, 4, TRUE); offset += 4;
1012     offset = dissect_session_desc(tree, tvb, offset);
1013     offset = display_unicode_string(tree, hf_dplay_type_29_game_name, tvb, offset);
1014
1015     if (password_offset != 0) {
1016         offset = display_unicode_string(tree, hf_dplay_type_29_password, tvb, offset);
1017     }
1018
1019     for (i=0; i < player_count; ++i) {
1020         proto_item *spp_item;
1021         proto_tree *spp_tree;
1022
1023         spp_item = proto_tree_add_text(tree, tvb, offset, 0, "Player %d", i);
1024         spp_tree = proto_item_add_subtree(spp_item, ett_dplay_type29_spp);
1025         offset = dissect_dplay_super_packed_player(spp_tree, tvb, offset);
1026     }
1027
1028     for (i=0; i < group_count; ++i) {
1029         proto_item *spp_item;
1030         proto_tree *spp_tree;
1031
1032         spp_item = proto_tree_add_text(tree, tvb, offset, 0, "Group %d", i);
1033         spp_tree = proto_item_add_subtree(spp_item, ett_dplay_type29_spp);
1034         offset = dissect_dplay_super_packed_player(spp_tree, tvb, offset);
1035     }
1036
1037     for (i=0; i < shortcut_count; ++i) {
1038         proto_item *spp_item;
1039         proto_tree *spp_tree;
1040
1041         spp_item = proto_tree_add_text(tree, tvb, offset, 0, "Shortcut %d", i);
1042         spp_tree = proto_item_add_subtree(spp_item, ett_dplay_type29_spp);
1043         offset = dissect_dplay_super_packed_player(spp_tree, tvb, offset);
1044     }
1045
1046     return offset;
1047 }
1048
1049 static gint dissect_type2e_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
1050 {
1051     proto_item *first_saddr_item = NULL, *second_saddr_item = NULL;
1052     proto_tree *first_saddr_tree = NULL, *second_saddr_tree = NULL;
1053     gint string_1_len, string_2_len;
1054
1055     proto_tree_add_item(tree, hf_dplay_type_2e_padding_1, tvb, offset, 4, FALSE); offset += 4;
1056     proto_tree_add_item(tree, hf_dplay_type_2e_dpid_1, tvb, offset, 4, FALSE); offset += 4;
1057     proto_tree_add_item(tree, hf_dplay_type_2e_unknown_1, tvb, offset, 20, FALSE); offset += 20;
1058     proto_tree_add_item(tree, hf_dplay_type_2e_dpid_2, tvb, offset, 4, FALSE); offset += 4;
1059     string_1_len = tvb_get_letohl(tvb, offset);
1060     proto_tree_add_item(tree, hf_dplay_type_2e_string_1_len, tvb, offset, 4, TRUE); offset += 4;
1061     string_2_len = tvb_get_letohl(tvb, offset);
1062     proto_tree_add_item(tree, hf_dplay_type_2e_string_2_len, tvb, offset, 4, TRUE); offset += 4;
1063     proto_tree_add_item(tree, hf_dplay_type_2e_unknown_2, tvb, offset, 12, FALSE); offset += 12;
1064     proto_tree_add_item(tree, hf_dplay_type_2e_dpid_3, tvb, offset, 4, FALSE); offset += 4;
1065     proto_tree_add_item(tree, hf_dplay_type_2e_unknown_3, tvb, offset, 12, FALSE); offset += 12;
1066
1067     if(string_1_len > 0)
1068         offset = display_unicode_string(tree, hf_dplay_type_2e_string_1, tvb, offset);
1069     if(string_2_len > 0)
1070         offset = display_unicode_string(tree, hf_dplay_type_2e_string_2, tvb, offset);
1071
1072     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
1073             "DirectPlay message type 0x002e s_addr_in structure 1");
1074     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type2e_saddr1);
1075
1076     proto_tree_add_item(first_saddr_tree, hf_dplay_type_2e_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
1077     proto_tree_add_item(first_saddr_tree, hf_dplay_type_2e_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
1078     proto_tree_add_item(first_saddr_tree, hf_dplay_type_2e_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
1079     proto_tree_add_item(first_saddr_tree, hf_dplay_type_2e_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
1080
1081     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
1082             "DirectPlay message type 0x002e s_addr_in structure 2");
1083     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type2e_saddr2);
1084
1085     proto_tree_add_item(second_saddr_tree, hf_dplay_type_2e_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
1086     proto_tree_add_item(second_saddr_tree, hf_dplay_type_2e_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
1087     proto_tree_add_item(second_saddr_tree, hf_dplay_type_2e_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
1088     proto_tree_add_item(second_saddr_tree, hf_dplay_type_2e_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
1089
1090     return offset;
1091 }
1092
1093 static gint dissect_type2f_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
1094 {
1095     proto_tree_add_item(tree, hf_dplay_type_2f_dpid, tvb, offset, 4, FALSE); offset += 4;
1096     return offset;
1097 }
1098
1099 static gint dissect_type38_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
1100 {
1101     proto_item *first_saddr_item = NULL, *second_saddr_item = NULL;
1102     proto_tree *first_saddr_tree = NULL, *second_saddr_tree = NULL;
1103     gint string_1_len, string_2_len;
1104
1105     proto_tree_add_item(tree, hf_dplay_type_38_padding_1, tvb, offset, 4, FALSE); offset += 4;
1106     proto_tree_add_item(tree, hf_dplay_type_38_dpid_1, tvb, offset, 4, FALSE); offset += 4;
1107     proto_tree_add_item(tree, hf_dplay_type_38_unknown_1, tvb, offset, 20, FALSE); offset += 20;
1108     proto_tree_add_item(tree, hf_dplay_type_38_dpid_2, tvb, offset, 4, FALSE); offset += 4;
1109     string_1_len = tvb_get_letohl(tvb, offset);
1110     proto_tree_add_item(tree, hf_dplay_type_38_string_1_len, tvb, offset, 4, TRUE); offset += 4;
1111     string_2_len = tvb_get_letohl(tvb, offset);
1112     proto_tree_add_item(tree, hf_dplay_type_38_string_2_len, tvb, offset, 4, TRUE); offset += 4;
1113     proto_tree_add_item(tree, hf_dplay_type_38_unknown_2, tvb, offset, 12, FALSE); offset += 12;
1114     proto_tree_add_item(tree, hf_dplay_type_38_dpid_3, tvb, offset, 4, FALSE); offset += 4;
1115     proto_tree_add_item(tree, hf_dplay_type_38_unknown_3, tvb, offset, 12, FALSE); offset += 12;
1116
1117     if(string_1_len > 0)
1118         offset = display_unicode_string(tree, hf_dplay_type_38_string_1, tvb, offset);
1119     if(string_2_len > 0)
1120         offset = display_unicode_string(tree, hf_dplay_type_38_string_2, tvb, offset);
1121
1122     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
1123             "DirectPlay message type 0x0038 s_addr_in structure 1");
1124     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type38_saddr1);
1125
1126     proto_tree_add_item(first_saddr_tree, hf_dplay_type_38_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
1127     proto_tree_add_item(first_saddr_tree, hf_dplay_type_38_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
1128     proto_tree_add_item(first_saddr_tree, hf_dplay_type_38_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
1129     proto_tree_add_item(first_saddr_tree, hf_dplay_type_38_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
1130
1131     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
1132             "DirectPlay message type 0x0038 s_addr_in structure 2");
1133     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type38_saddr2);
1134
1135     proto_tree_add_item(second_saddr_tree, hf_dplay_type_38_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
1136     proto_tree_add_item(second_saddr_tree, hf_dplay_type_38_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
1137     proto_tree_add_item(second_saddr_tree, hf_dplay_type_38_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
1138     proto_tree_add_item(second_saddr_tree, hf_dplay_type_38_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
1139
1140     return offset;
1141 }
1142
1143 static void dissect_dplay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1144 {
1145     guint16 message_type;
1146     guint16 second_message_type = -1;
1147     guint16 proto_version;
1148     guint16 packet_size;
1149     guint32 dplay_id;
1150     guint8 play_id[] = {'p','l','a','y'};
1151
1152     packet_size = tvb_get_letohs(tvb, 0);
1153     dplay_id = tvb_get_letohl(tvb, 20);
1154     message_type = tvb_get_letohs(tvb, 24);
1155     proto_version = tvb_get_letohs(tvb, 26);
1156
1157     if(memcmp(play_id, (guint8 *)&dplay_id, 4) != 0)
1158     {
1159         if(check_col(pinfo->cinfo, COL_PROTOCOL))
1160             col_set_str(pinfo->cinfo, COL_PROTOCOL, "DPLAY");
1161         /* Clear out stuff in the info column */
1162         if(check_col(pinfo->cinfo,COL_INFO))
1163             col_clear(pinfo->cinfo,COL_INFO);
1164         if(check_col(pinfo->cinfo,COL_INFO))
1165             col_add_fstr(pinfo->cinfo,COL_INFO, "DPlay data packet");
1166         return;
1167     }
1168
1169     if(message_type == 0x0015)
1170     {
1171         second_message_type = tvb_get_letohs(tvb, 72);
1172     }
1173
1174     if(check_col(pinfo->cinfo, COL_PROTOCOL))
1175         col_set_str(pinfo->cinfo, COL_PROTOCOL, "DPLAY");
1176     /* Clear out stuff in the info column */
1177     if(check_col(pinfo->cinfo,COL_INFO))
1178     {
1179         col_clear(pinfo->cinfo,COL_INFO);
1180     }
1181
1182     if(check_col(pinfo->cinfo,COL_INFO))
1183     {
1184         if(message_type == 0x0015)
1185             col_add_fstr(pinfo->cinfo,COL_INFO, "%s: %s, holding a %s",
1186                 val_to_str(proto_version, dplay_proto_dialect_val, "Unknown (0x%04x)"),
1187                 val_to_str(message_type, dplay_command_val, "Unknown (0x%04x)"),
1188                 val_to_str(second_message_type, dplay_command_val, "Unknown (0x%04x)"));
1189         else
1190             col_add_fstr(pinfo->cinfo,COL_INFO, "%s: %s",
1191                 val_to_str(proto_version, dplay_proto_dialect_val, "Unknown (0x%04x)"),
1192                 val_to_str(message_type, dplay_command_val, "Unknown (0x%04x)"));
1193     }
1194
1195     if(tree)
1196     {
1197         proto_item *dplay_item = NULL;
1198         proto_item *header_item = NULL;
1199         proto_item *data_item = NULL;
1200         proto_tree *dplay_tree = NULL;
1201         proto_tree *dplay_header = NULL;
1202         proto_tree *dplay_data = NULL;
1203         gint offset = 0;
1204
1205         dplay_item = proto_tree_add_item(tree, proto_dplay, tvb, 0, -1, FALSE);
1206         dplay_tree = proto_item_add_subtree(dplay_item, ett_dplay);
1207         header_item = proto_tree_add_text(dplay_tree, tvb, offset, DPLAY_HEADER_OFFSET, "DirectPlay header");
1208         dplay_header = proto_item_add_subtree(header_item, ett_dplay_header);
1209
1210         offset = dissect_dplay_header(dplay_header, tvb, offset);
1211
1212         /* Special handling for empty type 0x0004 packets */
1213         if(message_type == 0x0004)
1214             return;
1215
1216         data_item = proto_tree_add_text(dplay_tree, tvb, offset, -1, "DirectPlay data");
1217         dplay_data = proto_item_add_subtree(data_item, ett_dplay_data);
1218
1219         switch(message_type)
1220         {
1221             case 0x0001:
1222                 offset = dissect_type01_message(dplay_data, tvb, offset);
1223                 break;
1224             case 0x0002:
1225                 offset = dissect_type02_message(dplay_data, tvb, offset);
1226                 break;
1227             case 0x0004:
1228                 /* We should not get here. */
1229                 break;
1230             case 0x0005:
1231                 offset = dissect_type05_message(dplay_data, tvb, offset);
1232                 break;
1233             case 0x0007:
1234                 offset = dissect_type07_message(dplay_data, tvb, offset);
1235                 break;
1236             case 0x0008:
1237                 offset = dissect_type08_message(dplay_data, tvb, offset);
1238                 break;
1239             case 0x000b:
1240                 offset = dissect_type0b_message(dplay_data, tvb, offset);
1241                 break;
1242             case 0x000d:
1243                 offset = dissect_type0d_message(dplay_data, tvb, offset);
1244                 break;
1245             case 0x000e:
1246                 offset = dissect_type0e_message(dplay_data, tvb, offset);
1247                 break;
1248             case 0x000f:
1249                 offset = dissect_type0f_message(dplay_data, tvb, offset);
1250                 break;
1251             case 0x0013:
1252                 offset = dissect_type13_message(dplay_data, tvb, offset);
1253                 break;
1254             case 0x0015:
1255                 offset = dissect_type15_message(dplay_data, tvb, offset);
1256                 break;
1257             case 0x0016:
1258                 offset = dissect_type16_message(dplay_data, tvb, offset);
1259                 break;
1260             case 0x0017:
1261                 offset = dissect_type17_message(dplay_data, tvb, offset);
1262                 break;
1263             case 0x001a:
1264                 offset = dissect_type1a_message(dplay_data, tvb, offset);
1265                 break;
1266             case 0x0029:
1267                 offset = dissect_type29_message(dplay_data, tvb, offset);
1268                 break;
1269             case 0x002e:
1270                 offset = dissect_type2e_message(dplay_data, tvb, offset);
1271                 break;
1272             case 0x002f:
1273                 offset = dissect_type2f_message(dplay_data, tvb, offset);
1274                 break;
1275             case 0x0038:
1276                 offset = dissect_type38_message(dplay_data, tvb, offset);
1277                 break;
1278         }
1279     }
1280
1281 }
1282
1283 static gboolean heur_dissect_dplay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1284 {
1285     guint8 signature[] = {'p','l','a','y'};
1286     guint32 dplay_id;
1287
1288     if(!tvb_bytes_exist(tvb, 0, 24))
1289         return FALSE;
1290
1291     dplay_id = tvb_get_letohl(tvb, 20);
1292     if( memcmp(signature, (guint8 *)&dplay_id, 4) != 0)
1293         return FALSE;
1294
1295     dissect_dplay(tvb, pinfo, tree);
1296     return TRUE;
1297 }
1298
1299 void proto_register_dplay()
1300 {
1301     static hf_register_info hf [] = {
1302     /* Common data fields */
1303     { &hf_dplay_size,
1304         { "DirectPlay package size", "dplay.size", FT_UINT32, BASE_DEC,
1305         NULL, 0x0, "", HFILL}},
1306     { &hf_dplay_token,
1307         { "DirectPlay token", "dplay.token", FT_UINT32, BASE_HEX,
1308         VALS(dplay_token_val), 0x0, "", HFILL}},
1309     { &hf_dplay_saddr_af,
1310         { "DirectPlay s_addr_in address family", "dplay.saddr.af", FT_UINT16, BASE_HEX,
1311         VALS(dplay_af_val), 0x0, "", HFILL}},
1312     { &hf_dplay_saddr_port,
1313         { "DirectPlay s_addr_in port", "dplay.saddr.port", FT_UINT16, BASE_DEC,
1314         NULL, 0x0, "", HFILL}},
1315     { &hf_dplay_saddr_ip,
1316         { "DirectPlay s_addr_in ip address", "dplay.saddr.ip", FT_IPv4, BASE_NONE,
1317         NULL, 0x0, "", HFILL}},
1318     { &hf_dplay_saddr_padding,
1319         { "DirectPlay s_addr_in null padding", "dplay.saddr.padding", FT_BYTES, BASE_NONE,
1320         NULL, 0x0, "", HFILL}},
1321     { &hf_dplay_play_str,
1322         { "DirectPlay action string", "dplay.dplay_str", FT_STRING, BASE_NONE,
1323         NULL, 0x0, "", HFILL}},
1324     { &hf_dplay_command,
1325         { "DirectPlay command", "dplay.command", FT_UINT16, BASE_HEX,
1326         VALS(dplay_command_val), 0x0, "", HFILL}},
1327     { &hf_dplay_proto_dialect,
1328         { "DirectPlay dialect version", "dplay.dialect.version", FT_UINT16, BASE_HEX,
1329         VALS(dplay_proto_dialect_val), 0x0, "", HFILL}},
1330     { &hf_dplay_play_str_2,
1331         { "DirectPlay second action string", "dplay.dplay_str_2", FT_STRING, BASE_NONE,
1332         NULL, 0x0, "", HFILL}},
1333     { &hf_dplay_command_2,
1334         { "DirectPlay second command", "dplay.type_2", FT_UINT16, BASE_HEX,
1335         VALS(dplay_command_val), 0x0, "", HFILL}},
1336     { &hf_dplay_proto_dialect_2,
1337         { "DirectPlay second dialect version", "dplay.dialect.version_2", FT_UINT16, BASE_HEX,
1338         VALS(dplay_proto_dialect_val), 0x0, "", HFILL}},
1339
1340     /* special fields, to be phased out*/
1341     { &hf_dplay_data_type_0f,
1342         { "DirectPlay data for type 0f messages", "dplay.data.type_0f", FT_BYTES, BASE_HEX,
1343         NULL, 0x0, "", HFILL}},
1344     { &hf_dplay_data_type_1a,
1345         { "DirectPlay data for type 1a messages", "dplay.data.type_1a", FT_BYTES, BASE_HEX,
1346         NULL, 0x0, "", HFILL}},
1347
1348     /* Session Desc structure fields */
1349     { &hf_dplay_sess_desc_flags,
1350         { "DirectPlay session desc flags", "dplay.flags", FT_UINT32, BASE_HEX,
1351         NULL, 0x0, "", HFILL}},
1352     { &hf_dplay_flags_no_create_players,
1353         { "no create players flag", "dplay.flags.no_create_players", FT_BOOLEAN, 32,
1354         TFS(&tfs_dplay_flag), DPLAY_FLAG_NO_CREATE_PLAYERS, "No Create Players", HFILL}},
1355     { &hf_dplay_flags_0002,
1356         { "unused", "dplay.flags.unused", FT_BOOLEAN, 32,
1357         TFS(&tfs_dplay_flag), DPLAY_FLAG_0002, "Unused", HFILL}},
1358     { &hf_dplay_flags_migrate_host,
1359         { "migrate host flag", "dplay.flags.migrate_host", FT_BOOLEAN, 32,
1360         TFS(&tfs_dplay_flag), DPLAY_FLAG_MIGRATE_HOST, "Migrate Host", HFILL}},
1361     { &hf_dplay_flags_short_player_msg,
1362         { "short player message", "dplay.flags.short_player_msg", FT_BOOLEAN, 32,
1363         TFS(&tfs_dplay_flag), DPLAY_FLAG_SHORT_PLAYER_MSG, "Short Player Msg", HFILL}},
1364     { &hf_dplay_flags_ignored,
1365         { "ignored", "dplay.flags.ignored", FT_BOOLEAN, 32,
1366         TFS(&tfs_dplay_flag), DPLAY_FLAG_IGNORED, "Ignored", HFILL}},
1367     { &hf_dplay_flags_can_join,
1368         { "can join", "dplay.flags.can_join", FT_BOOLEAN, 32,
1369         TFS(&tfs_dplay_flag), DPLAY_FLAG_CAN_JOIN, "Can Join", HFILL}},
1370     { &hf_dplay_flags_use_ping,
1371         { "use ping", "dplay.flags.use_ping", FT_BOOLEAN, 32,
1372         TFS(&tfs_dplay_flag), DPLAY_FLAG_USE_PING, "Use Ping", HFILL}},
1373     { &hf_dplay_flags_no_player_updates,
1374         { "no player updates", "dplay.flags.no_player_updates", FT_BOOLEAN, 32,
1375         TFS(&tfs_dplay_flag), DPLAY_FLAG_NO_P_UPD, "No Player Updates", HFILL}},
1376     { &hf_dplay_flags_use_auth,
1377         { "use authentication", "dplay.flags.use_auth", FT_BOOLEAN, 32,
1378         TFS(&tfs_dplay_flag), DPLAY_FLAG_USE_AUTH, "Use Auth", HFILL}},
1379     { &hf_dplay_flags_private_session,
1380         { "private session", "dplay.flags.priv_sess", FT_BOOLEAN, 32,
1381         TFS(&tfs_dplay_flag), DPLAY_FLAG_PRIV_SESS, "Priv Session", HFILL}},
1382     { &hf_dplay_flags_password_req,
1383         { "password required", "dplay.flags.pass_req", FT_BOOLEAN, 32,
1384         TFS(&tfs_dplay_flag), DPLAY_FLAG_PASS_REQ, "Pass Req", HFILL}},
1385     { &hf_dplay_flags_route,
1386         { "route via game host", "dplay.flags.route", FT_BOOLEAN, 32,
1387         TFS(&tfs_dplay_flag), DPLAY_FLAG_ROUTE, "Route", HFILL}},
1388     { &hf_dplay_flags_server_player_only,
1389         { "get server player only", "dplay.flags.srv_p_only", FT_BOOLEAN, 32,
1390         TFS(&tfs_dplay_flag), DPLAY_FLAG_SRV_ONLY, "Svr Player Only", HFILL}},
1391     { &hf_dplay_flags_reliable,
1392         { "use reliable protocol", "dplay.flags.reliable", FT_BOOLEAN, 32,
1393         TFS(&tfs_dplay_flag), DPLAY_FLAG_RELIABLE, "Reliable", HFILL}},
1394     { &hf_dplay_flags_preserve_order,
1395         { "preserve order", "dplay.flags.order", FT_BOOLEAN, 32,
1396         TFS(&tfs_dplay_flag), DPLAY_FLAG_ORDER, "Order", HFILL}},
1397     { &hf_dplay_flags_optimize_latency,
1398         { "optimize for latency", "dplay.flags.opt_latency", FT_BOOLEAN, 32,
1399         TFS(&tfs_dplay_flag), DPLAY_FLAG_OPT_LAT, "Opt Latency", HFILL}},
1400     { &hf_dplay_flags_acqire_voice,
1401         { "acquire voice", "dplay.flags.acq_voice", FT_BOOLEAN, 32,
1402         TFS(&tfs_dplay_flag), DPLAY_FLAG_ACQ_VOICE, "Acq Voice", HFILL}},
1403     { &hf_dplay_flags_no_sess_desc_changes,
1404         { "no session desc changes", "dplay.flags.no_sess_desc", FT_BOOLEAN, 32,
1405         TFS(&tfs_dplay_flag), DPLAY_FLAG_NO_SESS_DESC_CHANGES, "No Sess Desc Changes", HFILL}},
1406     { &hf_dplay_instance_guid,
1407         { "DirectPlay instance guid", "dplay.instance.guid", FT_GUID, BASE_NONE,
1408         NULL, 0x0, "", HFILL}},
1409     { &hf_dplay_game_guid,
1410         { "DirectPlay game GUID", "dplay.game.guid", FT_GUID, BASE_NONE,
1411         NULL, 0x0, "", HFILL}},
1412     { &hf_dplay_sess_desc_length,
1413         { "DirectPlay session desc length", "dplay.sess_desc.length", FT_UINT32, BASE_DEC,
1414         NULL, 0x0, "", HFILL}},
1415     { &hf_dplay_max_players,
1416         { "DirectPlay max players ", "dplay.sess_desc.max_players", FT_UINT32, BASE_DEC,
1417         NULL, 0x0, "", HFILL}},
1418     { &hf_dplay_curr_players,
1419         { "DirectPlay current players", "dplay.sess_desc.curr_players", FT_UINT32, BASE_DEC,
1420         NULL, 0x0, "", HFILL}},
1421     { &hf_dplay_sess_name_ptr,
1422         { "Session description name pointer placeholder", "dplay.sess_desc.name_ptr", FT_BYTES, BASE_HEX,
1423         NULL, 0x0, "", HFILL}},
1424     { &hf_dplay_passwd_ptr,
1425         { "Session description password pointer placeholder", "dplay.sess_desc.pw_ptr", FT_BYTES, BASE_HEX,
1426         NULL, 0x0, "", HFILL}},
1427     { &hf_dplay_sess_desc_reserved_1,
1428         { "Session description reserved 1", "dplay.sess_desc.res_1", FT_BYTES, BASE_HEX,
1429         NULL, 0x0, "", HFILL}},
1430     { &hf_dplay_sess_desc_reserved_2,
1431         { "Session description reserved 2", "dplay.sess_desc.res_2", FT_BYTES, BASE_HEX,
1432         NULL, 0x0, "", HFILL}},
1433     { &hf_dplay_sess_desc_user_1,
1434         { "Session description user defined 1", "dplay.sess_desc.user_1", FT_BYTES, BASE_HEX,
1435         NULL, 0x0, "", HFILL}},
1436     { &hf_dplay_sess_desc_user_2,
1437         { "Session description user defined 2", "dplay.sess_desc.user_2", FT_BYTES, BASE_HEX,
1438         NULL, 0x0, "", HFILL}},
1439     { &hf_dplay_sess_desc_user_3,
1440         { "Session description user defined 3", "dplay.sess_desc.user_3", FT_BYTES, BASE_HEX,
1441         NULL, 0x0, "", HFILL}},
1442     { &hf_dplay_sess_desc_user_4,
1443         { "Session description user defined 4", "dplay.sess_desc.user_4", FT_BYTES, BASE_HEX,
1444         NULL, 0x0, "", HFILL}},
1445
1446     /* SuperPackedPlayer structure fields */
1447     { &hf_dplay_spp_size,
1448         { "SuperPackedPlayer size", "dplay.spp.size", FT_UINT32, BASE_DEC,
1449         NULL, 0x0, "", HFILL}},
1450     { &hf_dplay_spp_flags,
1451         { "SuperPackedPlayer flags", "dplay.spp.flags", FT_UINT32, BASE_HEX,
1452         NULL, 0x0, "", HFILL}},
1453     { &hf_dplay_spp_flags_sysplayer,
1454         { "is system player", "dplay.spp.flags.sysplayer", FT_BOOLEAN, 32,
1455         TFS(&tfs_dplay_flag), DPLAY_SPP_FLAG_SYSPLAYER, "", HFILL}},
1456     { &hf_dplay_spp_flags_nameserver,
1457         { "is name server", "dplay.spp.flags.nameserver", FT_BOOLEAN, 32,
1458         TFS(&tfs_dplay_flag), DPLAY_SPP_FLAG_NAMESERVER, "", HFILL}},
1459     { &hf_dplay_spp_flags_in_group,
1460         { "in group", "dplay.spp.flags.in_group", FT_BOOLEAN, 32,
1461         TFS(&tfs_dplay_flag), DPLAY_SPP_FLAG_IN_GROUP, "", HFILL}},
1462     { &hf_dplay_spp_flags_sending,
1463         { "sending player on local machine", "dplay.spp.flags.sending", FT_BOOLEAN, 32,
1464         TFS(&tfs_dplay_flag), DPLAY_SPP_FLAG_SENDING, "", HFILL}},
1465     { &hf_dplay_spp_id,
1466         { "SuperPackedPlayer ID", "dplay.spp.id", FT_BYTES, BASE_HEX,
1467         NULL, 0x0, "", HFILL}},
1468     { &hf_dplay_spp_player_info_mask,
1469         { "SuperPackedPlayer player info mask", "dplay.spp.pim", FT_UINT32, BASE_HEX,
1470         NULL, 0x0, "", HFILL}},
1471     { &hf_dplay_spp_have_short_name,
1472         { "SuperPackedPlayer have short name", "dplay.spp.pim.short_name", FT_UINT32, BASE_HEX,
1473         VALS(yes_no_val), 0x0, "", HFILL}},
1474     { &hf_dplay_spp_have_long_name,
1475         { "SuperPackedPlayer have long name", "dplay.spp.pim.long_name", FT_UINT32, BASE_HEX,
1476         VALS(yes_no_val), 0x0, "", HFILL}},
1477     { &hf_dplay_spp_sp_length_type,
1478         { "SuperPackedPlayer service provider length info", "dplay.spp.pim.sp_length", FT_UINT32, BASE_HEX,
1479         VALS(dplay_spp_length_val), 0x0, "", HFILL}},
1480     { &hf_dplay_spp_pd_length_type,
1481         { "SuperPackedPlayer player data length info", "dplay.spp.pim.pd_length", FT_UINT32, BASE_HEX,
1482         VALS(dplay_spp_length_val), 0x0, "", HFILL}},
1483     { &hf_dplay_spp_player_count_type,
1484         { "SuperPackedPlayer player count info", "dplay.spp.pim.player_count", FT_UINT32, BASE_HEX,
1485         VALS(dplay_spp_length_val), 0x0, "", HFILL}},
1486     { &hf_dplay_spp_have_parent_id,
1487         { "SuperPackedPlayer have parent ID", "dplay.spp.pim.parent_id", FT_UINT32, BASE_HEX,
1488         VALS(yes_no_val), 0x0, "", HFILL}},
1489     { &hf_dplay_spp_shortcut_count_type,
1490         { "SuperPackedPlayer shortcut count info", "dplay.spp.pim.shortcut_count", FT_UINT32, BASE_HEX,
1491         VALS(dplay_spp_length_val), 0x0, "", HFILL}},
1492     { &hf_dplay_spp_dialect,
1493         { "SuperPackedPlayer dialect version", "dplay.spp.dialect", FT_UINT32, BASE_HEX,
1494         VALS(&dplay_proto_dialect_val), 0x0, "", HFILL}},
1495     { &hf_dplay_spp_sys_player_id,
1496         { "SuperPackedPlayer system player ID", "dplay.spp.sysplayer_id", FT_BYTES, BASE_HEX,
1497         NULL, 0x0, "", HFILL}},
1498     { &hf_dplay_spp_short_name,
1499         { "SuperPackedPlayer short name", "dplay.spp.short_name", FT_STRING, BASE_NONE,
1500         NULL, 0x0, "", HFILL}},
1501     { &hf_dplay_spp_long_name,
1502         { "SuperPackedPlayer long name", "dplay.spp.short_name", FT_STRING, BASE_NONE,
1503         NULL, 0x0, "", HFILL}},
1504     { &hf_dplay_spp_player_data_length,
1505         { "SuperPackedPlayer player data length", "dplay.spp.pd_length", FT_UINT32, BASE_HEX,
1506         NULL, 0x0, "", HFILL}},
1507     { &hf_dplay_spp_player_data,
1508         { "SuperPackedPlayer player data", "dplay.spp.player_data", FT_BYTES, BASE_HEX,
1509         NULL, 0x0, "", HFILL}},
1510     { &hf_dplay_spp_sp_data_length,
1511         { "SuperPackedPlayer service provider data length", "dplay.spp.sp_data_length", FT_UINT32, BASE_HEX,
1512         NULL, 0x0, "", HFILL}},
1513     { &hf_dplay_spp_sp_data,
1514         { "SuperPackedPlayer service provider data", "dplay.spp.sp_data", FT_BYTES, BASE_HEX,
1515         NULL, 0x0, "", HFILL}},
1516     { &hf_dplay_spp_player_count,
1517         { "SuperPackedPlayer player count", "dplay.spp.player_count", FT_UINT32, BASE_HEX,
1518         NULL, 0x0, "", HFILL}},
1519     { &hf_dplay_spp_player_id,
1520         { "SuperPackedPlayer player ID", "dplay.spp.player_id", FT_BYTES, BASE_HEX,
1521         NULL, 0x0, "", HFILL}},
1522     { &hf_dplay_spp_parent_id,
1523         { "SuperPackedPlayer parent ID", "dplay.spp.parent_id", FT_BYTES, BASE_HEX,
1524         NULL, 0x0, "", HFILL}},
1525     { &hf_dplay_spp_shortcut_count,
1526         { "SuperPackedPlayer shortcut count", "dplay.spp.shortcut_count", FT_UINT32, BASE_HEX,
1527         NULL, 0x0, "", HFILL}},
1528     { &hf_dplay_spp_shortcut_id,
1529         { "SuperPackedPlayer shortcut ID", "dplay.spp.shortcut_id", FT_BYTES, BASE_HEX,
1530         NULL, 0x0, "", HFILL}},
1531
1532     /* Data fields for SecDesc struct */
1533     { &hf_dplay_sd_size,
1534         { "SecDesc struct size", "dplay.sd.size", FT_UINT32, BASE_DEC,
1535         NULL, 0x0, "", HFILL}},
1536     { &hf_dplay_sd_flags,
1537         { "SecDesc flags", "dplay.sd.flags", FT_UINT32, BASE_HEX,
1538         NULL, 0x0, "", HFILL}},
1539     { &hf_dplay_sd_sspi,
1540         { "SecDesc SSPI provider ptr", "dplay.sd.sspi", FT_BYTES, BASE_HEX,
1541         NULL, 0x0, "", HFILL}},
1542     { &hf_dplay_sd_capi,
1543         { "SecDesc CAPI provider ptr", "dplay.sd.capi", FT_BYTES, BASE_HEX,
1544         NULL, 0x0, "", HFILL}},
1545     { &hf_dplay_sd_capi_type,
1546         { "SecDesc CAPI provider type", "dplay.sd.capi_type", FT_UINT32, BASE_HEX,
1547         NULL, 0x0, "", HFILL}},
1548     { &hf_dplay_sd_enc_alg,
1549         { "SecDesc encryption algorithm" , "dplay.sd.enc_alg", FT_UINT32, BASE_HEX,
1550         VALS(dplay_enc_alg_val), 0x0, "", HFILL}},
1551
1552     /* Data fields for message type 0x0001 */
1553     { &hf_dplay_type_01_name_offset,
1554         { "Enum Session Reply name offset", "dplay.type_01.name_offs", FT_UINT32, BASE_DEC,
1555         NULL, 0x0, "", HFILL}},
1556     { &hf_dplay_type_01_game_name,
1557         { "Enum Session Reply game name", "dplay.type_01.game_name", FT_STRING, BASE_NONE,
1558         NULL, 0x0, "", HFILL}},
1559
1560     /* Data fields for message type 0x0002 */
1561     { &hf_dplay_type_02_game_guid,
1562         { "DirectPlay game GUID", "dplay.type02.game.guid", FT_GUID, BASE_NONE,
1563         NULL, 0x0, "", HFILL}},
1564     { &hf_dplay_type_02_password_offset,
1565         { "Enum Sessions password offset", "dplay.type02.password_offset", FT_UINT32, BASE_DEC,
1566         NULL, 0x0, "", HFILL}},
1567     { &hf_dplay_type_02_flags,
1568         { "Enum Session flags", "dplay.type02.flags", FT_UINT32, BASE_HEX,
1569         NULL, 0x0, "", HFILL}},
1570     { &hf_dplay_type_02_password,
1571         { "Session password", "dplay.type02.password", FT_STRING, BASE_NONE,
1572         NULL, 0x0, "", HFILL}},
1573     { &hf_enum_sess_flag_join,
1574         { "Enumerate joinable sessions", "dplay.type02.joinable", FT_BOOLEAN, 32,
1575         TFS(&tfs_dplay_flag), DPLAY_ENUM_SESS_FLAG_JOIN, "Joinable", HFILL}},
1576     { &hf_enum_sess_flag_all,
1577         { "Enumerate all sessions", "dplay.type02.all", FT_BOOLEAN, 32,
1578         TFS(&tfs_dplay_flag), DPLAY_ENUM_SESS_FLAG_ALL, "All", HFILL}},
1579     { &hf_enum_sess_flag_passwd,
1580         { "Enumerate sessions requiring a password", "dplay.type02.pw_req", FT_BOOLEAN, 32,
1581         TFS(&tfs_dplay_flag), DPLAY_ENUM_SESS_FLAG_PASSWD, "Password", HFILL}},
1582
1583     /* Data fields for message type 0x0005 */
1584     { &hf_dplay_type_05_flags,
1585         { "Player ID request flags", "dplay.type_05.flags", FT_UINT32, BASE_HEX,
1586         NULL, 0x0, "", HFILL}},
1587     { &hf_dplay_type_05_system_player,
1588         { "is system player", "dplay.type_05.flags.sys_player", FT_BOOLEAN, 32,
1589         TFS(&tfs_dplay_flag), DPLAY_TYPE05_FLAG_SYSPLAYER, "", HFILL}},
1590     { &hf_dplay_type_05_name_server,
1591         { "is name server", "dplay.type_05.flags.name_server", FT_BOOLEAN, 32,
1592         TFS(&tfs_dplay_flag), DPLAY_TYPE05_FLAG_NAMESERVER, "", HFILL}},
1593     { &hf_dplay_type_05_local,
1594         { "is local player", "dplay.type_05.flags.local", FT_BOOLEAN, 32,
1595         TFS(&tfs_dplay_flag), DPLAY_TYPE05_FLAG_LOCAL, "", HFILL}},
1596     { &hf_dplay_type_05_unknown,
1597         { "unknown", "dplay.type_05.flags.unknown", FT_BOOLEAN, 32,
1598         TFS(&tfs_dplay_flag), DPLAY_TYPE05_FLAG_UNKNOWN, "", HFILL}},
1599     { &hf_dplay_type_05_secure,
1600         { "is secure session", "dplay.type_05.flags.secure", FT_BOOLEAN, 32,
1601         TFS(&tfs_dplay_flag), DPLAY_TYPE05_FLAG_SECURE, "", HFILL}},
1602
1603     /* Data fields for message type 0x0007 */
1604     { &hf_dplay_type_07_dpid,
1605         { "DirectPlay ID", "dplay.type_07.dpid", FT_BYTES, BASE_HEX,
1606         NULL, 0x0, "", HFILL}},
1607     { &hf_dplay_type_07_sspi_offset,
1608         { "SSPI provider offset", "dplay.type_07.sspi_offset", FT_UINT32, BASE_DEC,
1609         NULL, 0x0, "", HFILL}},
1610     { &hf_dplay_type_07_capi_offset,
1611         { "CAPI provider offset", "dplay.type_07.capi_offset", FT_UINT32, BASE_DEC,
1612         NULL, 0x0, "", HFILL}},
1613     { &hf_dplay_type_07_hresult,
1614         { "Request player HRESULT", "dplay.type_07.hresult", FT_UINT32, BASE_DEC,
1615         NULL, 0x0, "", HFILL}},
1616     { &hf_dplay_type_07_sspi,
1617         { "SSPI provider", "dplay.type_07.sspi", FT_STRING, BASE_NONE,
1618         NULL, 0x0, "", HFILL}},
1619     { &hf_dplay_type_07_capi,
1620         { "CAPI provider", "dplay.type_07.capi", FT_STRING, BASE_NONE,
1621         NULL, 0x0, "", HFILL}},
1622
1623     /* Data fields for message type 0x0008 */
1624     { &hf_dplay_type_08_padding_1,
1625         { "DirectPlay message type 0x0008 padding 1", "dplay.type_08.padding_1", FT_BYTES, BASE_HEX,
1626         NULL, 0x0, "", HFILL}},
1627     { &hf_dplay_type_08_dpid_1,
1628         { "DirectPlay message type 0x0008 client DP ID", "dplay.type_08.dpid_1", FT_BYTES, BASE_HEX,
1629         NULL, 0x0, "", HFILL}},
1630     { &hf_dplay_type_08_unknown_1,
1631         { "DirectPlay message type 0x0008 unknown 1", "dplay.type_08.unknown_1", FT_BYTES, BASE_HEX,
1632         NULL, 0x0, "", HFILL}},
1633     { &hf_dplay_type_08_dpid_2,
1634         { "DirectPlay message type 0x0008 client DP ID", "dplay.type_08.dpid_2", FT_BYTES, BASE_HEX,
1635         NULL, 0x0, "", HFILL}},
1636     { &hf_dplay_type_08_string_1_len,
1637         { "DirectPlay message type 0x0008 string 1 length", "dplay.type_08.string_1.length", FT_UINT32,
1638         BASE_DEC, NULL, 0x0, "", HFILL}},
1639     { &hf_dplay_type_08_string_2_len,
1640         { "DirectPlay message type 0x0008 string 2 length", "dplay.type_08.string_2.length", FT_UINT32,
1641         BASE_DEC, NULL, 0x0, "", HFILL}},
1642     { &hf_dplay_type_08_unknown_2,
1643         { "DirectPlay message type 0x0008 unknown 2", "dplay.type_08.unknown_2", FT_BYTES, BASE_HEX,
1644         NULL, 0x0, "", HFILL}},
1645     { &hf_dplay_type_08_dpid_3,
1646         { "DirectPlay message type 0x0008 client DP ID", "dplay.type_08.dpid_3", FT_BYTES, BASE_HEX,
1647         NULL, 0x0, "", HFILL}},
1648     { &hf_dplay_type_08_unknown_3,
1649         { "DirectPlay message type 0x0008 unknown 3", "dplay.type_08.unknown_3", FT_BYTES, BASE_HEX,
1650         NULL, 0x0, "", HFILL}},
1651     { &hf_dplay_type_08_string_1,
1652         { "DirectPlay message type 0x0008 string 1", "dplay.type_08.string_1", FT_STRING, BASE_NONE,
1653         NULL, 0x0, "", HFILL}},
1654     { &hf_dplay_type_08_string_2,
1655         { "DirectPlay message type 0x0008 string 2", "dplay.type_08.string_2", FT_STRING, BASE_NONE,
1656         NULL, 0x0, "", HFILL}},
1657     { &hf_dplay_type_08_saddr_af_1,
1658         { "DirectPlay message type 0x0008 s_addr_in address family 1", "dplay.type_08.saddr.af_1", FT_UINT16,
1659             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1660     { &hf_dplay_type_08_saddr_port_1,
1661         { "DirectPlay message type 0x0008 s_addr_in port 1", "dplay.type_08.saddr.port_1", FT_UINT16, BASE_DEC,
1662         NULL, 0x0, "", HFILL}},
1663     { &hf_dplay_type_08_saddr_ip_1,
1664         { "DirectPlay message type 0x0008 s_addr_in ip 1", "dplay.type_08.saddr.ip_1", FT_IPv4, BASE_NONE,
1665         NULL, 0x0, "", HFILL}},
1666     { &hf_dplay_type_08_saddr_padd_1,
1667         { "DirectPlay message type 0x0008 s_addr_in padding 1", "dplay.type_08.saddr.padd_1", FT_BYTES, BASE_HEX,
1668         NULL, 0x0, "", HFILL}},
1669     { &hf_dplay_type_08_saddr_af_2,
1670         { "DirectPlay message type 0x0008 s_addr_in address family 2", "dplay.type_08.saddr.af_2", FT_UINT16,
1671             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1672     { &hf_dplay_type_08_saddr_port_2,
1673         { "DirectPlay message type 0x0008 s_addr_in port 2", "dplay.type_08.saddr.port_2", FT_UINT16, BASE_DEC,
1674         NULL, 0x0, "", HFILL}},
1675     { &hf_dplay_type_08_saddr_ip_2,
1676         { "DirectPlay message type 0x0008 s_addr_in ip 2", "dplay.type_08.saddr.ip_2", FT_IPv4, BASE_NONE,
1677         NULL, 0x0, "", HFILL}},
1678     { &hf_dplay_type_08_saddr_padd_2,
1679         { "DirectPlay message type 0x0008 s_addr_in padding 2", "dplay.type_08.saddr.padd_2", FT_BYTES, BASE_HEX,
1680         NULL, 0x0, "", HFILL}},
1681     { &hf_dplay_type_08_padding_2,
1682         { "DirectPlay message type 0x0008 padding 2", "dplay.type_08.padding_2", FT_BYTES, BASE_HEX,
1683         NULL, 0x0, "", HFILL}},
1684
1685     /* Data fields for message type 0x000b */
1686     { &hf_dplay_type_0b_padding_1,
1687         { "DirectPlay message type 0x000b padding 1", "dplay.type_0b.padding_1", FT_BYTES, BASE_HEX,
1688         NULL, 0x0, "", HFILL}},
1689     { &hf_dplay_type_0b_dpid,
1690         { "DirectPlay message type 0x000b DP ID", "dplay.type_0b.dpid", FT_BYTES, BASE_HEX,
1691         NULL, 0x0, "", HFILL}},
1692     { &hf_dplay_type_0b_padding_2,
1693         { "DirectPlay message type 0x000b padding 2", "dplay.type_0b.padding_2", FT_BYTES, BASE_HEX,
1694         NULL, 0x0, "", HFILL}},
1695
1696     /* Data fields for message type 0x000d */
1697     { &hf_dplay_type_0d_padding_1,
1698         { "DirectPlay message type 0x000d padding 1", "dplay.type_0d.padding_1", FT_BYTES, BASE_HEX,
1699         NULL, 0x0, "", HFILL}},
1700     { &hf_dplay_type_0d_dpid_1,
1701         { "DirectPlay message type 0x000d DP ID 1", "dplay.type_0d.dpid_1", FT_BYTES, BASE_HEX,
1702         NULL, 0x0, "", HFILL}},
1703     { &hf_dplay_type_0d_dpid_2,
1704         { "DirectPlay message type 0x000d DP ID 2", "dplay.type_0d.dpid_2", FT_BYTES, BASE_HEX,
1705         NULL, 0x0, "", HFILL}},
1706     { &hf_dplay_type_0d_padding_2,
1707         { "DirectPlay message type 0x000d padding 2", "dplay.type_0d.padding_2", FT_BYTES, BASE_HEX,
1708         NULL, 0x0, "", HFILL}},
1709
1710     /* Data fields for message type 0x000e */
1711     { &hf_dplay_type_0e_padding_1,
1712         { "DirectPlay message type 0x000e padding 1", "dplay.type_0e.padding_1", FT_BYTES, BASE_HEX,
1713         NULL, 0x0, "", HFILL}},
1714     { &hf_dplay_type_0e_dpid_1,
1715         { "DirectPlay message type 0x000e DP ID 1", "dplay.type_0e.dpid_1", FT_BYTES, BASE_HEX,
1716         NULL, 0x0, "", HFILL}},
1717     { &hf_dplay_type_0e_dpid_2,
1718         { "DirectPlay message type 0x000e DP ID 2", "dplay.type_0e.dpid_2", FT_BYTES, BASE_HEX,
1719         NULL, 0x0, "", HFILL}},
1720     { &hf_dplay_type_0e_padding_2,
1721         { "DirectPlay message type 0x000e padding 2", "dplay.type_0e.padding_2", FT_BYTES, BASE_HEX,
1722         NULL, 0x0, "", HFILL}},
1723
1724     /* Data fields for message type 0x0013 */
1725     { &hf_dplay_type_13_padding_1,
1726         { "DirectPlay message type 0x0013 padding 1", "dplay.type_13.padding_1", FT_BYTES, BASE_HEX,
1727         NULL, 0x0, "", HFILL}},
1728     { &hf_dplay_type_13_dpid_1,
1729         { "DirectPlay message type 0x0013 client DP ID", "dplay.type_13.dpid_1", FT_BYTES, BASE_HEX,
1730         NULL, 0x0, "", HFILL}},
1731     { &hf_dplay_type_13_unknown_1,
1732         { "DirectPlay message type 0x0013 unknown 1", "dplay.type_13.unknown_1", FT_BYTES, BASE_HEX,
1733         NULL, 0x0, "", HFILL}},
1734     { &hf_dplay_type_13_dpid_2,
1735         { "DirectPlay message type 0x0013 client DP ID", "dplay.type_13.dpid_2", FT_BYTES, BASE_HEX,
1736         NULL, 0x0, "", HFILL}},
1737     { &hf_dplay_type_13_unknown_2,
1738         { "DirectPlay message type 0x0013 unknown 2", "dplay.type_13.unknown_2", FT_BYTES, BASE_HEX,
1739         NULL, 0x0, "", HFILL}},
1740     { &hf_dplay_type_13_dpid_3,
1741         { "DirectPlay message type 0x0013 client DP ID", "dplay.type_13.dpid_3", FT_BYTES, BASE_HEX,
1742         NULL, 0x0, "", HFILL}},
1743     { &hf_dplay_type_13_unknown_3,
1744         { "DirectPlay message type 0x0013 unknown 3", "dplay.type_13.unknown_3", FT_BYTES, BASE_HEX,
1745         NULL, 0x0, "", HFILL}},
1746     { &hf_dplay_type_13_saddr_af_1,
1747         { "DirectPlay message type 0x0013 s_addr_in address family 1", "dplay.type_13.saddr.af_1", FT_UINT16,
1748             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1749     { &hf_dplay_type_13_saddr_port_1,
1750         { "DirectPlay message type 0x0013 s_addr_in port 1", "dplay.type_13.saddr.port_1", FT_UINT16, BASE_DEC,
1751         NULL, 0x0, "", HFILL}},
1752     { &hf_dplay_type_13_saddr_ip_1,
1753         { "DirectPlay message type 0x0013 s_addr_in ip 1", "dplay.type_13.saddr.ip_1", FT_IPv4, BASE_NONE,
1754         NULL, 0x0, "", HFILL}},
1755     { &hf_dplay_type_13_saddr_padd_1,
1756         { "DirectPlay message type 0x0013 s_addr_in padding 1", "dplay.type_13.saddr.padd_1", FT_BYTES, BASE_HEX,
1757         NULL, 0x0, "", HFILL}},
1758     { &hf_dplay_type_13_saddr_af_2,
1759         { "DirectPlay message type 0x0013 s_addr_in address family 2", "dplay.type_13.saddr.af_2", FT_UINT16,
1760             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1761     { &hf_dplay_type_13_saddr_port_2,
1762         { "DirectPlay message type 0x0013 s_addr_in port 2", "dplay.type_13.saddr.port_2", FT_UINT16, BASE_DEC,
1763         NULL, 0x0, "", HFILL}},
1764     { &hf_dplay_type_13_saddr_ip_2,
1765         { "DirectPlay message type 0x0013 s_addr_in ip 2", "dplay.type_13.saddr.ip_2", FT_IPv4, BASE_NONE,
1766         NULL, 0x0, "", HFILL}},
1767     { &hf_dplay_type_13_saddr_padd_2,
1768         { "DirectPlay message type 0x0013 s_addr_in padding 2", "dplay.type_13.saddr.padd_2", FT_BYTES, BASE_HEX,
1769         NULL, 0x0, "", HFILL}},
1770     { &hf_dplay_type_13_padding_2,
1771         { "DirectPlay message type 0x0013 padding 2", "dplay.type_13.padding_2", FT_BYTES, BASE_HEX,
1772         NULL, 0x0, "", HFILL}},
1773     { &hf_dplay_type_13_dpid_4,
1774         { "DirectPlay message type 0x0013 server DP ID", "dplay.type_13.dpid_4", FT_BYTES, BASE_HEX,
1775         NULL, 0x0, "", HFILL}},
1776
1777     /* Data fields for message type 0x0015 */
1778     { &hf_dplay_container_guid,
1779         { "DirectPlay container GUID", "dplay.container.guid", FT_GUID, BASE_NONE,
1780         NULL, 0x0, "", HFILL}},
1781     { &hf_dplay_type_15_padding_1,
1782         { "DirectPlay message type 0x0015 padding 1", "dplay.type_15.padding_1", FT_BYTES, BASE_HEX,
1783         NULL, 0x0, "", HFILL}},
1784     { &hf_dplay_type_15_size_1,
1785         { "DirectPlay encapsulated packet size 1", "dplay.type_15.encap_size_1", FT_UINT32, BASE_DEC,
1786         NULL, 0x0, "", HFILL}},
1787     { &hf_dplay_type_15_padding_2,
1788         { "DirectPlay message type 0x0015 padding 2", "dplay.type_15.padding_2", FT_BYTES, BASE_HEX,
1789         NULL, 0x0, "", HFILL}},
1790     { &hf_dplay_type_15_unknown_1,
1791         { "DirectPlay message type 0x0015 unknown", "dplay.type_15.unknown_1", FT_UINT32, BASE_DEC,
1792         NULL, 0x0, "", HFILL}},
1793     { &hf_dplay_type_15_size_2,
1794         { "DirectPlay encapsulated packet size 2", "dplay.type_15.encap_size_2", FT_UINT32, BASE_DEC,
1795         NULL, 0x0, "", HFILL}},
1796     { &hf_dplay_type_15_padding_3,
1797         { "DirectPlay message type 0x0015 padding 3", "dplay.type_15.padding_3", FT_BYTES, BASE_HEX,
1798         NULL, 0x0, "", HFILL}},
1799
1800     /* Data field for message type 0x0016 */
1801     { &hf_dplay_type_16_data,
1802         { "DirectPlay type 0x0016 message data", "dplay.data.type_16", FT_BYTES, BASE_HEX,
1803         NULL, 0x0, "", HFILL}},
1804
1805     /* Data field for message type 0x0017 */
1806     { &hf_dplay_type_17_data,
1807         { "DirectPlay type 0x0017 message data", "dplay.data.type_17", FT_BYTES, BASE_HEX,
1808         NULL, 0x0, "", HFILL}},
1809
1810     /* Data fields for message type 0x0029 */
1811     { &hf_dplay_type_29_player_count,
1812         { "SuperEnumPlayers Reply player count", "dplay.type_29.player_count", FT_UINT32,
1813         BASE_DEC, NULL, 0x0, "", HFILL}},
1814     { &hf_dplay_type_29_group_count,
1815         { "SuperEnumPlayers Reply group count", "dplay.type_29.group_count", FT_UINT32,
1816         BASE_DEC, NULL, 0x0, "", HFILL}},
1817     { &hf_dplay_type_29_packed_offset,
1818         { "SuperEnumPlayers Reply packed offset", "dplay.type_29.packed_offset", FT_UINT32,
1819         BASE_DEC, NULL, 0x0, "", HFILL}},
1820     { &hf_dplay_type_29_shortcut_count,
1821         { "SuperEnumPlayers Reply shortcut count", "dplay.type_29.shortcut_count", FT_UINT32,
1822         BASE_DEC, NULL, 0x0, "", HFILL}},
1823     { &hf_dplay_type_29_description_offset,
1824         { "SuperEnumPlayers Reply description offset", "dplay.type_29.desc_offset", FT_UINT32,
1825         BASE_DEC, NULL, 0x0, "", HFILL}},
1826     { &hf_dplay_type_29_name_offset,
1827         { "SuperEnumPlayers Reply name offset", "dplay.type_29.name_offset", FT_UINT32,
1828         BASE_DEC, NULL, 0x0, "", HFILL}},
1829     { &hf_dplay_type_29_password_offset,
1830         { "SuperEnumPlayers Reply password offset", "dplay.type_29.pass_offset", FT_UINT32,
1831         BASE_DEC, NULL, 0x0, "", HFILL}},
1832     { &hf_dplay_type_29_game_name,
1833         { "SuperEnumPlayers Reply game name", "dplay.type_29.game_name", FT_STRING, BASE_NONE,
1834         NULL, 0x0, "", HFILL}},
1835     { &hf_dplay_type_29_password,
1836         { "SuperEnumPlayers Reply Password", "dplay.type_29.password", FT_STRING, BASE_NONE,
1837         NULL, 0x0, "", HFILL}},
1838
1839     /* Data fields for message type 0x002e */
1840     { &hf_dplay_type_2e_padding_1,
1841         { "DirectPlay message type 0x002e padding 1", "dplay.type_2e.padding_1", FT_BYTES, BASE_HEX,
1842         NULL, 0x0, "", HFILL}},
1843     { &hf_dplay_type_2e_dpid_1,
1844         { "DirectPlay message type 0x002e client DP ID", "dplay.type_2e.dpid_1", FT_BYTES, BASE_HEX,
1845         NULL, 0x0, "", HFILL}},
1846     { &hf_dplay_type_2e_unknown_1,
1847         { "DirectPlay message type 0x002e unknown 1", "dplay.type_2e.unknown_1", FT_BYTES, BASE_HEX,
1848         NULL, 0x0, "", HFILL}},
1849     { &hf_dplay_type_2e_dpid_2,
1850         { "DirectPlay message type 0x002e client DP ID", "dplay.type_2e.dpid_2", FT_BYTES, BASE_HEX,
1851         NULL, 0x0, "", HFILL}},
1852     { &hf_dplay_type_2e_string_1_len,
1853         { "DirectPlay message type 0x002e string 1 length", "dplay.type_2e.string_1.length", FT_UINT32,
1854         BASE_DEC, NULL, 0x0, "", HFILL}},
1855     { &hf_dplay_type_2e_string_2_len,
1856         { "DirectPlay message type 0x002e string 2 length", "dplay.type_2e.string_2.length", FT_UINT32,
1857         BASE_DEC, NULL, 0x0, "", HFILL}},
1858     { &hf_dplay_type_2e_unknown_2,
1859         { "DirectPlay message type 0x002e unknown 2", "dplay.type_2e.unknown_2", FT_BYTES, BASE_HEX,
1860         NULL, 0x0, "", HFILL}},
1861     { &hf_dplay_type_2e_dpid_3,
1862         { "DirectPlay message type 0x002e client DP ID", "dplay.type_2e.dpid_3", FT_BYTES, BASE_HEX,
1863         NULL, 0x0, "", HFILL}},
1864     { &hf_dplay_type_2e_unknown_3,
1865         { "DirectPlay message type 0x002e unknown 3", "dplay.type_2e.unknown_3", FT_BYTES, BASE_HEX,
1866         NULL, 0x0, "", HFILL}},
1867     { &hf_dplay_type_2e_string_1,
1868         { "DirectPlay message type 0x002e string 1", "dplay.type_2e.string_1", FT_STRING, BASE_NONE,
1869         NULL, 0x0, "", HFILL}},
1870     { &hf_dplay_type_2e_string_2,
1871         { "DirectPlay message type 0x002e string 2", "dplay.type_2e.string_2", FT_STRING, BASE_NONE,
1872         NULL, 0x0, "", HFILL}},
1873     { &hf_dplay_type_2e_saddr_af_1,
1874         { "DirectPlay message type 0x002e s_addr_in address family 1", "dplay.type_2e.saddr.af_1", FT_UINT16,
1875             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1876     { &hf_dplay_type_2e_saddr_port_1,
1877         { "DirectPlay message type 0x002e s_addr_in port 1", "dplay.type_2e.saddr.port_1", FT_UINT16, BASE_DEC,
1878         NULL, 0x0, "", HFILL}},
1879     { &hf_dplay_type_2e_saddr_ip_1,
1880         { "DirectPlay message type 0x002e s_addr_in ip 1", "dplay.type_2e.saddr.ip_1", FT_IPv4, BASE_NONE,
1881         NULL, 0x0, "", HFILL}},
1882     { &hf_dplay_type_2e_saddr_padd_1,
1883         { "DirectPlay message type 0x002e s_addr_in padding 1", "dplay.type_2e.saddr.padd_1", FT_BYTES, BASE_HEX,
1884         NULL, 0x0, "", HFILL}},
1885     { &hf_dplay_type_2e_saddr_af_2,
1886         { "DirectPlay message type 0x002e s_addr_in address family 2", "dplay.type_2e.saddr.af_2", FT_UINT16,
1887             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1888     { &hf_dplay_type_2e_saddr_port_2,
1889         { "DirectPlay message type 0x002e s_addr_in port 2", "dplay.type_2e.saddr.port_2", FT_UINT16, BASE_DEC,
1890         NULL, 0x0, "", HFILL}},
1891     { &hf_dplay_type_2e_saddr_ip_2,
1892         { "DirectPlay message type 0x002e s_addr_in ip 2", "dplay.type_2e.saddr.ip_2", FT_IPv4, BASE_NONE,
1893         NULL, 0x0, "", HFILL}},
1894     { &hf_dplay_type_2e_saddr_padd_2,
1895         { "DirectPlay message type 0x002e s_addr_in padding 2", "dplay.type_2e.saddr.padd_2", FT_BYTES, BASE_HEX,
1896         NULL, 0x0, "", HFILL}},
1897
1898     /* Data fields for message type 0x002f */
1899     { &hf_dplay_type_2f_dpid,
1900         { "DirectPlay message type 0x002f DP ID", "dplay.type_29.dpid", FT_BYTES, BASE_HEX,
1901         NULL, 0x0, "", HFILL}},
1902
1903     /* Data fields for message type 0x0038 */
1904     { &hf_dplay_type_38_padding_1,
1905         { "DirectPlay message type 0x0038 padding 1", "dplay.type_38.padding_1", FT_BYTES, BASE_HEX,
1906         NULL, 0x0, "", HFILL}},
1907     { &hf_dplay_type_38_dpid_1,
1908         { "DirectPlay message type 0x0038 client DP ID", "dplay.type_38.dpid_1", FT_BYTES, BASE_HEX,
1909         NULL, 0x0, "", HFILL}},
1910     { &hf_dplay_type_38_unknown_1,
1911         { "DirectPlay message type 0x0038 unknown 1", "dplay.type_38.unknown_1", FT_BYTES, BASE_HEX,
1912         NULL, 0x0, "", HFILL}},
1913     { &hf_dplay_type_38_dpid_2,
1914         { "DirectPlay message type 0x0038 client DP ID", "dplay.type_38.dpid_2", FT_BYTES, BASE_HEX,
1915         NULL, 0x0, "", HFILL}},
1916     { &hf_dplay_type_38_string_1_len,
1917         { "DirectPlay message type 0x0038 string 1 length", "dplay.type_38.string_1.length", FT_UINT32,
1918         BASE_DEC, NULL, 0x0, "", HFILL}},
1919     { &hf_dplay_type_38_string_2_len,
1920         { "DirectPlay message type 0x0038 string 2 length", "dplay.type_38.string_2.length", FT_UINT32,
1921         BASE_DEC, NULL, 0x0, "", HFILL}},
1922     { &hf_dplay_type_38_unknown_2,
1923         { "DirectPlay message type 0x0038 unknown 2", "dplay.type_38.unknown_2", FT_BYTES, BASE_HEX,
1924         NULL, 0x0, "", HFILL}},
1925     { &hf_dplay_type_38_dpid_3,
1926         { "DirectPlay message type 0x0038 client DP ID", "dplay.type_38.dpid_3", FT_BYTES, BASE_HEX,
1927         NULL, 0x0, "", HFILL}},
1928     { &hf_dplay_type_38_unknown_3,
1929         { "DirectPlay message type 0x0038 unknown 3", "dplay.type_38.unknown_3", FT_BYTES, BASE_HEX,
1930         NULL, 0x0, "", HFILL}},
1931     { &hf_dplay_type_38_string_1,
1932         { "DirectPlay message type 0x0038 string 1", "dplay.type_38.string_1", FT_STRING, BASE_NONE,
1933         NULL, 0x0, "", HFILL}},
1934     { &hf_dplay_type_38_string_2,
1935         { "DirectPlay message type 0x0038 string 2", "dplay.type_38.string_2", FT_STRING, BASE_NONE,
1936         NULL, 0x0, "", HFILL}},
1937     { &hf_dplay_type_38_saddr_af_1,
1938         { "DirectPlay message type 0x0038 s_addr_in address family 1", "dplay.type_38.saddr.af_1", FT_UINT16,
1939             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1940     { &hf_dplay_type_38_saddr_port_1,
1941         { "DirectPlay message type 0x0038 s_addr_in port 1", "dplay.type_38.saddr.port_1", FT_UINT16, BASE_DEC,
1942         NULL, 0x0, "", HFILL}},
1943     { &hf_dplay_type_38_saddr_ip_1,
1944         { "DirectPlay message type 0x0038 s_addr_in ip 1", "dplay.type_38.saddr.ip_1", FT_IPv4, BASE_NONE,
1945         NULL, 0x0, "", HFILL}},
1946     { &hf_dplay_type_38_saddr_padd_1,
1947         { "DirectPlay message type 0x0038 s_addr_in padding 1", "dplay.type_38.saddr.padd_1", FT_BYTES, BASE_HEX,
1948         NULL, 0x0, "", HFILL}},
1949     { &hf_dplay_type_38_saddr_af_2,
1950         { "DirectPlay message type 0x0038 s_addr_in address family 2", "dplay.type_38.saddr.af_2", FT_UINT16,
1951             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1952     { &hf_dplay_type_38_saddr_port_2,
1953         { "DirectPlay message type 0x0038 s_addr_in port 2", "dplay.type_38.saddr.port_2", FT_UINT16, BASE_DEC,
1954         NULL, 0x0, "", HFILL}},
1955     { &hf_dplay_type_38_saddr_ip_2,
1956         { "DirectPlay message type 0x0038 s_addr_in ip 2", "dplay.type_38.saddr.ip_2", FT_IPv4, BASE_NONE,
1957         NULL, 0x0, "", HFILL}},
1958     { &hf_dplay_type_38_saddr_padd_2,
1959         { "DirectPlay message type 0x0038 s_addr_in padding 2", "dplay.type_38.saddr.padd_2", FT_BYTES, BASE_HEX,
1960         NULL, 0x0, "", HFILL}},
1961     };
1962
1963     static gint *ett[] = {
1964         &ett_dplay,
1965         &ett_dplay_header,
1966         &ett_dplay_sockaddr,
1967         &ett_dplay_data,
1968         &ett_dplay_flags,
1969         &ett_dplay_enc_packet,
1970         &ett_dplay_sess_desc_flags,
1971         &ett_dplay_spp_flags,
1972         &ett_dplay_spp_info_mask,
1973         &ett_dplay_type02_flags,
1974         &ett_dplay_type05_flags,
1975         &ett_dplay_type08_saddr1,
1976         &ett_dplay_type08_saddr2,
1977         &ett_dplay_type13_saddr1,
1978         &ett_dplay_type13_saddr2,
1979         &ett_dplay_type29_spp,
1980         &ett_dplay_type2e_saddr1,
1981         &ett_dplay_type2e_saddr2,
1982         &ett_dplay_type38_saddr1,
1983         &ett_dplay_type38_saddr2,
1984     };
1985     module_t *dplay_module;
1986
1987     if(proto_dplay == -1)
1988     {
1989         proto_dplay = proto_register_protocol (
1990                 "DirectPlay Protocol",
1991                 "DPLAY",
1992                 "dplay"
1993                 );
1994         proto_register_field_array(proto_dplay, hf, array_length(hf));
1995         proto_register_subtree_array(ett, array_length(ett));
1996         dplay_module = prefs_register_protocol(proto_dplay, proto_reg_handoff_dplay);
1997     }
1998 }
1999
2000 void proto_reg_handoff_dplay(void)
2001 {
2002     static int initialized = FALSE;
2003
2004     if(!initialized)
2005     {
2006         initialized = TRUE;
2007         heur_dissector_add("udp", heur_dissect_dplay, proto_dplay);
2008         heur_dissector_add("tcp", heur_dissect_dplay, proto_dplay);
2009         dplay_handle = create_dissector_handle(dissect_dplay, proto_dplay);
2010     }
2011 }
2012