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