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