1 /* packet-dtpt.c
2  * Routines for Microsoft ActiveSync Desktop Pass-Through (DTPT) packet
3  * dissection
4  *
5  * Uwe Girlich <uwe@planetquake.com>
6  *	http://www.synce.org/moin/ProtocolDocumentation/DesktopPassThrough
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-quake.c
13  *
14  * SPDX-License-Identifier: GPL-2.0-or-later
15  */
16 
17 #include "config.h"
18 
19 
20 #include <epan/packet.h>
21 #include <epan/conversation.h>
22 #include <epan/prefs.h>
23 #include <epan/to_str.h>
24 #include <epan/aftypes.h>
25 #include <epan/ipproto.h>
26 
27 void proto_register_dtpt(void);
28 
29 static int proto_dtpt = -1;
30 
31 static int hf_dtpt_version = -1;
32 static int hf_dtpt_message_type = -1;
33 static int hf_dtpt_flags = -1;
34 static int hf_dtpt_flags_deep = -1;
35 static int hf_dtpt_flags_containers = -1;
36 static int hf_dtpt_flags_nocontainers = -1;
37 static int hf_dtpt_flags_nearest = -1;
38 static int hf_dtpt_flags_return_name = -1;
39 static int hf_dtpt_flags_return_type = -1;
40 static int hf_dtpt_flags_return_version = -1;
41 static int hf_dtpt_flags_return_comment = -1;
42 static int hf_dtpt_flags_return_addr = -1;
43 static int hf_dtpt_flags_return_blob = -1;
44 static int hf_dtpt_flags_return_aliases = -1;
45 static int hf_dtpt_flags_return_query_string = -1;
46 static int hf_dtpt_flags_flushcache = -1;
47 static int hf_dtpt_flags_flushprevious = -1;
48 static int hf_dtpt_flags_res_service = -1;
49 static int hf_dtpt_payload_size = -1;
50 static int hf_dtpt_handle = -1;
51 static int hf_dtpt_error = -1;
52 static int hf_dtpt_buffer_size = -1;
53 static int hf_dtpt_data_size = -1;
54 static int hf_dtpt_queryset_rawsize = -1;
55 static int hf_dtpt_queryset_size = -1;
56 static int hf_dtpt_queryset_service_instance_name_pointer = -1;
57 static int hf_dtpt_queryset_service_class_id_pointer = -1;
58 static int hf_dtpt_queryset_version = -1;
59 static int hf_dtpt_queryset_comment_pointer = -1;
60 static int hf_dtpt_queryset_namespace = -1;
61 static int hf_dtpt_queryset_provider_id_pointer = -1;
62 static int hf_dtpt_queryset_context_pointer = -1;
63 static int hf_dtpt_queryset_protocols_number = -1;
64 static int hf_dtpt_queryset_protocols_pointer = -1;
65 static int hf_dtpt_queryset_query_string_pointer = -1;
66 static int hf_dtpt_queryset_cs_addrs_number = -1;
67 static int hf_dtpt_queryset_cs_addrs_pointer = -1;
68 static int hf_dtpt_queryset_output_flags = -1;
69 static int hf_dtpt_queryset_blob_pointer = -1;
70 static int hf_dtpt_wstring_length = -1;
71 static int hf_dtpt_wstring_data = -1;
72 static int hf_dtpt_guid_length = -1;
73 static int hf_dtpt_guid_data = -1;
74 static int hf_dtpt_service_instance_name = -1;
75 static int hf_dtpt_service_class_id = -1;
76 static int hf_dtpt_comment = -1;
77 static int hf_dtpt_ns_provider_id = -1;
78 static int hf_dtpt_context = -1;
79 static int hf_dtpt_protocols_number = -1;
80 static int hf_dtpt_protocols_length = -1;
81 static int hf_dtpt_protocol_family = -1;
82 static int hf_dtpt_protocol_protocol = -1;
83 static int hf_dtpt_query_string = -1;
84 static int hf_dtpt_cs_addrs_number = -1;
85 static int hf_dtpt_cs_addrs_length1 = -1;
86 static int hf_dtpt_cs_addr_socket_type = -1;
87 static int hf_dtpt_cs_addr_protocol = -1;
88 static int hf_dtpt_cs_addr_local_pointer = -1;
89 static int hf_dtpt_cs_addr_local_length = -1;
90 static int hf_dtpt_cs_addr_local = -1;
91 static int hf_dtpt_cs_addr_remote_pointer = -1;
92 static int hf_dtpt_cs_addr_remote_length = -1;
93 static int hf_dtpt_cs_addr_remote = -1;
94 static int hf_dtpt_sockaddr_length = -1;
95 static int hf_dtpt_sockaddr_family = -1;
96 static int hf_dtpt_sockaddr_port = -1;
97 static int hf_dtpt_sockaddr_address = -1;
98 static int hf_dtpt_blob_rawsize = -1;
99 static int hf_dtpt_blob_size = -1;
100 static int hf_dtpt_blob_data_pointer = -1;
101 static int hf_dtpt_blob_data_length = -1;
102 static int hf_dtpt_blob_data = -1;
103 static int hf_dtpt_connect_addr = -1;
104 static int hf_dtpt_padding = -1;
105 
106 static gint ett_dtpt = -1;
107 static gint ett_dtpt_flags = -1;
108 static gint ett_dtpt_queryset = -1;
109 static gint ett_dtpt_wstring = -1;
110 static gint ett_dtpt_guid = -1;
111 static gint ett_dtpt_protocols = -1;
112 static gint ett_dtpt_protocol = -1;
113 static gint ett_dtpt_cs_addrs = -1;
114 static gint ett_dtpt_cs_addr1 = -1;
115 static gint ett_dtpt_cs_addr2 = -1;
116 static gint ett_dtpt_sockaddr = -1;
117 static gint ett_dtpt_blobraw = -1;
118 static gint ett_dtpt_blob = -1;
119 
120 
121 
122 static dissector_handle_t	dtpt_conversation_handle;
123 /** static dissector_handle_t	dtpt_data_handle;  **/
124 
125 
126 /* Server port */
127 #define TCP_SERVER_PORT     5721
128 
129 static const value_string names_message_type[] = {
130 #define LookupBeginRequest 9
131 	{	LookupBeginRequest, "LookupBeginRequest" },
132 #define LookupBeginResponse 10
133 	{	LookupBeginResponse, "LookupBeginResponse" },
134 #define LookupNextRequest 11
135 	{	LookupNextRequest, "LookupNextRequest" },
136 #define LookupNextResponse 12
137 	{	LookupNextResponse, "LookupNextResponse" },
138 #define LookupEndRequest 13
139 	{	LookupEndRequest, "LookupEndRequest" },
140 #define ConnectRequest 1
141 	{	ConnectRequest, "ConnectRequest" },
142 #define ConnectResponseOK 0x5A
143 	{	ConnectResponseOK, "ConnectResponseOK" },
144 #define ConnectResponseERR 0x5B
145 	{	ConnectResponseERR, "ConnectResponseERR" },
146 	{ 0, NULL }
147 };
148 
149 static const value_string names_error[] = {
150 	{	0,     "OK" },
151 	{	10014, "WSAEFAULT" },
152 	{	10060, "WSAETIMEDOUT" },
153 	{	10108, "WSASERVICE_NOT_FOUND" },
154 	{	11001, "WSAHOST_NOT_FOUND" },
155 	{	0, NULL	}
156 };
157 
158 static const value_string names_family[] = {
159 	{	WINSOCK_AF_INET, "AF_INET"	},
160 	{	0, NULL	}
161 };
162 
163 /*
164  * Winsock's SOCK_ values.  These are probably the same as they are on
165  * other OSes, as they probably all come from 4.2BSD, but it's still
166  * best to define them ourselves (to avoid problems if other OSes
167  * define them differently, and to avoid having to include system
168  * header files that might require a bunch of other includes).
169  */
170 #define WINSOCK_SOCK_STREAM	1
171 #define WINSOCK_SOCK_DGRAM	2
172 #define WINSOCK_SOCK_RAW	3
173 
174 static const value_string names_socket_type[] = {
175 	{	WINSOCK_SOCK_STREAM,	"SOCK_STREAM"	},
176 	{	WINSOCK_SOCK_DGRAM,	"SOCK_DGRAM"	},
177 	{	WINSOCK_SOCK_RAW,	"SOCK_RAW"	},
178 	{	0, NULL	}
179 };
180 
181 #define DTPT_PROTO_IP		0
182 #define DTPT_PROTO_TCP		IP_PROTO_TCP
183 #define DTPT_PROTO_UDP		IP_PROTO_UDP
184 
185 static const value_string names_protocol[] = {
186 	{	DTPT_PROTO_IP,	"IPPROTO_IP"	},
187 	{	DTPT_PROTO_TCP,	"IPPROTO_TCP"	},
188 	{	DTPT_PROTO_UDP,	"IPPROTP_UDP"	},
189 	{	0, NULL	}
190 };
191 
192 #define LUP_DEEP                0x0001
193 #define LUP_CONTAINERS          0x0002
194 #define LUP_NOCONTAINERS        0x0004
195 #define LUP_NEAREST             0x0008
196 #define LUP_RETURN_NAME         0x0010
197 #define LUP_RETURN_TYPE         0x0020
198 #define LUP_RETURN_VERSION      0x0040
199 #define LUP_RETURN_COMMENT      0x0080
200 #define LUP_RETURN_ADDR         0x0100
201 #define LUP_RETURN_BLOB         0x0200
202 #define LUP_RETURN_ALIASES      0x0400
203 #define LUP_RETURN_QUERY_STRING 0x0800
204 #define LUP_FLUSHCACHE          0x1000
205 #define LUP_FLUSHPREVIOUS       0x2000
206 #define LUP_RES_SERVICE         0x8000
207 
208 #define SOCKADDR_WITH_LEN	1
209 #define SOCKADDR_CONNECT	2
210 
211 static int
212 dissect_dtpt_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
213 static int
214 dissect_dtpt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
215 
216 
217 static int
dissect_dtpt_wstring(tvbuff_t * tvb,guint offset,proto_tree * tree,int hfindex)218 dissect_dtpt_wstring(tvbuff_t *tvb, guint offset, proto_tree *tree, int hfindex)
219 {
220 	guint32	wstring_length;
221 	guint32	wstring_size;
222 	char	*wstring_data = NULL;
223 	guint32	wstring_padding = 0;
224 
225 	wstring_length = tvb_get_letohl(tvb, offset);
226 	wstring_data = tvb_get_string_enc(wmem_packet_scope(), tvb, offset+4, wstring_length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
227 	wstring_size = wstring_length;
228 	if (wstring_size%4) {
229 		wstring_padding = (4-wstring_size%4);
230 		wstring_size += wstring_padding;
231 	}
232 	if (tree) {
233 		proto_item	*dtpt_wstring_item;
234 		proto_tree	*dtpt_wstring_tree;
235 		dtpt_wstring_item = proto_tree_add_string(tree, hfindex,
236 			tvb, offset+0, 4+wstring_size, wstring_data);
237 		dtpt_wstring_tree = proto_item_add_subtree(dtpt_wstring_item, ett_dtpt_wstring);
238 		if (dtpt_wstring_tree) {
239 			proto_tree_add_uint(dtpt_wstring_tree, hf_dtpt_wstring_length,
240 				tvb, offset+0, 4, wstring_length);
241 			if (wstring_length)
242 				proto_tree_add_string(dtpt_wstring_tree, hf_dtpt_wstring_data,
243 					tvb, offset+4, wstring_length, wstring_data);
244 			if (wstring_padding)
245 				proto_tree_add_item(dtpt_wstring_tree, hf_dtpt_padding, tvb,
246 					offset+4+wstring_length,wstring_padding, ENC_NA);
247 		}
248 	}
249 	offset += 4+wstring_size;
250 	return offset;
251 }
252 
253 static int
dissect_dtpt_guid(tvbuff_t * tvb,guint offset,proto_tree * tree,int hfindex)254 dissect_dtpt_guid(tvbuff_t *tvb, guint offset, proto_tree *tree, int hfindex)
255 {
256 	guint32	guid_length;
257 
258 	guid_length = tvb_get_letohl(tvb, offset);
259 	if (tree) {
260 		e_guid_t	guid;
261 		proto_item	*dtpt_guid_item = NULL;
262 		proto_tree	*dtpt_guid_tree = NULL;
263 		const gchar	*guid_name = NULL;
264 
265 		if (guid_length) {
266 			tvb_get_guid(tvb, offset+4, &guid, ENC_LITTLE_ENDIAN);
267 		}
268 		else {
269 			memset(&guid, 0, sizeof(guid));
270 		}
271 		dtpt_guid_item = proto_tree_add_guid(tree, hfindex, tvb, offset, 4 + guid_length, &guid);
272 		if (dtpt_guid_item) {
273 			guid_name = guids_get_guid_name(&guid, wmem_packet_scope());
274 			if (guid_name != NULL)
275 				proto_item_set_text(dtpt_guid_item, "%s: %s (%s)",
276 				proto_registrar_get_name(hfindex), guid_name, guid_to_str(wmem_packet_scope(), &guid));
277 			dtpt_guid_tree = proto_item_add_subtree(dtpt_guid_item, ett_dtpt_guid);
278 		}
279 		if (dtpt_guid_tree) {
280 			proto_item	*dtpt_guid_data_item = NULL;
281 
282 			proto_tree_add_uint(dtpt_guid_tree, hf_dtpt_guid_length,
283 				tvb, offset, 4, guid_length);
284 			if (guid_length) {
285 				dtpt_guid_data_item = proto_tree_add_guid(dtpt_guid_tree, hf_dtpt_guid_data,
286 					tvb, offset+4, guid_length, &guid);
287 				if (guid_name != NULL && dtpt_guid_data_item != NULL) {
288 					proto_item_set_text(dtpt_guid_data_item, "%s: %s (%s)",
289 					proto_registrar_get_name(hf_dtpt_guid_data),
290 					guid_name, guid_to_str(wmem_packet_scope(), &guid));
291 				}
292 			}
293 		}
294 	}
295 	offset+=4;
296 	offset+=guid_length;
297 
298 	return offset;
299 }
300 
301 static int
dissect_dtpt_sockaddr(tvbuff_t * tvb,guint offset,proto_tree * tree,int hfindex,int sockaddr_type)302 dissect_dtpt_sockaddr(tvbuff_t *tvb, guint offset, proto_tree *tree, int hfindex, int sockaddr_type)
303 {
304 	guint32	sockaddr_length = 0;
305 	proto_item	*sockaddr_item = NULL;
306 	proto_tree	*sockaddr_tree = NULL;
307 	guint32		sockaddr_len1 = 0;
308 	guint32		sockaddr_len2 = 0;
309 
310 	switch (sockaddr_type) {
311 		case SOCKADDR_WITH_LEN:
312 			sockaddr_len1=4;
313 			sockaddr_len2=16;
314 		break;
315 		case SOCKADDR_CONNECT:
316 			sockaddr_len1=0;
317 			sockaddr_len2=30;
318 		break;
319 	}
320 
321 	if (sockaddr_type == SOCKADDR_WITH_LEN)
322 		sockaddr_length = tvb_get_letohl(tvb, offset + 0);
323 
324 	if (tree) {
325 		sockaddr_tree = proto_tree_add_subtree(tree, tvb, offset, sockaddr_len1+sockaddr_len2,
326 			ett_dtpt_sockaddr, NULL, proto_registrar_get_name(hfindex));
327 
328 		if (sockaddr_type == SOCKADDR_WITH_LEN)
329 			proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_length,
330 						tvb, offset+0, 4, sockaddr_length);
331 	}
332 
333 	offset += sockaddr_len1;
334 
335 	if (sockaddr_tree) {
336 		switch (sockaddr_type) {
337 			case SOCKADDR_WITH_LEN: {
338 				guint16 family;
339 
340 				family = tvb_get_letohs(tvb, offset);
341 				proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_family,
342 						tvb, offset, 2, family);
343 				switch (family) {
344 					case WINSOCK_AF_INET: {
345 						guint16 port;
346 
347 						port = tvb_get_ntohs(tvb,offset+2);
348 						proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_port,
349 											tvb, offset+2,2,port);
350 						proto_tree_add_item(sockaddr_tree, hf_dtpt_sockaddr_address,
351 											tvb, offset+4,4,ENC_BIG_ENDIAN);
352 						proto_tree_add_item(sockaddr_tree, hf_dtpt_padding, tvb, offset+8, 8, ENC_NA);
353 						proto_item_append_text(sockaddr_item, ": %s:%d", tvb_ip_to_str(wmem_packet_scope(), tvb,offset+4), port);
354 					}
355 					break;
356 				}
357 			}
358 			break;
359 			case SOCKADDR_CONNECT: {
360 				guint32	family;
361 
362 				family = tvb_get_letohl(tvb, offset+0);
363 				proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_family,
364 						tvb, offset+0, 4, family);
365 				switch (family) {
366 					case WINSOCK_AF_INET: {
367 						guint16 port;
368 
369 						proto_tree_add_item(sockaddr_tree, hf_dtpt_padding, tvb, offset+4, 4, ENC_NA);
370 						port = tvb_get_ntohs(tvb,offset+8);
371 						proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_port,
372 							tvb, offset+8,2,port);
373 						proto_tree_add_item(sockaddr_tree, hf_dtpt_sockaddr_address,
374 							tvb, offset+10,4,ENC_BIG_ENDIAN);
375 						proto_tree_add_item(sockaddr_tree, hf_dtpt_padding, tvb, offset+14, 16, ENC_NA);
376 						proto_item_append_text(sockaddr_item, ": %s:%d", tvb_ip_to_str(wmem_packet_scope(), tvb,offset+10), port);
377 					}
378 					break;
379 				}
380 			}
381 			break;
382 		}
383 
384 	}
385 	offset += sockaddr_len2;
386 	return offset;
387 }
388 
389 static int
dissect_dtpt_conversation(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)390 dissect_dtpt_conversation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
391 {
392 	guint		offset = 0;
393 
394 	/* First try to decode it as "normal" DTPT packets. */
395 	offset = dissect_dtpt(tvb, pinfo, tree, NULL);
396 
397 	if (offset == 0) {
398 		/* No, maybe it was a DTPT data packet. */
399 		offset = dissect_dtpt_data(tvb, pinfo, tree);
400 	}
401 
402 	/* Handle any remaining bytes ... */
403 	if (tvb_reported_length_remaining(tvb, offset) > 0) {
404 		/* ... as data. */
405 		call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
406 	}
407 	return tvb_reported_length(tvb);
408 }
409 
410 
411 static int
dissect_dtpt_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)412 dissect_dtpt_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
413 {
414 	proto_item	*dtpt_item;
415 	proto_tree	*dtpt_tree;
416 	proto_tree	*dtpt_queryset_tree;
417 	guint		offset = 0;
418 	guint32		queryset_rawsize;
419 	guint32		queryset_size;
420 	guint32		num_protocols;
421 	guint32		protocols_length = 0;
422 	guint32		addrs_start;
423 	guint32		num_addrs;
424 	guint32		addrs_length1 = 0;
425 	proto_item	*dtpt_addrs_item = NULL;
426 	proto_tree	*dtpt_addrs_tree = NULL;
427 	guint32		blob_rawsize = 0;
428 	guint32		blob_size = 0;
429 	guint32		blob_data_length = 0;
430 
431 	queryset_rawsize = tvb_get_letohl(tvb, offset + 0);
432 	if (queryset_rawsize != 60) return 0;
433 	queryset_size = tvb_get_letohl(tvb, offset + 4);
434 	if (queryset_size != 60) return 0;
435 
436 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DTPT");
437 	col_set_str(pinfo->cinfo, COL_INFO, "QuerySet");
438 
439 	dtpt_item = proto_tree_add_item(tree, proto_dtpt, tvb, 0, -1, ENC_NA);
440 	dtpt_tree = proto_item_add_subtree(dtpt_item, ett_dtpt);
441 
442 	if (dtpt_tree) {
443 		proto_tree_add_uint(dtpt_tree, hf_dtpt_queryset_rawsize,
444 			tvb, 0, 4, queryset_rawsize);
445 
446 		dtpt_queryset_tree = proto_tree_add_subtree(dtpt_tree, tvb, 4, 60,
447 			ett_dtpt_queryset, NULL, "QuerySet raw");
448 
449 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_size,
450 			tvb, offset+4+0,  4, ENC_LITTLE_ENDIAN);
451 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_service_instance_name_pointer,
452 			tvb, offset+4+4,  4, ENC_LITTLE_ENDIAN);
453 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_service_class_id_pointer,
454 			tvb, offset+4+8,  4, ENC_LITTLE_ENDIAN);
455 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_version,
456 			tvb, offset+4+12, 4, ENC_LITTLE_ENDIAN);
457 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_comment_pointer,
458 			tvb, offset+4+16, 4, ENC_LITTLE_ENDIAN);
459 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_namespace,
460 			tvb, offset+4+20, 4, ENC_LITTLE_ENDIAN);
461 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_provider_id_pointer,
462 			tvb, offset+4+24, 4, ENC_LITTLE_ENDIAN);
463 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_context_pointer,
464 			tvb, offset+4+28, 4, ENC_LITTLE_ENDIAN);
465 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_protocols_number,
466 			tvb, offset+4+32, 4, ENC_LITTLE_ENDIAN);
467 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_protocols_pointer,
468 			tvb, offset+4+36, 4, ENC_LITTLE_ENDIAN);
469 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_query_string_pointer,
470 			tvb, offset+4+40, 4, ENC_LITTLE_ENDIAN);
471 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_cs_addrs_number,
472 			tvb, offset+4+44, 4, ENC_LITTLE_ENDIAN);
473 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_cs_addrs_pointer,
474 			tvb, offset+4+48, 4, ENC_LITTLE_ENDIAN);
475 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_output_flags,
476 			tvb, offset+4+52, 4, ENC_LITTLE_ENDIAN);
477 		proto_tree_add_item(dtpt_queryset_tree, hf_dtpt_queryset_blob_pointer,
478 			tvb, offset+4+56, 4, ENC_LITTLE_ENDIAN);
479 	}
480 
481 	offset += 4;
482 	offset += 60;
483 
484 	offset = dissect_dtpt_wstring(tvb, offset, dtpt_tree, hf_dtpt_service_instance_name);
485 	offset = dissect_dtpt_guid   (tvb, offset, dtpt_tree, hf_dtpt_service_class_id     );
486 	offset = dissect_dtpt_wstring(tvb, offset, dtpt_tree, hf_dtpt_comment              );
487 	offset = dissect_dtpt_guid   (tvb, offset, dtpt_tree, hf_dtpt_ns_provider_id       );
488 	offset = dissect_dtpt_wstring(tvb, offset, dtpt_tree, hf_dtpt_context              );
489 	num_protocols = tvb_get_letohl(tvb, offset);
490 	if (num_protocols>0) {
491 		protocols_length = tvb_get_letohl(tvb, offset+4);
492 	}
493 	if (dtpt_tree) {
494 		proto_tree	*dtpt_protocols_tree = NULL;
495 		guint32		i;
496 
497 		dtpt_protocols_tree = proto_tree_add_subtree_format(dtpt_tree,
498 				tvb, offset, 4+(num_protocols>0?4:0)+num_protocols*8,
499 				ett_dtpt_protocols, NULL, "Protocols: %d", num_protocols);
500 
501 		if (dtpt_protocols_tree) {
502 			proto_tree_add_uint(dtpt_protocols_tree, hf_dtpt_protocols_number,
503 					tvb, offset, 4, num_protocols);
504 			if (num_protocols>0)
505 				proto_tree_add_uint(dtpt_protocols_tree, hf_dtpt_protocols_length,
506 						tvb, offset+4, 4, protocols_length);
507 			for (i=0;i<num_protocols;i++) {
508 				proto_tree	*dtpt_protocol_tree = NULL;
509 
510 				dtpt_protocol_tree = proto_tree_add_subtree_format(dtpt_protocols_tree,
511 						tvb, offset+4+4+i*8, 8, ett_dtpt_protocol, NULL, "Protocol[%d]", i+1);
512 
513 				proto_tree_add_item(dtpt_protocol_tree, hf_dtpt_protocol_family,
514 					tvb, offset+4+4+i*8, 4, ENC_LITTLE_ENDIAN);
515 				proto_tree_add_item(dtpt_protocol_tree, hf_dtpt_protocol_protocol,
516 					tvb, offset+4+4+i*8+4, 4, ENC_LITTLE_ENDIAN);
517 			}
518 		}
519 	}
520 	offset += 4 + (num_protocols>0?4:0) + num_protocols*8;
521 	offset = dissect_dtpt_wstring(tvb, offset, dtpt_tree, hf_dtpt_query_string);
522 
523 	addrs_start = offset;
524 	num_addrs = tvb_get_letohl(tvb, offset);
525 	if (num_addrs>0) {
526 		addrs_length1 = tvb_get_letohl(tvb, offset+4);
527 	}
528 	if (dtpt_tree) {
529 		dtpt_addrs_tree = proto_tree_add_subtree(dtpt_tree,
530 			tvb, offset, -1, ett_dtpt_cs_addrs, &dtpt_addrs_item, "Addresses");
531 		if (dtpt_addrs_tree) {
532 			proto_tree_add_uint(dtpt_addrs_tree, hf_dtpt_cs_addrs_number,
533 				tvb, offset, 4, num_addrs);
534 			if (num_addrs>0)
535 				proto_tree_add_uint(dtpt_addrs_tree, hf_dtpt_cs_addrs_length1,
536 					tvb, offset+4, 4, addrs_length1);
537 		}
538 	}
539 	offset += 4 + (num_addrs>0?4:0);
540 
541 	if (num_addrs>0) {
542 		guint32	i;
543 		guint32	offset2;
544 
545 		offset2 = offset + 24*num_addrs;
546 
547 		for (i=0;i<num_addrs;i++,offset+=24) {
548 			proto_tree	*dtpt_addr1_tree = NULL;
549 			proto_item	*dtpt_addr2_item = NULL;
550 			proto_tree	*dtpt_addr2_tree = NULL;
551 			guint32		offset2_start;
552 
553 			if (dtpt_addrs_tree) {
554 				dtpt_addr1_tree = proto_tree_add_subtree_format(dtpt_addrs_tree,
555 					tvb, offset, 24, ett_dtpt_cs_addr1, NULL, "Address[%u] Part 1", i+1);
556 
557 				proto_tree_add_item(dtpt_addr1_tree, hf_dtpt_cs_addr_local_pointer,
558 					tvb, offset+ 0, 4, ENC_LITTLE_ENDIAN);
559 				proto_tree_add_item(dtpt_addr1_tree, hf_dtpt_cs_addr_local_length,
560 					tvb, offset+ 4, 4, ENC_LITTLE_ENDIAN);
561 				proto_tree_add_item(dtpt_addr1_tree, hf_dtpt_cs_addr_remote_pointer,
562 					tvb, offset+ 8, 4, ENC_LITTLE_ENDIAN);
563 				proto_tree_add_item(dtpt_addr1_tree, hf_dtpt_cs_addr_remote_length,
564 					tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
565 				proto_tree_add_item(dtpt_addr1_tree, hf_dtpt_cs_addr_socket_type,
566 					tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
567 				proto_tree_add_item(dtpt_addr1_tree, hf_dtpt_cs_addr_protocol,
568 					tvb, offset+20, 4, ENC_LITTLE_ENDIAN);
569 
570 				dtpt_addr2_tree = proto_tree_add_subtree_format(dtpt_addrs_tree,
571 					tvb, offset2, -1, ett_dtpt_cs_addr2, &dtpt_addr2_item, "Address[%u] Part 2", i+1);
572 			}
573 
574 			offset2_start = offset2;
575 
576 			offset2 = dissect_dtpt_sockaddr(tvb, offset2, dtpt_addr2_tree, hf_dtpt_cs_addr_local, SOCKADDR_WITH_LEN);
577 			offset2 = dissect_dtpt_sockaddr(tvb, offset2, dtpt_addr2_tree, hf_dtpt_cs_addr_remote, SOCKADDR_WITH_LEN);
578 
579 			proto_item_set_len(dtpt_addr2_item,
580 					offset2 - offset2_start);
581 		}
582 		offset = offset2;
583 	}
584 
585 	proto_item_set_len(dtpt_addrs_item, offset - addrs_start);
586 	proto_item_set_len(dtpt_item, offset);
587 
588 	blob_rawsize = tvb_get_letohl(tvb, offset);
589 	if (blob_rawsize>=4) {
590 		blob_size = tvb_get_letohl(tvb,offset+4+0);
591 	}
592 
593 	if (dtpt_tree) {
594 		proto_tree	*dtpt_blobraw_tree;
595 
596 		proto_tree_add_uint(dtpt_tree, hf_dtpt_blob_rawsize,
597 				tvb, offset+0, 4, blob_rawsize);
598 		if (blob_rawsize>0) {
599 			dtpt_blobraw_tree = proto_tree_add_subtree(dtpt_tree,
600 				tvb, offset+4, blob_rawsize, ett_dtpt_blobraw, NULL, "Blob raw");
601 
602 			if (dtpt_blobraw_tree) {
603 				proto_tree_add_uint(dtpt_blobraw_tree, hf_dtpt_blob_size,
604 					tvb, offset+4+0, 4, blob_size);
605 				proto_tree_add_item(dtpt_blobraw_tree, hf_dtpt_blob_data_pointer,
606 					tvb, offset+4+4, 4, ENC_LITTLE_ENDIAN);
607 			}
608 		}
609 	}
610 
611 	offset += 4+blob_rawsize;
612 
613 	proto_item_set_len(dtpt_item, offset);
614 
615 	if (blob_size>0) {
616 		proto_tree	*dtpt_blob_tree;
617 
618 		blob_data_length = tvb_get_letohl(tvb,offset);
619 
620 		if (dtpt_tree) {
621 			dtpt_blob_tree = proto_tree_add_subtree(dtpt_tree,
622 				tvb, offset, 4+blob_data_length, ett_dtpt_blob, NULL, "Blob");
623 
624 			if (dtpt_blob_tree) {
625 				proto_tree_add_uint(dtpt_blob_tree, hf_dtpt_blob_data_length,
626 					tvb, offset+0, 4, blob_data_length);
627 				proto_tree_add_item(dtpt_blob_tree, hf_dtpt_blob_data,
628 					tvb, offset+4, blob_data_length, ENC_NA);
629 			}
630 		}
631 		offset += 4+blob_data_length;
632 		if (dtpt_item)
633 			proto_item_set_len(dtpt_item, offset);
634 	}
635 
636 	return offset;
637 }
638 
639 static int
dissect_dtpt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)640 dissect_dtpt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
641 {
642 	proto_tree	*dtpt_tree;
643 	proto_item	*dtpt_item;
644 	guint8		version;
645 	guint8		message_type;
646 	guint32		payload_size;
647 
648 	version = tvb_get_guint8(tvb, 0);
649 	if (version != 1) return 0;
650 	message_type = tvb_get_guint8(tvb, 1);
651 	switch (message_type) {
652 		case LookupBeginRequest:
653 		case LookupBeginResponse:
654 		case LookupNextRequest:
655 		case LookupNextResponse:
656 		case LookupEndRequest:
657 			if (tvb_reported_length(tvb) != 20) return 0;
658 		break;
659 		case ConnectRequest:
660 		case ConnectResponseOK:
661 		case ConnectResponseERR:
662 			if (tvb_reported_length(tvb) != 36) return 0;
663 		break;
664 		default:
665 			return 0;
666 	}
667 
668 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DTPT");
669 	col_add_str(pinfo->cinfo, COL_INFO, val_to_str(message_type, names_message_type, "Unknown (%d)"));
670 
671 	if (message_type == LookupBeginRequest) {
672 		conversation_t *c;
673 		c = find_or_create_conversation(pinfo);
674 		conversation_set_dissector(c, dtpt_conversation_handle);
675 	}
676 
677 	dtpt_item = proto_tree_add_item(tree, proto_dtpt, tvb, 0, -1, ENC_NA);
678 	dtpt_tree = proto_item_add_subtree(dtpt_item, ett_dtpt);
679 
680 	if (dtpt_tree) {
681 		proto_tree_add_uint(dtpt_tree, hf_dtpt_version,
682 			tvb, 0, 1, version);
683 		proto_tree_add_uint(dtpt_tree, hf_dtpt_message_type,
684 			tvb, 1, 1, message_type);
685 
686 		switch (message_type) {
687 			case LookupBeginRequest: {
688 				static int * const flags[] = {
689 					&hf_dtpt_flags_res_service,
690 					&hf_dtpt_flags_flushprevious,
691 					&hf_dtpt_flags_flushcache,
692 					&hf_dtpt_flags_return_query_string,
693 					&hf_dtpt_flags_return_aliases,
694 					&hf_dtpt_flags_return_blob,
695 					&hf_dtpt_flags_return_addr,
696 					&hf_dtpt_flags_return_comment,
697 					&hf_dtpt_flags_return_version,
698 					&hf_dtpt_flags_return_type,
699 					&hf_dtpt_flags_return_name,
700 					&hf_dtpt_flags_nearest,
701 					&hf_dtpt_flags_nocontainers,
702 					&hf_dtpt_flags_containers,
703 					&hf_dtpt_flags_deep,
704 					NULL
705 				};
706 
707 				proto_tree_add_bitmask(dtpt_tree, tvb, 12, hf_dtpt_flags, ett_dtpt_flags, flags, ENC_LITTLE_ENDIAN);
708 
709 				payload_size = tvb_get_letohl(tvb, 16);
710 				proto_tree_add_uint(dtpt_tree, hf_dtpt_payload_size,
711 					tvb, 16, 4, payload_size);
712 			}
713 			break;
714 			case LookupBeginResponse: {
715 				proto_tree_add_item(dtpt_tree, hf_dtpt_handle,
716 					tvb, 4, 8, ENC_LITTLE_ENDIAN);
717 				proto_tree_add_item(dtpt_tree, hf_dtpt_error,
718 					tvb, 12, 4, ENC_LITTLE_ENDIAN);
719 			}
720 			break;
721 			case LookupNextRequest: {
722 				proto_tree_add_item(dtpt_tree, hf_dtpt_handle,
723 					tvb, 4, 8, ENC_LITTLE_ENDIAN);
724 				proto_tree_add_item(dtpt_tree, hf_dtpt_buffer_size,
725 					tvb, 16, 4, ENC_LITTLE_ENDIAN);
726 			}
727 			break;
728 			case LookupNextResponse: {
729 				proto_tree_add_item(dtpt_tree, hf_dtpt_error,
730 					tvb, 12, 4, ENC_LITTLE_ENDIAN);
731 				proto_tree_add_item(dtpt_tree, hf_dtpt_data_size,
732 					tvb, 16, 4, ENC_LITTLE_ENDIAN);
733 			}
734 			break;
735 			case LookupEndRequest: {
736 				proto_tree_add_item(dtpt_tree, hf_dtpt_handle,
737 					tvb, 4, 8, ENC_LITTLE_ENDIAN);
738 			}
739 			break;
740 			case ConnectRequest: {
741 				dissect_dtpt_sockaddr(tvb, 2, dtpt_tree, hf_dtpt_connect_addr, SOCKADDR_CONNECT);
742 				proto_tree_add_item(dtpt_tree, hf_dtpt_error,
743 					tvb, 32, 4, ENC_LITTLE_ENDIAN);
744 			}
745 			break;
746 			case ConnectResponseOK: {
747 				dissect_dtpt_sockaddr(tvb, 2, dtpt_tree, hf_dtpt_connect_addr, SOCKADDR_CONNECT);
748 				proto_tree_add_item(dtpt_tree, hf_dtpt_error,
749 					tvb, 32, 4, ENC_LITTLE_ENDIAN);
750 			}
751 			break;
752 			case ConnectResponseERR: {
753 				dissect_dtpt_sockaddr(tvb, 2, dtpt_tree, hf_dtpt_connect_addr, SOCKADDR_CONNECT);
754 				proto_tree_add_item(dtpt_tree, hf_dtpt_error,
755 					tvb, 32, 4, ENC_LITTLE_ENDIAN);
756 			}
757 			break;
758 		}
759 	}
760 
761 	return tvb_captured_length(tvb);
762 }
763 
764 void proto_reg_handoff_dtpt(void);
765 
766 void
proto_register_dtpt(void)767 proto_register_dtpt(void)
768 {
769 	static hf_register_info hf[] = {
770 		{ &hf_dtpt_version,
771 		  { "Version", "dtpt.version",
772 		    FT_UINT8, BASE_DEC, NULL, 0x0,
773 		    "Protocol Version", HFILL }},
774 
775 		{ &hf_dtpt_message_type,
776 		  { "Message Type", "dtpt.message_type",
777 		    FT_UINT8, BASE_DEC, VALS(names_message_type), 0x0,
778 		    "Packet Message Type", HFILL }},
779 
780 		{ &hf_dtpt_flags,
781 		  { "ControlFlags", "dtpt.flags",
782 		    FT_UINT32, BASE_HEX, NULL, 0x0,
783 		    "ControlFlags as documented for WSALookupServiceBegin", HFILL }},
784 
785 		{ &hf_dtpt_flags_deep,
786 		  { "DEEP", "dtpt.flags.deep",
787 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_DEEP,
788 		    NULL, HFILL }},
789 
790 		{ &hf_dtpt_flags_containers,
791 		  { "CONTAINERS", "dtpt.flags.containers",
792 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_CONTAINERS,
793 		    NULL, HFILL }},
794 
795 		{ &hf_dtpt_flags_nocontainers,
796 		  { "NOCONTAINERS", "dtpt.flags.nocontainers",
797 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_NOCONTAINERS,
798 		    NULL, HFILL }},
799 
800 		{ &hf_dtpt_flags_nearest,
801 		  { "NEAREST", "dtpt.flags.nearest",
802 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_NEAREST,
803 		    NULL, HFILL }},
804 
805 		{ &hf_dtpt_flags_return_name,
806 		  { "RETURN_NAME", "dtpt.flags.return_name",
807 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RETURN_NAME,
808 		    NULL, HFILL }},
809 
810 		{ &hf_dtpt_flags_return_type,
811 		  { "RETURN_TYPE", "dtpt.flags.return_type",
812 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RETURN_TYPE,
813 		    NULL, HFILL }},
814 
815 		{ &hf_dtpt_flags_return_version,
816 		  { "RETURN_VERSION", "dtpt.flags.return_version",
817 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RETURN_VERSION,
818 		    NULL, HFILL }},
819 
820 		{ &hf_dtpt_flags_return_comment,
821 		  { "RETURN_COMMENT", "dtpt.flags.return_comment",
822 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RETURN_COMMENT,
823 		    NULL, HFILL }},
824 
825 		{ &hf_dtpt_flags_return_addr,
826 		  { "RETURN_ADDR", "dtpt.flags.return_addr",
827 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RETURN_ADDR,
828 		    NULL, HFILL }},
829 
830 		{ &hf_dtpt_flags_return_blob,
831 		  { "RETURN_BLOB", "dtpt.flags.return_blob",
832 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RETURN_BLOB,
833 		    NULL, HFILL }},
834 
835 		{ &hf_dtpt_flags_return_aliases,
836 		  { "RETURN_ALIASES", "dtpt.flags.return_aliases",
837 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RETURN_ALIASES,
838 		    NULL, HFILL }},
839 
840 		{ &hf_dtpt_flags_return_query_string,
841 		  { "RETURN_QUERY_STRING", "dtpt.flags.return_query_string",
842 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RETURN_QUERY_STRING,
843 		    NULL, HFILL }},
844 
845 		{ &hf_dtpt_flags_flushcache,
846 		  { "FLUSHCACHE", "dtpt.flags.flushcache",
847 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_FLUSHCACHE,
848 		    NULL, HFILL }},
849 
850 		{ &hf_dtpt_flags_flushprevious,
851 		  { "FLUSHPREVIOUS", "dtpt.flags.flushprevious",
852 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_FLUSHPREVIOUS,
853 		    NULL, HFILL }},
854 
855 		{ &hf_dtpt_flags_res_service,
856 		  { "RES_SERVICE", "dtpt.flags.res_service",
857 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset), LUP_RES_SERVICE,
858 		    NULL, HFILL }},
859 
860 		{ &hf_dtpt_payload_size,
861 		  { "Payload Size", "dtpt.payload_size",
862 		    FT_UINT32, BASE_DEC, NULL, 0x0,
863 		    "Payload Size of the following packet containing a serialized WSAQUERYSET", HFILL }},
864 
865 		{ &hf_dtpt_handle,
866 		  { "Handle", "dtpt.handle",
867 		    FT_UINT64, BASE_HEX, NULL, 0x0,
868 		    "Lookup handle", HFILL }},
869 
870 		{ &hf_dtpt_error,
871 		  { "Last Error", "dtpt.error",
872 		    FT_UINT32, BASE_DEC, VALS(names_error), 0x0,
873 		    NULL, HFILL }},
874 
875 		{ &hf_dtpt_buffer_size,
876 		  { "Buffer Size", "dtpt.buffer_size",
877 		    FT_UINT32, BASE_DEC, NULL, 0x0,
878 		    NULL, HFILL }},
879 
880 		{ &hf_dtpt_data_size,
881 		  { "Data Size", "dtpt.data_size",
882 		    FT_UINT32, BASE_DEC, NULL, 0x0,
883 		    NULL, HFILL }},
884 
885 		{ &hf_dtpt_queryset_rawsize,
886 		  { "QuerySet Size", "dtpt.queryset_size",
887 		    FT_UINT32, BASE_DEC, NULL, 0x0,
888 		    "Size of the binary WSAQUERYSET", HFILL }},
889 
890 		{ &hf_dtpt_queryset_size,
891 		  { "dwSize", "dtpt.queryset.dwSize",
892 		    FT_UINT32, BASE_DEC, NULL, 0x0,
893 		    "dwSize field in WSAQUERYSET", HFILL }},
894 
895 		{ &hf_dtpt_queryset_service_instance_name_pointer,
896 		  { "lpszServiceInstanceName", "dtpt.queryset.lpszServiceInstanceName",
897 		    FT_UINT32, BASE_HEX, NULL, 0x0,
898 		    "lpszServiceInstanceName field in WSAQUERYSET", HFILL }},
899 
900 		{ &hf_dtpt_queryset_service_class_id_pointer,
901 		  { "lpServiceClassId", "dtpt.queryset.lpServiceClassId",
902 		    FT_UINT32, BASE_HEX, NULL, 0x0,
903 		    "lpServiceClassId in the WSAQUERYSET", HFILL }},
904 
905 		{ &hf_dtpt_queryset_version,
906 		  { "lpVersion", "dtpt.queryset.lpVersion",
907 		    FT_UINT32, BASE_DEC, NULL, 0x0,
908 		    "lpVersion in WSAQUERYSET", HFILL }},
909 
910 		{ &hf_dtpt_queryset_comment_pointer,
911 		  { "lpszComment", "dtpt.lpszComment",
912 		    FT_UINT32, BASE_HEX, NULL, 0x0,
913 		    "lpszComment field in WSAQUERYSET", HFILL }},
914 
915 		{ &hf_dtpt_queryset_namespace,
916 		  { "dwNameSpace", "dtpt.queryset.dwNameSpace",
917 		    FT_UINT32, BASE_DEC, NULL, 0x0,
918 		    "dwNameSpace field in WSAQUERYSE", HFILL }},
919 
920 		{ &hf_dtpt_queryset_provider_id_pointer,
921 		  { "lpNSProviderId", "dtpt.queryset.lpNSProviderId",
922 		    FT_UINT32, BASE_HEX, NULL, 0x0,
923 		    "lpNSProviderId field in WSAQUERYSET", HFILL }},
924 
925 		{ &hf_dtpt_queryset_context_pointer,
926 		  { "lpszContext", "dtpt.queryset.lpszContext",
927 		    FT_UINT32, BASE_HEX, NULL, 0x0,
928 		    "lpszContext field in WSAQUERYSET", HFILL }},
929 
930 		{ &hf_dtpt_queryset_protocols_number,
931 		  { "dwNumberOfProtocols", "dtpt.queryset.dwNumberOfProtocols",
932 		    FT_UINT32, BASE_DEC, NULL, 0x0,
933 		    "dwNumberOfProtocols field in WSAQUERYSET", HFILL }},
934 
935 		{ &hf_dtpt_queryset_protocols_pointer,
936 		  { "lpafpProtocols", "dtpt.queryset.lpafpProtocols",
937 		    FT_UINT32, BASE_HEX, NULL, 0x0,
938 		    "lpafpProtocols field in WSAQUERYSET", HFILL }},
939 
940 		{ &hf_dtpt_queryset_query_string_pointer,
941 		  { "lpszQueryString", "dtpt.queryset.lpszQueryString",
942 		    FT_UINT32, BASE_HEX, NULL, 0x0,
943 		    "lpszQueryString field in WSAQUERYSET", HFILL }},
944 
945 		{ &hf_dtpt_queryset_cs_addrs_number,
946 		  { "dwNumberOfCsAddrs", "dtpt.queryset.dwNumberOfCsAddrs",
947 		    FT_UINT32, BASE_DEC, NULL, 0x0,
948 		    "dwNumberOfCsAddrs field in WSAQUERYSET", HFILL }},
949 
950 		{ &hf_dtpt_queryset_cs_addrs_pointer,
951 		  { "lpcsaBuffer", "dtpt.queryset.lpcsaBuffer",
952 		    FT_UINT32, BASE_HEX, NULL, 0x0,
953 		    "lpcsaBuffer field in WSAQUERYSET", HFILL }},
954 
955 		{ &hf_dtpt_queryset_output_flags,
956 		  { "dwOutputFlags", "dtpt.queryset.dwOutputFlags",
957 		    FT_UINT32, BASE_HEX, NULL, 0x0,
958 		    "dwOutputFlags field in WSAQUERYSET", HFILL }},
959 
960 		{ &hf_dtpt_queryset_blob_pointer,
961 		  { "lpBlob", "dtpt.queryset.lpBlob",
962 		    FT_UINT32, BASE_HEX, NULL, 0x0,
963 		    "lpBlob field in WSAQUERYSET", HFILL }},
964 
965 		{ &hf_dtpt_wstring_length,
966 		  { "Length", "dtpt.wstring.length",
967 		    FT_UINT32, BASE_DEC, NULL, 0x0,
968 		    "String Length", HFILL }},
969 
970 		{ &hf_dtpt_wstring_data,
971 		  { "Data", "dtpt.wstring.data",
972 		    FT_STRING, BASE_NONE, NULL, 0x0,
973 		    "String Data", HFILL }},
974 
975 		{ &hf_dtpt_guid_length,
976 		  { "Length", "dtpt.guid.length",
977 		    FT_UINT32, BASE_DEC, NULL, 0x0,
978 		    "GUID Length", HFILL }},
979 
980 		{ &hf_dtpt_guid_data,
981 		  { "Data", "dtpt.guid.data",
982 		    FT_GUID, BASE_NONE, NULL, 0x0,
983 		    "GUID Data", HFILL }},
984 
985 		{ &hf_dtpt_service_instance_name,
986 		  { "Service Instance Name", "dtpt.service_instance_name",
987 		    FT_STRINGZ, BASE_NONE, NULL, 0x0,
988 		    NULL, HFILL }},
989 
990 		{ &hf_dtpt_service_class_id,
991 		  { "Service Class ID", "dtpt.service_class_id",
992 		    FT_GUID, BASE_NONE, NULL, 0x0,
993 		    NULL, HFILL }},
994 
995 		{ &hf_dtpt_comment,
996 		  { "Comment", "dtpt.comment",
997 		    FT_STRINGZ, BASE_NONE, NULL, 0x0,
998 		    NULL, HFILL }},
999 
1000 		{ &hf_dtpt_ns_provider_id,
1001 		  { "NS Provider ID", "dtpt.ns_provider_id",
1002 		    FT_GUID, BASE_NONE, NULL, 0x0,
1003 		    NULL, HFILL }},
1004 
1005 		{ &hf_dtpt_context,
1006 		  { "Context", "dtpt.context",
1007 		    FT_STRINGZ, BASE_NONE, NULL, 0x0,
1008 		    NULL, HFILL }},
1009 
1010 		{ &hf_dtpt_protocols_number,
1011 		  { "Number of Protocols", "dtpt.protocols.number",
1012 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1013 		    NULL, HFILL }},
1014 
1015 		{ &hf_dtpt_protocols_length,
1016 		  { "Length of Protocols", "dtpt.protocols.length",
1017 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1018 		    NULL, HFILL }},
1019 
1020 		{ &hf_dtpt_protocol_family,
1021 		  { "Family", "dtpt.protocol.family",
1022 		    FT_UINT32, BASE_DEC, VALS(names_family), 0x0,
1023 		    "Protocol Family", HFILL }},
1024 
1025 		{ &hf_dtpt_protocol_protocol,
1026 		  { "Protocol", "dtpt.protocol.protocol",
1027 		    FT_UINT32, BASE_DEC, VALS(names_protocol), 0x0,
1028 		    "Protocol Protocol", HFILL }},
1029 
1030 		{ &hf_dtpt_query_string,
1031 		  { "Query String", "dtpt.query_string",
1032 		    FT_STRINGZ, BASE_NONE, NULL, 0x0,
1033 		    NULL, HFILL }},
1034 
1035 		{ &hf_dtpt_cs_addrs_number,
1036 		  { "Number of CS Addresses", "dtpt.cs_addrs.number",
1037 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1038 		    NULL, HFILL }},
1039 
1040 		{ &hf_dtpt_cs_addrs_length1,
1041 		  { "Length of CS Addresses Part 1", "dtpt.cs_addrs.length1",
1042 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1043 		    NULL, HFILL }},
1044 
1045 		{ &hf_dtpt_cs_addr_socket_type,
1046 		  { "Socket Type", "dtpt.cs_addrs.socket_type",
1047 		    FT_UINT32, BASE_DEC, VALS(names_socket_type), 0x0,
1048 		    NULL, HFILL }},
1049 
1050 		{ &hf_dtpt_cs_addr_protocol,
1051 		  { "Protocol", "dtpt.cs_addrs.protocol",
1052 		    FT_UINT32, BASE_DEC, VALS(names_protocol), 0x0,
1053 		    NULL, HFILL }},
1054 
1055 		{ &hf_dtpt_cs_addr_local_pointer,
1056 		  { "Local Address Pointer", "dtpt.cs_addr.local_pointer",
1057 		    FT_UINT32, BASE_HEX, NULL, 0x0,
1058 		    NULL, HFILL }},
1059 
1060 		{ &hf_dtpt_cs_addr_local_length,
1061 		  { "Local Address Length", "dtpt.cs_addr.local_length",
1062 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1063 		    "Local Address Pointer", HFILL }},
1064 
1065 		{ &hf_dtpt_cs_addr_local,
1066 		  { "Local Address", "dtpt.cs_addr.local",
1067 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1068 		    NULL, HFILL }},
1069 
1070 		{ &hf_dtpt_cs_addr_remote_pointer,
1071 		  { "Remote Address Pointer", "dtpt.cs_addr.remote_pointer",
1072 		    FT_UINT32, BASE_HEX, NULL, 0x0,
1073 		    NULL, HFILL }},
1074 
1075 		{ &hf_dtpt_cs_addr_remote_length,
1076 		  { "Remote Address Length", "dtpt.cs_addr.remote_length",
1077 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1078 		    "Remote Address Pointer", HFILL }},
1079 
1080 		{ &hf_dtpt_cs_addr_remote,
1081 		  { "Remote Address", "dtpt.cs_addr.remote",
1082 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1083 		    NULL, HFILL }},
1084 
1085 		{ &hf_dtpt_sockaddr_length,
1086 		  { "Length", "dtpt.sockaddr.length",
1087 		    FT_UINT16, BASE_DEC, NULL, 0x0,
1088 		    "Socket Address Length", HFILL }},
1089 
1090 		{ &hf_dtpt_sockaddr_family,
1091 		  { "Family", "dtpt.sockaddr.family",
1092 		    FT_UINT16, BASE_DEC, VALS(names_family), 0x0,
1093 		    "Socket Address Family", HFILL }},
1094 
1095 		{ &hf_dtpt_sockaddr_port,
1096 		  { "Port", "dtpt.sockaddr.port",
1097 		    FT_UINT16, BASE_DEC, NULL, 0x0,
1098 		    "Socket Address Port", HFILL }},
1099 
1100 		{ &hf_dtpt_sockaddr_address,
1101 		  { "Address", "dtpt.sockaddr.address",
1102 		    FT_IPv4, BASE_NONE, NULL, 0x0,
1103 		    "Socket Address Address", HFILL }},
1104 
1105 		{ &hf_dtpt_blob_rawsize,
1106 		  { "Blob Size", "dtpt.blob_size",
1107 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1108 		    "Size of the binary BLOB", HFILL }},
1109 
1110 		{ &hf_dtpt_blob_size,
1111 		  { "cbSize", "dtpt.blob.cbSize",
1112 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1113 		    "cbSize field in BLOB", HFILL }},
1114 
1115 		{ &hf_dtpt_blob_data_pointer,
1116 		  { "pBlobData", "dtpt.blob.pBlobData",
1117 		    FT_UINT32, BASE_HEX, NULL, 0x0,
1118 		    "pBlobData field in BLOB", HFILL }},
1119 
1120 		{ &hf_dtpt_blob_data_length,
1121 		  { "Length", "dtpt.blob.data_length",
1122 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1123 		    "Length of the Blob Data Block", HFILL }},
1124 
1125 		{ &hf_dtpt_blob_data,
1126 		  { "Data", "dtpt.blob.data",
1127 		    FT_BYTES, BASE_NONE, NULL, 0x0,
1128 		    "Blob Data Block", HFILL }},
1129 
1130 		{ &hf_dtpt_connect_addr,
1131 		  { "Address", "dtpt.connect_addr",
1132 		    FT_UINT32, BASE_DEC, NULL, 0x0,
1133 		    "Connect to Address", HFILL }},
1134 
1135 		{ &hf_dtpt_padding,
1136 		  { "Padding", "dtpt.padding",
1137 		    FT_BYTES, BASE_NONE, NULL, 0x0,
1138 		    NULL, HFILL }},
1139 	};
1140 	static gint *ett[] = {
1141 		&ett_dtpt,
1142 		&ett_dtpt_flags,
1143 		&ett_dtpt_queryset,
1144 		&ett_dtpt_wstring,
1145 		&ett_dtpt_guid,
1146 		&ett_dtpt_protocols,
1147 		&ett_dtpt_protocol,
1148 		&ett_dtpt_cs_addrs,
1149 		&ett_dtpt_cs_addr1,
1150 		&ett_dtpt_cs_addr2,
1151 		&ett_dtpt_sockaddr,
1152 		&ett_dtpt_blobraw,
1153 		&ett_dtpt_blob,
1154 	};
1155 	e_guid_t guid_svcid_inet_hostaddrbyname       = {0x0002A803, 0x0000, 0x0000, {0xC0,0,0,0,0,0,0,0x46}};
1156 	e_guid_t guid_svcid_inet_hostaddrbyinetstring = {0x0002A801, 0x0000, 0x0000, {0xC0,0,0,0,0,0,0,0x46}};
1157 	guids_add_guid(&guid_svcid_inet_hostaddrbyname,       "SVCID_INET_HOSTADDRBYNAME");
1158 	guids_add_guid(&guid_svcid_inet_hostaddrbyinetstring, "SVCID_INET_HOSTADDRBYINETSTRING");
1159 
1160 	proto_dtpt = proto_register_protocol("DeskTop PassThrough Protocol",
1161 					     "DTPT", "dtpt");
1162 	proto_register_field_array(proto_dtpt, hf, array_length(hf));
1163 	proto_register_subtree_array(ett, array_length(ett));
1164 }
1165 
1166 
1167 void
proto_reg_handoff_dtpt(void)1168 proto_reg_handoff_dtpt(void)
1169 {
1170 	dissector_handle_t	dtpt_handle;
1171 
1172 	dtpt_handle = create_dissector_handle(dissect_dtpt, proto_dtpt);
1173 	dtpt_conversation_handle = create_dissector_handle(dissect_dtpt_conversation, proto_dtpt);
1174 /**	dtpt_data_handle = create_dissector_handle(dissect_dtpt_data, proto_dtpt); **/
1175 
1176 	dissector_add_uint_with_preference("tcp.port", TCP_SERVER_PORT, dtpt_handle);
1177 }
1178 
1179 /*
1180  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1181  *
1182  * Local variables:
1183  * c-basic-offset: 8
1184  * tab-width: 8
1185  * indent-tabs-mode: t
1186  * End:
1187  *
1188  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1189  * :indentSize=8:tabSize=8:noTabs=false:
1190  */
1191