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 static int hf_dplay_data_type_29 = -1;
109
110 /* Session description structure fields */
111 static int hf_dplay_sess_desc_length = -1;
112 static int hf_dplay_game_guid = -1;
113 static int hf_dplay_instance_guid = -1;
114 static int hf_dplay_max_players = -1;
115 static int hf_dplay_curr_players = -1;
116 static int hf_dplay_sess_name_ptr = -1;
117 static int hf_dplay_passwd_ptr = -1;
118 static int hf_dplay_sess_desc_reserved_1 = -1;
119 static int hf_dplay_sess_desc_reserved_2 = -1;
120 static int hf_dplay_sess_desc_user_1 = -1;
121 static int hf_dplay_sess_desc_user_2 = -1;
122 static int hf_dplay_sess_desc_user_3 = -1;
123 static int hf_dplay_sess_desc_user_4 = -1;
124
125 /* Message Type 0x0001 data fields */
126 static int hf_dplay_type_01_name_offset = -1;
127 static int hf_dplay_type_01_game_name = -1;
128
129 /* Message Type 0x0002 data fields */
130 static int hf_dplay_type_02_game_guid = -1;
131 static int hf_dplay_type_02_ignored = -1;
132
133 /* Message Type 0x0005 data fields */
134 static int hf_dplay_type_05_request = -1;
135
136 /* Message Type 0x0007 data fields */
137 static int hf_dplay_type_07_dpid = -1;
138 static int hf_dplay_type_07_padding = -1;
139
140 /* Message Type 0x0008 data fields */
141 static int hf_dplay_type_08_padding_1 = -1;     /* 4 bytes */
142 static int hf_dplay_type_08_dpid_1 = -1;        /* 4 bytes */
143 static int hf_dplay_type_08_unknown_1 = -1;     /*20 bytes */
144 static int hf_dplay_type_08_dpid_2 = -1;        /* 4 bytes */
145 static int hf_dplay_type_08_string_1_len = -1;
146 static int hf_dplay_type_08_string_2_len = -1;
147 static int hf_dplay_type_08_unknown_2 = -1;     /*20 bytes */
148 static int hf_dplay_type_08_dpid_3 = -1;        /* 4 bytes */
149 static int hf_dplay_type_08_unknown_3 = -1;     /*12 bytes */
150 static int hf_dplay_type_08_string_1 = -1;
151 static int hf_dplay_type_08_string_2 = -1;
152 static int hf_dplay_type_08_saddr_af_1 = -1;    /* 2 bytes */
153 static int hf_dplay_type_08_saddr_port_1 = -1;  /* 2 bytes */
154 static int hf_dplay_type_08_saddr_ip_1 = -1;    /* 4 bytes */
155 static int hf_dplay_type_08_saddr_padd_1 = -1;  /* 8 bytes */
156 static int hf_dplay_type_08_saddr_af_2 = -1;    /* 2 bytes */
157 static int hf_dplay_type_08_saddr_port_2 = -1;  /* 2 bytes */
158 static int hf_dplay_type_08_saddr_ip_2 = -1;    /* 4 bytes */
159 static int hf_dplay_type_08_saddr_padd_2 = -1;  /* 8 bytes */
160 static int hf_dplay_type_08_padding_2 = -1;     /* 2 bytes */
161
162 /* Message Type 0x000b data fields */
163 static int hf_dplay_type_0b_padding_1 = -1;
164 static int hf_dplay_type_0b_dpid = -1;
165 static int hf_dplay_type_0b_padding_2 = -1;
166
167 /* Message Type 0x000d data fields */
168 static int hf_dplay_type_0d_padding_1 = -1;     /* 4 bytes */
169 static int hf_dplay_type_0d_dpid_1 = -1;        /* 4 bytes */
170 static int hf_dplay_type_0d_dpid_2 = -1;        /* 4 bytes */
171 static int hf_dplay_type_0d_padding_2 = -1;     /* 8 bytes */
172
173 /* Message Type 0x000e data fields */
174 static int hf_dplay_type_0e_padding_1 = -1;     /* 4 bytes */
175 static int hf_dplay_type_0e_dpid_1 = -1;        /* 4 bytes */
176 static int hf_dplay_type_0e_dpid_2 = -1;        /* 4 bytes */
177 static int hf_dplay_type_0e_padding_2 = -1;     /* 8 bytes */
178
179
180 /* Message Type 0x0013 data fields */
181 static int hf_dplay_type_13_padding_1 = -1;     /* 4 bytes */
182 static int hf_dplay_type_13_dpid_1 = -1;        /* 4 bytes */
183 static int hf_dplay_type_13_unknown_1 = -1;     /*20 bytes */
184 static int hf_dplay_type_13_dpid_2 = -1;        /* 4 bytes */
185 static int hf_dplay_type_13_unknown_2 = -1;     /*20 bytes */
186 static int hf_dplay_type_13_dpid_3 = -1;        /* 4 bytes */
187 static int hf_dplay_type_13_unknown_3 = -1;     /*12 bytes */
188 static int hf_dplay_type_13_saddr_af_1 = -1;    /* 2 bytes */
189 static int hf_dplay_type_13_saddr_port_1 = -1;  /* 2 bytes */
190 static int hf_dplay_type_13_saddr_ip_1 = -1;    /* 4 bytes */
191 static int hf_dplay_type_13_saddr_padd_1 = -1;  /* 8 bytes */
192 static int hf_dplay_type_13_saddr_af_2 = -1;    /* 2 bytes */
193 static int hf_dplay_type_13_saddr_port_2 = -1;  /* 2 bytes */
194 static int hf_dplay_type_13_saddr_ip_2 = -1;    /* 4 bytes */
195 static int hf_dplay_type_13_saddr_padd_2 = -1;  /* 8 bytes */
196 static int hf_dplay_type_13_padding_2 = -1;     /* 2 bytes */
197 static int hf_dplay_type_13_dpid_4 = -1;        /* 4 bytes */
198
199 /* Message Type 0x0015 data fields */
200 static int hf_dplay_container_guid = -1;
201 static int hf_dplay_type_15_padding_1 = -1;
202 static int hf_dplay_type_15_size_1 = -1;
203 static int hf_dplay_type_15_padding_2 = -1;
204 static int hf_dplay_type_15_unknown_1 = -1;
205 static int hf_dplay_type_15_size_2 = -1;
206 static int hf_dplay_type_15_padding_3 = -1;
207
208 /* Message Type 0x0016 data field */
209 static int hf_dplay_type_16_data = -1;
210
211 /* Message Type 0x0017 data field */
212 static int hf_dplay_type_17_data = -1;
213
214 /* Message Type 0x0029 data fields */
215 static int hf_dplay_type_29_unknown_uint32_01 = -1; /* seems to always be 3 */
216 static int hf_dplay_type_29_message_end_type = -1;  /* mostly 0, alternative packet ending on 1 */
217 static int hf_dplay_type_29_unknown_uint32_03 = -1;
218 static int hf_dplay_type_29_unknown_uint32_04 = -1;
219 static int hf_dplay_type_29_unknown_uint32_05 = -1;
220 static int hf_dplay_type_29_unknown_uint32_06 = -1;
221 static int hf_dplay_type_29_unknown_uint32_07 = -1;
222 static int hf_dplay_type_29_unknown_uint32_08 = -1;
223 static int hf_dplay_type_29_magic_16_bytes = -1;
224 static int hf_dplay_type_29_dpid_1 = -1;
225 static int hf_dplay_type_29_unknown_3 = -1;
226 static int hf_dplay_type_29_game_name = -1;
227 static int hf_dplay_type_29_unknown_uint32_10 = -1;
228 static int hf_dplay_type_29_unknown_uint32_11 = -1;
229 static int hf_dplay_type_29_dpid_2 = -1;
230 static int hf_dplay_type_29_unknown_uint32_12 = -1;
231 static int hf_dplay_type_29_unknown_uint32_13 = -1;
232 static int hf_dplay_type_29_saddr_field_len_1 = -1;
233 static int hf_dplay_type_29_saddr_af_1 = -1;
234 static int hf_dplay_type_29_saddr_port_1 = -1;
235 static int hf_dplay_type_29_saddr_ip_1 = -1;
236 static int hf_dplay_type_29_saddr_padd_1 = -1;
237 static int hf_dplay_type_29_saddr_af_2 = -1;
238 static int hf_dplay_type_29_saddr_port_2 = -1;
239 static int hf_dplay_type_29_saddr_ip_2 = -1;
240 static int hf_dplay_type_29_saddr_padd_2 = -1;
241 static int hf_dplay_type_29_unknown_uint32_14 = -1;
242 static int hf_dplay_type_29_unknown_uint32_15 = -1;
243 static int hf_dplay_type_29_dpid_3 = -1;
244 static int hf_dplay_type_29_unknown_uint32_16 = -1;
245 static int hf_dplay_type_29_unknown_uint32_17 = -1;
246 static int hf_dplay_type_29_saddr_field_len_2 = -1;
247 static int hf_dplay_type_29_saddr_af_3 = -1;
248 static int hf_dplay_type_29_saddr_port_3 = -1;
249 static int hf_dplay_type_29_saddr_ip_3 = -1;
250 static int hf_dplay_type_29_saddr_padd_3 = -1;
251 static int hf_dplay_type_29_saddr_af_4 = -1;
252 static int hf_dplay_type_29_saddr_port_4 = -1;
253 static int hf_dplay_type_29_saddr_ip_4 = -1;
254 static int hf_dplay_type_29_saddr_padd_4 = -1;
255 static int hf_dplay_type_29_unknown_uint32_18 = -1;
256 static int hf_dplay_type_29_unknown_uint32_19= -1;
257 static int hf_dplay_type_29_dpid_4 = -1;
258 static int hf_dplay_type_29_unknown_uint32_20 = -1;
259 static int hf_dplay_type_29_dpid_5 = -1;
260
261 /* Message Type 0x002e data fields */
262 static int hf_dplay_type_2e_padding_1 = -1;
263 static int hf_dplay_type_2e_dpid_1 = -1;
264 static int hf_dplay_type_2e_unknown_1 = -1;
265 static int hf_dplay_type_2e_dpid_2 = -1;
266 static int hf_dplay_type_2e_string_1_len = -1;
267 static int hf_dplay_type_2e_string_2_len = -1;
268 static int hf_dplay_type_2e_unknown_2 = -1;
269 static int hf_dplay_type_2e_dpid_3 = -1;
270 static int hf_dplay_type_2e_unknown_3 = -1;
271 static int hf_dplay_type_2e_string_1 = -1;
272 static int hf_dplay_type_2e_string_2 = -1;
273 static int hf_dplay_type_2e_saddr_af_1 = -1;
274 static int hf_dplay_type_2e_saddr_port_1 = -1;
275 static int hf_dplay_type_2e_saddr_ip_1 = -1;
276 static int hf_dplay_type_2e_saddr_padd_1 = -1;
277 static int hf_dplay_type_2e_saddr_af_2 = -1;
278 static int hf_dplay_type_2e_saddr_port_2 = -1;
279 static int hf_dplay_type_2e_saddr_ip_2 = -1;
280 static int hf_dplay_type_2e_saddr_padd_2 = -1;
281
282 /* Message Type 0x002f data fields */
283 static int hf_dplay_type_2f_dpid = -1;
284
285 /* Message Type 0x0038 data fields */
286 static int hf_dplay_type_38_padding_1 = -1;     /* 4 bytes */
287 static int hf_dplay_type_38_dpid_1 = -1;        /* 4 bytes */
288 static int hf_dplay_type_38_unknown_1 = -1;     /*20 bytes */
289 static int hf_dplay_type_38_dpid_2 = -1;        /* 4 bytes */
290 static int hf_dplay_type_38_string_1_len = -1;
291 static int hf_dplay_type_38_string_2_len = -1;
292 static int hf_dplay_type_38_unknown_2 = -1;     /*20 bytes */
293 static int hf_dplay_type_38_dpid_3 = -1;        /* 4 bytes */
294 static int hf_dplay_type_38_unknown_3 = -1;     /*12 bytes */
295 static int hf_dplay_type_38_string_1 = -1;
296 static int hf_dplay_type_38_string_2 = -1;
297 static int hf_dplay_type_38_saddr_af_1 = -1;    /* 2 bytes */
298 static int hf_dplay_type_38_saddr_port_1 = -1;  /* 2 bytes */
299 static int hf_dplay_type_38_saddr_ip_1 = -1;    /* 4 bytes */
300 static int hf_dplay_type_38_saddr_padd_1 = -1;  /* 8 bytes */
301 static int hf_dplay_type_38_saddr_af_2 = -1;    /* 2 bytes */
302 static int hf_dplay_type_38_saddr_port_2 = -1;  /* 2 bytes */
303 static int hf_dplay_type_38_saddr_ip_2 = -1;    /* 4 bytes */
304 static int hf_dplay_type_38_saddr_padd_2 = -1;  /* 8 bytes */
305
306 /* various */
307 static gint ett_dplay = -1;
308 static gint ett_dplay_header = -1;
309 static gint ett_dplay_sockaddr = -1;
310 static gint ett_dplay_data = -1;
311 static gint ett_dplay_enc_packet = -1;
312 static gint ett_dplay_flags = -1;
313 static gint ett_dplay_sess_desc_flags = -1;
314 static gint ett_dplay_type08_saddr1 = -1;
315 static gint ett_dplay_type08_saddr2 = -1;
316 static gint ett_dplay_type13_saddr1 = -1;
317 static gint ett_dplay_type13_saddr2 = -1;
318 static gint ett_dplay_type29_saddr1 = -1;
319 static gint ett_dplay_type29_saddr2 = -1;
320 static gint ett_dplay_type29_saddr3 = -1;
321 static gint ett_dplay_type29_saddr4 = -1;
322 static gint ett_dplay_type2e_saddr1 = -1;
323 static gint ett_dplay_type2e_saddr2 = -1;
324 static gint ett_dplay_type38_saddr1 = -1;
325 static gint ett_dplay_type38_saddr2 = -1;
326
327 static const value_string dplay_command_val[] = {
328     { 0x0001, "Enum Sessions Reply" },
329     { 0x0002, "Enum Sessions" },
330     { 0x0003, "Enum Players Reply" },
331     { 0x0004, "Enum Players" },
332     { 0x0005, "Request Player ID" },
333     { 0x0006, "Request Group ID" },
334     { 0x0007, "Request Player Reply" },
335     { 0x0008, "Create Player" },
336     { 0x0009, "Create Group" },
337     { 0x000a, "Player Message" },
338     { 0x000b, "Delete Player" },
339     { 0x000c, "Delete Group" },
340     { 0x000d, "Add Player To Group" },
341     { 0x000e, "Delete Player From Group" },
342     { 0x000f, "Player Data Changed" },
343     { 0x0010, "Player Name Changed" },
344     { 0x0011, "Group Data Changed" },
345     { 0x0012, "Group Name Changed" },
346     { 0x0013, "Add Forward Request" },
347     /* There is no command 0x0014 */
348     { 0x0015, "Packet" },
349     { 0x0016, "Ping" },
350     { 0x0017, "Pong" },
351     { 0x0018, "You Are Dead" },
352     { 0x0019, "Player Wrapper" },
353     { 0x001a, "Session Desc Changed" },
354     { 0x001c, "Challenge" },
355     { 0x001d, "Access Granted" },
356     { 0x001e, "Logon Denied" },
357     { 0x001f, "Auth Error" },
358     { 0x0020, "Negotiate" },
359     { 0x0021, "Challenge Response" },
360     { 0x0022, "Signed"},
361     /* There is no command 0x0023 */
362     { 0x0024, "Add Forward Reply" },
363     { 0x0025, "Ask For Multicast" },
364     { 0x0026, "Ask For Multicast Guaranteed" },
365     { 0x0027, "Add Shortcut To Group" },
366     { 0x0028, "Delete Group From Group" },
367     { 0x0029, "Super Enum Players Reply" },
368     /* There is no command 0x002a */
369     { 0x002b, "Key Exchange" },
370     { 0x002c, "Key Exchange Reply" },
371     { 0x002d, "Chat" },
372     { 0x002e, "Add Forward" },
373     { 0x002f, "Add Forward ACK" },
374     { 0x0030, "Packet2 Data" },
375     { 0x0031, "Packet2 ACK" },
376     /* No commands 0x0032, 0x0033, 0x0034 */
377     { 0x0035, "I Am Nameserver" },
378     { 0x0036, "Voice" },
379     { 0x0037, "Multicast Delivery" },
380     { 0x0038, "Create Players Verify"},
381     { 0     , NULL },
382 };
383
384 static const value_string dplay_af_val[] = {
385     { 0x0002, "AF_INET" },
386     { 0x0006, "AF_IPX" },
387     { 0     , NULL},
388 };
389
390 static const value_string dplay_proto_dialect_val[] = {
391     { 0x0009, "dplay 6" },
392     { 0x000a, "dplay 6.1" },
393     { 0x000b, "dplay 6.1a" },
394     { 0x000c, "dplay 7.1" },
395     { 0x000d, "dplay 8" },
396     { 0x000e, "dplay 9"},
397     { 0     , NULL},
398 };
399
400 static const value_string dplay_token_val[] = {
401     { 0xfab, "Remote Message" },
402     { 0xcab, "Forwarded Message" },
403     { 0xbab, "Server Message" },
404 };
405
406 static const value_string dplay_type05_request[] = {
407     { 0x00000008, "eight"},
408     { 0x00000009, "nine"},
409     { 0         , NULL},
410 };
411
412 static const value_string dplay_type29_end_type[] = {
413     { 0x00000000, "sockaddr"},
414     { 0x00000001, "DPID"},
415     { 0         , NULL},
416 };
417
418 static const true_false_string tfs_dplay_flag = {
419     "present",
420     "absent"
421 };
422
423 /* borrowed from epan/dissectors/packets-smb-common.c */
424 static gint display_unicode_string(proto_tree *tree, gint hf_index, tvbuff_t *tvb, gint offset)
425 {
426     char *str, *p;
427     gint len;
428     gint charoffset;
429     guint16 character;
430
431     /* display a unicode string from the tree and return new offset */
432
433     /*
434      * Get the length of the string.
435      * XXX - is it a bug or a feature that this will throw an exception
436      * if we don't find the '\0'?  I think it's a feature.
437      */
438     len = 0;
439     while ((character = tvb_get_letohs(tvb, offset + len)) != '\0')
440         len += 2;
441     len += 2;   /* count the '\0' too */
442
443     /*
444      * Allocate a buffer for the string; "len" is the length in
445      * bytes, not the length in characters.
446      */
447     str = ep_alloc(len/2);
448
449     /*
450      * XXX - this assumes the string is just ISO 8859-1; we need
451      * to better handle multiple character sets in Wireshark,
452      * including Unicode/ISO 10646, and multiple encodings of
453      * that character set (UCS-2, UTF-8, etc.).
454      */
455     charoffset = offset;
456     p = str;
457     while ((character = tvb_get_letohs(tvb, charoffset)) != '\0') {
458         *p++ = (char) character;
459         charoffset += 2;
460     }
461     *p = '\0';
462
463     proto_tree_add_string(tree, hf_index, tvb, offset, len, str);
464
465     return  offset+len;
466 }
467
468 static gint dissect_sockaddr_in(proto_tree *tree, tvbuff_t *tvb, gint offset)
469 {
470     proto_item *sa_item = NULL;
471     proto_tree *sa_tree = NULL;
472
473     sa_item = proto_tree_add_text(tree, tvb, offset, 16,
474             "DirectPlay sockaddr_in structure");
475     sa_tree = proto_item_add_subtree(sa_item, ett_dplay_sockaddr);
476     proto_tree_add_item(sa_tree, hf_dplay_saddr_af, tvb, offset, 2, TRUE); offset += 2;
477     proto_tree_add_item(sa_tree, hf_dplay_saddr_port, tvb, offset, 2, FALSE); offset += 2;
478     proto_tree_add_item(sa_tree, hf_dplay_saddr_ip, tvb, offset, 4, FALSE); offset += 4;
479     proto_tree_add_item(sa_tree, hf_dplay_saddr_padding, tvb, offset, 8, FALSE); offset += 8;
480     return offset;
481 }
482
483 static gint dissect_session_desc(proto_tree *tree, tvbuff_t *tvb, gint offset)
484 {
485     gint data_len;
486     guint32 flags;
487     proto_item *flags_item = NULL;
488     proto_tree *flags_tree = NULL;
489
490     data_len = tvb_get_letohl(tvb, offset);
491     flags = tvb_get_letohl(tvb, offset+4);
492
493     proto_tree_add_item(tree, hf_dplay_sess_desc_length, tvb, offset, 4, TRUE); offset += 4;
494     flags_item = proto_tree_add_item(tree, hf_dplay_sess_desc_flags, tvb, offset, 4, TRUE);
495     flags_tree = proto_item_add_subtree(flags_item, ett_dplay_sess_desc_flags);
496     proto_tree_add_boolean(flags_tree, hf_dplay_flags_no_sess_desc_changes, tvb, offset, 4, flags);
497     proto_tree_add_boolean(flags_tree, hf_dplay_flags_acqire_voice, tvb, offset, 4, flags);
498     proto_tree_add_boolean(flags_tree, hf_dplay_flags_optimize_latency, tvb, offset, 4, flags);
499     proto_tree_add_boolean(flags_tree, hf_dplay_flags_preserve_order, tvb, offset, 4, flags);
500     proto_tree_add_boolean(flags_tree, hf_dplay_flags_reliable, tvb, offset, 4, flags);
501     proto_tree_add_boolean(flags_tree, hf_dplay_flags_server_player_only, tvb, offset, 4, flags);
502     proto_tree_add_boolean(flags_tree, hf_dplay_flags_route, tvb, offset, 4, flags);
503     proto_tree_add_boolean(flags_tree, hf_dplay_flags_password_req, tvb, offset, 4, flags);
504     proto_tree_add_boolean(flags_tree, hf_dplay_flags_private_session, tvb, offset, 4, flags);
505     proto_tree_add_boolean(flags_tree, hf_dplay_flags_use_auth, tvb, offset, 4, flags);
506     proto_tree_add_boolean(flags_tree, hf_dplay_flags_no_player_updates, tvb, offset, 4, flags);
507     proto_tree_add_boolean(flags_tree, hf_dplay_flags_use_ping, tvb, offset, 4, flags);
508     proto_tree_add_boolean(flags_tree, hf_dplay_flags_can_join, tvb, offset, 4, flags);
509     proto_tree_add_boolean(flags_tree, hf_dplay_flags_ignored, tvb, offset, 4, flags);
510     proto_tree_add_boolean(flags_tree, hf_dplay_flags_short_player_msg, tvb, offset, 4, flags);
511     proto_tree_add_boolean(flags_tree, hf_dplay_flags_migrate_host, tvb, offset, 4, flags);
512     proto_tree_add_boolean(flags_tree, hf_dplay_flags_0002, tvb, offset, 4, flags);
513     proto_tree_add_boolean(flags_tree, hf_dplay_flags_no_create_players, tvb, offset, 4, flags);
514     offset += 4;
515
516     proto_tree_add_item(tree, hf_dplay_instance_guid, tvb, offset, 16, FALSE); offset += 16;
517     proto_tree_add_item(tree, hf_dplay_game_guid, tvb, offset, 16, FALSE); offset += 16;
518     proto_tree_add_item(tree, hf_dplay_max_players, tvb, offset, 4, TRUE); offset += 4;
519     proto_tree_add_item(tree, hf_dplay_curr_players, tvb, offset, 4, TRUE); offset += 4;
520     proto_tree_add_item(tree, hf_dplay_sess_name_ptr, tvb, offset, 4, FALSE); offset += 4;
521     proto_tree_add_item(tree, hf_dplay_passwd_ptr, tvb, offset, 4, FALSE); offset += 4;
522     proto_tree_add_item(tree, hf_dplay_sess_desc_reserved_1, tvb, offset, 4, FALSE); offset += 4;
523     proto_tree_add_item(tree, hf_dplay_sess_desc_reserved_2, tvb, offset, 4, FALSE); offset += 4;
524     proto_tree_add_item(tree, hf_dplay_sess_desc_user_1, tvb, offset, 4, FALSE); offset += 4;
525     proto_tree_add_item(tree, hf_dplay_sess_desc_user_2, tvb, offset, 4, FALSE); offset += 4;
526     proto_tree_add_item(tree, hf_dplay_sess_desc_user_3, tvb, offset, 4, FALSE); offset += 4;
527     proto_tree_add_item(tree, hf_dplay_sess_desc_user_4, tvb, offset, 4, FALSE); offset += 4;
528
529     return offset;
530 }
531
532 static gint dissect_dplay_header(proto_tree *tree, tvbuff_t *tvb, gint offset)
533 {
534     guint32 mixed, size, token;
535
536     mixed = tvb_get_letohl(tvb, offset);
537     size = mixed & 0x000FFFFF;
538     token = (mixed & 0xFFF00000) >> 20;
539
540     proto_tree_add_uint(tree, hf_dplay_size, tvb, offset, 4, size);
541     proto_tree_add_uint(tree, hf_dplay_token, tvb, offset, 4, token);
542     offset += 4;
543     offset = dissect_sockaddr_in(tree, tvb, offset);
544     proto_tree_add_item(tree, hf_dplay_play_str, tvb, offset, 4, TRUE); offset += 4;
545     proto_tree_add_item(tree, hf_dplay_command, tvb, offset, 2, TRUE); offset += 2;
546     proto_tree_add_item(tree, hf_dplay_proto_dialect, tvb, offset, 2, TRUE); offset += 2;
547     return offset;
548 }
549
550 static gint dissect_type01_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
551 {
552     guint32 name_offset;
553
554     offset = dissect_session_desc(tree, tvb, offset);
555     name_offset = tvb_get_letohl(tvb, offset);
556     proto_tree_add_item(tree, hf_dplay_type_01_name_offset, tvb, offset, 4, TRUE); offset += 4;
557
558     if (name_offset != 0) {
559         offset = display_unicode_string(tree, hf_dplay_type_01_game_name, tvb, offset);
560     }
561     return offset;
562 }
563
564 static gint dissect_type02_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
565 {
566     proto_tree_add_item(tree, hf_dplay_type_02_game_guid, tvb, offset, 16, FALSE); offset += 16;
567     proto_tree_add_item(tree, hf_dplay_type_02_ignored, tvb, offset, 8, FALSE);
568     return offset;
569 }
570
571 static gint dissect_type05_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
572 {
573     proto_tree_add_item(tree, hf_dplay_type_05_request, tvb, offset, 4, TRUE); offset += 4;
574     return offset;
575 }
576
577 static gint dissect_type07_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
578 {
579     proto_tree_add_item(tree, hf_dplay_type_07_dpid, tvb, offset, 4, FALSE); offset += 4;
580     proto_tree_add_item(tree, hf_dplay_type_07_padding, tvb, offset, 36, FALSE); offset += 36;
581     return offset;
582 }
583
584 static gint dissect_type08_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
585 {
586     proto_item *first_saddr_item = NULL, *second_saddr_item = NULL;
587     proto_tree *first_saddr_tree = NULL, *second_saddr_tree = NULL;
588     gint string_1_len, string_2_len;
589
590     proto_tree_add_item(tree, hf_dplay_type_08_padding_1, tvb, offset, 4, FALSE); offset += 4;
591     proto_tree_add_item(tree, hf_dplay_type_08_dpid_1, tvb, offset, 4, FALSE); offset += 4;
592     proto_tree_add_item(tree, hf_dplay_type_08_unknown_1, tvb, offset, 20, FALSE); offset += 20;
593     proto_tree_add_item(tree, hf_dplay_type_08_dpid_2, tvb, offset, 4, FALSE); offset += 4;
594     string_1_len = tvb_get_letohl(tvb, offset);
595     proto_tree_add_item(tree, hf_dplay_type_08_string_1_len, tvb, offset, 4, TRUE); offset += 4;
596     string_2_len = tvb_get_letohl(tvb, offset);
597     proto_tree_add_item(tree, hf_dplay_type_08_string_2_len, tvb, offset, 4, TRUE); offset += 4;
598     proto_tree_add_item(tree, hf_dplay_type_08_unknown_2, tvb, offset, 12, FALSE); offset += 12;
599     proto_tree_add_item(tree, hf_dplay_type_08_dpid_3, tvb, offset, 4, FALSE); offset += 4;
600     proto_tree_add_item(tree, hf_dplay_type_08_unknown_3, tvb, offset, 12, FALSE); offset += 12;
601
602     if(string_1_len > 0)
603         offset = display_unicode_string(tree, hf_dplay_type_08_string_1, tvb, offset);
604     if(string_2_len > 0)
605         offset = display_unicode_string(tree, hf_dplay_type_08_string_2, tvb, offset);
606
607     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
608             "DirectPlay message type 0x0008 s_addr_in structure 1");
609     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type08_saddr1);
610
611     proto_tree_add_item(first_saddr_tree, hf_dplay_type_08_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
612     proto_tree_add_item(first_saddr_tree, hf_dplay_type_08_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
613     proto_tree_add_item(first_saddr_tree, hf_dplay_type_08_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
614     proto_tree_add_item(first_saddr_tree, hf_dplay_type_08_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
615
616     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
617             "DirectPlay message type 0x0008 s_addr_in structure 2");
618     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type08_saddr2);
619
620     proto_tree_add_item(second_saddr_tree, hf_dplay_type_08_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
621     proto_tree_add_item(second_saddr_tree, hf_dplay_type_08_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
622     proto_tree_add_item(second_saddr_tree, hf_dplay_type_08_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
623     proto_tree_add_item(second_saddr_tree, hf_dplay_type_08_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
624
625     proto_tree_add_item(tree, hf_dplay_type_08_padding_2, tvb, offset, 6, FALSE); offset += 6;
626
627     return offset;
628 }
629
630 static gint dissect_type0b_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
631 {
632     proto_tree_add_item(tree, hf_dplay_type_0b_padding_1, tvb, offset, 4, FALSE); offset += 4;
633     proto_tree_add_item(tree, hf_dplay_type_0b_dpid, tvb, offset, 4, FALSE); offset += 4;
634     proto_tree_add_item(tree, hf_dplay_type_0b_padding_2, tvb, offset, 12, FALSE); offset += 12;
635     return offset;
636 }
637
638 static gint dissect_type0d_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
639 {
640     proto_tree_add_item(tree, hf_dplay_type_0d_padding_1, tvb, offset, 4, FALSE); offset += 4;
641     proto_tree_add_item(tree, hf_dplay_type_0d_dpid_1, tvb, offset, 4, FALSE); offset += 4;
642     proto_tree_add_item(tree, hf_dplay_type_0d_dpid_2, tvb, offset, 4, FALSE); offset += 4;
643     proto_tree_add_item(tree, hf_dplay_type_0d_padding_2, tvb, offset, 8, FALSE); offset += 8;
644     return offset;
645 }
646
647 static gint dissect_type0e_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
648 {
649     proto_tree_add_item(tree, hf_dplay_type_0e_padding_1, tvb, offset, 4, FALSE); offset += 4;
650     proto_tree_add_item(tree, hf_dplay_type_0e_dpid_1, tvb, offset, 4, FALSE); offset += 4;
651     proto_tree_add_item(tree, hf_dplay_type_0e_dpid_2, tvb, offset, 4, FALSE); offset += 4;
652     proto_tree_add_item(tree, hf_dplay_type_0e_padding_2, tvb, offset, 8, FALSE); offset += 8;
653     return offset;
654 }
655
656 static gint dissect_type0f_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
657 {
658     proto_tree_add_item(tree, hf_dplay_data_type_0f, tvb, offset, -1, FALSE);
659     return offset;
660 }
661
662 static gint dissect_type13_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
663 {
664     proto_item *first_saddr_item = NULL, *second_saddr_item = NULL;
665     proto_tree *first_saddr_tree = NULL, *second_saddr_tree = NULL;
666
667     proto_tree_add_item(tree, hf_dplay_type_13_padding_1, tvb, offset, 4, FALSE); offset += 4;
668     proto_tree_add_item(tree, hf_dplay_type_13_dpid_1, tvb, offset, 4, FALSE); offset += 4;
669     proto_tree_add_item(tree, hf_dplay_type_13_unknown_1, tvb, offset, 20, FALSE); offset += 20;
670     proto_tree_add_item(tree, hf_dplay_type_13_dpid_2, tvb, offset, 4, FALSE); offset += 4;
671     proto_tree_add_item(tree, hf_dplay_type_13_unknown_2, tvb, offset, 20, FALSE); offset += 20;
672     proto_tree_add_item(tree, hf_dplay_type_13_dpid_3, tvb, offset, 4, FALSE); offset += 4;
673     proto_tree_add_item(tree, hf_dplay_type_13_unknown_3, tvb, offset, 12, FALSE); offset += 12;
674
675     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
676             "DirectPlay message type 0x0013 s_addr_in structure 1");
677     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type13_saddr1);
678
679     proto_tree_add_item(first_saddr_tree, hf_dplay_type_13_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
680     proto_tree_add_item(first_saddr_tree, hf_dplay_type_13_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
681     proto_tree_add_item(first_saddr_tree, hf_dplay_type_13_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
682     proto_tree_add_item(first_saddr_tree, hf_dplay_type_13_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
683
684     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
685             "DirectPlay message type 0x0013 s_addr_in structure 2");
686     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type13_saddr2);
687
688     proto_tree_add_item(second_saddr_tree, hf_dplay_type_13_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
689     proto_tree_add_item(second_saddr_tree, hf_dplay_type_13_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
690     proto_tree_add_item(second_saddr_tree, hf_dplay_type_13_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
691     proto_tree_add_item(second_saddr_tree, hf_dplay_type_13_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
692
693     proto_tree_add_item(tree, hf_dplay_type_13_padding_2, tvb, offset, 2, FALSE); offset += 2;
694     proto_tree_add_item(tree, hf_dplay_type_13_dpid_4, tvb, offset, 4, FALSE); offset += 4;
695
696     return offset;
697 }
698
699 static gint dissect_type15_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
700 {
701     guint16 second_message_type;
702     proto_item *enc_item = NULL;
703     proto_tree *enc_tree = NULL;
704     second_message_type = tvb_get_letohs(tvb, 72);
705
706     proto_tree_add_item(tree, hf_dplay_container_guid, tvb, offset, 16, FALSE); offset += 16;
707     proto_tree_add_item(tree, hf_dplay_type_15_padding_1, tvb, offset, 4, FALSE); offset += 4;
708     proto_tree_add_item(tree, hf_dplay_type_15_size_1, tvb, offset, 4, TRUE); offset += 4;
709     proto_tree_add_item(tree, hf_dplay_type_15_padding_2, tvb, offset, 4, FALSE); offset += 4;
710     proto_tree_add_item(tree, hf_dplay_type_15_unknown_1, tvb, offset, 4, TRUE); offset += 4;
711     proto_tree_add_item(tree, hf_dplay_type_15_size_2, tvb, offset, 4, TRUE); offset += 4;
712     proto_tree_add_item(tree, hf_dplay_type_15_padding_3, tvb, offset, 4, FALSE); offset += 4;
713
714     enc_item = proto_tree_add_text(tree, tvb, offset, -1, "DirectPlay encapsulated packet");
715     enc_tree = proto_item_add_subtree(enc_item, ett_dplay_enc_packet);
716
717     proto_tree_add_item(enc_tree, hf_dplay_play_str_2, tvb, offset, 4, FALSE); offset += 4;
718     proto_tree_add_item(enc_tree, hf_dplay_command_2, tvb, offset, 2, TRUE); offset += 2;
719     proto_tree_add_item(enc_tree, hf_dplay_proto_dialect_2, tvb, offset, 2, TRUE); offset += 2;
720
721     switch(second_message_type)
722     {
723         case 0x0005:
724             offset = dissect_type05_message(enc_tree, tvb, offset);
725             break;
726         case 0x0007:
727             offset = dissect_type05_message(enc_tree, tvb, offset);
728             break;
729         case 0x0008:
730             offset = dissect_type08_message(enc_tree, tvb, offset);
731             break;
732         case 0x000b:
733             offset = dissect_type0b_message(enc_tree, tvb, offset);
734             break;
735         case 0x0013:
736             offset = dissect_type13_message(enc_tree, tvb, offset);
737             break;
738         case 0x001a:
739             offset = dissect_type1a_message(enc_tree, tvb, offset);
740             break;
741         case 0x002e:
742             offset = dissect_type2e_message(enc_tree, tvb, offset);
743             break;
744     }
745
746     return offset;
747 }
748
749 static gint dissect_type16_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
750 {
751     proto_tree_add_item(tree, hf_dplay_type_16_data, tvb, offset, -1, FALSE);
752     return offset;
753 }
754
755 static gint dissect_type17_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
756 {
757     proto_tree_add_item(tree, hf_dplay_type_17_data, tvb, offset, -1, FALSE);
758     return offset;
759 }
760
761 static gint dissect_type1a_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
762 {
763     proto_tree_add_item(tree, hf_dplay_data_type_1a, tvb, offset, -1, FALSE);
764     return offset;
765 }
766
767 static gint dissect_type29_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
768 {
769     proto_item *first_saddr_item = NULL,
770                *second_saddr_item = NULL, *third_saddr_item = NULL,
771                *fourth_saddr_item = NULL;
772     proto_tree *first_saddr_tree = NULL,
773                *second_saddr_tree = NULL, *third_saddr_tree = NULL,
774                *fourth_saddr_tree = NULL;
775
776     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_01, tvb, offset, 4, TRUE); offset += 4;
777     proto_tree_add_item(tree, hf_dplay_type_29_message_end_type, tvb, offset, 4, TRUE); offset += 4;
778     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_03, tvb, offset, 4, TRUE); offset += 4;
779     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_04, tvb, offset, 4, TRUE); offset += 4;
780     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_05, tvb, offset, 4, TRUE); offset += 4;
781     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_06, tvb, offset, 4, TRUE); offset += 4;
782     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_07, tvb, offset, 4, TRUE); offset += 4;
783     offset =  dissect_session_desc(tree, tvb, offset);
784
785     offset = display_unicode_string(tree, hf_dplay_type_29_game_name, tvb, offset);
786     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_10, tvb, offset, 4, TRUE); offset += 4;
787     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_11, tvb, offset, 4, TRUE); offset += 4;
788     proto_tree_add_item(tree, hf_dplay_type_29_dpid_2, tvb, offset, 4, FALSE); offset += 4;
789     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_12, tvb, offset, 4, TRUE); offset += 4;
790     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_13, tvb, offset, 4, TRUE); offset += 4;
791     proto_tree_add_item(tree, hf_dplay_type_29_saddr_field_len_1, tvb, offset, 1, FALSE); offset += 1;
792
793     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
794             "DirectPlay message type 0x0029 s_addr_in structure 1");
795     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type29_saddr1);
796
797     proto_tree_add_item(first_saddr_tree, hf_dplay_type_29_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
798     proto_tree_add_item(first_saddr_tree, hf_dplay_type_29_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
799     proto_tree_add_item(first_saddr_tree, hf_dplay_type_29_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
800     proto_tree_add_item(first_saddr_tree, hf_dplay_type_29_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
801
802     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
803             "DirectPlay message type 0x0029 s_addr_in structure 2");
804     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type29_saddr2);
805
806     proto_tree_add_item(second_saddr_tree, hf_dplay_type_29_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
807     proto_tree_add_item(second_saddr_tree, hf_dplay_type_29_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
808     proto_tree_add_item(second_saddr_tree, hf_dplay_type_29_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
809     proto_tree_add_item(second_saddr_tree, hf_dplay_type_29_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
810
811     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_14, tvb, offset, 4, TRUE); offset += 4;
812     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_15, tvb, offset, 4, TRUE); offset += 4;
813     proto_tree_add_item(tree, hf_dplay_type_29_dpid_3, tvb, offset, 4, FALSE); offset += 4;
814     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_16, tvb, offset, 4, TRUE); offset += 4;
815     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_17, tvb, offset, 4, TRUE); offset += 4;
816     proto_tree_add_item(tree, hf_dplay_type_29_saddr_field_len_2, tvb, offset, 1, FALSE); offset += 1;
817
818     third_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
819             "DirectPlay message type 0x0029 s_addr_in structure 3");
820     third_saddr_tree = proto_item_add_subtree(third_saddr_item,
821                     ett_dplay_type29_saddr3);
822
823     proto_tree_add_item(third_saddr_tree, hf_dplay_type_29_saddr_af_3, tvb, offset, 2, TRUE); offset += 2;
824     proto_tree_add_item(third_saddr_tree, hf_dplay_type_29_saddr_port_3, tvb, offset, 2, FALSE); offset += 2;
825     proto_tree_add_item(third_saddr_tree, hf_dplay_type_29_saddr_ip_3, tvb, offset, 4, FALSE); offset += 4;
826     proto_tree_add_item(third_saddr_tree, hf_dplay_type_29_saddr_padd_3, tvb, offset, 8, FALSE); offset += 8;
827
828     fourth_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
829             "DirectPlay message type 0x0029 s_addr_in structure 4");
830     fourth_saddr_tree = proto_item_add_subtree(fourth_saddr_item,
831                     ett_dplay_type29_saddr4);
832
833     proto_tree_add_item(fourth_saddr_tree, hf_dplay_type_29_saddr_af_4, tvb, offset, 2, TRUE); offset += 2;
834     proto_tree_add_item(fourth_saddr_tree, hf_dplay_type_29_saddr_port_4, tvb, offset, 2, FALSE); offset += 2;
835     proto_tree_add_item(fourth_saddr_tree, hf_dplay_type_29_saddr_ip_4, tvb, offset, 4, FALSE); offset += 4;
836     proto_tree_add_item(fourth_saddr_tree, hf_dplay_type_29_saddr_padd_4, tvb, offset, 8, FALSE); offset += 8;
837
838     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_18, tvb, offset, 4, TRUE); offset += 4;
839     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_19, tvb, offset, 4, TRUE); offset += 4;
840     proto_tree_add_item(tree, hf_dplay_type_29_dpid_4, tvb, offset, 4, FALSE); offset += 4;
841     proto_tree_add_item(tree, hf_dplay_type_29_unknown_uint32_20, tvb, offset, 4, TRUE); offset += 4;
842     proto_tree_add_item(tree, hf_dplay_type_29_dpid_5, tvb, offset, 4, FALSE); offset += 4;
843
844     /* still some parts missing here */
845     proto_tree_add_item(tree, hf_dplay_data_type_29, tvb, offset, -1, FALSE);
846     /* here we parse another saddr_field_len and two saddr structs */
847     return offset;
848 }
849
850 static gint dissect_type2e_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
851 {
852     proto_item *first_saddr_item = NULL, *second_saddr_item = NULL;
853     proto_tree *first_saddr_tree = NULL, *second_saddr_tree = NULL;
854     gint string_1_len, string_2_len;
855
856     proto_tree_add_item(tree, hf_dplay_type_2e_padding_1, tvb, offset, 4, FALSE); offset += 4;
857     proto_tree_add_item(tree, hf_dplay_type_2e_dpid_1, tvb, offset, 4, FALSE); offset += 4;
858     proto_tree_add_item(tree, hf_dplay_type_2e_unknown_1, tvb, offset, 20, FALSE); offset += 20;
859     proto_tree_add_item(tree, hf_dplay_type_2e_dpid_2, tvb, offset, 4, FALSE); offset += 4;
860     string_1_len = tvb_get_letohl(tvb, offset);
861     proto_tree_add_item(tree, hf_dplay_type_2e_string_1_len, tvb, offset, 4, TRUE); offset += 4;
862     string_2_len = tvb_get_letohl(tvb, offset);
863     proto_tree_add_item(tree, hf_dplay_type_2e_string_2_len, tvb, offset, 4, TRUE); offset += 4;
864     proto_tree_add_item(tree, hf_dplay_type_2e_unknown_2, tvb, offset, 12, FALSE); offset += 12;
865     proto_tree_add_item(tree, hf_dplay_type_2e_dpid_3, tvb, offset, 4, FALSE); offset += 4;
866     proto_tree_add_item(tree, hf_dplay_type_2e_unknown_3, tvb, offset, 12, FALSE); offset += 12;
867
868     if(string_1_len > 0)
869         offset = display_unicode_string(tree, hf_dplay_type_2e_string_1, tvb, offset);
870     if(string_2_len > 0)
871         offset = display_unicode_string(tree, hf_dplay_type_2e_string_2, tvb, offset);
872
873     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
874             "DirectPlay message type 0x002e s_addr_in structure 1");
875     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type2e_saddr1);
876
877     proto_tree_add_item(first_saddr_tree, hf_dplay_type_2e_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
878     proto_tree_add_item(first_saddr_tree, hf_dplay_type_2e_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
879     proto_tree_add_item(first_saddr_tree, hf_dplay_type_2e_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
880     proto_tree_add_item(first_saddr_tree, hf_dplay_type_2e_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
881
882     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
883             "DirectPlay message type 0x002e s_addr_in structure 2");
884     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type2e_saddr2);
885
886     proto_tree_add_item(second_saddr_tree, hf_dplay_type_2e_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
887     proto_tree_add_item(second_saddr_tree, hf_dplay_type_2e_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
888     proto_tree_add_item(second_saddr_tree, hf_dplay_type_2e_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
889     proto_tree_add_item(second_saddr_tree, hf_dplay_type_2e_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
890
891     return offset;
892 }
893
894 static gint dissect_type2f_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
895 {
896     proto_tree_add_item(tree, hf_dplay_type_2f_dpid, tvb, offset, 4, FALSE); offset += 4;
897     return offset;
898 }
899
900 static gint dissect_type38_message(proto_tree *tree, tvbuff_t *tvb, gint offset)
901 {
902     proto_item *first_saddr_item = NULL, *second_saddr_item = NULL;
903     proto_tree *first_saddr_tree = NULL, *second_saddr_tree = NULL;
904     gint string_1_len, string_2_len;
905
906     proto_tree_add_item(tree, hf_dplay_type_38_padding_1, tvb, offset, 4, FALSE); offset += 4;
907     proto_tree_add_item(tree, hf_dplay_type_38_dpid_1, tvb, offset, 4, FALSE); offset += 4;
908     proto_tree_add_item(tree, hf_dplay_type_38_unknown_1, tvb, offset, 20, FALSE); offset += 20;
909     proto_tree_add_item(tree, hf_dplay_type_38_dpid_2, tvb, offset, 4, FALSE); offset += 4;
910     string_1_len = tvb_get_letohl(tvb, offset);
911     proto_tree_add_item(tree, hf_dplay_type_38_string_1_len, tvb, offset, 4, TRUE); offset += 4;
912     string_2_len = tvb_get_letohl(tvb, offset);
913     proto_tree_add_item(tree, hf_dplay_type_38_string_2_len, tvb, offset, 4, TRUE); offset += 4;
914     proto_tree_add_item(tree, hf_dplay_type_38_unknown_2, tvb, offset, 12, FALSE); offset += 12;
915     proto_tree_add_item(tree, hf_dplay_type_38_dpid_3, tvb, offset, 4, FALSE); offset += 4;
916     proto_tree_add_item(tree, hf_dplay_type_38_unknown_3, tvb, offset, 12, FALSE); offset += 12;
917
918     if(string_1_len > 0)
919         offset = display_unicode_string(tree, hf_dplay_type_38_string_1, tvb, offset);
920     if(string_2_len > 0)
921         offset = display_unicode_string(tree, hf_dplay_type_38_string_2, tvb, offset);
922
923     first_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
924             "DirectPlay message type 0x0038 s_addr_in structure 1");
925     first_saddr_tree = proto_item_add_subtree(first_saddr_item, ett_dplay_type38_saddr1);
926
927     proto_tree_add_item(first_saddr_tree, hf_dplay_type_38_saddr_af_1, tvb, offset, 2, TRUE); offset += 2;
928     proto_tree_add_item(first_saddr_tree, hf_dplay_type_38_saddr_port_1, tvb, offset, 2, FALSE); offset += 2;
929     proto_tree_add_item(first_saddr_tree, hf_dplay_type_38_saddr_ip_1, tvb, offset, 4, FALSE); offset += 4;
930     proto_tree_add_item(first_saddr_tree, hf_dplay_type_38_saddr_padd_1, tvb, offset, 8, FALSE); offset += 8;
931
932     second_saddr_item = proto_tree_add_text(tree, tvb, offset, 16,
933             "DirectPlay message type 0x0038 s_addr_in structure 2");
934     second_saddr_tree = proto_item_add_subtree(second_saddr_item, ett_dplay_type38_saddr2);
935
936     proto_tree_add_item(second_saddr_tree, hf_dplay_type_38_saddr_af_2, tvb, offset, 2, TRUE); offset += 2;
937     proto_tree_add_item(second_saddr_tree, hf_dplay_type_38_saddr_port_2, tvb, offset, 2, FALSE); offset += 2;
938     proto_tree_add_item(second_saddr_tree, hf_dplay_type_38_saddr_ip_2, tvb, offset, 4, FALSE); offset += 4;
939     proto_tree_add_item(second_saddr_tree, hf_dplay_type_38_saddr_padd_2, tvb, offset, 8, FALSE); offset += 8;
940
941     return offset;
942 }
943
944 static void dissect_dplay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
945 {
946     guint16 message_type;
947     guint16 second_message_type = -1;
948     guint16 proto_version;
949     guint16 packet_size;
950     guint32 dplay_id;
951     guint8 play_id[] = {'p','l','a','y'};
952
953     packet_size = tvb_get_letohs(tvb, 0);
954     dplay_id = tvb_get_letohl(tvb, 20);
955     message_type = tvb_get_letohs(tvb, 24);
956     proto_version = tvb_get_letohs(tvb, 26);
957
958     if(memcmp(play_id, (guint8 *)&dplay_id, 4) != 0)
959     {
960         if(check_col(pinfo->cinfo, COL_PROTOCOL))
961             col_set_str(pinfo->cinfo, COL_PROTOCOL, "DPLAY");
962         /* Clear out stuff in the info column */
963         if(check_col(pinfo->cinfo,COL_INFO))
964             col_clear(pinfo->cinfo,COL_INFO);
965         if(check_col(pinfo->cinfo,COL_INFO))
966             col_add_fstr(pinfo->cinfo,COL_INFO, "DPlay data packet");
967         return;
968     }
969
970     if(message_type == 0x0015)
971     {
972         second_message_type = tvb_get_letohs(tvb, 72);
973     }
974
975     if(check_col(pinfo->cinfo, COL_PROTOCOL))
976         col_set_str(pinfo->cinfo, COL_PROTOCOL, "DPLAY");
977     /* Clear out stuff in the info column */
978     if(check_col(pinfo->cinfo,COL_INFO))
979     {
980         col_clear(pinfo->cinfo,COL_INFO);
981     }
982
983     if(check_col(pinfo->cinfo,COL_INFO))
984     {
985         if(message_type == 0x0015)
986             col_add_fstr(pinfo->cinfo,COL_INFO, "%s: %s, holding a %s",
987                 val_to_str(proto_version, dplay_proto_dialect_val, "Unknown (0x%04x)"),
988                 val_to_str(message_type, dplay_command_val, "Unknown (0x%04x)"),
989                 val_to_str(second_message_type, dplay_command_val, "Unknown (0x%04x)"));
990         else
991             col_add_fstr(pinfo->cinfo,COL_INFO, "%s: %s",
992                 val_to_str(proto_version, dplay_proto_dialect_val, "Unknown (0x%04x)"),
993                 val_to_str(message_type, dplay_command_val, "Unknown (0x%04x)"));
994     }
995
996     if(tree)
997     {
998         proto_item *dplay_item = NULL;
999         proto_item *header_item = NULL;
1000         proto_item *data_item = NULL;
1001         proto_tree *dplay_tree = NULL;
1002         proto_tree *dplay_header = NULL;
1003         proto_tree *dplay_data = NULL;
1004         gint offset = 0;
1005
1006         dplay_item = proto_tree_add_item(tree, proto_dplay, tvb, 0, -1, FALSE);
1007         dplay_tree = proto_item_add_subtree(dplay_item, ett_dplay);
1008         header_item = proto_tree_add_text(dplay_tree, tvb, offset, DPLAY_HEADER_OFFSET, "DirectPlay header");
1009         dplay_header = proto_item_add_subtree(header_item, ett_dplay_header);
1010
1011         offset = dissect_dplay_header(dplay_header, tvb, offset);
1012
1013         /* Special handling for empty type 0x0004 packets */
1014         if(message_type == 0x0004)
1015             return;
1016
1017         data_item = proto_tree_add_text(dplay_tree, tvb, offset, -1, "DirectPlay data");
1018         dplay_data = proto_item_add_subtree(data_item, ett_dplay_data);
1019
1020         switch(message_type)
1021         {
1022             case 0x0001:
1023                 offset = dissect_type01_message(dplay_data, tvb, offset);
1024                 break;
1025             case 0x0002:
1026                 offset = dissect_type02_message(dplay_data, tvb, offset);
1027                 break;
1028             case 0x0004:
1029                 /* We should not get here. */
1030                 break;
1031             case 0x0005:
1032                 offset = dissect_type05_message(dplay_data, tvb, offset);
1033                 break;
1034             case 0x0007:
1035                 offset = dissect_type07_message(dplay_data, tvb, offset);
1036                 break;
1037             case 0x0008:
1038                 offset = dissect_type08_message(dplay_data, tvb, offset);
1039                 break;
1040             case 0x000b:
1041                 offset = dissect_type0b_message(dplay_data, tvb, offset);
1042                 break;
1043             case 0x000d:
1044                 offset = dissect_type0d_message(dplay_data, tvb, offset);
1045                 break;
1046             case 0x000e:
1047                 offset = dissect_type0e_message(dplay_data, tvb, offset);
1048                 break;
1049             case 0x000f:
1050                 offset = dissect_type0f_message(dplay_data, tvb, offset);
1051                 break;
1052             case 0x0013:
1053                 offset = dissect_type13_message(dplay_data, tvb, offset);
1054                 break;
1055             case 0x0015:
1056                 offset = dissect_type15_message(dplay_data, tvb, offset);
1057                 break;
1058             case 0x0016:
1059                 offset = dissect_type16_message(dplay_data, tvb, offset);
1060                 break;
1061             case 0x0017:
1062                 offset = dissect_type17_message(dplay_data, tvb, offset);
1063                 break;
1064             case 0x001a:
1065                 offset = dissect_type1a_message(dplay_data, tvb, offset);
1066                 break;
1067             case 0x0029:
1068                 offset = dissect_type29_message(dplay_data, tvb, offset);
1069                 break;
1070             case 0x002e:
1071                 offset = dissect_type2e_message(dplay_data, tvb, offset);
1072                 break;
1073             case 0x002f:
1074                 offset = dissect_type2f_message(dplay_data, tvb, offset);
1075                 break;
1076             case 0x0038:
1077                 offset = dissect_type38_message(dplay_data, tvb, offset);
1078                 break;
1079         }
1080     }
1081
1082 }
1083
1084 static gboolean heur_dissect_dplay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1085 {
1086     guint8 signature[] = {'p','l','a','y'};
1087     guint32 dplay_id;
1088
1089     if(!tvb_bytes_exist(tvb, 0, 24))
1090         return FALSE;
1091
1092     dplay_id = tvb_get_letohl(tvb, 20);
1093     if( memcmp(signature, (guint8 *)&dplay_id, 4) != 0)
1094         return FALSE;
1095
1096     dissect_dplay(tvb, pinfo, tree);
1097     return TRUE;
1098 }
1099
1100 void proto_register_dplay()
1101 {
1102     static hf_register_info hf [] = {
1103     /* Common data fields */
1104     { &hf_dplay_size,
1105         { "DirectPlay package size", "dplay.size", FT_UINT32, BASE_DEC,
1106         NULL, 0x0, "", HFILL}},
1107     { &hf_dplay_token,
1108         { "DirectPlay token", "dplay.token", FT_UINT32, BASE_HEX,
1109         VALS(dplay_token_val), 0x0, "", HFILL}},
1110     { &hf_dplay_saddr_af,
1111         { "DirectPlay s_addr_in address family", "dplay.saddr.af", FT_UINT16, BASE_HEX,
1112         VALS(dplay_af_val), 0x0, "", HFILL}},
1113     { &hf_dplay_saddr_port,
1114         { "DirectPlay s_addr_in port", "dplay.saddr.port", FT_UINT16, BASE_DEC,
1115         NULL, 0x0, "", HFILL}},
1116     { &hf_dplay_saddr_ip,
1117         { "DirectPlay s_addr_in ip address", "dplay.saddr.ip", FT_IPv4, BASE_NONE,
1118         NULL, 0x0, "", HFILL}},
1119     { &hf_dplay_saddr_padding,
1120         { "DirectPlay s_addr_in null padding", "dplay.saddr.padding", FT_BYTES, BASE_NONE,
1121         NULL, 0x0, "", HFILL}},
1122     { &hf_dplay_play_str,
1123         { "DirectPlay action string", "dplay.dplay_str", FT_STRING, BASE_NONE,
1124         NULL, 0x0, "", HFILL}},
1125     { &hf_dplay_command,
1126         { "DirectPlay command", "dplay.command", FT_UINT16, BASE_HEX,
1127         VALS(dplay_command_val), 0x0, "", HFILL}},
1128     { &hf_dplay_proto_dialect,
1129         { "DirectPlay dialect version", "dplay.dialect.version", FT_UINT16, BASE_HEX,
1130         VALS(dplay_proto_dialect_val), 0x0, "", HFILL}},
1131     { &hf_dplay_play_str_2,
1132         { "DirectPlay second action string", "dplay.dplay_str_2", FT_STRING, BASE_NONE,
1133         NULL, 0x0, "", HFILL}},
1134     { &hf_dplay_command_2,
1135         { "DirectPlay second command", "dplay.type_2", FT_UINT16, BASE_HEX,
1136         VALS(dplay_command_val), 0x0, "", HFILL}},
1137     { &hf_dplay_proto_dialect_2,
1138         { "DirectPlay second dialect version", "dplay.dialect.version_2", FT_UINT16, BASE_HEX,
1139         VALS(dplay_proto_dialect_val), 0x0, "", HFILL}},
1140
1141     /* special fields, to be phased out*/
1142     { &hf_dplay_data_type_0f,
1143         { "DirectPlay data for type 0f messages", "dplay.data.type_0f", FT_BYTES, BASE_HEX,
1144         NULL, 0x0, "", HFILL}},
1145     { &hf_dplay_data_type_1a,
1146         { "DirectPlay data for type 1a messages", "dplay.data.type_1a", FT_BYTES, BASE_HEX,
1147         NULL, 0x0, "", HFILL}},
1148     { &hf_dplay_data_type_29,
1149         { "DirectPlay data for type 29 messages", "dplay.data.type_29", FT_BYTES, BASE_HEX,
1150         NULL, 0x0, "", HFILL}},
1151
1152     /* Session Desc structure fields */
1153     { &hf_dplay_sess_desc_flags,
1154         { "DirectPlay session desc flags", "dplay.flags", FT_UINT32, BASE_HEX,
1155         NULL, 0x0, "", HFILL}},
1156     { &hf_dplay_flags_no_create_players,
1157         { "no create players flag", "dplay.flags.no_create_players", FT_BOOLEAN, 32,
1158         TFS(&tfs_dplay_flag), DPLAY_FLAG_NO_CREATE_PLAYERS, "No Create Players", HFILL}},
1159     { &hf_dplay_flags_0002,
1160         { "unused", "dplay.flags.unused", FT_BOOLEAN, 32,
1161         TFS(&tfs_dplay_flag), DPLAY_FLAG_0002, "Unused", HFILL}},
1162     { &hf_dplay_flags_migrate_host,
1163         { "migrate host flag", "dplay.flags.migrate_host", FT_BOOLEAN, 32,
1164         TFS(&tfs_dplay_flag), DPLAY_FLAG_MIGRATE_HOST, "Migrate Host", HFILL}},
1165     { &hf_dplay_flags_short_player_msg,
1166         { "short player message", "dplay.flags.short_player_msg", FT_BOOLEAN, 32,
1167         TFS(&tfs_dplay_flag), DPLAY_FLAG_SHORT_PLAYER_MSG, "Short Player Msg", HFILL}},
1168     { &hf_dplay_flags_ignored,
1169         { "ignored", "dplay.flags.ignored", FT_BOOLEAN, 32,
1170         TFS(&tfs_dplay_flag), DPLAY_FLAG_IGNORED, "Ignored", HFILL}},
1171     { &hf_dplay_flags_can_join,
1172         { "can join", "dplay.flags.can_join", FT_BOOLEAN, 32,
1173         TFS(&tfs_dplay_flag), DPLAY_FLAG_CAN_JOIN, "Can Join", HFILL}},
1174     { &hf_dplay_flags_use_ping,
1175         { "use ping", "dplay.flags.use_ping", FT_BOOLEAN, 32,
1176         TFS(&tfs_dplay_flag), DPLAY_FLAG_USE_PING, "Use Ping", HFILL}},
1177     { &hf_dplay_flags_no_player_updates,
1178         { "no player updates", "dplay.flags.no_player_updates", FT_BOOLEAN, 32,
1179         TFS(&tfs_dplay_flag), DPLAY_FLAG_NO_P_UPD, "No Player Updates", HFILL}},
1180     { &hf_dplay_flags_use_auth,
1181         { "use authentication", "dplay.flags.use_auth", FT_BOOLEAN, 32,
1182         TFS(&tfs_dplay_flag), DPLAY_FLAG_USE_AUTH, "Use Auth", HFILL}},
1183     { &hf_dplay_flags_private_session,
1184         { "private session", "dplay.flags.priv_sess", FT_BOOLEAN, 32,
1185         TFS(&tfs_dplay_flag), DPLAY_FLAG_PRIV_SESS, "Priv Session", HFILL}},
1186     { &hf_dplay_flags_password_req,
1187         { "password required", "dplay.flags.pass_req", FT_BOOLEAN, 32,
1188         TFS(&tfs_dplay_flag), DPLAY_FLAG_PASS_REQ, "Pass Req", HFILL}},
1189     { &hf_dplay_flags_route,
1190         { "route via game host", "dplay.flags.route", FT_BOOLEAN, 32,
1191         TFS(&tfs_dplay_flag), DPLAY_FLAG_ROUTE, "Route", HFILL}},
1192     { &hf_dplay_flags_server_player_only,
1193         { "get server player only", "dplay.flags.srv_p_only", FT_BOOLEAN, 32,
1194         TFS(&tfs_dplay_flag), DPLAY_FLAG_SRV_ONLY, "Svr Player Only", HFILL}},
1195     { &hf_dplay_flags_reliable,
1196         { "use reliable protocol", "dplay.flags.reliable", FT_BOOLEAN, 32,
1197         TFS(&tfs_dplay_flag), DPLAY_FLAG_RELIABLE, "Reliable", HFILL}},
1198     { &hf_dplay_flags_preserve_order,
1199         { "preserve order", "dplay.flags.order", FT_BOOLEAN, 32,
1200         TFS(&tfs_dplay_flag), DPLAY_FLAG_ORDER, "Order", HFILL}},
1201     { &hf_dplay_flags_optimize_latency,
1202         { "optimize for latency", "dplay.flags.opt_latency", FT_BOOLEAN, 32,
1203         TFS(&tfs_dplay_flag), DPLAY_FLAG_OPT_LAT, "Opt Latency", HFILL}},
1204     { &hf_dplay_flags_acqire_voice,
1205         { "acquire voice", "dplay.flags.acq_voice", FT_BOOLEAN, 32,
1206         TFS(&tfs_dplay_flag), DPLAY_FLAG_ACQ_VOICE, "Acq Voice", HFILL}},
1207     { &hf_dplay_flags_no_sess_desc_changes,
1208         { "no session desc changes", "dplay.flags.no_sess_desc", FT_BOOLEAN, 32,
1209         TFS(&tfs_dplay_flag), DPLAY_FLAG_NO_SESS_DESC_CHANGES, "No Sess Desc Changes", HFILL}},
1210     { &hf_dplay_instance_guid,
1211         { "DirectPlay instance guid", "dplay.instance.guid", FT_GUID, BASE_NONE,
1212         NULL, 0x0, "", HFILL}},
1213     { &hf_dplay_game_guid,
1214         { "DirectPlay game GUID", "dplay.game.guid", FT_GUID, BASE_NONE,
1215         NULL, 0x0, "", HFILL}},
1216     { &hf_dplay_sess_desc_length,
1217         { "DirectPlay session desc length", "dplay.sess_desc.length", FT_UINT32, BASE_DEC,
1218         NULL, 0x0, "", HFILL}},
1219     { &hf_dplay_max_players,
1220         { "DirectPlay max players ", "dplay.sess_desc.max_players", FT_UINT32, BASE_DEC,
1221         NULL, 0x0, "", HFILL}},
1222     { &hf_dplay_curr_players,
1223         { "DirectPlay current players", "dplay.sess_desc.curr_players", FT_UINT32, BASE_DEC,
1224         NULL, 0x0, "", HFILL}},
1225     { &hf_dplay_sess_name_ptr,
1226         { "Session description name pointer placeholder", "dplay.sess_desc.name_ptr", FT_BYTES, BASE_HEX,
1227         NULL, 0x0, "", HFILL}},
1228     { &hf_dplay_passwd_ptr,
1229         { "Session description password pointer placeholder", "dplay.sess_desc.pw_ptr", FT_BYTES, BASE_HEX,
1230         NULL, 0x0, "", HFILL}},
1231     { &hf_dplay_sess_desc_reserved_1,
1232         { "Session description reserved 1", "dplay.sess_desc.res_1", FT_BYTES, BASE_HEX,
1233         NULL, 0x0, "", HFILL}},
1234     { &hf_dplay_sess_desc_reserved_2,
1235         { "Session description reserved 2", "dplay.sess_desc.res_2", FT_BYTES, BASE_HEX,
1236         NULL, 0x0, "", HFILL}},
1237     { &hf_dplay_sess_desc_user_1,
1238         { "Session description user defined 1", "dplay.sess_desc.user_1", FT_BYTES, BASE_HEX,
1239         NULL, 0x0, "", HFILL}},
1240     { &hf_dplay_sess_desc_user_2,
1241         { "Session description user defined 2", "dplay.sess_desc.user_2", FT_BYTES, BASE_HEX,
1242         NULL, 0x0, "", HFILL}},
1243     { &hf_dplay_sess_desc_user_3,
1244         { "Session description user defined 3", "dplay.sess_desc.user_3", FT_BYTES, BASE_HEX,
1245         NULL, 0x0, "", HFILL}},
1246     { &hf_dplay_sess_desc_user_4,
1247         { "Session description user defined 4", "dplay.sess_desc.user_4", FT_BYTES, BASE_HEX,
1248         NULL, 0x0, "", HFILL}},
1249
1250     /* Data fields for message type 0x0001 */
1251     { &hf_dplay_type_01_name_offset,
1252         { "Enum Session Reply name offset", "dplay.type_01.name_offs", FT_UINT32, BASE_DEC,
1253         NULL, 0x0, "", HFILL}},
1254     { &hf_dplay_type_01_game_name,
1255         { "Enum Session Reply game name", "dplay.type_01.game_name", FT_STRING, BASE_NONE,
1256         NULL, 0x0, "", HFILL}},
1257
1258     /* Data fields for message type 0x0002 */
1259     { &hf_dplay_type_02_game_guid,
1260         { "DirectPlay game GUID", "dplay.type02.game.guid", FT_GUID, BASE_NONE,
1261         NULL, 0x0, "", HFILL}},
1262     { &hf_dplay_type_02_ignored,
1263         { "DirectPlay message type 0x0002 ignored", "dplay.type02.ignored", FT_BYTES, BASE_HEX,
1264         NULL, 0x0, "", HFILL}},
1265
1266     /* Data fields for message type 0x0005 */
1267     { &hf_dplay_type_05_request,
1268         { "DirectPlay ID request", "dplay.type_05.request", FT_UINT32, BASE_HEX,
1269         VALS(dplay_type05_request), 0x0, "", HFILL}},
1270
1271     /* Data fields for message type 0x0007 */
1272     { &hf_dplay_type_07_dpid,
1273         { "DirectPlay ID", "dplay.type_07.dpid", FT_BYTES, BASE_HEX,
1274         NULL, 0x0, "", HFILL}},
1275     { &hf_dplay_type_07_padding,
1276         { "DirectPlay message type 0x0007 padding", "dplay.type_07.padding", FT_BYTES, BASE_HEX,
1277         NULL, 0x0, "", HFILL}},
1278
1279     /* Data fields for message type 0x0008 */
1280     { &hf_dplay_type_08_padding_1,
1281         { "DirectPlay message type 0x0008 padding 1", "dplay.type_08.padding_1", FT_BYTES, BASE_HEX,
1282         NULL, 0x0, "", HFILL}},
1283     { &hf_dplay_type_08_dpid_1,
1284         { "DirectPlay message type 0x0008 client DP ID", "dplay.type_08.dpid_1", FT_BYTES, BASE_HEX,
1285         NULL, 0x0, "", HFILL}},
1286     { &hf_dplay_type_08_unknown_1,
1287         { "DirectPlay message type 0x0008 unknown 1", "dplay.type_08.unknown_1", FT_BYTES, BASE_HEX,
1288         NULL, 0x0, "", HFILL}},
1289     { &hf_dplay_type_08_dpid_2,
1290         { "DirectPlay message type 0x0008 client DP ID", "dplay.type_08.dpid_2", FT_BYTES, BASE_HEX,
1291         NULL, 0x0, "", HFILL}},
1292     { &hf_dplay_type_08_string_1_len,
1293         { "DirectPlay message type 0x0008 string 1 length", "dplay.type_08.string_1.length", FT_UINT32,
1294         BASE_DEC, NULL, 0x0, "", HFILL}},
1295     { &hf_dplay_type_08_string_2_len,
1296         { "DirectPlay message type 0x0008 string 2 length", "dplay.type_08.string_2.length", FT_UINT32,
1297         BASE_DEC, NULL, 0x0, "", HFILL}},
1298     { &hf_dplay_type_08_unknown_2,
1299         { "DirectPlay message type 0x0008 unknown 2", "dplay.type_08.unknown_2", FT_BYTES, BASE_HEX,
1300         NULL, 0x0, "", HFILL}},
1301     { &hf_dplay_type_08_dpid_3,
1302         { "DirectPlay message type 0x0008 client DP ID", "dplay.type_08.dpid_3", FT_BYTES, BASE_HEX,
1303         NULL, 0x0, "", HFILL}},
1304     { &hf_dplay_type_08_unknown_3,
1305         { "DirectPlay message type 0x0008 unknown 3", "dplay.type_08.unknown_3", FT_BYTES, BASE_HEX,
1306         NULL, 0x0, "", HFILL}},
1307     { &hf_dplay_type_08_string_1,
1308         { "DirectPlay message type 0x0008 string 1", "dplay.type_08.string_1", FT_STRING, BASE_NONE,
1309         NULL, 0x0, "", HFILL}},
1310     { &hf_dplay_type_08_string_2,
1311         { "DirectPlay message type 0x0008 string 2", "dplay.type_08.string_2", FT_STRING, BASE_NONE,
1312         NULL, 0x0, "", HFILL}},
1313     { &hf_dplay_type_08_saddr_af_1,
1314         { "DirectPlay message type 0x0008 s_addr_in address family 1", "dplay.type_08.saddr.af_1", FT_UINT16,
1315             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1316     { &hf_dplay_type_08_saddr_port_1,
1317         { "DirectPlay message type 0x0008 s_addr_in port 1", "dplay.type_08.saddr.port_1", FT_UINT16, BASE_DEC,
1318         NULL, 0x0, "", HFILL}},
1319     { &hf_dplay_type_08_saddr_ip_1,
1320         { "DirectPlay message type 0x0008 s_addr_in ip 1", "dplay.type_08.saddr.ip_1", FT_IPv4, BASE_NONE,
1321         NULL, 0x0, "", HFILL}},
1322     { &hf_dplay_type_08_saddr_padd_1,
1323         { "DirectPlay message type 0x0008 s_addr_in padding 1", "dplay.type_08.saddr.padd_1", FT_BYTES, BASE_HEX,
1324         NULL, 0x0, "", HFILL}},
1325     { &hf_dplay_type_08_saddr_af_2,
1326         { "DirectPlay message type 0x0008 s_addr_in address family 2", "dplay.type_08.saddr.af_2", FT_UINT16,
1327             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1328     { &hf_dplay_type_08_saddr_port_2,
1329         { "DirectPlay message type 0x0008 s_addr_in port 2", "dplay.type_08.saddr.port_2", FT_UINT16, BASE_DEC,
1330         NULL, 0x0, "", HFILL}},
1331     { &hf_dplay_type_08_saddr_ip_2,
1332         { "DirectPlay message type 0x0008 s_addr_in ip 2", "dplay.type_08.saddr.ip_2", FT_IPv4, BASE_NONE,
1333         NULL, 0x0, "", HFILL}},
1334     { &hf_dplay_type_08_saddr_padd_2,
1335         { "DirectPlay message type 0x0008 s_addr_in padding 2", "dplay.type_08.saddr.padd_2", FT_BYTES, BASE_HEX,
1336         NULL, 0x0, "", HFILL}},
1337     { &hf_dplay_type_08_padding_2,
1338         { "DirectPlay message type 0x0008 padding 2", "dplay.type_08.padding_2", FT_BYTES, BASE_HEX,
1339         NULL, 0x0, "", HFILL}},
1340
1341     /* Data fields for message type 0x000b */
1342     { &hf_dplay_type_0b_padding_1,
1343         { "DirectPlay message type 0x000b padding 1", "dplay.type_0b.padding_1", FT_BYTES, BASE_HEX,
1344         NULL, 0x0, "", HFILL}},
1345     { &hf_dplay_type_0b_dpid,
1346         { "DirectPlay message type 0x000b DP ID", "dplay.type_0b.dpid", FT_BYTES, BASE_HEX,
1347         NULL, 0x0, "", HFILL}},
1348     { &hf_dplay_type_0b_padding_2,
1349         { "DirectPlay message type 0x000b padding 2", "dplay.type_0b.padding_2", FT_BYTES, BASE_HEX,
1350         NULL, 0x0, "", HFILL}},
1351
1352     /* Data fields for message type 0x000d */
1353     { &hf_dplay_type_0d_padding_1,
1354         { "DirectPlay message type 0x000d padding 1", "dplay.type_0d.padding_1", FT_BYTES, BASE_HEX,
1355         NULL, 0x0, "", HFILL}},
1356     { &hf_dplay_type_0d_dpid_1,
1357         { "DirectPlay message type 0x000d DP ID 1", "dplay.type_0d.dpid_1", FT_BYTES, BASE_HEX,
1358         NULL, 0x0, "", HFILL}},
1359     { &hf_dplay_type_0d_dpid_2,
1360         { "DirectPlay message type 0x000d DP ID 2", "dplay.type_0d.dpid_2", FT_BYTES, BASE_HEX,
1361         NULL, 0x0, "", HFILL}},
1362     { &hf_dplay_type_0d_padding_2,
1363         { "DirectPlay message type 0x000d padding 2", "dplay.type_0d.padding_2", FT_BYTES, BASE_HEX,
1364         NULL, 0x0, "", HFILL}},
1365
1366     /* Data fields for message type 0x000e */
1367     { &hf_dplay_type_0e_padding_1,
1368         { "DirectPlay message type 0x000e padding 1", "dplay.type_0e.padding_1", FT_BYTES, BASE_HEX,
1369         NULL, 0x0, "", HFILL}},
1370     { &hf_dplay_type_0e_dpid_1,
1371         { "DirectPlay message type 0x000e DP ID 1", "dplay.type_0e.dpid_1", FT_BYTES, BASE_HEX,
1372         NULL, 0x0, "", HFILL}},
1373     { &hf_dplay_type_0e_dpid_2,
1374         { "DirectPlay message type 0x000e DP ID 2", "dplay.type_0e.dpid_2", FT_BYTES, BASE_HEX,
1375         NULL, 0x0, "", HFILL}},
1376     { &hf_dplay_type_0e_padding_2,
1377         { "DirectPlay message type 0x000e padding 2", "dplay.type_0e.padding_2", FT_BYTES, BASE_HEX,
1378         NULL, 0x0, "", HFILL}},
1379
1380     /* Data fields for message type 0x0013 */
1381     { &hf_dplay_type_13_padding_1,
1382         { "DirectPlay message type 0x0013 padding 1", "dplay.type_13.padding_1", FT_BYTES, BASE_HEX,
1383         NULL, 0x0, "", HFILL}},
1384     { &hf_dplay_type_13_dpid_1,
1385         { "DirectPlay message type 0x0013 client DP ID", "dplay.type_13.dpid_1", FT_BYTES, BASE_HEX,
1386         NULL, 0x0, "", HFILL}},
1387     { &hf_dplay_type_13_unknown_1,
1388         { "DirectPlay message type 0x0013 unknown 1", "dplay.type_13.unknown_1", FT_BYTES, BASE_HEX,
1389         NULL, 0x0, "", HFILL}},
1390     { &hf_dplay_type_13_dpid_2,
1391         { "DirectPlay message type 0x0013 client DP ID", "dplay.type_13.dpid_2", FT_BYTES, BASE_HEX,
1392         NULL, 0x0, "", HFILL}},
1393     { &hf_dplay_type_13_unknown_2,
1394         { "DirectPlay message type 0x0013 unknown 2", "dplay.type_13.unknown_2", FT_BYTES, BASE_HEX,
1395         NULL, 0x0, "", HFILL}},
1396     { &hf_dplay_type_13_dpid_3,
1397         { "DirectPlay message type 0x0013 client DP ID", "dplay.type_13.dpid_3", FT_BYTES, BASE_HEX,
1398         NULL, 0x0, "", HFILL}},
1399     { &hf_dplay_type_13_unknown_3,
1400         { "DirectPlay message type 0x0013 unknown 3", "dplay.type_13.unknown_3", FT_BYTES, BASE_HEX,
1401         NULL, 0x0, "", HFILL}},
1402     { &hf_dplay_type_13_saddr_af_1,
1403         { "DirectPlay message type 0x0013 s_addr_in address family 1", "dplay.type_13.saddr.af_1", FT_UINT16,
1404             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1405     { &hf_dplay_type_13_saddr_port_1,
1406         { "DirectPlay message type 0x0013 s_addr_in port 1", "dplay.type_13.saddr.port_1", FT_UINT16, BASE_DEC,
1407         NULL, 0x0, "", HFILL}},
1408     { &hf_dplay_type_13_saddr_ip_1,
1409         { "DirectPlay message type 0x0013 s_addr_in ip 1", "dplay.type_13.saddr.ip_1", FT_IPv4, BASE_NONE,
1410         NULL, 0x0, "", HFILL}},
1411     { &hf_dplay_type_13_saddr_padd_1,
1412         { "DirectPlay message type 0x0013 s_addr_in padding 1", "dplay.type_13.saddr.padd_1", FT_BYTES, BASE_HEX,
1413         NULL, 0x0, "", HFILL}},
1414     { &hf_dplay_type_13_saddr_af_2,
1415         { "DirectPlay message type 0x0013 s_addr_in address family 2", "dplay.type_13.saddr.af_2", FT_UINT16,
1416             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1417     { &hf_dplay_type_13_saddr_port_2,
1418         { "DirectPlay message type 0x0013 s_addr_in port 2", "dplay.type_13.saddr.port_2", FT_UINT16, BASE_DEC,
1419         NULL, 0x0, "", HFILL}},
1420     { &hf_dplay_type_13_saddr_ip_2,
1421         { "DirectPlay message type 0x0013 s_addr_in ip 2", "dplay.type_13.saddr.ip_2", FT_IPv4, BASE_NONE,
1422         NULL, 0x0, "", HFILL}},
1423     { &hf_dplay_type_13_saddr_padd_2,
1424         { "DirectPlay message type 0x0013 s_addr_in padding 2", "dplay.type_13.saddr.padd_2", FT_BYTES, BASE_HEX,
1425         NULL, 0x0, "", HFILL}},
1426     { &hf_dplay_type_13_padding_2,
1427         { "DirectPlay message type 0x0013 padding 2", "dplay.type_13.padding_2", FT_BYTES, BASE_HEX,
1428         NULL, 0x0, "", HFILL}},
1429     { &hf_dplay_type_13_dpid_4,
1430         { "DirectPlay message type 0x0013 server DP ID", "dplay.type_13.dpid_4", FT_BYTES, BASE_HEX,
1431         NULL, 0x0, "", HFILL}},
1432
1433     /* Data fields for message type 0x0015 */
1434     { &hf_dplay_container_guid,
1435         { "DirectPlay container GUID", "dplay.container.guid", FT_GUID, BASE_NONE,
1436         NULL, 0x0, "", HFILL}},
1437     { &hf_dplay_type_15_padding_1,
1438         { "DirectPlay message type 0x0015 padding 1", "dplay.type_15.padding_1", FT_BYTES, BASE_HEX,
1439         NULL, 0x0, "", HFILL}},
1440     { &hf_dplay_type_15_size_1,
1441         { "DirectPlay encapsulated packet size 1", "dplay.type_15.encap_size_1", FT_UINT32, BASE_DEC,
1442         NULL, 0x0, "", HFILL}},
1443     { &hf_dplay_type_15_padding_2,
1444         { "DirectPlay message type 0x0015 padding 2", "dplay.type_15.padding_2", FT_BYTES, BASE_HEX,
1445         NULL, 0x0, "", HFILL}},
1446     { &hf_dplay_type_15_unknown_1,
1447         { "DirectPlay message type 0x0015 unknown", "dplay.type_15.unknown_1", FT_UINT32, BASE_DEC,
1448         NULL, 0x0, "", HFILL}},
1449     { &hf_dplay_type_15_size_2,
1450         { "DirectPlay encapsulated packet size 2", "dplay.type_15.encap_size_2", FT_UINT32, BASE_DEC,
1451         NULL, 0x0, "", HFILL}},
1452     { &hf_dplay_type_15_padding_3,
1453         { "DirectPlay message type 0x0015 padding 3", "dplay.type_15.padding_3", FT_BYTES, BASE_HEX,
1454         NULL, 0x0, "", HFILL}},
1455
1456     /* Data field for message type 0x0016 */
1457     { &hf_dplay_type_16_data,
1458         { "DirectPlay type 0x0016 message data", "dplay.data.type_16", FT_BYTES, BASE_HEX,
1459         NULL, 0x0, "", HFILL}},
1460
1461     /* Data field for message type 0x0017 */
1462     { &hf_dplay_type_17_data,
1463         { "DirectPlay type 0x0017 message data", "dplay.data.type_17", FT_BYTES, BASE_HEX,
1464         NULL, 0x0, "", HFILL}},
1465
1466     /* Data fields for message type 0x0029 */
1467     { &hf_dplay_type_29_unknown_uint32_01,
1468         { "DirectPlay message type 0x0029 unknown uint32 1 (3)", "dplay.type_29.unknown_uint32_01", FT_UINT32,
1469         BASE_DEC, NULL, 0x0, "", HFILL}},
1470     { &hf_dplay_type_29_message_end_type,
1471         { "DirectPlay message type 0x0029 message end type", "dplay.type_29.msg_end_type", FT_UINT32,
1472         BASE_DEC, VALS(dplay_type29_end_type), 0x0, "", HFILL}},
1473     { &hf_dplay_type_29_unknown_uint32_03,
1474         { "DirectPlay message type 0x0029 unknown uint32 3", "dplay.type_29.unknown_uint32_03", FT_UINT32,
1475         BASE_DEC, NULL, 0x0, "", HFILL}},
1476     { &hf_dplay_type_29_unknown_uint32_04,
1477         { "DirectPlay message type 0x0029 unknown uint32 4 (0)", "dplay.type_29.unknown_uint32_04", FT_UINT32,
1478         BASE_DEC, NULL, 0x0, "", HFILL}},
1479     { &hf_dplay_type_29_unknown_uint32_05,
1480         { "DirectPlay message type 0x0029 unknown uint32 5 (36)", "dplay.type_29.unknown_uint32_05", FT_UINT32,
1481         BASE_DEC, NULL, 0x0, "", HFILL}},
1482     { &hf_dplay_type_29_unknown_uint32_06,
1483         { "DirectPlay message type 0x0029 unknown uint32 6 (116)", "dplay.type_29.unknown_uint32_06", FT_UINT32,
1484         BASE_DEC, NULL, 0x0, "", HFILL}},
1485     { &hf_dplay_type_29_unknown_uint32_07,
1486         { "DirectPlay message type 0x0029 unknown uint32 7 (0)", "dplay.type_29.unknown_uint32_07", FT_UINT32,
1487         BASE_DEC, NULL, 0x0, "", HFILL}},
1488     { &hf_dplay_type_29_unknown_uint32_08,
1489         { "DirectPlay message type 0x0029 unknown uint32 8 (80)", "dplay.type_29.unknown_uint32_08", FT_UINT32,
1490         BASE_DEC, NULL, 0x0, "", HFILL}},
1491     { &hf_dplay_type_29_magic_16_bytes,
1492         { "DirectPlay message type 0x0029 magic 16 bytes", "dplay.type_29.magic_16_bytes", FT_BYTES, BASE_HEX,
1493         NULL, 0x0, "", HFILL}},
1494     { &hf_dplay_type_29_dpid_1,
1495         { "DirectPlay message type 0x0029 DPID", "dplay.type_29.dpid", FT_BYTES, BASE_HEX,
1496         NULL, 0x0, "", HFILL}},
1497     { &hf_dplay_type_29_unknown_3,
1498         { "DirectPlay message type 0x0029 unknown 3", "dplay.type_29.unknown_3", FT_BYTES, BASE_HEX,
1499         NULL, 0x0, "", HFILL}},
1500     { &hf_dplay_type_29_game_name,
1501         { "DirectPlay message type 0x0029 game name", "dplay.type_29.game_name", FT_STRING, BASE_NONE,
1502         NULL, 0x0, "", HFILL}},
1503     { &hf_dplay_type_29_unknown_uint32_10,
1504         { "DirectPlay message type 0x0029 unknown uint32 10", "dplay.type_29.unknown_uint32_10", FT_UINT32,
1505         BASE_DEC, NULL, 0x0, "", HFILL}},
1506     { &hf_dplay_type_29_unknown_uint32_11,
1507         { "DirectPlay message type 0x0029 unknown uint32 11", "dplay.type_29.unknown_uint32_11", FT_UINT32,
1508         BASE_DEC, NULL, 0x0, "", HFILL}},
1509     { &hf_dplay_type_29_dpid_2,
1510         { "DirectPlay message type 0x0029 DPID", "dplay.type_29.dpid", FT_BYTES, BASE_HEX,
1511         NULL, 0x0, "", HFILL}},
1512     { &hf_dplay_type_29_unknown_uint32_12,
1513         { "DirectPlay message type 0x0029 unknown uint32 12 (4)", "dplay.type_29.unknown_uint32_12", FT_UINT32,
1514         BASE_DEC, NULL, 0x0, "", HFILL}},
1515     { &hf_dplay_type_29_unknown_uint32_13,
1516         { "DirectPlay message type 0x0029 unknown uint32 13 (14)", "dplay.type_29.unknown_uint32_13", FT_UINT32,
1517         BASE_DEC, NULL, 0x0, "", HFILL}},
1518     { &hf_dplay_type_29_saddr_field_len_1,
1519         { "DirectPlay message type 0x0029 saddr field len 1", "dplay.type_29.saddr_field_len_1", FT_UINT8,
1520         BASE_DEC, NULL, 0x0, "", HFILL}},
1521     { &hf_dplay_type_29_saddr_af_1,
1522         { "DirectPlay message type 0x0029 s_addr_in address family 1", "dplay.type_29.saddr.af_1", FT_UINT16,
1523             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1524     { &hf_dplay_type_29_saddr_port_1,
1525         { "DirectPlay message type 0x0029 s_addr_in port 1", "dplay.type_29.saddr.port_1", FT_UINT16, BASE_DEC,
1526         NULL, 0x0, "", HFILL}},
1527     { &hf_dplay_type_29_saddr_ip_1,
1528         { "DirectPlay message type 0x0029 s_addr_in ip 1", "dplay.type_29.saddr.ip_1", FT_IPv4, BASE_NONE,
1529         NULL, 0x0, "", HFILL}},
1530     { &hf_dplay_type_29_saddr_padd_1,
1531         { "DirectPlay message type 0x0029 s_addr_in padding 1", "dplay.type_29.saddr.padd_1", FT_BYTES, BASE_HEX,
1532         NULL, 0x0, "", HFILL}},
1533     { &hf_dplay_type_29_saddr_af_2,
1534         { "DirectPlay message type 0x0029 s_addr_in address family 2", "dplay.type_29.saddr.af_2", FT_UINT16,
1535             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1536     { &hf_dplay_type_29_saddr_port_2,
1537         { "DirectPlay message type 0x0029 s_addr_in port 2", "dplay.type_29.saddr.port_2", FT_UINT16, BASE_DEC,
1538         NULL, 0x0, "", HFILL}},
1539     { &hf_dplay_type_29_saddr_ip_2,
1540         { "DirectPlay message type 0x0029 s_addr_in ip 2", "dplay.type_29.saddr.ip_2", FT_IPv4, BASE_NONE,
1541         NULL, 0x0, "", HFILL}},
1542     { &hf_dplay_type_29_saddr_padd_2,
1543         { "DirectPlay message type 0x0029 s_addr_in padding 2", "dplay.type_29.saddr.padd_2", FT_BYTES, BASE_HEX,
1544         NULL, 0x0, "", HFILL}},
1545     { &hf_dplay_type_29_unknown_uint32_14,
1546         { "DirectPlay message type 0x0029 unknown uint32 14 (16)", "dplay.type_29.unknown_uint32_14", FT_UINT32,
1547         BASE_DEC, NULL, 0x0, "", HFILL}},
1548     { &hf_dplay_type_29_unknown_uint32_15,
1549         { "DirectPlay message type 0x0029 unknown uint32 15 (15)", "dplay.type_29.unknown_uint32_15", FT_UINT32,
1550         BASE_DEC, NULL, 0x0, "", HFILL}},
1551     { &hf_dplay_type_29_dpid_3,
1552         { "DirectPlay message type 0x0029 DPID", "dplay.type_29.dpid", FT_BYTES, BASE_HEX,
1553         NULL, 0x0, "", HFILL}},
1554     { &hf_dplay_type_29_unknown_uint32_16,
1555         { "DirectPlay message type 0x0029 unknown uint32 16 (4)", "dplay.type_29.unknown_uint32_16", FT_UINT32,
1556         BASE_DEC, NULL, 0x0, "", HFILL}},
1557     { &hf_dplay_type_29_unknown_uint32_17,
1558         { "DirectPlay message type 0x0029 unknown uint32 17 (14)", "dplay.type_29.unknown_uint32_17", FT_UINT32,
1559         BASE_DEC, NULL, 0x0, "", HFILL}},
1560     { &hf_dplay_type_29_saddr_field_len_2,
1561         { "DirectPlay message type 0x0029 saddr field len 2", "dplay.type_29.saddr_field_len_2", FT_UINT8,
1562         BASE_DEC, NULL, 0x0, "", HFILL}},
1563     { &hf_dplay_type_29_saddr_af_3,
1564         { "DirectPlay message type 0x0029 s_addr_in address family 3", "dplay.type_29.saddr.af_3", FT_UINT16,
1565             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1566     { &hf_dplay_type_29_saddr_port_3,
1567         { "DirectPlay message type 0x0029 s_addr_in port 3", "dplay.type_29.saddr.port_3", FT_UINT16, BASE_DEC,
1568         NULL, 0x0, "", HFILL}},
1569     { &hf_dplay_type_29_saddr_ip_3,
1570         { "DirectPlay message type 0x0029 s_addr_in ip 3", "dplay.type_29.saddr.ip_3", FT_IPv4, BASE_NONE,
1571         NULL, 0x0, "", HFILL}},
1572     { &hf_dplay_type_29_saddr_padd_3,
1573         { "DirectPlay message type 0x0029 s_addr_in padding 3", "dplay.type_29.saddr.padd_3", FT_BYTES, BASE_HEX,
1574         NULL, 0x0, "", HFILL}},
1575     { &hf_dplay_type_29_saddr_af_4,
1576         { "DirectPlay message type 0x0029 s_addr_in address family 4", "dplay.type_29.saddr.af_4", FT_UINT16,
1577             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1578     { &hf_dplay_type_29_saddr_port_4,
1579         { "DirectPlay message type 0x0029 s_addr_in port 4", "dplay.type_29.saddr.port_4", FT_UINT16, BASE_DEC,
1580         NULL, 0x0, "", HFILL}},
1581     { &hf_dplay_type_29_saddr_ip_4,
1582         { "DirectPlay message type 0x0029 s_addr_in ip 4", "dplay.type_29.saddr.ip42", FT_IPv4, BASE_NONE,
1583         NULL, 0x0, "", HFILL}},
1584     { &hf_dplay_type_29_saddr_padd_4,
1585         { "DirectPlay message type 0x0029 s_addr_in padding 4", "dplay.type_29.saddr.padd_4", FT_BYTES, BASE_HEX,
1586         NULL, 0x0, "", HFILL}},
1587     { &hf_dplay_type_29_unknown_uint32_18,
1588         { "DirectPlay message type 0x0029 unknown uint32 18 (16)", "dplay.type_29.unknown_uint32_18", FT_UINT32,
1589         BASE_DEC, NULL, 0x0, "", HFILL}},
1590     { &hf_dplay_type_29_unknown_uint32_19,
1591         { "DirectPlay message type 0x0029 unknown uint32 19 (15)", "dplay.type_29.unknown_uint32_19", FT_UINT32,
1592         BASE_DEC, NULL, 0x0, "", HFILL}},
1593     { &hf_dplay_type_29_dpid_4,
1594         { "DirectPlay message type 0x0029 DPID", "dplay.type_29.dpid_4", FT_BYTES, BASE_HEX,
1595         NULL, 0x0, "", HFILL}},
1596     { &hf_dplay_type_29_unknown_uint32_20,
1597         { "DirectPlay message type 0x0029 unknown uint32 20", "dplay.type_29.unknown_uint32_20", FT_UINT32,
1598         BASE_DEC, NULL, 0x0, "", HFILL}},
1599     { &hf_dplay_type_29_dpid_5,
1600         { "DirectPlay message type 0x0029 DPID", "dplay.type_29.dpid_5", FT_BYTES, BASE_HEX,
1601         NULL, 0x0, "", HFILL}},
1602
1603     /* Data fields for message type 0x002e */
1604     { &hf_dplay_type_2e_padding_1,
1605         { "DirectPlay message type 0x002e padding 1", "dplay.type_2e.padding_1", FT_BYTES, BASE_HEX,
1606         NULL, 0x0, "", HFILL}},
1607     { &hf_dplay_type_2e_dpid_1,
1608         { "DirectPlay message type 0x002e client DP ID", "dplay.type_2e.dpid_1", FT_BYTES, BASE_HEX,
1609         NULL, 0x0, "", HFILL}},
1610     { &hf_dplay_type_2e_unknown_1,
1611         { "DirectPlay message type 0x002e unknown 1", "dplay.type_2e.unknown_1", FT_BYTES, BASE_HEX,
1612         NULL, 0x0, "", HFILL}},
1613     { &hf_dplay_type_2e_dpid_2,
1614         { "DirectPlay message type 0x002e client DP ID", "dplay.type_2e.dpid_2", FT_BYTES, BASE_HEX,
1615         NULL, 0x0, "", HFILL}},
1616     { &hf_dplay_type_2e_string_1_len,
1617         { "DirectPlay message type 0x002e string 1 length", "dplay.type_2e.string_1.length", FT_UINT32,
1618         BASE_DEC, NULL, 0x0, "", HFILL}},
1619     { &hf_dplay_type_2e_string_2_len,
1620         { "DirectPlay message type 0x002e string 2 length", "dplay.type_2e.string_2.length", FT_UINT32,
1621         BASE_DEC, NULL, 0x0, "", HFILL}},
1622     { &hf_dplay_type_2e_unknown_2,
1623         { "DirectPlay message type 0x002e unknown 2", "dplay.type_2e.unknown_2", FT_BYTES, BASE_HEX,
1624         NULL, 0x0, "", HFILL}},
1625     { &hf_dplay_type_2e_dpid_3,
1626         { "DirectPlay message type 0x002e client DP ID", "dplay.type_2e.dpid_3", FT_BYTES, BASE_HEX,
1627         NULL, 0x0, "", HFILL}},
1628     { &hf_dplay_type_2e_unknown_3,
1629         { "DirectPlay message type 0x002e unknown 3", "dplay.type_2e.unknown_3", FT_BYTES, BASE_HEX,
1630         NULL, 0x0, "", HFILL}},
1631     { &hf_dplay_type_2e_string_1,
1632         { "DirectPlay message type 0x002e string 1", "dplay.type_2e.string_1", FT_STRING, BASE_NONE,
1633         NULL, 0x0, "", HFILL}},
1634     { &hf_dplay_type_2e_string_2,
1635         { "DirectPlay message type 0x002e string 2", "dplay.type_2e.string_2", FT_STRING, BASE_NONE,
1636         NULL, 0x0, "", HFILL}},
1637     { &hf_dplay_type_2e_saddr_af_1,
1638         { "DirectPlay message type 0x002e s_addr_in address family 1", "dplay.type_2e.saddr.af_1", FT_UINT16,
1639             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1640     { &hf_dplay_type_2e_saddr_port_1,
1641         { "DirectPlay message type 0x002e s_addr_in port 1", "dplay.type_2e.saddr.port_1", FT_UINT16, BASE_DEC,
1642         NULL, 0x0, "", HFILL}},
1643     { &hf_dplay_type_2e_saddr_ip_1,
1644         { "DirectPlay message type 0x002e s_addr_in ip 1", "dplay.type_2e.saddr.ip_1", FT_IPv4, BASE_NONE,
1645         NULL, 0x0, "", HFILL}},
1646     { &hf_dplay_type_2e_saddr_padd_1,
1647         { "DirectPlay message type 0x002e s_addr_in padding 1", "dplay.type_2e.saddr.padd_1", FT_BYTES, BASE_HEX,
1648         NULL, 0x0, "", HFILL}},
1649     { &hf_dplay_type_2e_saddr_af_2,
1650         { "DirectPlay message type 0x002e s_addr_in address family 2", "dplay.type_2e.saddr.af_2", FT_UINT16,
1651             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1652     { &hf_dplay_type_2e_saddr_port_2,
1653         { "DirectPlay message type 0x002e s_addr_in port 2", "dplay.type_2e.saddr.port_2", FT_UINT16, BASE_DEC,
1654         NULL, 0x0, "", HFILL}},
1655     { &hf_dplay_type_2e_saddr_ip_2,
1656         { "DirectPlay message type 0x002e s_addr_in ip 2", "dplay.type_2e.saddr.ip_2", FT_IPv4, BASE_NONE,
1657         NULL, 0x0, "", HFILL}},
1658     { &hf_dplay_type_2e_saddr_padd_2,
1659         { "DirectPlay message type 0x002e s_addr_in padding 2", "dplay.type_2e.saddr.padd_2", FT_BYTES, BASE_HEX,
1660         NULL, 0x0, "", HFILL}},
1661
1662     /* Data fields for message type 0x002f */
1663     { &hf_dplay_type_2f_dpid,
1664         { "DirectPlay message type 0x002f DP ID", "dplay.type_29.dpid", FT_BYTES, BASE_HEX,
1665         NULL, 0x0, "", HFILL}},
1666
1667     /* Data fields for message type 0x0038 */
1668     { &hf_dplay_type_38_padding_1,
1669         { "DirectPlay message type 0x0038 padding 1", "dplay.type_38.padding_1", FT_BYTES, BASE_HEX,
1670         NULL, 0x0, "", HFILL}},
1671     { &hf_dplay_type_38_dpid_1,
1672         { "DirectPlay message type 0x0038 client DP ID", "dplay.type_38.dpid_1", FT_BYTES, BASE_HEX,
1673         NULL, 0x0, "", HFILL}},
1674     { &hf_dplay_type_38_unknown_1,
1675         { "DirectPlay message type 0x0038 unknown 1", "dplay.type_38.unknown_1", FT_BYTES, BASE_HEX,
1676         NULL, 0x0, "", HFILL}},
1677     { &hf_dplay_type_38_dpid_2,
1678         { "DirectPlay message type 0x0038 client DP ID", "dplay.type_38.dpid_2", FT_BYTES, BASE_HEX,
1679         NULL, 0x0, "", HFILL}},
1680     { &hf_dplay_type_38_string_1_len,
1681         { "DirectPlay message type 0x0038 string 1 length", "dplay.type_38.string_1.length", FT_UINT32,
1682         BASE_DEC, NULL, 0x0, "", HFILL}},
1683     { &hf_dplay_type_38_string_2_len,
1684         { "DirectPlay message type 0x0038 string 2 length", "dplay.type_38.string_2.length", FT_UINT32,
1685         BASE_DEC, NULL, 0x0, "", HFILL}},
1686     { &hf_dplay_type_38_unknown_2,
1687         { "DirectPlay message type 0x0038 unknown 2", "dplay.type_38.unknown_2", FT_BYTES, BASE_HEX,
1688         NULL, 0x0, "", HFILL}},
1689     { &hf_dplay_type_38_dpid_3,
1690         { "DirectPlay message type 0x0038 client DP ID", "dplay.type_38.dpid_3", FT_BYTES, BASE_HEX,
1691         NULL, 0x0, "", HFILL}},
1692     { &hf_dplay_type_38_unknown_3,
1693         { "DirectPlay message type 0x0038 unknown 3", "dplay.type_38.unknown_3", FT_BYTES, BASE_HEX,
1694         NULL, 0x0, "", HFILL}},
1695     { &hf_dplay_type_38_string_1,
1696         { "DirectPlay message type 0x0038 string 1", "dplay.type_38.string_1", FT_STRING, BASE_NONE,
1697         NULL, 0x0, "", HFILL}},
1698     { &hf_dplay_type_38_string_2,
1699         { "DirectPlay message type 0x0038 string 2", "dplay.type_38.string_2", FT_STRING, BASE_NONE,
1700         NULL, 0x0, "", HFILL}},
1701     { &hf_dplay_type_38_saddr_af_1,
1702         { "DirectPlay message type 0x0038 s_addr_in address family 1", "dplay.type_38.saddr.af_1", FT_UINT16,
1703             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1704     { &hf_dplay_type_38_saddr_port_1,
1705         { "DirectPlay message type 0x0038 s_addr_in port 1", "dplay.type_38.saddr.port_1", FT_UINT16, BASE_DEC,
1706         NULL, 0x0, "", HFILL}},
1707     { &hf_dplay_type_38_saddr_ip_1,
1708         { "DirectPlay message type 0x0038 s_addr_in ip 1", "dplay.type_38.saddr.ip_1", FT_IPv4, BASE_NONE,
1709         NULL, 0x0, "", HFILL}},
1710     { &hf_dplay_type_38_saddr_padd_1,
1711         { "DirectPlay message type 0x0038 s_addr_in padding 1", "dplay.type_38.saddr.padd_1", FT_BYTES, BASE_HEX,
1712         NULL, 0x0, "", HFILL}},
1713     { &hf_dplay_type_38_saddr_af_2,
1714         { "DirectPlay message type 0x0038 s_addr_in address family 2", "dplay.type_38.saddr.af_2", FT_UINT16,
1715             BASE_DEC, VALS(dplay_af_val), 0x0, "", HFILL}},
1716     { &hf_dplay_type_38_saddr_port_2,
1717         { "DirectPlay message type 0x0038 s_addr_in port 2", "dplay.type_38.saddr.port_2", FT_UINT16, BASE_DEC,
1718         NULL, 0x0, "", HFILL}},
1719     { &hf_dplay_type_38_saddr_ip_2,
1720         { "DirectPlay message type 0x0038 s_addr_in ip 2", "dplay.type_38.saddr.ip_2", FT_IPv4, BASE_NONE,
1721         NULL, 0x0, "", HFILL}},
1722     { &hf_dplay_type_38_saddr_padd_2,
1723         { "DirectPlay message type 0x0038 s_addr_in padding 2", "dplay.type_38.saddr.padd_2", FT_BYTES, BASE_HEX,
1724         NULL, 0x0, "", HFILL}},
1725     };
1726
1727     static gint *ett[] = {
1728         &ett_dplay,
1729         &ett_dplay_header,
1730         &ett_dplay_sockaddr,
1731         &ett_dplay_data,
1732         &ett_dplay_flags,
1733         &ett_dplay_enc_packet,
1734         &ett_dplay_sess_desc_flags,
1735         &ett_dplay_type08_saddr1,
1736         &ett_dplay_type08_saddr2,
1737         &ett_dplay_type13_saddr1,
1738         &ett_dplay_type13_saddr2,
1739         &ett_dplay_type29_saddr1,
1740         &ett_dplay_type29_saddr2,
1741         &ett_dplay_type29_saddr3,
1742         &ett_dplay_type29_saddr4,
1743         &ett_dplay_type2e_saddr1,
1744         &ett_dplay_type2e_saddr2,
1745         &ett_dplay_type38_saddr1,
1746         &ett_dplay_type38_saddr2,
1747     };
1748     module_t *dplay_module;
1749
1750     if(proto_dplay == -1)
1751     {
1752         proto_dplay = proto_register_protocol (
1753                 "DirectPlay Protocol",
1754                 "DPLAY",
1755                 "dplay"
1756                 );
1757         proto_register_field_array(proto_dplay, hf, array_length(hf));
1758         proto_register_subtree_array(ett, array_length(ett));
1759         dplay_module = prefs_register_protocol(proto_dplay, proto_reg_handoff_dplay);
1760     }
1761 }
1762
1763 void proto_reg_handoff_dplay(void)
1764 {
1765     static int initialized = FALSE;
1766
1767     if(!initialized)
1768     {
1769         initialized = TRUE;
1770         heur_dissector_add("udp", heur_dissect_dplay, proto_dplay);
1771         heur_dissector_add("tcp", heur_dissect_dplay, proto_dplay);
1772         dplay_handle = create_dissector_handle(dissect_dplay, proto_dplay);
1773     }
1774 }
1775