Show lengths as decimal, not hex.
[obnox/wireshark/wip.git] / packet-ntlmssp.c
1 /* packet-ntlmssp.c
2  * Routines for NTLM Secure Service Provider
3  * Devin Heitmueller <dheitmueller@netilla.com>
4  *
5  * $Id: packet-ntlmssp.c,v 1.3 2002/07/10 06:17:55 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #include <glib.h>
35 #include <epan/packet.h>
36
37 /* Message types */
38
39 #define NTLMSSP_NEGOTIATE 1
40 #define NTLMSSP_CHALLENGE 2
41 #define NTLMSSP_AUTH      3
42 #define NTLMSSP_UNKNOWN   4
43
44 static const value_string ntlmssp_message_types[] = {
45   { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
46   { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
47   { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
48   { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" }
49 };
50
51 static const true_false_string flags_set_truth = {
52   "Set",
53   "Not set"
54 };
55
56 /* 
57  * NTLMSSP negotiation flags 
58  * Taken from Samba
59  */
60 #define NTLMSSP_NEGOTIATE_UNICODE          0x00000001
61 #define NTLMSSP_NEGOTIATE_OEM              0x00000002
62 #define NTLMSSP_REQUEST_TARGET             0x00000004
63 #define NTLMSSP_NEGOTIATE_00000008         0x00000008
64 #define NTLMSSP_NEGOTIATE_SIGN             0x00000010
65 #define NTLMSSP_NEGOTIATE_SEAL             0x00000020
66 #define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE   0x00000040
67 #define NTLMSSP_NEGOTIATE_LM_KEY           0x00000080
68 #define NTLMSSP_NEGOTIATE_NETWARE          0x00000100
69 #define NTLMSSP_NEGOTIATE_NTLM             0x00000200
70 #define NTLMSSP_NEGOTIATE_00000400         0x00000400
71 #define NTLMSSP_NEGOTIATE_00000800         0x00000800
72 #define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED  0x00001000
73 #define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
74 #define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL  0x00004000
75 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN      0x00008000
76 #define NTLMSSP_CHAL_INIT_RESPONSE         0x00010000
77 #define NTLMSSP_CHAL_ACCEPT_RESPONSE       0x00020000
78 #define NTLMSSP_CHAL_NON_NT_SESSION_KEY    0x00040000
79 #define NTLMSSP_NEGOTIATE_NTLM2            0x00080000
80 #define NTLMSSP_NEGOTIATE_00100000         0x00100000
81 #define NTLMSSP_NEGOTIATE_00200000         0x00200000
82 #define NTLMSSP_NEGOTIATE_00400000         0x00400000
83 #define NTLMSSP_CHAL_TARGET_INFO           0x00800000
84 #define NTLMSSP_NEGOTIATE_01000000         0x01000000
85 #define NTLMSSP_NEGOTIATE_02000000         0x02000000
86 #define NTLMSSP_NEGOTIATE_04000000         0x04000000
87 #define NTLMSSP_NEGOTIATE_08000000         0x08000000
88 #define NTLMSSP_NEGOTIATE_10000000         0x10000000
89 #define NTLMSSP_NEGOTIATE_128              0x20000000
90 #define NTLMSSP_NEGOTIATE_KEY_EXCH         0x40000000
91 #define NTLMSSP_NEGOTIATE_80000000         0x80000000
92
93
94 static int proto_ntlmssp = -1;
95 static int hf_ntlmssp = -1;
96 static int hf_ntlmssp_auth = -1;
97 static int hf_ntlmssp_message_type = -1;
98 static int hf_ntlmssp_negotiate_flags = -1;
99 static int hf_ntlmssp_negotiate_flags_01 = -1;
100 static int hf_ntlmssp_negotiate_flags_02 = -1;
101 static int hf_ntlmssp_negotiate_flags_04 = -1;
102 static int hf_ntlmssp_negotiate_flags_08 = -1;
103 static int hf_ntlmssp_negotiate_flags_10 = -1;
104 static int hf_ntlmssp_negotiate_flags_20 = -1;
105 static int hf_ntlmssp_negotiate_flags_40 = -1;
106 static int hf_ntlmssp_negotiate_flags_80 = -1;
107 static int hf_ntlmssp_negotiate_flags_100 = -1;
108 static int hf_ntlmssp_negotiate_flags_200 = -1;
109 static int hf_ntlmssp_negotiate_flags_400 = -1;
110 static int hf_ntlmssp_negotiate_flags_800 = -1;
111 static int hf_ntlmssp_negotiate_flags_1000 = -1;
112 static int hf_ntlmssp_negotiate_flags_2000 = -1;
113 static int hf_ntlmssp_negotiate_flags_4000 = -1;
114 static int hf_ntlmssp_negotiate_flags_8000 = -1;
115 static int hf_ntlmssp_negotiate_flags_10000 = -1;
116 static int hf_ntlmssp_negotiate_flags_20000 = -1;
117 static int hf_ntlmssp_negotiate_flags_40000 = -1;
118 static int hf_ntlmssp_negotiate_flags_80000 = -1;
119 static int hf_ntlmssp_negotiate_flags_100000 = -1;
120 static int hf_ntlmssp_negotiate_flags_200000 = -1;
121 static int hf_ntlmssp_negotiate_flags_400000 = -1;
122 static int hf_ntlmssp_negotiate_flags_800000 = -1;
123 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
124 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
125 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
126 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
127 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
128 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
129 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
130 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
131 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
132 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
133 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
134 static int hf_ntlmssp_negotiate_workstation = -1;
135 static int hf_ntlmssp_negotiate_domain_strlen = -1;
136 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
137 static int hf_ntlmssp_negotiate_domain_buffer = -1;
138 static int hf_ntlmssp_negotiate_domain = -1;
139 static int hf_ntlmssp_ntlm_challenge = -1;
140 static int hf_ntlmssp_reserved = -1;
141 static int hf_ntlmssp_challenge_unknown1 = -1;
142 static int hf_ntlmssp_challenge_unknown2 = -1;
143
144 static gint ett_ntlmssp = -1;
145 static gint ett_ntlmssp_negotiate_flags = -1;
146
147 static int
148 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset, 
149                                  proto_tree *ntlmssp_tree,
150                                  guint32 negotiate_flags)
151 {
152   proto_tree *negotiate_flags_tree = NULL;
153   proto_item *tf = NULL;
154
155   if (ntlmssp_tree) {
156     tf = proto_tree_add_uint (ntlmssp_tree, 
157                               hf_ntlmssp_negotiate_flags, 
158                               tvb, offset, 4, negotiate_flags);
159     negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
160   }
161
162   proto_tree_add_boolean (negotiate_flags_tree, 
163                           hf_ntlmssp_negotiate_flags_80000000, 
164                           tvb, offset, 4, negotiate_flags);
165   proto_tree_add_boolean (negotiate_flags_tree, 
166                           hf_ntlmssp_negotiate_flags_40000000, 
167                           tvb, offset, 4, negotiate_flags);
168   proto_tree_add_boolean (negotiate_flags_tree, 
169                           hf_ntlmssp_negotiate_flags_20000000, 
170                           tvb, offset, 4, negotiate_flags);
171   proto_tree_add_boolean (negotiate_flags_tree, 
172                           hf_ntlmssp_negotiate_flags_10000000, 
173                           tvb, offset, 4, negotiate_flags);
174   proto_tree_add_boolean (negotiate_flags_tree, 
175                           hf_ntlmssp_negotiate_flags_8000000, 
176                           tvb, offset, 4, negotiate_flags);
177   proto_tree_add_boolean (negotiate_flags_tree, 
178                           hf_ntlmssp_negotiate_flags_4000000, 
179                           tvb, offset, 4, negotiate_flags);
180   proto_tree_add_boolean (negotiate_flags_tree, 
181                           hf_ntlmssp_negotiate_flags_2000000, 
182                           tvb, offset, 4, negotiate_flags);
183   proto_tree_add_boolean (negotiate_flags_tree, 
184                           hf_ntlmssp_negotiate_flags_1000000, 
185                           tvb, offset, 4, negotiate_flags);
186   proto_tree_add_boolean (negotiate_flags_tree, 
187                           hf_ntlmssp_negotiate_flags_800000, 
188                           tvb, offset, 4, negotiate_flags);
189   proto_tree_add_boolean (negotiate_flags_tree, 
190                           hf_ntlmssp_negotiate_flags_400000, 
191                           tvb, offset, 4, negotiate_flags);
192   proto_tree_add_boolean (negotiate_flags_tree, 
193                           hf_ntlmssp_negotiate_flags_200000, 
194                           tvb, offset, 4, negotiate_flags);
195   proto_tree_add_boolean (negotiate_flags_tree, 
196                           hf_ntlmssp_negotiate_flags_100000, 
197                           tvb, offset, 4, negotiate_flags);
198   proto_tree_add_boolean (negotiate_flags_tree, 
199                           hf_ntlmssp_negotiate_flags_80000, 
200                           tvb, offset, 4, negotiate_flags);
201   proto_tree_add_boolean (negotiate_flags_tree, 
202                           hf_ntlmssp_negotiate_flags_40000, 
203                           tvb, offset, 4, negotiate_flags);
204   proto_tree_add_boolean (negotiate_flags_tree, 
205                           hf_ntlmssp_negotiate_flags_20000, 
206                           tvb, offset, 4, negotiate_flags);
207   proto_tree_add_boolean (negotiate_flags_tree, 
208                           hf_ntlmssp_negotiate_flags_10000, 
209                           tvb, offset, 4, negotiate_flags);
210   proto_tree_add_boolean (negotiate_flags_tree, 
211                           hf_ntlmssp_negotiate_flags_8000, 
212                           tvb, offset, 4, negotiate_flags);
213   proto_tree_add_boolean (negotiate_flags_tree, 
214                           hf_ntlmssp_negotiate_flags_4000, 
215                           tvb, offset, 4, negotiate_flags);
216   proto_tree_add_boolean (negotiate_flags_tree, 
217                           hf_ntlmssp_negotiate_flags_2000, 
218                           tvb, offset, 4, negotiate_flags);
219   proto_tree_add_boolean (negotiate_flags_tree,
220                           hf_ntlmssp_negotiate_flags_1000,
221                           tvb, offset, 4, negotiate_flags);
222   proto_tree_add_boolean (negotiate_flags_tree, 
223                           hf_ntlmssp_negotiate_flags_800, 
224                           tvb, offset, 4, negotiate_flags);
225   proto_tree_add_boolean (negotiate_flags_tree, 
226                           hf_ntlmssp_negotiate_flags_400, 
227                           tvb, offset, 4, negotiate_flags);
228   proto_tree_add_boolean (negotiate_flags_tree, 
229                           hf_ntlmssp_negotiate_flags_200, 
230                           tvb, offset, 4, negotiate_flags);
231   proto_tree_add_boolean (negotiate_flags_tree, 
232                           hf_ntlmssp_negotiate_flags_100, 
233                           tvb, offset, 4, negotiate_flags);
234   proto_tree_add_boolean (negotiate_flags_tree,
235                           hf_ntlmssp_negotiate_flags_80, 
236                           tvb, offset, 4, negotiate_flags);
237   proto_tree_add_boolean (negotiate_flags_tree, 
238                           hf_ntlmssp_negotiate_flags_40, 
239                           tvb, offset, 4, negotiate_flags);
240   proto_tree_add_boolean (negotiate_flags_tree, 
241                           hf_ntlmssp_negotiate_flags_20, 
242                           tvb, offset, 4, negotiate_flags);
243   proto_tree_add_boolean (negotiate_flags_tree, 
244                           hf_ntlmssp_negotiate_flags_10,
245                           tvb, offset, 4, negotiate_flags);
246   proto_tree_add_boolean (negotiate_flags_tree, 
247                           hf_ntlmssp_negotiate_flags_08, 
248                           tvb, offset, 4, negotiate_flags);
249   proto_tree_add_boolean (negotiate_flags_tree, 
250                           hf_ntlmssp_negotiate_flags_04, 
251                           tvb, offset, 4, negotiate_flags);
252   proto_tree_add_boolean (negotiate_flags_tree, 
253                           hf_ntlmssp_negotiate_flags_02, 
254                           tvb, offset, 4, negotiate_flags);
255   proto_tree_add_boolean (negotiate_flags_tree, 
256                           hf_ntlmssp_negotiate_flags_01, 
257                           tvb, offset, 4, negotiate_flags);  
258
259   return (offset + 4);
260 }
261
262
263 static int
264 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, 
265                            proto_tree *ntlmssp_tree)
266 {
267   guint32 negotiate_flags;
268   guint16 workstation_length;
269   guint16 domain_length;
270
271   /* NTLMSSP Negotiate Flags */
272   negotiate_flags = tvb_get_letohs (tvb, offset);
273   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
274                                             negotiate_flags);
275
276   /* Calling workstation domain name length */
277   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_domain_strlen,
278                        tvb, offset, 2, TRUE);
279   domain_length = tvb_get_letohs (tvb, offset);
280   offset += 2;
281
282   /* Calling workstation domain name max length */
283   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_domain_maxlen,
284                        tvb, offset, 2, TRUE);
285   offset += 2;
286
287
288   /* Calling workstation domain name buffer? */
289   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_domain_buffer,
290                        tvb, offset, 4, TRUE);
291   offset += 4;
292
293   /* Calling workstation name length */
294   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_workstation_strlen,
295                        tvb, offset, 2, TRUE);
296   workstation_length = tvb_get_letohs (tvb, offset);
297   offset += 2;
298
299   /* Calling workstation name max length */
300   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_workstation_maxlen,
301                        tvb, offset, 2, TRUE);
302   offset += 2;
303
304   /* Calling workstation name buffer? */
305   proto_tree_add_uint(ntlmssp_tree, hf_ntlmssp_negotiate_workstation_buffer,
306                       tvb, offset, 4, TRUE);
307   offset += 4;
308
309   /* Calling workstation name */
310   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_workstation,
311                        tvb, offset, workstation_length, FALSE);
312   offset += workstation_length;
313
314   /* Calling domain name */
315   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_negotiate_domain,
316                        tvb, offset, domain_length, FALSE);
317   offset += domain_length;
318
319   return offset;
320 }
321
322
323 static int
324 dissect_ntlmssp_challenge (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
325 {
326   guint32 negotiate_flags;
327
328   /* Skip over the two unknown fields */
329   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_unknown1,
330                        tvb, offset, 4, TRUE);
331   offset += 4;
332
333   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_unknown2,
334                        tvb, offset, 4, TRUE);
335   offset += 4;
336
337   /* NTLMSSP Negotiate Flags */
338   negotiate_flags = tvb_get_letohs (tvb, offset);
339   offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
340                                             negotiate_flags);
341
342   /* NTLMSSP NT Lan Manager Challenge */
343   proto_tree_add_item (ntlmssp_tree,
344                        hf_ntlmssp_ntlm_challenge,
345                        tvb, offset, 8, FALSE);
346   offset += 8;
347   
348   /* Reserved (function not completely known) */
349   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
350                        tvb, offset, 8, FALSE);
351   offset += 8;
352
353   return offset;
354 }
355
356
357 static void
358 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
359 {
360   guint32 ntlmssp_message_type;
361   int offset = 0;
362   int payloadsize = 0;
363   proto_tree *ntlmssp_tree = NULL;
364   proto_item *tf = NULL;
365
366   /* Compute the total size of the data to be parsed */
367   payloadsize = tvb_length_remaining(tvb, 0);
368   
369   /* Setup a new tree for the NTLMSSP payload */
370   if (tree) {
371     tf = proto_tree_add_item (tree, 
372                               hf_ntlmssp,
373                               tvb, offset, payloadsize, FALSE);
374     
375     ntlmssp_tree = proto_item_add_subtree (tf, 
376                                            ett_ntlmssp);
377   }
378   
379   /* NTLMSSP constant */
380   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth, 
381                        tvb, offset, 8, FALSE);
382   offset += 8;
383
384   /* NTLMSSP Message Type */
385   proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
386                        tvb, offset, 4, TRUE);
387   ntlmssp_message_type = tvb_get_letohl (tvb, offset);
388   offset += 4;
389
390   /* Call the appropriate dissector based on the Message Type */
391   switch (ntlmssp_message_type) {
392
393   case NTLMSSP_NEGOTIATE:
394     offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
395     break;
396
397   case NTLMSSP_CHALLENGE:
398     offset = dissect_ntlmssp_challenge (tvb, offset, ntlmssp_tree);
399     break;
400
401   case NTLMSSP_AUTH:
402     proto_tree_add_text (ntlmssp_tree, tvb, offset, 
403                          (payloadsize - 12), 
404                          "Unknown contents");
405     break;
406
407   default:
408     /* Unrecognized message type */
409     proto_tree_add_text (ntlmssp_tree, tvb, offset, 
410                          (payloadsize - 12), 
411                          "Unrecognized NTLMSSP Message");
412     break;
413   }
414 }
415
416 void
417 proto_register_ntlmssp(void)
418 {
419
420   static hf_register_info hf[] = {
421     { &hf_ntlmssp,
422       { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
423     
424     { &hf_ntlmssp_auth, 
425       { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
426     
427     { &hf_ntlmssp_message_type,
428       { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
429     
430     { &hf_ntlmssp_negotiate_flags,
431       { "Flags", "dcerpc.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
432     { &hf_ntlmssp_negotiate_flags_01,
433       
434       { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
435     { &hf_ntlmssp_negotiate_flags_02,
436       { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
437     { &hf_ntlmssp_negotiate_flags_04,
438       { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
439     { &hf_ntlmssp_negotiate_flags_08,
440       { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
441     { &hf_ntlmssp_negotiate_flags_10,
442       { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
443     { &hf_ntlmssp_negotiate_flags_20,
444       { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
445     { &hf_ntlmssp_negotiate_flags_40,
446       { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
447     { &hf_ntlmssp_negotiate_flags_80,
448       { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
449     { &hf_ntlmssp_negotiate_flags_100,
450       { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
451     { &hf_ntlmssp_negotiate_flags_200,
452       { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
453     { &hf_ntlmssp_negotiate_flags_400,
454       { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
455     { &hf_ntlmssp_negotiate_flags_800,
456       { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
457     { &hf_ntlmssp_negotiate_flags_1000,
458       { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
459     { &hf_ntlmssp_negotiate_flags_2000,
460       { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
461     { &hf_ntlmssp_negotiate_flags_4000,
462       { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
463     { &hf_ntlmssp_negotiate_flags_8000,
464       { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
465     { &hf_ntlmssp_negotiate_flags_10000,
466       { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
467     { &hf_ntlmssp_negotiate_flags_20000,
468       { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
469     { &hf_ntlmssp_negotiate_flags_40000,
470       { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
471     { &hf_ntlmssp_negotiate_flags_80000,
472       { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
473     { &hf_ntlmssp_negotiate_flags_100000,
474       { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
475     { &hf_ntlmssp_negotiate_flags_200000,
476       { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
477     { &hf_ntlmssp_negotiate_flags_400000,
478       { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
479     { &hf_ntlmssp_negotiate_flags_800000,
480       { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
481     { &hf_ntlmssp_negotiate_flags_1000000,
482       { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
483     { &hf_ntlmssp_negotiate_flags_2000000,
484       { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
485     { &hf_ntlmssp_negotiate_flags_4000000,
486       { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
487     { &hf_ntlmssp_negotiate_flags_8000000,
488       { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
489     { &hf_ntlmssp_negotiate_flags_10000000,
490       { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
491     { &hf_ntlmssp_negotiate_flags_20000000,
492       { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
493     { &hf_ntlmssp_negotiate_flags_40000000,
494       { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
495     { &hf_ntlmssp_negotiate_flags_80000000,
496       { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
497     { &hf_ntlmssp_negotiate_workstation_strlen,
498       { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
499     { &hf_ntlmssp_negotiate_workstation_maxlen,
500       { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
501     { &hf_ntlmssp_negotiate_workstation_buffer,
502       { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
503     { &hf_ntlmssp_negotiate_workstation,
504       { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
505     { &hf_ntlmssp_negotiate_domain_strlen,
506       { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
507     { &hf_ntlmssp_negotiate_domain_maxlen,
508       { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
509     { &hf_ntlmssp_negotiate_domain_buffer,
510       { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
511     { &hf_ntlmssp_negotiate_domain,
512       { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
513     { &hf_ntlmssp_ntlm_challenge,
514       { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
515     { &hf_ntlmssp_reserved,
516       { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
517     { &hf_ntlmssp_challenge_unknown1,
518       { "Unknown1", "ntlmssp.challenge.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
519     { &hf_ntlmssp_challenge_unknown2,
520       { "Unknown2", "ntlmssp.challenge.unknown2", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
521   };
522
523
524   static gint *ett[] = {
525     &ett_ntlmssp,
526     &ett_ntlmssp_negotiate_flags,
527   };
528
529   proto_ntlmssp = proto_register_protocol (
530                                            "NTLM Secure Service Provider", /* name */
531                                            "NTLMSSP",   /* short name */
532                                            "ntlmssp"    /* abbrev */
533                                            );
534   proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
535   proto_register_subtree_array (ett, array_length (ett));
536   
537   register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
538 }