HTTPS (almost) everywhere.
[metze/wireshark/wip.git] / epan / dissectors / packet-ncp2222.inc
1 #define FAKE_TREE_IS_VISIBLE 1
2 /* fake that the tree is visible so that proto.c will not try to
3  "fake" generation of finfo values/nodes.
4   Thus this means netware dissector is slower than it has to, but it wont crash.
5   once the dissector is refactored to avoid calling fvalue_ functions directly this faking of whether the tree is visible or not can be removed.
6 */
7
8
9 /* packet-ncp2222.inc
10  *
11  * Routines for NetWare Core Protocol. This C code gets #include'd
12  * into packet-ncp2222.c, which is generated from ncp2222.py. It's
13  * #include'd instead of being in a separate compilation unit so
14  * that all the data tables in packet-ncp2222.c can remain static.
15  *
16  * Gilbert Ramirez <gram@alumni.rice.edu>
17  * Modified to decode NDS packets by Greg Morris <gmorris@novell.com>
18  *
19  * Portions Copyright (c) Gilbert Ramirez 2000-2002
20  * Portions Copyright (c) Novell, Inc. 2000-2003
21  *
22  * Wireshark - Network traffic analyzer
23  * By Gerald Combs <gerald@wireshark.org>
24  * Copyright 2000 Gerald Combs
25  *
26  * SPDX-License-Identifier: GPL-2.0-or-later
27  */
28
29 gboolean    nds_defragment  = TRUE;
30 gboolean    nds_echo_eid    = TRUE;
31 gboolean    ncp_echo_err    = TRUE;
32 gboolean    ncp_echo_conn   = FALSE;
33 gboolean    ncp_echo_server = TRUE;
34 gboolean    ncp_echo_file   = FALSE;
35 gboolean    ncp_newstyle    = TRUE;
36
37 extern dissector_handle_t nds_data_handle;
38 typedef struct {
39     guint32     nds_frag_verb;
40     guint32     nds_frag_version;
41     guint32     nds_frag_flags;
42     guint32     nds_frag_prot_flags;
43     guint32     nds_length;
44     guint32     nds_frag;
45     gboolean    nds_fragmented;
46     guint8      sequence;
47 } frag_info;
48
49 static frag_info           frags[100];
50 static char    mv_resolve_name_string[128];
51
52 static const fragment_items nds_frag_items = {
53     &ett_nds_segment,
54     &ett_nds_segments,
55     &hf_nds_segments,
56     &hf_nds_segment,
57     &hf_nds_segment_overlap,
58     &hf_nds_segment_overlap_conflict,
59     &hf_nds_segment_multiple_tails,
60     &hf_nds_segment_too_long_segment,
61     &hf_nds_segment_error,
62     &hf_nds_segment_count,
63     NULL,
64     &hf_nds_reassembled_length,
65     /* Reassembled data field */
66     NULL,
67     "segments"
68 };
69
70 /* Table for reassembly of fragments. */
71 static reassembly_table nds_reassembly_table;
72
73 #define NDS_TAG_NO_SUCH_ENTRY           0x00000000
74 #define NDS_TAG_LOCAL_ENTRY             0x00000001
75 #define NDS_TAG_REMOTE_ENTRY            0x00000002
76 #define NDS_TAG_ALIAS_ENTRY             0x00000003
77 #define NDS_TAG_REFERRAL_INFORMATION    0x00000004
78 #define NDS_TAG_ENTRY_AND_REFERRALS     0x00000006
79
80 /* Search objects */
81 #define NDS_SEARCH_ENTRY                         0
82 #define NDS_SEARCH_SUBORDINATES                  1
83 #define NDS_SEARCH_SUBTREE                       2
84 #define NDS_SEARCH_PARTITION                     3
85
86 /* Search Referral Types */
87 #define NDS_ALIAS_REFERRAL                       0
88 #define NDS_PARTITION_REFERRAL                   1
89
90 /* Search Filter Types */
91 #define NDS_SEARCH_ITEM                          0
92 #define NDS_SEARCH_OR                            1
93 #define NDS_SEARCH_AND                           2
94 #define NDS_SEARCH_NOT                           3
95
96 /* Search Operators */
97 #define NDS_SEARCH_EQUAL                         7
98 #define NDS_SEARCH_GREATER_OR_EQUAL              8
99 #define NDS_SEARCH_LESS_OR_EQUAL                 9
100 #define NDS_SEARCH_APPROX                       10
101 #define NDS_SEARCH_PRESENT                      15
102 #define NDS_SEARCH_RDN                          16
103 #define NDS_SEARCH_BASE_CLASS                   17
104 #define NDS_SEARCH_MODIFICATION_GE              18  /* Deprecated, use DS_SEARCH_ENTRY_MTS_GE */
105 #define NDS_SEARCH_VALUE_TIME_GE                19  /* Deprecated, use DS_SEARCH_VALUE_MTS_GE */
106 #define NDS_SEARCH_REFERENCES                   20
107 #define NDS_SEARCH_DN_IN_VALUE                  21
108 #define NDS_SEARCH_SCHEMA_IN_VALUE              22
109 #define NDS_SEARCH_ENTRY_FLAGS                  23
110 #define NDS_SEARCH_ENTRY_HAS_FLAG               24
111 #define NDS_SEARCH_VALUE_FLAGS                  25
112 #define NDS_SEARCH_VALUE_HAS_FLAG               26
113 #define NDS_SEARCH_ATTR_FLAGS                   27
114 #define NDS_SEARCH_ATTR_HAS_FLAG                28
115 #define NDS_SEARCH_EID                          29
116
117 #define NDS_SEARCH_ENTRY_MTS_GE                 18
118 #define NDS_SEARCH_ENTRY_MTS_G                  30
119 #define NDS_SEARCH_ENTRY_MTS_LE                 31
120 #define NDS_SEARCH_ENTRY_MTS_L                  32
121 #define NDS_SEARCH_ENTRY_MTS_EQ                 33
122 #define NDS_SEARCH_ENTRY_MTS_EQ_APPROX          34
123 #define NDS_SEARCH_VALUE_MTS_GE                 19
124 #define NDS_SEARCH_VALUE_MTS_G                  35
125 #define NDS_SEARCH_VALUE_MTS_LE                 36
126 #define NDS_SEARCH_VALUE_MTS_L                  37
127 #define NDS_SEARCH_VALUE_MTS_EQ                 38
128 #define NDS_SEARCH_VALUE_MTS_EQ_APPROX          39
129
130 #define NDS_SEARCH_ENTRY_CTS_GE                 40
131 #define NDS_SEARCH_ENTRY_CTS_G                  41
132 #define NDS_SEARCH_ENTRY_CTS_LE                 42
133 #define NDS_SEARCH_ENTRY_CTS_L                  43
134 #define NDS_SEARCH_ENTRY_CTS_EQ                 44
135 #define NDS_SEARCH_ENTRY_CTS_EQ_APPROX          45
136 #define NDS_SEARCH_VALUE_CTS_GE                 46
137 #define NDS_SEARCH_VALUE_CTS_G                  47
138 #define NDS_SEARCH_VALUE_CTS_LE                 48
139 #define NDS_SEARCH_VALUE_CTS_L                  49
140 #define NDS_SEARCH_VALUE_CTS_EQ                 50
141 #define NDS_SEARCH_VALUE_CTS_EQ_APPROX          51
142 #define NDS_SEARCH_EXTENSIBLE                   52
143 #define NDS_SEARCH_ENTRY_SUBCOUNT_GE            53
144 #define NDS_SEARCH_ENTRY_SUBCOUNT_G             54
145 #define NDS_SEARCH_ENTRY_SUBCOUNT_LE            55
146 #define NDS_SEARCH_ENTRY_SUBCOUNT_L             56
147 #define NDS_SEARCH_ENTRY_SUBCOUNT_EQ            57
148
149 #define DCS_OPS                         0x10000000L
150 #define DCS_MOD_GE_WITH_ATTR            DCS_OPS + NDS_SEARCH_MODIFICATION_GE
151 #define DCS_VALUE_GE_WITH_ATTR          DCS_OPS + NDS_SEARCH_VALUE_TIME_GE
152 #define DCS_MASK                        ~DCS_OPS
153
154 /* Iterator verbs */
155 #define IT_CLEAR                                 1
156 #define IT_COPY                                  2
157 #define IT_COUNT                                 3
158 #define IT_CREATE                                4
159 #define IT_CURRENT                               5
160 #define IT_DESTROY                               6
161 #define IT_DONE                                  7
162 #define IT_FIRST                                 8
163 #define IT_GETPOSITION                           9
164 #define IT_LAST                                 10
165 #define IT_NEXT                                 11
166 #define IT_PREV                                 12
167 #define IT_POSITION                             13
168 #define IT_POSITION_IT                          14
169 #define IT_SETINDEX                             15
170 #define IT_SETFILTER                            16
171 #define IT_SKIP                                 17
172 #define IT_TYPEDOWN                             18
173 #define IT_ATFIRST                              19
174 #define IT_ATEOF                                20
175 #define IT_GETINDEX                             21
176 #define IT_ISPOSITIONABLE                       22
177 #define IT_ATBOF                                23
178 #define IT_ATLAST                               24
179
180 /* Iteration information flags */
181 #define DSI_OUTPUT_FIELDS               0x00000001U
182 #define DSI_ENTRY_ID                    0x00000002U
183 #define DSI_ENTRY_FLAGS                 0x00000004U
184 #define DSI_SUBORDINATE_COUNT           0x00000008U
185 #define DSI_MODIFICATION_TIME           0x00000010U
186 #define DSI_MODIFICATION_TIMESTAMP      0x00000020U
187 #define DSI_CREATION_TIMESTAMP          0x00000040U
188 #define DSI_PARTITION_ROOT_ID           0x00000080U
189 #define DSI_PARENT_ID                   0x00000100U
190 #define DSI_REVISION_COUNT              0x00000200U
191 #define DSI_REPLICA_TYPE                0x00000400U
192 #define DSI_BASE_CLASS                  0x00000800U
193 #define DSI_ENTRY_RDN                   0x00001000U
194 #define DSI_ENTRY_DN                    0x00002000U
195 #define DSI_PARTITION_ROOT_DN           0x00004000U
196 #define DSI_PARENT_DN                   0x00008000U
197 #define DSI_PURGE_TIME                  0x00010000U
198 #define DSI_DEREFERENCED_BASE_CLASS     0x00020000
199 #define DSI_REPLICA_NUMBER              0x00040000
200 #define DSI_REPLICA_STATE               0x00080000
201 #define DSI_FEDERATION_BOUNDARY         0x00100000
202 #define DSI_SCHEMA_BOUNDARY             0x00200000
203 #define DSI_FEDERATION_BOUNDARY_ID      0x00400000
204 #define DSI_SCHEMA_BOUNDARY_ID          0x00800000
205 #define DSI_CUR_SUBCOUNT                0x01000000
206 #define DSI_LOCAL_ENTRY_FLAGS           0x02000000
207
208 static const value_string zensearchenum[] = {
209     { 0, "[Root]" },
210     { 1, "Object Container" },
211     { 2, "Associated Container" },
212     { 3, "Selected Container" },
213     {0, NULL }
214 };
215
216 static const value_string itersearchenum[] = {
217     { NDS_SEARCH_ITEM, "Search Item" },
218     { NDS_SEARCH_OR, "OR" },
219     { NDS_SEARCH_AND, "AND" },
220     { NDS_SEARCH_NOT, "NOT" },
221     { NDS_SEARCH_EQUAL, "Equals" },
222     { NDS_SEARCH_GREATER_OR_EQUAL, "Greater or Equals" },
223     { NDS_SEARCH_LESS_OR_EQUAL, "Less or Equals" },
224     { NDS_SEARCH_APPROX, "Approximately" },
225     { NDS_SEARCH_PRESENT, "Present" },
226     { NDS_SEARCH_RDN, "Relative Distinguished Name" },
227     { NDS_SEARCH_BASE_CLASS, "Base Class" },
228     { NDS_SEARCH_MODIFICATION_GE, "Modification Greater or Equal" },
229     { NDS_SEARCH_VALUE_TIME_GE, "Time Value Greater or Equal" },
230     { NDS_SEARCH_REFERENCES, "References" },
231     { NDS_SEARCH_DN_IN_VALUE, "Designated Name in Value" },
232     { NDS_SEARCH_SCHEMA_IN_VALUE, "Schema in Value" },
233     { NDS_SEARCH_ENTRY_FLAGS, "Entry Flags" },
234     { NDS_SEARCH_ENTRY_HAS_FLAG, "Entry has Flags" },
235     { NDS_SEARCH_VALUE_FLAGS, "Value Flags" },
236     { NDS_SEARCH_VALUE_HAS_FLAG, "Value has Flags" },
237     { NDS_SEARCH_ATTR_FLAGS, "Attribute Flags" },
238     { NDS_SEARCH_ATTR_HAS_FLAG, "Attribute has Flags" },
239     { NDS_SEARCH_EID, "Entry ID" },
240     { NDS_SEARCH_ENTRY_MTS_GE, "Entry Modification Timestamp Greater or Equal" },
241     { NDS_SEARCH_ENTRY_MTS_G, "Entry Modification Timestamp Greater" },
242     { NDS_SEARCH_ENTRY_MTS_LE, "Entry Modification Timestamp Less or Equals" },
243     { NDS_SEARCH_ENTRY_MTS_L, "Entry Modification Timestamp Less" },
244     { NDS_SEARCH_ENTRY_MTS_EQ, "Entry Modification Timestamp Equals" },
245     { NDS_SEARCH_ENTRY_MTS_EQ_APPROX, "Entry Modification Timestamp Equals Approximately" },
246     { NDS_SEARCH_VALUE_MTS_GE, "Value Modification Timestamp Greater or Equal" },
247     { NDS_SEARCH_VALUE_MTS_G, "Value Modification Timestamp Greater" },
248     { NDS_SEARCH_VALUE_MTS_LE, "Value Modification Timestamp Less or Equals" },
249     { NDS_SEARCH_VALUE_MTS_L, "Value Modification Timestamp Less" },
250     { NDS_SEARCH_VALUE_MTS_EQ, "Value Modification Timestamp Equals" },
251     { NDS_SEARCH_VALUE_MTS_EQ_APPROX, "Value Modification Timestamp Equals Approximately" },
252     { NDS_SEARCH_ENTRY_CTS_GE, "Entry Creation Timestamp Greater or Equals" },
253     { NDS_SEARCH_ENTRY_CTS_G, "Entry Creation Timestamp Greater" },
254     { NDS_SEARCH_ENTRY_CTS_LE, "Entry Creation Timestamp Less or Equals" },
255     { NDS_SEARCH_ENTRY_CTS_L, "Entry Creation Timestamp Less" },
256     { NDS_SEARCH_ENTRY_CTS_EQ, "Entry Creation Timestamp Equals" },
257     { NDS_SEARCH_ENTRY_CTS_EQ_APPROX, "Entry Creation Timestamp Equals Approximately" },
258     { NDS_SEARCH_VALUE_CTS_GE, "Value Creation Timestamp Greater or Equals" },
259     { NDS_SEARCH_VALUE_CTS_G, "Value Creation Timestamp Greater" },
260     { NDS_SEARCH_VALUE_CTS_LE, "Value Creation Timestamp Less or Equals" },
261     { NDS_SEARCH_VALUE_CTS_L, "Value Creation Timestamp Less" },
262     { NDS_SEARCH_VALUE_CTS_EQ, "Value Creation Timestamp Equals" },
263     { NDS_SEARCH_VALUE_CTS_EQ_APPROX, "Value Creation Timestamp Equals Approximately" },
264     { NDS_SEARCH_EXTENSIBLE, "Extensible" },
265     { NDS_SEARCH_ENTRY_SUBCOUNT_GE, "Entry SubCount Greater or Equals" },
266     { NDS_SEARCH_ENTRY_SUBCOUNT_G, "Entry SubCount Greater" },
267     { NDS_SEARCH_ENTRY_SUBCOUNT_LE, "Entry SubCount Less or Equals" },
268     { NDS_SEARCH_ENTRY_SUBCOUNT_L, "Entry SubCount Less" },
269     { NDS_SEARCH_ENTRY_SUBCOUNT_EQ, "Entry SubCount Equals" },
270     {0, NULL }
271 };
272
273 static const value_string iterator_subverbs[] = {
274     { IT_CLEAR, "Clear" },
275     { IT_COPY, "Copy" },
276     { IT_COUNT, "Count" },
277     { IT_CREATE, "Create" },
278     { IT_CURRENT, "Current" },
279     { IT_DESTROY, "Destroy" },
280     { IT_DONE, "Done" },
281     { IT_FIRST, "First" },
282     { IT_GETPOSITION, "Get Position" },
283     { IT_LAST, "Last" },
284     { IT_NEXT, "Next" },
285     { IT_PREV, "Previous" },
286     { IT_POSITION, "Position" },
287     { IT_POSITION_IT, "Position Iterator" },
288     { IT_SETINDEX, "Set Index" },
289     { IT_SETFILTER, "Set Filter" },
290     { IT_SKIP, "Skip" },
291     { IT_TYPEDOWN, "Type Down" },
292     { IT_ATFIRST, "At First" },
293     { IT_ATEOF, "At End of File" },
294     { IT_GETINDEX, "Get Index" },
295     { IT_ISPOSITIONABLE, "Is Positionable" },
296     { IT_ATBOF, "At Beginning of File" },
297     { IT_ATLAST, "At Last" },
298     { 0, NULL }
299 };
300
301
302 static const value_string nds_tuned_tags[] = {
303     { 0, "RDN Hint" },
304     { 1, "RDN History" },
305     {0, NULL }
306 };
307
308 #if 0
309 static const value_string nds_scope_vals[] = {
310     { 0, "Search Scope: 0x0000 - Examine base object only" },
311     { 1, "Search Scope: 0x0001 - Search the immediate subordinates of the base object" },
312     { 2, "Search Scope: 0x0002 - Search the base object and all of its subordinates" },
313     { 3, "Search Scope: 0x0003 - Search the base objects and all objects in its partition (NDS version 8 or higher)" },
314     {0, NULL }
315 };
316 #endif
317
318 static const value_string nds_tuned_item_tags[] = {
319     { 0, "Single Item" },
320     { 1, "Multiple Items" },
321     {0, NULL }
322 };
323
324 static const value_string nds_tags[] = {
325     { NDS_TAG_NO_SUCH_ENTRY,        "No Such Entry" },
326     { NDS_TAG_LOCAL_ENTRY,          "Local Entry" },
327     { NDS_TAG_REMOTE_ENTRY,         "Remote Entry" },
328     { NDS_TAG_ALIAS_ENTRY,          "Alias Entry" },
329     { NDS_TAG_REFERRAL_INFORMATION, "Referral Information" },
330     { NDS_TAG_ENTRY_AND_REFERRALS,  "Entry and Referrals" },
331     { 0, NULL }
332 };
333
334 static const range_string nds_info_type[] = {
335     { 0x00000000, 0x00000000, "Attribute Names Only / " },
336     { 0x00000001, 0x00000001, "Attribute Name & Value / " },
337     { 0x00000002, 0x00000002, "Effective Privileges / " },
338     { 0x00000003, 0x00000003, "Value Information / " },
339     { 0x00000004, 0x00000004, "Abbreviated Value / " },
340     { 0x00000005, 0xFFFFFFFF, "No Info Type Set" },
341     { 0, 0, NULL }
342 };
343
344 static const value_string nds_kind_of_changes[] = {
345     { 0x00000000, "Add Attribute" },
346     { 0x00000001, "Remove Attribute" },
347     { 0x00000002, "Add Value" },
348     { 0x00000003, "Remove Value" },
349     { 0x00000004, "Add Additional Value" },
350     { 0x00000005, "Overwrite Value" },
351     { 0x00000006, "Clear Attribute" },
352     { 0x00000007, "Clear Value" },
353     { 0, NULL }
354 };
355
356 static const value_string es_type[] = {
357     { 0x00000000, "No type is specified" },
358     { 0x00000001, "Unicode string" },
359     { 0x00000002, "Partial name" },
360     { 0x00000003, "Referrals" },
361     { 0x00000004, "Tuned name" },
362     { 0x00000005, "GUID attribute" },
363     { 0x00000006, "Local entry ID" },
364     { 0x00000007, "Number of defined entry specifiers" },
365     { 0, NULL }
366 };
367
368 static const value_string ncp_rights_vals[] = {
369     { 0x00, "No Rights"},
370     { 0x01, "Read"},
371     { 0x02, "Write"},
372     { 0x03, "Read, Write"},
373     { 0x04, "Deny Read"},
374     { 0x05, "Read, Deny Read"},
375     { 0x06, "Write, Deny Read"},
376     { 0x07, "Read, Write, Deny Read"},
377     { 0x08, "Deny Write"},
378     { 0x09, "Read, Deny Write"},
379     { 0x0a, "Write, Deny Write"},
380     { 0x0b, "Read, Write, Deny Write"},
381     { 0x0c, "Deny Read, Deny Write"},
382     { 0x0d, "Read, Deny Read, Deny Write"},
383     { 0x0e, "Write, Deny Read, Deny Write"},
384     { 0x0f, "Read, Write, Deny Read, Deny Write"},
385     { 0x10, "Compatibility"},
386     { 0x11, "Read, Compatibility"},
387     { 0x12, "Write, Compatibility"},
388     { 0x13, "Read, Write, Compatibility"},
389     { 0x14, "Deny Read, Compatibility"},
390     { 0x15, "Read, Deny Read, Compatibility"},
391     { 0x16, "Write, Deny Read, Compatibility"},
392     { 0x17, "Read, Write, Deny Read, Compatibility"},
393     { 0x18, "Deny Write, Compatibility"},
394     { 0x19, "Read, Deny Write, Compatibility"},
395     { 0x1a, "Write, Deny Write, Compatibility"},
396     { 0x1b, "Read, Write, Deny Write, Compatibility"},
397     { 0x1c, "Deny Read, Deny Write, Compatibility"},
398     { 0x1d, "Read, Deny Read, Deny Write, Compatibility"},
399     { 0x1e, "Write, Deny Read, Deny Write, Compatibility"},
400     { 0x1f, "Read, Write, Deny Read, Deny Write, Compatibility"},
401     { 0x40, "File Write Through"},
402     { 0x41, "Read, File Write Through"},
403     { 0x42, "Write, File Write Through"},
404     { 0x43, "Read, Write, File Write Through"},
405     { 0x44, "Deny Read, File Write Through"},
406     { 0x45, "Read, Deny Read, File Write Through"},
407     { 0x46, "Write, Deny Read, File Write Through"},
408     { 0x47, "Read, Write, Deny Read, File Write Through"},
409     { 0x48, "Deny Write, File Write Through"},
410     { 0x49, "Read, Deny Write, File Write Through"},
411     { 0x4a, "Write, Deny Write, File Write Through"},
412     { 0x4b, "Read, Write, Deny Write, File Write Through"},
413     { 0x4c, "Deny Read, Deny Write, File Write Through"},
414     { 0x4d, "Read, Deny Read, Deny Write, File Write Through"},
415     { 0x4e, "Write, Deny Read, Deny Write, File Write Through"},
416     { 0x4f, "Read, Write, Deny Read, Deny Write, File Write Through"},
417     { 0x50, "Compatibility, File Write Through"},
418     { 0x51, "Read, Compatibility, File Write Through"},
419     { 0x52, "Write, Compatibility, File Write Through"},
420     { 0x53, "Read, Write, Compatibility, File Write Through"},
421     { 0x54, "Deny Read, Compatibility, File Write Through"},
422     { 0x55, "Read, Deny Read, Compatibility, File Write Through"},
423     { 0x56, "Write, Deny Read, Compatibility, File Write Through"},
424     { 0x57, "Read, Write, Deny Read, Compatibility, File Write Through"},
425     { 0x58, "Deny Write, Compatibility, File Write Through"},
426     { 0x59, "Read, Deny Write, Compatibility, File Write Through"},
427     { 0x5a, "Write, Deny Write, Compatibility, File Write Through"},
428     { 0x5b, "Read, Write, Deny Write, Compatibility, File Write Through"},
429     { 0x5c, "Deny Read, Deny Write, Compatibility, File Write Through"},
430     { 0x5d, "Read, Deny Read, Deny Write, Compatibility, File Write Through"},
431     { 0x5e, "Write, Deny Read, Deny Write, Compatibility, File Write Through"},
432     { 0x5f, "Read, Write, Deny Read, Deny Write, Compatibility, File Write Through"},
433     { 0,    NULL }
434 };
435
436 static const value_string open_create_mode_vals[] = {
437     { 0x01, "Open"},
438     { 0x02, "Replace"},
439     { 0x03, "Open, Replace"},
440     { 0x08, "Create"},
441     { 0x09, "Open, Create"},
442     { 0x0a, "Replace, Create"},
443     { 0x0b, "Open, Replace, Create"},
444     { 0x20, "64-bit"},
445     { 0x21, "Open, 64-bit"},
446     { 0x22, "Replace, 64-bit"},
447     { 0x23, "Open, Replace, 64-bit"},
448     { 0x28, "Create, 64-bit"},
449     { 0x29, "Open, Create, 64-bit"},
450     { 0x2a, "Replace, Create, 64-bit"},
451     { 0x2b, "Open, Replace, Create, 64-bit"},
452     { 0x40, "Read Only"},
453     { 0x41, "Open, Read Only"},
454     { 0x42, "Replace, Read Only"},
455     { 0x43, "Open, Replace, Read Only"},
456     { 0x48, "Create, Read Only"},
457     { 0x49, "Open, Create, Read Only"},
458     { 0x4a, "Replace, Create, Read Only"},
459     { 0x4b, "Open, Replace, Create, Read Only"},
460     { 0x60, "64-bit, Read Only"},
461     { 0x61, "Open, 64-bit, Read Only"},
462     { 0x62, "Replace, 64-bit, Read Only"},
463     { 0x63, "Open, Replace, 64-bit, Read Only"},
464     { 0x68, "Create, 64-bit, Read Only"},
465     { 0x69, "Open, Create, 64-bit, Read Only"},
466     { 0x6a, "Replace, Create, 64-bit, Read Only"},
467     { 0x6b, "Open, Replace, Create, 64-bit, Read Only"},
468     { 0x80, "Op-Lock"},
469     { 0x81, "Open, Op-Lock"},
470     { 0x82, "Replace, Op-Lock"},
471     { 0x83, "Open, Replace, Op-Lock"},
472     { 0x88, "Create, Op-Lock"},
473     { 0x89, "Open, Create, Op-Lock"},
474     { 0x8a, "Replace, Create, Op-Lock"},
475     { 0x8b, "Open, Replace, Create, Op-Lock"},
476     { 0xa0, "64-bit, Op-Lock"},
477     { 0xa1, "Open, 64-bit, Op-Lock"},
478     { 0xa2, "Replace, 64-bit, Op-Lock"},
479     { 0xa3, "Open, Replace, 64-bit, Op-Lock"},
480     { 0xa8, "Create, 64-bit, Op-Lock"},
481     { 0xa9, "Open, Create, 64-bit, Op-Lock"},
482     { 0xaa, "Replace, Create, 64-bit, Op-Lock"},
483     { 0xab, "Open, Replace, Create, 64-bit, Op-Lock"},
484     { 0xc0, "Read Only, Op-Lock"},
485     { 0xc1, "Open, Read Only, Op-Lock"},
486     { 0xc2, "Replace, Read Only, Op-Lock"},
487     { 0xc3, "Open, Replace, Read Only, Op-Lock"},
488     { 0xc8, "Create, Read Only, Op-Lock"},
489     { 0xc9, "Open, Create, Read Only, Op-Lock"},
490     { 0xca, "Replace, Create, Read Only, Op-Lock"},
491     { 0xcb, "Open, Replace, Create, Read Only, Op-Lock"},
492     { 0xe0, "64-bit, Read Only, Op-Lock"},
493     { 0xe1, "Open, 64-bit, Read Only, Op-Lock"},
494     { 0xe2, "Replace, 64-bit, Read Only, Op-Lock"},
495     { 0xe3, "Open, Replace, 64-bit, Read Only, Op-Lock"},
496     { 0xe8, "Create, 64-bit, Read Only, Op-Lock"},
497     { 0xe9, "Open, Create, 64-bit, Read Only, Op-Lock"},
498     { 0xea, "Replace, Create, 64-bit, Read Only, Op-Lock"},
499     { 0xeb, "Open, Replace, Create, 64-bit, Read Only, Op-Lock"},
500     { 0,    NULL }
501 };
502
503 static const value_string open_create_action_vals[] = {
504     { 0x01, "Opened"},
505     { 0x02, "Created"},
506     { 0x03, "Opened, Created"},
507     { 0x04, "Replaced"},
508     { 0x05, "Opened, Replaced"},
509     { 0x06, "Created, Replaced"},
510     { 0x07, "Opened, Created, Replaced"},
511     { 0x08, "Compressed"},
512     { 0x09, "Opened, Compressed"},
513     { 0x0a, "Created, Compressed"},
514     { 0x0b, "Opened, Created, Compressed"},
515     { 0x0c, "Replaced, Compressed"},
516     { 0x0d, "Opened, Replaced, Compressed"},
517     { 0x0e, "Created, Replaced, Compressed"},
518     { 0x0f, "Opened, Created, Replaced, Compressed"},
519     { 0x80, "Read Only"},
520     { 0x81, "Opened, Read Only"},
521     { 0x82, "Created, Read Only"},
522     { 0x83, "Opened, Created, Read Only"},
523     { 0x84, "Replaced, Read Only"},
524     { 0x85, "Opened, Replaced, Read Only"},
525     { 0x86, "Created, Replaced, Read Only"},
526     { 0x87, "Opened, Created, Replaced, Read Only"},
527     { 0x88, "Compressed, Read Only"},
528     { 0x89, "Opened, Compressed, Read Only"},
529     { 0x8a, "Created, Compressed, Read Only"},
530     { 0x8b, "Opened, Created, Compressed, Read Only"},
531     { 0x8c, "Replaced, Compressed, Read Only"},
532     { 0x8d, "Opened, Replaced, Compressed, Read Only"},
533     { 0x8e, "Created, Replaced, Compressed, Read Only"},
534     { 0x8f, "Opened, Created, Replaced, Compressed, Read Only"},
535     { 0,    NULL }
536 };
537
538 static const value_string access_rights_vals[] = {
539     { 0x0000, "No Rights"},
540     { 0x0001, "Read"},
541     { 0x0002, "Write"},
542     { 0x0003, "Read, Write"},
543     { 0x0004, "Open"},
544     { 0x0005, "Read, Open"},
545     { 0x0006, "Write, Open"},
546     { 0x0007, "Read, Write, Open"},
547     { 0x0008, "Create"},
548     { 0x0009, "Read, Create"},
549     { 0x000a, "Write, Create"},
550     { 0x000b, "Read, Write, Create"},
551     { 0x000c, "Open, Create"},
552     { 0x000d, "Read, Open, Create"},
553     { 0x000e, "Write, Open, Create"},
554     { 0x000f, "Read, Write, Open, Create"},
555     { 0x0010, "Delete"},
556     { 0x0011, "Read, Delete"},
557     { 0x0012, "Write, Delete"},
558     { 0x0013, "Read, Write, Delete"},
559     { 0x0014, "Open, Delete"},
560     { 0x0015, "Read, Open, Delete"},
561     { 0x0016, "Write, Open, Delete"},
562     { 0x0017, "Read, Write, Open, Delete"},
563     { 0x0018, "Create, Delete"},
564     { 0x0019, "Read, Create, Delete"},
565     { 0x001a, "Write, Create, Delete"},
566     { 0x001b, "Read, Write, Create, Delete"},
567     { 0x001c, "Open, Create, Delete"},
568     { 0x001d, "Read, Open, Create, Delete"},
569     { 0x001e, "Write, Open, Create, Delete"},
570     { 0x001f, "Read, Write, Open, Create, Delete"},
571     { 0x0020, "Parental"},
572     { 0x0021, "Read, Parental"},
573     { 0x0022, "Write, Parental"},
574     { 0x0023, "Read, Write, Parental"},
575     { 0x0024, "Open, Parental"},
576     { 0x0025, "Read, Open, Parental"},
577     { 0x0026, "Write, Open, Parental"},
578     { 0x0027, "Read, Write, Open, Parental"},
579     { 0x0028, "Create, Parental"},
580     { 0x0029, "Read, Create, Parental"},
581     { 0x002a, "Write, Create, Parental"},
582     { 0x002b, "Read, Write, Create, Parental"},
583     { 0x002c, "Open, Create, Parental"},
584     { 0x002d, "Read, Open, Create, Parental"},
585     { 0x002e, "Write, Open, Create, Parental"},
586     { 0x002f, "Read, Write, Open, Create, Parental"},
587     { 0x0030, "Delete, Parental"},
588     { 0x0031, "Read, Delete, Parental"},
589     { 0x0032, "Write, Delete, Parental"},
590     { 0x0033, "Read, Write, Delete, Parental"},
591     { 0x0034, "Open, Delete, Parental"},
592     { 0x0035, "Read, Open, Delete, Parental"},
593     { 0x0036, "Write, Open, Delete, Parental"},
594     { 0x0037, "Read, Write, Open, Delete, Parental"},
595     { 0x0038, "Create, Delete, Parental"},
596     { 0x0039, "Read, Create, Delete, Parental"},
597     { 0x003a, "Write, Create, Delete, Parental"},
598     { 0x003b, "Read, Write, Create, Delete, Parental"},
599     { 0x003c, "Open, Create, Delete, Parental"},
600     { 0x003d, "Read, Open, Create, Delete, Parental"},
601     { 0x003e, "Write, Open, Create, Delete, Parental"},
602     { 0x003f, "Read, Write, Open, Create, Delete, Parental"},
603     { 0x0040, "Search"},
604     { 0x0041, "Read, Search"},
605     { 0x0042, "Write, Search"},
606     { 0x0043, "Read, Write, Search"},
607     { 0x0044, "Open, Search"},
608     { 0x0045, "Read, Open, Search"},
609     { 0x0046, "Write, Open, Search"},
610     { 0x0047, "Read, Write, Open, Search"},
611     { 0x0048, "Create, Search"},
612     { 0x0049, "Read, Create, Search"},
613     { 0x004a, "Write, Create, Search"},
614     { 0x004b, "Read, Write, Create, Search"},
615     { 0x004c, "Open, Create, Search"},
616     { 0x004d, "Read, Open, Create, Search"},
617     { 0x004e, "Write, Open, Create, Search"},
618     { 0x004f, "Read, Write, Open, Create, Search"},
619     { 0x0050, "Delete, Search"},
620     { 0x0051, "Read, Delete, Search"},
621     { 0x0052, "Write, Delete, Search"},
622     { 0x0053, "Read, Write, Delete, Search"},
623     { 0x0054, "Open, Delete, Search"},
624     { 0x0055, "Read, Open, Delete, Search"},
625     { 0x0056, "Write, Open, Delete, Search"},
626     { 0x0057, "Read, Write, Open, Delete, Search"},
627     { 0x0058, "Create, Delete, Search"},
628     { 0x0059, "Read, Create, Delete, Search"},
629     { 0x005a, "Write, Create, Delete, Search"},
630     { 0x005b, "Read, Write, Create, Delete, Search"},
631     { 0x005c, "Open, Create, Delete, Search"},
632     { 0x005d, "Read, Open, Create, Delete, Search"},
633     { 0x005e, "Write, Open, Create, Delete, Search"},
634     { 0x005f, "Read, Write, Open, Create, Delete, Search"},
635     { 0x0060, "Parental, Search"},
636     { 0x0061, "Read, Parental, Search"},
637     { 0x0062, "Write, Parental, Search"},
638     { 0x0063, "Read, Write, Parental, Search"},
639     { 0x0064, "Open, Parental, Search"},
640     { 0x0065, "Read, Open, Parental, Search"},
641     { 0x0066, "Write, Open, Parental, Search"},
642     { 0x0067, "Read, Write, Open, Parental, Search"},
643     { 0x0068, "Create, Parental, Search"},
644     { 0x0069, "Read, Create, Parental, Search"},
645     { 0x006a, "Write, Create, Parental, Search"},
646     { 0x006b, "Read, Write, Create, Parental, Search"},
647     { 0x006c, "Open, Create, Parental, Search"},
648     { 0x006d, "Read, Open, Create, Parental, Search"},
649     { 0x006e, "Write, Open, Create, Parental, Search"},
650     { 0x006f, "Read, Write, Open, Create, Parental, Search"},
651     { 0x0070, "Delete, Parental, Search"},
652     { 0x0071, "Read, Delete, Parental, Search"},
653     { 0x0072, "Write, Delete, Parental, Search"},
654     { 0x0073, "Read, Write, Delete, Parental, Search"},
655     { 0x0074, "Open, Delete, Parental, Search"},
656     { 0x0075, "Read, Open, Delete, Parental, Search"},
657     { 0x0076, "Write, Open, Delete, Parental, Search"},
658     { 0x0077, "Read, Write, Open, Delete, Parental, Search"},
659     { 0x0078, "Create, Delete, Parental, Search"},
660     { 0x0079, "Read, Create, Delete, Parental, Search"},
661     { 0x007a, "Write, Create, Delete, Parental, Search"},
662     { 0x007b, "Read, Write, Create, Delete, Parental, Search"},
663     { 0x007c, "Open, Create, Delete, Parental, Search"},
664     { 0x007d, "Read, Open, Create, Delete, Parental, Search"},
665     { 0x007e, "Write, Open, Create, Delete, Parental, Search"},
666     { 0x007f, "Read, Write, Open, Create, Delete, Parental, Search"},
667     { 0x0080, "Modify"},
668     { 0x0081, "Read, Modify"},
669     { 0x0082, "Write, Modify"},
670     { 0x0083, "Read, Write, Modify"},
671     { 0x0084, "Open, Modify"},
672     { 0x0085, "Read, Open, Modify"},
673     { 0x0086, "Write, Open, Modify"},
674     { 0x0087, "Read, Write, Open, Modify"},
675     { 0x0088, "Create, Modify"},
676     { 0x0089, "Read, Create, Modify"},
677     { 0x008a, "Write, Create, Modify"},
678     { 0x008b, "Read, Write, Create, Modify"},
679     { 0x008c, "Open, Create, Modify"},
680     { 0x008d, "Read, Open, Create, Modify"},
681     { 0x008e, "Write, Open, Create, Modify"},
682     { 0x008f, "Read, Write, Open, Create, Modify"},
683     { 0x0090, "Delete, Modify"},
684     { 0x0091, "Read, Delete, Modify"},
685     { 0x0092, "Write, Delete, Modify"},
686     { 0x0093, "Read, Write, Delete, Modify"},
687     { 0x0094, "Open, Delete, Modify"},
688     { 0x0095, "Read, Open, Delete, Modify"},
689     { 0x0096, "Write, Open, Delete, Modify"},
690     { 0x0097, "Read, Write, Open, Delete, Modify"},
691     { 0x0098, "Create, Delete, Modify"},
692     { 0x0099, "Read, Create, Delete, Modify"},
693     { 0x009a, "Write, Create, Delete, Modify"},
694     { 0x009b, "Read, Write, Create, Delete, Modify"},
695     { 0x009c, "Open, Create, Delete, Modify"},
696     { 0x009d, "Read, Open, Create, Delete, Modify"},
697     { 0x009e, "Write, Open, Create, Delete, Modify"},
698     { 0x009f, "Read, Write, Open, Create, Delete, Modify"},
699     { 0x00a0, "Parental, Modify"},
700     { 0x00a1, "Read, Parental, Modify"},
701     { 0x00a2, "Write, Parental, Modify"},
702     { 0x00a3, "Read, Write, Parental, Modify"},
703     { 0x00a4, "Open, Parental, Modify"},
704     { 0x00a5, "Read, Open, Parental, Modify"},
705     { 0x00a6, "Write, Open, Parental, Modify"},
706     { 0x00a7, "Read, Write, Open, Parental, Modify"},
707     { 0x00a8, "Create, Parental, Modify"},
708     { 0x00a9, "Read, Create, Parental, Modify"},
709     { 0x00aa, "Write, Create, Parental, Modify"},
710     { 0x00ab, "Read, Write, Create, Parental, Modify"},
711     { 0x00ac, "Open, Create, Parental, Modify"},
712     { 0x00ad, "Read, Open, Create, Parental, Modify"},
713     { 0x00ae, "Write, Open, Create, Parental, Modify"},
714     { 0x00af, "Read, Write, Open, Create, Parental, Modify"},
715     { 0x00b0, "Delete, Parental, Modify"},
716     { 0x00b1, "Read, Delete, Parental, Modify"},
717     { 0x00b2, "Write, Delete, Parental, Modify"},
718     { 0x00b3, "Read, Write, Delete, Parental, Modify"},
719     { 0x00b4, "Open, Delete, Parental, Modify"},
720     { 0x00b5, "Read, Open, Delete, Parental, Modify"},
721     { 0x00b6, "Write, Open, Delete, Parental, Modify"},
722     { 0x00b7, "Read, Write, Open, Delete, Parental, Modify"},
723     { 0x00b8, "Create, Delete, Parental, Modify"},
724     { 0x00b9, "Read, Create, Delete, Parental, Modify"},
725     { 0x00ba, "Write, Create, Delete, Parental, Modify"},
726     { 0x00bb, "Read, Write, Create, Delete, Parental, Modify"},
727     { 0x00bc, "Open, Create, Delete, Parental, Modify"},
728     { 0x00bd, "Read, Open, Create, Delete, Parental, Modify"},
729     { 0x00be, "Write, Open, Create, Delete, Parental, Modify"},
730     { 0x00bf, "Read, Write, Open, Create, Delete, Parental, Modify"},
731     { 0x00c0, "Search, Modify"},
732     { 0x00c1, "Read, Search, Modify"},
733     { 0x00c2, "Write, Search, Modify"},
734     { 0x00c3, "Read, Write, Search, Modify"},
735     { 0x00c4, "Open, Search, Modify"},
736     { 0x00c5, "Read, Open, Search, Modify"},
737     { 0x00c6, "Write, Open, Search, Modify"},
738     { 0x00c7, "Read, Write, Open, Search, Modify"},
739     { 0x00c8, "Create, Search, Modify"},
740     { 0x00c9, "Read, Create, Search, Modify"},
741     { 0x00ca, "Write, Create, Search, Modify"},
742     { 0x00cb, "Read, Write, Create, Search, Modify"},
743     { 0x00cc, "Open, Create, Search, Modify"},
744     { 0x00cd, "Read, Open, Create, Search, Modify"},
745     { 0x00ce, "Write, Open, Create, Search, Modify"},
746     { 0x00cf, "Read, Write, Open, Create, Search, Modify"},
747     { 0x00d0, "Delete, Search, Modify"},
748     { 0x00d1, "Read, Delete, Search, Modify"},
749     { 0x00d2, "Write, Delete, Search, Modify"},
750     { 0x00d3, "Read, Write, Delete, Search, Modify"},
751     { 0x00d4, "Open, Delete, Search, Modify"},
752     { 0x00d5, "Read, Open, Delete, Search, Modify"},
753     { 0x00d6, "Write, Open, Delete, Search, Modify"},
754     { 0x00d7, "Read, Write, Open, Delete, Search, Modify"},
755     { 0x00d8, "Create, Delete, Search, Modify"},
756     { 0x00d9, "Read, Create, Delete, Search, Modify"},
757     { 0x00da, "Write, Create, Delete, Search, Modify"},
758     { 0x00db, "Read, Write, Create, Delete, Search, Modify"},
759     { 0x00dc, "Open, Create, Delete, Search, Modify"},
760     { 0x00dd, "Read, Open, Create, Delete, Search, Modify"},
761     { 0x00de, "Write, Open, Create, Delete, Search, Modify"},
762     { 0x00df, "Read, Write, Open, Create, Delete, Search, Modify"},
763     { 0x00e0, "Parental, Search, Modify"},
764     { 0x00e1, "Read, Parental, Search, Modify"},
765     { 0x00e2, "Write, Parental, Search, Modify"},
766     { 0x00e3, "Read, Write, Parental, Search, Modify"},
767     { 0x00e4, "Open, Parental, Search, Modify"},
768     { 0x00e5, "Read, Open, Parental, Search, Modify"},
769     { 0x00e6, "Write, Open, Parental, Search, Modify"},
770     { 0x00e7, "Read, Write, Open, Parental, Search, Modify"},
771     { 0x00e8, "Create, Parental, Search, Modify"},
772     { 0x00e9, "Read, Create, Parental, Search, Modify"},
773     { 0x00ea, "Write, Create, Parental, Search, Modify"},
774     { 0x00eb, "Read, Write, Create, Parental, Search, Modify"},
775     { 0x00ec, "Open, Create, Parental, Search, Modify"},
776     { 0x00ed, "Read, Open, Create, Parental, Search, Modify"},
777     { 0x00ee, "Write, Open, Create, Parental, Search, Modify"},
778     { 0x00ef, "Read, Write, Open, Create, Parental, Search, Modify"},
779     { 0x00f0, "Delete, Parental, Search, Modify"},
780     { 0x00f1, "Read, Delete, Parental, Search, Modify"},
781     { 0x00f2, "Write, Delete, Parental, Search, Modify"},
782     { 0x00f3, "Read, Write, Delete, Parental, Search, Modify"},
783     { 0x00f4, "Open, Delete, Parental, Search, Modify"},
784     { 0x00f5, "Read, Open, Delete, Parental, Search, Modify"},
785     { 0x00f6, "Write, Open, Delete, Parental, Search, Modify"},
786     { 0x00f7, "Read, Write, Open, Delete, Parental, Search, Modify"},
787     { 0x00f8, "Create, Delete, Parental, Search, Modify"},
788     { 0x00f9, "Read, Create, Delete, Parental, Search, Modify"},
789     { 0x00fa, "Write, Create, Delete, Parental, Search, Modify"},
790     { 0x00fb, "Read, Write, Create, Delete, Parental, Search, Modify"},
791     { 0x00fc, "Open, Create, Delete, Parental, Search, Modify"},
792     { 0x00fd, "Read, Open, Create, Delete, Parental, Search, Modify"},
793     { 0x00fe, "Write, Open, Create, Delete, Parental, Search, Modify"},
794     { 0x00ff, "Read, Write, Open, Create, Delete, Parental, Search, Modify"},
795     { 0x0100, "Supervisor"},
796     { 0x0101, "Read, Supervisor"},
797     { 0x0102, "Write, Supervisor"},
798     { 0x0103, "Read, Write, Supervisor"},
799     { 0x0104, "Open, Supervisor"},
800     { 0x0105, "Read, Open, Supervisor"},
801     { 0x0106, "Write, Open, Supervisor"},
802     { 0x0107, "Read, Write, Open, Supervisor"},
803     { 0x0108, "Create, Supervisor"},
804     { 0x0109, "Read, Create, Supervisor"},
805     { 0x010a, "Write, Create, Supervisor"},
806     { 0x010b, "Read, Write, Create, Supervisor"},
807     { 0x010c, "Open, Create, Supervisor"},
808     { 0x010d, "Read, Open, Create, Supervisor"},
809     { 0x010e, "Write, Open, Create, Supervisor"},
810     { 0x010f, "Read, Write, Open, Create, Supervisor"},
811     { 0x0110, "Delete, Supervisor"},
812     { 0x0111, "Read, Delete, Supervisor"},
813     { 0x0112, "Write, Delete, Supervisor"},
814     { 0x0113, "Read, Write, Delete, Supervisor"},
815     { 0x0114, "Open, Delete, Supervisor"},
816     { 0x0115, "Read, Open, Delete, Supervisor"},
817     { 0x0116, "Write, Open, Delete, Supervisor"},
818     { 0x0117, "Read, Write, Open, Delete, Supervisor"},
819     { 0x0118, "Create, Delete, Supervisor"},
820     { 0x0119, "Read, Create, Delete, Supervisor"},
821     { 0x011a, "Write, Create, Delete, Supervisor"},
822     { 0x011b, "Read, Write, Create, Delete, Supervisor"},
823     { 0x011c, "Open, Create, Delete, Supervisor"},
824     { 0x011d, "Read, Open, Create, Delete, Supervisor"},
825     { 0x011e, "Write, Open, Create, Delete, Supervisor"},
826     { 0x011f, "Read, Write, Open, Create, Delete, Supervisor"},
827     { 0x0120, "Parental, Supervisor"},
828     { 0x0121, "Read, Parental, Supervisor"},
829     { 0x0122, "Write, Parental, Supervisor"},
830     { 0x0123, "Read, Write, Parental, Supervisor"},
831     { 0x0124, "Open, Parental, Supervisor"},
832     { 0x0125, "Read, Open, Parental, Supervisor"},
833     { 0x0126, "Write, Open, Parental, Supervisor"},
834     { 0x0127, "Read, Write, Open, Parental, Supervisor"},
835     { 0x0128, "Create, Parental, Supervisor"},
836     { 0x0129, "Read, Create, Parental, Supervisor"},
837     { 0x012a, "Write, Create, Parental, Supervisor"},
838     { 0x012b, "Read, Write, Create, Parental, Supervisor"},
839     { 0x012c, "Open, Create, Parental, Supervisor"},
840     { 0x012d, "Read, Open, Create, Parental, Supervisor"},
841     { 0x012e, "Write, Open, Create, Parental, Supervisor"},
842     { 0x012f, "Read, Write, Open, Create, Parental, Supervisor"},
843     { 0x0130, "Delete, Parental, Supervisor"},
844     { 0x0131, "Read, Delete, Parental, Supervisor"},
845     { 0x0132, "Write, Delete, Parental, Supervisor"},
846     { 0x0133, "Read, Write, Delete, Parental, Supervisor"},
847     { 0x0134, "Open, Delete, Parental, Supervisor"},
848     { 0x0135, "Read, Open, Delete, Parental, Supervisor"},
849     { 0x0136, "Write, Open, Delete, Parental, Supervisor"},
850     { 0x0137, "Read, Write, Open, Delete, Parental, Supervisor"},
851     { 0x0138, "Create, Delete, Parental, Supervisor"},
852     { 0x0139, "Read, Create, Delete, Parental, Supervisor"},
853     { 0x013a, "Write, Create, Delete, Parental, Supervisor"},
854     { 0x013b, "Read, Write, Create, Delete, Parental, Supervisor"},
855     { 0x013c, "Open, Create, Delete, Parental, Supervisor"},
856     { 0x013d, "Read, Open, Create, Delete, Parental, Supervisor"},
857     { 0x013e, "Write, Open, Create, Delete, Parental, Supervisor"},
858     { 0x013f, "Read, Write, Open, Create, Delete, Parental, Supervisor"},
859     { 0x0140, "Search, Supervisor"},
860     { 0x0141, "Read, Search, Supervisor"},
861     { 0x0142, "Write, Search, Supervisor"},
862     { 0x0143, "Read, Write, Search, Supervisor"},
863     { 0x0144, "Open, Search, Supervisor"},
864     { 0x0145, "Read, Open, Search, Supervisor"},
865     { 0x0146, "Write, Open, Search, Supervisor"},
866     { 0x0147, "Read, Write, Open, Search, Supervisor"},
867     { 0x0148, "Create, Search, Supervisor"},
868     { 0x0149, "Read, Create, Search, Supervisor"},
869     { 0x014a, "Write, Create, Search, Supervisor"},
870     { 0x014b, "Read, Write, Create, Search, Supervisor"},
871     { 0x014c, "Open, Create, Search, Supervisor"},
872     { 0x014d, "Read, Open, Create, Search, Supervisor"},
873     { 0x014e, "Write, Open, Create, Search, Supervisor"},
874     { 0x014f, "Read, Write, Open, Create, Search, Supervisor"},
875     { 0x0150, "Delete, Search, Supervisor"},
876     { 0x0151, "Read, Delete, Search, Supervisor"},
877     { 0x0152, "Write, Delete, Search, Supervisor"},
878     { 0x0153, "Read, Write, Delete, Search, Supervisor"},
879     { 0x0154, "Open, Delete, Search, Supervisor"},
880     { 0x0155, "Read, Open, Delete, Search, Supervisor"},
881     { 0x0156, "Write, Open, Delete, Search, Supervisor"},
882     { 0x0157, "Read, Write, Open, Delete, Search, Supervisor"},
883     { 0x0158, "Create, Delete, Search, Supervisor"},
884     { 0x0159, "Read, Create, Delete, Search, Supervisor"},
885     { 0x015a, "Write, Create, Delete, Search, Supervisor"},
886     { 0x015b, "Read, Write, Create, Delete, Search, Supervisor"},
887     { 0x015c, "Open, Create, Delete, Search, Supervisor"},
888     { 0x015d, "Read, Open, Create, Delete, Search, Supervisor"},
889     { 0x015e, "Write, Open, Create, Delete, Search, Supervisor"},
890     { 0x015f, "Read, Write, Open, Create, Delete, Search, Supervisor"},
891     { 0x0160, "Parental, Search, Supervisor"},
892     { 0x0161, "Read, Parental, Search, Supervisor"},
893     { 0x0162, "Write, Parental, Search, Supervisor"},
894     { 0x0163, "Read, Write, Parental, Search, Supervisor"},
895     { 0x0164, "Open, Parental, Search, Supervisor"},
896     { 0x0165, "Read, Open, Parental, Search, Supervisor"},
897     { 0x0166, "Write, Open, Parental, Search, Supervisor"},
898     { 0x0167, "Read, Write, Open, Parental, Search, Supervisor"},
899     { 0x0168, "Create, Parental, Search, Supervisor"},
900     { 0x0169, "Read, Create, Parental, Search, Supervisor"},
901     { 0x016a, "Write, Create, Parental, Search, Supervisor"},
902     { 0x016b, "Read, Write, Create, Parental, Search, Supervisor"},
903     { 0x016c, "Open, Create, Parental, Search, Supervisor"},
904     { 0x016d, "Read, Open, Create, Parental, Search, Supervisor"},
905     { 0x016e, "Write, Open, Create, Parental, Search, Supervisor"},
906     { 0x016f, "Read, Write, Open, Create, Parental, Search, Supervisor"},
907     { 0x0170, "Delete, Parental, Search, Supervisor"},
908     { 0x0171, "Read, Delete, Parental, Search, Supervisor"},
909     { 0x0172, "Write, Delete, Parental, Search, Supervisor"},
910     { 0x0173, "Read, Write, Delete, Parental, Search, Supervisor"},
911     { 0x0174, "Open, Delete, Parental, Search, Supervisor"},
912     { 0x0175, "Read, Open, Delete, Parental, Search, Supervisor"},
913     { 0x0176, "Write, Open, Delete, Parental, Search, Supervisor"},
914     { 0x0177, "Read, Write, Open, Delete, Parental, Search, Supervisor"},
915     { 0x0178, "Create, Delete, Parental, Search, Supervisor"},
916     { 0x0179, "Read, Create, Delete, Parental, Search, Supervisor"},
917     { 0x017a, "Write, Create, Delete, Parental, Search, Supervisor"},
918     { 0x017b, "Read, Write, Create, Delete, Parental, Search, Supervisor"},
919     { 0x017c, "Open, Create, Delete, Parental, Search, Supervisor"},
920     { 0x017d, "Read, Open, Create, Delete, Parental, Search, Supervisor"},
921     { 0x017e, "Write, Open, Create, Delete, Parental, Search, Supervisor"},
922     { 0x017f, "Read, Write, Open, Create, Delete, Parental, Search, Supervisor"},
923     { 0x0180, "Modify, Supervisor"},
924     { 0x0181, "Read, Modify, Supervisor"},
925     { 0x0182, "Write, Modify, Supervisor"},
926     { 0x0183, "Read, Write, Modify, Supervisor"},
927     { 0x0184, "Open, Modify, Supervisor"},
928     { 0x0185, "Read, Open, Modify, Supervisor"},
929     { 0x0186, "Write, Open, Modify, Supervisor"},
930     { 0x0187, "Read, Write, Open, Modify, Supervisor"},
931     { 0x0188, "Create, Modify, Supervisor"},
932     { 0x0189, "Read, Create, Modify, Supervisor"},
933     { 0x018a, "Write, Create, Modify, Supervisor"},
934     { 0x018b, "Read, Write, Create, Modify, Supervisor"},
935     { 0x018c, "Open, Create, Modify, Supervisor"},
936     { 0x018d, "Read, Open, Create, Modify, Supervisor"},
937     { 0x018e, "Write, Open, Create, Modify, Supervisor"},
938     { 0x018f, "Read, Write, Open, Create, Modify, Supervisor"},
939     { 0x0190, "Delete, Modify, Supervisor"},
940     { 0x0191, "Read, Delete, Modify, Supervisor"},
941     { 0x0192, "Write, Delete, Modify, Supervisor"},
942     { 0x0193, "Read, Write, Delete, Modify, Supervisor"},
943     { 0x0194, "Open, Delete, Modify, Supervisor"},
944     { 0x0195, "Read, Open, Delete, Modify, Supervisor"},
945     { 0x0196, "Write, Open, Delete, Modify, Supervisor"},
946     { 0x0197, "Read, Write, Open, Delete, Modify, Supervisor"},
947     { 0x0198, "Create, Delete, Modify, Supervisor"},
948     { 0x0199, "Read, Create, Delete, Modify, Supervisor"},
949     { 0x019a, "Write, Create, Delete, Modify, Supervisor"},
950     { 0x019b, "Read, Write, Create, Delete, Modify, Supervisor"},
951     { 0x019c, "Open, Create, Delete, Modify, Supervisor"},
952     { 0x019d, "Read, Open, Create, Delete, Modify, Supervisor"},
953     { 0x019e, "Write, Open, Create, Delete, Modify, Supervisor"},
954     { 0x019f, "Read, Write, Open, Create, Delete, Modify, Supervisor"},
955     { 0x01a0, "Parental, Modify, Supervisor"},
956     { 0x01a1, "Read, Parental, Modify, Supervisor"},
957     { 0x01a2, "Write, Parental, Modify, Supervisor"},
958     { 0x01a3, "Read, Write, Parental, Modify, Supervisor"},
959     { 0x01a4, "Open, Parental, Modify, Supervisor"},
960     { 0x01a5, "Read, Open, Parental, Modify, Supervisor"},
961     { 0x01a6, "Write, Open, Parental, Modify, Supervisor"},
962     { 0x01a7, "Read, Write, Open, Parental, Modify, Supervisor"},
963     { 0x01a8, "Create, Parental, Modify, Supervisor"},
964     { 0x01a9, "Read, Create, Parental, Modify, Supervisor"},
965     { 0x01aa, "Write, Create, Parental, Modify, Supervisor"},
966     { 0x01ab, "Read, Write, Create, Parental, Modify, Supervisor"},
967     { 0x01ac, "Open, Create, Parental, Modify, Supervisor"},
968     { 0x01ad, "Read, Open, Create, Parental, Modify, Supervisor"},
969     { 0x01ae, "Write, Open, Create, Parental, Modify, Supervisor"},
970     { 0x01af, "Read, Write, Open, Create, Parental, Modify, Supervisor"},
971     { 0x01b0, "Delete, Parental, Modify, Supervisor"},
972     { 0x01b1, "Read, Delete, Parental, Modify, Supervisor"},
973     { 0x01b2, "Write, Delete, Parental, Modify, Supervisor"},
974     { 0x01b3, "Read, Write, Delete, Parental, Modify, Supervisor"},
975     { 0x01b4, "Open, Delete, Parental, Modify, Supervisor"},
976     { 0x01b5, "Read, Open, Delete, Parental, Modify, Supervisor"},
977     { 0x01b6, "Write, Open, Delete, Parental, Modify, Supervisor"},
978     { 0x01b7, "Read, Write, Open, Delete, Parental, Modify, Supervisor"},
979     { 0x01b8, "Create, Delete, Parental, Modify, Supervisor"},
980     { 0x01b9, "Read, Create, Delete, Parental, Modify, Supervisor"},
981     { 0x01ba, "Write, Create, Delete, Parental, Modify, Supervisor"},
982     { 0x01bb, "Read, Write, Create, Delete, Parental, Modify, Supervisor"},
983     { 0x01bc, "Open, Create, Delete, Parental, Modify, Supervisor"},
984     { 0x01bd, "Read, Open, Create, Delete, Parental, Modify, Supervisor"},
985     { 0x01be, "Write, Open, Create, Delete, Parental, Modify, Supervisor"},
986     { 0x01bf, "Read, Write, Open, Create, Delete, Parental, Modify, Supervisor"},
987     { 0x01c0, "Search, Modify, Supervisor"},
988     { 0x01c1, "Read, Search, Modify, Supervisor"},
989     { 0x01c2, "Write, Search, Modify, Supervisor"},
990     { 0x01c3, "Read, Write, Search, Modify, Supervisor"},
991     { 0x01c4, "Open, Search, Modify, Supervisor"},
992     { 0x01c5, "Read, Open, Search, Modify, Supervisor"},
993     { 0x01c6, "Write, Open, Search, Modify, Supervisor"},
994     { 0x01c7, "Read, Write, Open, Search, Modify, Supervisor"},
995     { 0x01c8, "Create, Search, Modify, Supervisor"},
996     { 0x01c9, "Read, Create, Search, Modify, Supervisor"},
997     { 0x01ca, "Write, Create, Search, Modify, Supervisor"},
998     { 0x01cb, "Read, Write, Create, Search, Modify, Supervisor"},
999     { 0x01cc, "Open, Create, Search, Modify, Supervisor"},
1000     { 0x01cd, "Read, Open, Create, Search, Modify, Supervisor"},
1001     { 0x01ce, "Write, Open, Create, Search, Modify, Supervisor"},
1002     { 0x01cf, "Read, Write, Open, Create, Search, Modify, Supervisor"},
1003     { 0x01d0, "Delete, Search, Modify, Supervisor"},
1004     { 0x01d1, "Read, Delete, Search, Modify, Supervisor"},
1005     { 0x01d2, "Write, Delete, Search, Modify, Supervisor"},
1006     { 0x01d3, "Read, Write, Delete, Search, Modify, Supervisor"},
1007     { 0x01d4, "Open, Delete, Search, Modify, Supervisor"},
1008     { 0x01d5, "Read, Open, Delete, Search, Modify, Supervisor"},
1009     { 0x01d6, "Write, Open, Delete, Search, Modify, Supervisor"},
1010     { 0x01d7, "Read, Write, Open, Delete, Search, Modify, Supervisor"},
1011     { 0x01d8, "Create, Delete, Search, Modify, Supervisor"},
1012     { 0x01d9, "Read, Create, Delete, Search, Modify, Supervisor"},
1013     { 0x01da, "Write, Create, Delete, Search, Modify, Supervisor"},
1014     { 0x01db, "Read, Write, Create, Delete, Search, Modify, Supervisor"},
1015     { 0x01dc, "Open, Create, Delete, Search, Modify, Supervisor"},
1016     { 0x01dd, "Read, Open, Create, Delete, Search, Modify, Supervisor"},
1017     { 0x01de, "Write, Open, Create, Delete, Search, Modify, Supervisor"},
1018     { 0x01df, "Read, Write, Open, Create, Delete, Search, Modify, Supervisor"},
1019     { 0x01e0, "Parental, Search, Modify, Supervisor"},
1020     { 0x01e1, "Read, Parental, Search, Modify, Supervisor"},
1021     { 0x01e2, "Write, Parental, Search, Modify, Supervisor"},
1022     { 0x01e3, "Read, Write, Parental, Search, Modify, Supervisor"},
1023     { 0x01e4, "Open, Parental, Search, Modify, Supervisor"},
1024     { 0x01e5, "Read, Open, Parental, Search, Modify, Supervisor"},
1025     { 0x01e6, "Write, Open, Parental, Search, Modify, Supervisor"},
1026     { 0x01e7, "Read, Write, Open, Parental, Search, Modify, Supervisor"},
1027     { 0x01e8, "Create, Parental, Search, Modify, Supervisor"},
1028     { 0x01e9, "Read, Create, Parental, Search, Modify, Supervisor"},
1029     { 0x01ea, "Write, Create, Parental, Search, Modify, Supervisor"},
1030     { 0x01eb, "Read, Write, Create, Parental, Search, Modify, Supervisor"},
1031     { 0x01ec, "Open, Create, Parental, Search, Modify, Supervisor"},
1032     { 0x01ed, "Read, Open, Create, Parental, Search, Modify, Supervisor"},
1033     { 0x01ee, "Write, Open, Create, Parental, Search, Modify, Supervisor"},
1034     { 0x01ef, "Read, Write, Open, Create, Parental, Search, Modify, Supervisor"},
1035     { 0x01f0, "Delete, Parental, Search, Modify, Supervisor"},
1036     { 0x01f1, "Read, Delete, Parental, Search, Modify, Supervisor"},
1037     { 0x01f2, "Write, Delete, Parental, Search, Modify, Supervisor"},
1038     { 0x01f3, "Read, Write, Delete, Parental, Search, Modify, Supervisor"},
1039     { 0x01f4, "Open, Delete, Parental, Search, Modify, Supervisor"},
1040     { 0x01f5, "Read, Open, Delete, Parental, Search, Modify, Supervisor"},
1041     { 0x01f6, "Write, Open, Delete, Parental, Search, Modify, Supervisor"},
1042     { 0x01f7, "Read, Write, Open, Delete, Parental, Search, Modify, Supervisor"},
1043     { 0x01f8, "Create, Delete, Parental, Search, Modify, Supervisor"},
1044     { 0x01f9, "Read, Create, Delete, Parental, Search, Modify, Supervisor"},
1045     { 0x01fa, "Write, Create, Delete, Parental, Search, Modify, Supervisor"},
1046     { 0x01fb, "Read, Write, Create, Delete, Parental, Search, Modify, Supervisor"},
1047     { 0x01fc, "Open, Create, Delete, Parental, Search, Modify, Supervisor"},
1048     { 0x01fd, "Read, Open, Create, Delete, Parental, Search, Modify, Supervisor"},
1049     { 0x01fe, "Write, Open, Create, Delete, Parental, Search, Modify, Supervisor"},
1050     { 0x01ff, "Read, Write, Open, Create, Delete, Parental, Search, Modify, Supervisor"},
1051     { 0,    NULL }
1052 };
1053
1054
1055 static const value_string nds_reply_errors[] = {
1056     { 0xffffffff, "(-1) Insufficient Space" },
1057     { 0xffffff89, "(-119) Buffer too Small" },
1058     { 0xffffff88, "(-120) RR Volume Flag Not Set" },
1059     { 0xffffff87, "(-121) No Items Found" },
1060     { 0xffffff86, "(-122) Connection Already Temporary" },
1061     { 0xffffff85, "(-123) Connection Already Logged In" },
1062     { 0xffffff84, "(-124) Connection Not Authenticated" },
1063     { 0xffffff83, "(-125) Connection Not Logged In" },
1064     { 0xffffff82, "(-126) NCP Boundary Check Failed" },
1065     { 0xffffff81, "(-127) Lock Waiting" },
1066     { 0xffffff80, "(-128) Lock Fail" },
1067     { 0xffffff7f, "(-129) Out of Handles" },
1068     { 0xffffff7e, "(-130) No Open Privilege" },
1069     { 0xffffff7d, "(-131) Hard IO Error" },
1070     { 0xffffff7c, "(-132) No Create Privilege" },
1071     { 0xffffff7b, "(-133) No Create Delete Privilege" },
1072     { 0xffffff7a, "(-134) Create Duplicate When Read Only" },
1073     { 0xffffff79, "(-135) Create File with Invalid Name" },
1074     { 0xffffff78, "(-136) Invalid File Handle" },
1075     { 0xffffff77, "(-137) No Search Privilege"   },
1076     { 0xffffff76, "(-138) No Delete Privilege" },
1077     { 0xffffff75, "(-139) No Rename Privilege" },
1078     { 0xffffff74, "(-140) No Set Privilege" },
1079     { 0xffffff73, "(-141) Some File in Use" },
1080     { 0xffffff72, "(-142) All File in Use" },
1081     { 0xffffff71, "(-143) Some Read Only" },
1082     { 0xffffff70, "(-144) All Read Only" },
1083     { 0xffffff6f, "(-145) Some names Exist" },
1084     { 0xffffff6e, "(-146) All Names Exist" },
1085     { 0xffffff6d, "(-147) No Read Privilege" },
1086     { 0xffffff6c, "(-148) No Write Privilege" },
1087     { 0xffffff6b, "(-149) File Detached" },
1088     { 0xffffff6a, "(-150) No Alloc Space/Target Not a Subdirectory/Insuffficient Memory" },
1089     { 0xffffff69, "(-151) No Spool Space" },
1090     { 0xffffff68, "(-152) Invalid Volume" },
1091     { 0xffffff67, "(-153) Directory Full" },
1092     { 0xffffff66, "(-154) Rename Across Volume" },
1093     { 0xffffff65, "(-155) Bad Directory Handle" },
1094     { 0xffffff64, "(-156) Invalid Path/No Such Extension" },
1095     { 0xffffff63, "(-157) No Directory Handles" },
1096     { 0xffffff62, "(-158) Bad File Name" },
1097     { 0xffffff61, "(-159) Directory Active" },
1098     { 0xffffff60, "(-160) Directory Not Empty" },
1099     { 0xffffff5f, "(-161) Directory IO Error" },
1100     { 0xffffff5e, "(-162) IO Locked" },
1101     { 0xffffff5d, "(-163) Transaction Restarted" },
1102     { 0xffffff5c, "(-164) Rename Directory Invalid" },
1103     { 0xffffff5b, "(-165) Invalid Open/Create Mode" },
1104     { 0xffffff5a, "(-166) Already in Use" },
1105     { 0xffffff59, "(-167) Invalid Resource Tag" },
1106     { 0xffffff58, "(-168) Access Denied" },
1107     { 0xffffff44, "(-188) Login Signing Required" },
1108     { 0xffffff43, "(-189) Login Encryption Required" },
1109     { 0xffffff42, "(-190) Invalid Data Stream" },
1110     { 0xffffff41, "(-191) Invalid Name Space" },
1111     { 0xffffff40, "(-192) No Accounting Privileges" },
1112     { 0xffffff3f, "(-193) No Account Balance" },
1113     { 0xffffff3e, "(-194) Credit Limit Exceeded" },
1114     { 0xffffff3d, "(-195) Too Many Holds" },
1115     { 0xffffff3c, "(-196) Accounting Disabled" },
1116     { 0xffffff3b, "(-197) Intruder Login Lockout" },
1117     { 0xffffff3a, "(-198) No Console Rights" },
1118     { 0xffffff30, "(-208) Queue IO Failure" },
1119     { 0xffffff2f, "(-209) No Queue" },
1120     { 0xffffff2e, "(-210) No Queue Server" },
1121     { 0xffffff2d, "(-211) No Queue Rights" },
1122     { 0xffffff2c, "(-212) Queue Full" },
1123     { 0xffffff2b, "(-213) No Queue Job" },
1124     { 0xffffff2a, "(-214) No Queue Job Rights/Unencrypted Not Allowed" },
1125     { 0xffffff29, "(-215) Queue In Service/Duplicate Password" },
1126     { 0xffffff28, "(-216) Queue Not Active/Password Too Short" },
1127     { 0xffffff27, "(-217) Queue Station Not Server/Maximum Logins Exceeded" },
1128     { 0xffffff26, "(-218) Queue Halted/Bad Login Time" },
1129     { 0xffffff25, "(-219) Queue Maximum Servers/Node Address Violation" },
1130     { 0xffffff24, "(-220) Login Account Expired" },
1131     { 0xffffff22, "(-222) Bad Password" },
1132     { 0xffffff21, "(-223) Password Expired" },
1133     { 0xffffff20, "(-224) No Login Connection Available" },
1134     { 0xffffff18, "(-232) Write to Group Property" },
1135     { 0xffffff17, "(-233) Member Already Exists" },
1136     { 0xffffff16, "(-234) No Such Member" },
1137     { 0xffffff15, "(-235) Property Not Group" },
1138     { 0xffffff14, "(-236) No Such Value Set" },
1139     { 0xffffff13, "(-237) Property Already Exists" },
1140     { 0xffffff12, "(-238) Object Already Exists" },
1141     { 0xffffff11, "(-239) Illegal Name" },
1142     { 0xffffff10, "(-240) Illegal Wildcard" },
1143     { 0xffffff0f, "(-241) Bindery Security" },
1144     { 0xffffff0e, "(-242) No Object Read Rights" },
1145     { 0xffffff0d, "(-243) No Object Rename Rights" },
1146     { 0xffffff0c, "(-244) No Object Delete Rights" },
1147     { 0xffffff0b, "(-245) No Object Create Rights" },
1148     { 0xffffff0a, "(-246) No Property Delete Rights" },
1149     { 0xffffff09, "(-247) No Property Create Rights" },
1150     { 0xffffff08, "(-248) No Property Write Rights" },
1151     { 0xffffff07, "(-249) No Property Read Rights" },
1152     { 0xffffff06, "(-250) Temp Remap" },
1153     { 0xffffff05, "(-251) Unknown Request/No Such Property" },
1154     { 0xffffff04, "(-252) Message Queue Full/Target Already Has Message/No Such Object" },
1155     { 0xffffff03, "(-253) Bad Station Number" },
1156     { 0xffffff02, "(-254) Bindery Locked/Directory Locked/Spool Delete/Trustee not Found/Timeout" },
1157     { 0xffffff01, "(-255) Hard Failure" },
1158     { 0xfffffed3, "(-301) Not Enough Memory" },
1159     { 0xfffffed2, "(-302) Bad Key" },
1160     { 0xfffffed1, "(-303) Bad Context" },
1161     { 0xfffffed0, "(-304) Buffer Full" },
1162     { 0xfffffecf, "(-305) List Empty" },
1163     { 0xfffffece, "(-306) Bad Syntax"   },
1164     { 0xfffffecd, "(-307) Buffer Empty" },
1165     { 0xfffffecc, "(-308) Bad Verb" },
1166     { 0xfffffecb, "(-309) Expected Identifier" },
1167     { 0xfffffeca, "(-310) Expected Equals" },
1168     { 0xfffffec9, "(-311) Attribute Type Expected" },
1169     { 0xfffffec8, "(-312) Attribute Type Not Expected" },
1170     { 0xfffffec7, "(-313) Filter Tree Empty" },
1171     { 0xfffffec6, "(-314) Invalid Object Name" },
1172     { 0xfffffec5, "(-315) Expected RDN Delimiter" },
1173     { 0xfffffec4, "(-316) Too Many Tokens" },
1174     { 0xfffffec3, "(-317) Inconsistent MultiAVA" },
1175     { 0xfffffec2, "(-318) Country Name Too Long" },
1176     { 0xfffffec1, "(-319) Internal Error" },
1177     { 0xfffffec0, "(-320) Can't Add Root" },
1178     { 0xfffffebf, "(-321) Unable to Attach" },
1179     { 0xfffffebe, "(-322) Invalid Iteration Handle" },
1180     { 0xfffffebd, "(-323) Buffer Zero Length" },
1181     { 0xfffffebc, "(-324) Invalid Replica Type" },
1182     { 0xfffffebb, "(-325) Invalid Attribute Syntax" },
1183     { 0xfffffeba, "(-326) Invalid Filter Syntax" },
1184     { 0xfffffeb8, "(-328) Unicode Error during Context Creation" },
1185     { 0xfffffeb7, "(-329) Invalid Union Tag" },
1186     { 0xfffffeb6, "(-330) Invalid Server Response" },
1187     { 0xfffffeb5, "(-331) Null Pointer" },
1188     { 0xfffffeb4, "(-332) No Server Found" },
1189     { 0xfffffeb3, "(-333) No Connection" },
1190     { 0xfffffeb2, "(-334) RDN Too Long" },
1191     { 0xfffffeb1, "(-335) Duplicate Type" },
1192     { 0xfffffeb0, "(-336) Data Store Failure" },
1193     { 0xfffffeaf, "(-337) Not Logged In" },
1194     { 0xfffffeae, "(-338) Invalid Password Characters" },
1195     { 0xfffffead, "(-339) Failed Server Authentication" },
1196     { 0xfffffeac, "(-340) Transport Failed" },
1197     { 0xfffffeab, "(-341) No Such Syntax" },
1198     { 0xfffffeaa, "(-342) Invalid DS Name" },
1199     { 0xfffffea9, "(-343) Attribute Name Too Long" },
1200     { 0xfffffea8, "(-344) Invalid TDS" },
1201     { 0xfffffea7, "(-345) Invalid DS Version" },
1202     { 0xfffffea6, "(-346) Unicode Translation" },
1203     { 0xfffffea5, "(-347) Schema Name Too Long" },
1204     { 0xfffffea4, "(-348) Unicode File Not Found" },
1205     { 0xfffffea3, "(-349) Unicode Already Loaded" },
1206     { 0xfffffea2, "(-350) Not Context Owner" },
1207     { 0xfffffea1, "(-351) Attempt to Authenticate" },
1208     { 0xfffffea0, "(-352) No Writable Replicas" },
1209     { 0xfffffe9f, "(-353) DN Too Long" },
1210     { 0xfffffe9e, "(-354) Rename Not Allowed" },
1211     { 0xfffffe9d, "(-355) Not NDS for NT" },
1212     { 0xfffffe9c, "(-356) NDS for NT - No Domain" },
1213     { 0xfffffe9b, "(-357) NDS for NT - Sync Disabled" },
1214     { 0xfffffe9a, "(-358) Iterator Invalid Handle" },
1215     { 0xfffffe99, "(-359) Iterator Invalid Position" },
1216     { 0xfffffe98, "(-360) Iterator Invalid Search Data" },
1217     { 0xfffffe97, "(-361) Iterator Invalid Scope" },
1218     { 0xfffffda7, "(-601) No Such Entry" },
1219     { 0xfffffda6, "(-602) No Such Value" },
1220     { 0xfffffda5, "(-603) No Such Attribute" },
1221     { 0xfffffda4, "(-604) No Such Class" },
1222     { 0xfffffda3, "(-605) No Such Partition" },
1223     { 0xfffffda2, "(-606) Entry Already Exists" },
1224     { 0xfffffda1, "(-607) Not Effective Class" },
1225     { 0xfffffda0, "(-608) Illegal Attribute" },
1226     { 0xfffffd9f, "(-609) Missing Mandatory" },
1227     { 0xfffffd9e, "(-610) Illegal DS Name" },
1228     { 0xfffffd9d, "(-611) Illegal Containment" },
1229     { 0xfffffd9c, "(-612) Can't Have Multiple Values" },
1230     { 0xfffffd9b, "(-613) Syntax Violation" },
1231     { 0xfffffd9a, "(-614) Duplicate Value" },
1232     { 0xfffffd99, "(-615) Attribute Already Exists" },
1233     { 0xfffffd98, "(-616) Maximum Entries Exist" },
1234     { 0xfffffd97, "(-617) Database Format" },
1235     { 0xfffffd96, "(-618) Inconsistent Database" },
1236     { 0xfffffd95, "(-619) Invalid Comparison" },
1237     { 0xfffffd94, "(-620) Comparison Failed" },
1238     { 0xfffffd93, "(-621) Transaction Tracking Disabled" },
1239     { 0xfffffd92, "(-622) Invalid Transport" },
1240     { 0xfffffd91, "(-623) Syntax Invalid in Name" },
1241     { 0xfffffd90, "(-624) Replica Already Exists" },
1242     { 0xfffffd8f, "(-625) Transport Failure" },
1243     { 0xfffffd8e, "(-626) All Referrals Failed" },
1244     { 0xfffffd8d, "(-627) Can't Remove Naming Value" },
1245     { 0xfffffd8c, "(-628) Object Class Violation" },
1246     { 0xfffffd8b, "(-629) Entry is Not Leaf" },
1247     { 0xfffffd8a, "(-630) Different Tree" },
1248     { 0xfffffd89, "(-631) Illegal Replica Type" },
1249     { 0xfffffd88, "(-632) System Failure" },
1250     { 0xfffffd87, "(-633) Invalid Entry for Root" },
1251     { 0xfffffd86, "(-634) No Referrals" },
1252     { 0xfffffd85, "(-635) Remote Failure" },
1253     { 0xfffffd84, "(-636) Unreachable Server" },
1254     { 0xfffffd83, "(-637) Previous Move in Progress" },
1255     { 0xfffffd82, "(-638) No Character Mapping" },
1256     { 0xfffffd81, "(-639) Incomplete Authentication" },
1257     { 0xfffffd80, "(-640) Invalid Certificate" },
1258     { 0xfffffd7f, "(-641) Invalid Request" },
1259     { 0xfffffd7e, "(-642) Invalid Iteration" },
1260     { 0xfffffd7d, "(-643) Schema is Non-removable" },
1261     { 0xfffffd7c, "(-644) Schema is in Use" },
1262     { 0xfffffd7b, "(-645) Class Already Exists" },
1263     { 0xfffffd7a, "(-646) Bad Naming Attributes" },
1264     { 0xfffffd79, "(-647) Not Root Partition" },
1265     { 0xfffffd78, "(-648) Insufficient Stack" },
1266     { 0xfffffd77, "(-649) Insufficient Buffer" },
1267     { 0xfffffd76, "(-650) Ambiguous Containment" },
1268     { 0xfffffd75, "(-651) Ambiguous Naming" },
1269     { 0xfffffd74, "(-652) Duplicate Mandatory" },
1270     { 0xfffffd73, "(-653) Duplicate Optional" },
1271     { 0xfffffd72, "(-654) Partition Busy" },
1272     { 0xfffffd71, "(-655) Multiple Replicas" },
1273     { 0xfffffd70, "(-656) Crucial Replica" },
1274     { 0xfffffd6f, "(-657) Schema Sync in Progress" },
1275     { 0xfffffd6e, "(-658) Skulk in Progress" },
1276     { 0xfffffd6d, "(-659) Time Not Synchronized" },
1277     { 0xfffffd6c, "(-660) Record in Use" },
1278     { 0xfffffd6b, "(-661) DS Volume Not Mounted" },
1279     { 0xfffffd6a, "(-662) DS Volume IO Failure" },
1280     { 0xfffffd69, "(-663) DS Locked" },
1281     { 0xfffffd68, "(-664) Old Epoch" },
1282     { 0xfffffd67, "(-665) New Epoch" },
1283     { 0xfffffd66, "(-666) Incompatible DS Version" },
1284     { 0xfffffd65, "(-667) Partition Root" },
1285     { 0xfffffd64, "(-668) Entry Not Container" },
1286     { 0xfffffd63, "(-669) Failed Authentication" },
1287     { 0xfffffd62, "(-670) Invalid Context" },
1288     { 0xfffffd61, "(-671) No Such Parent" },
1289     { 0xfffffd60, "(-672) No Access" },
1290     { 0xfffffd5f, "(-673) Replica Not On" },
1291     { 0xfffffd5e, "(-674) Invalid Name Service" },
1292     { 0xfffffd5d, "(-675) Invalid Task" },
1293     { 0xfffffd5c, "(-676) Invalid Connection Handle" },
1294     { 0xfffffd5b, "(-677) Invalid Identity" },
1295     { 0xfffffd5a, "(-678) Duplicate ACL" },
1296     { 0xfffffd59, "(-679) Partition Already Exists" },
1297     { 0xfffffd58, "(-680) Transport Modified" },
1298     { 0xfffffd57, "(-681) Alias of an Alias" },
1299     { 0xfffffd56, "(-682) Auditing Failed" },
1300     { 0xfffffd55, "(-683) Invalid API Version" },
1301     { 0xfffffd54, "(-684) Secure NCP Violation" },
1302     { 0xfffffd53, "(-685) Move in Progress" },
1303     { 0xfffffd52, "(-686) Not a Leaf Partition" },
1304     { 0xfffffd51, "(-687) Cannot Abort" },
1305     { 0xfffffd50, "(-688) Cache Overflow" },
1306     { 0xfffffd4f, "(-689) Invalid Subordinate Count" },
1307     { 0xfffffd4e, "(-690) Invalid RDN" },
1308     { 0xfffffd4d, "(-691) Modification Time Not Current" },
1309     { 0xfffffd4c, "(-692) Incorrect Base Class" },
1310     { 0xfffffd4b, "(-693) Missing Reference" },
1311     { 0xfffffd4a, "(-694) Lost Entry" },
1312     { 0xfffffd49, "(-695) Agent Already Registered" },
1313     { 0xfffffd48, "(-696) DS Loader Busy" },
1314     { 0xfffffd47, "(-697) DS Cannot Reload" },
1315     { 0xfffffd46, "(-698) Replica in Skulk" },
1316     { 0xfffffd45, "(-699) Fatal" },
1317     { 0xfffffd44, "(-700) Obsolete API" },
1318     { 0xfffffd43, "(-701) Synchronization Disabled" },
1319     { 0xfffffd42, "(-702) Invalid Parameter" },
1320     { 0xfffffd41, "(-703) Duplicate Template" },
1321     { 0xfffffd40, "(-704) No Master Replica" },
1322     { 0xfffffd3f, "(-705) Duplicate Containment" },
1323     { 0xfffffd3e, "(-706) Not a Sibling" },
1324     { 0xfffffd3d, "(-707) Invalid Signature" },
1325     { 0xfffffd3c, "(-708) Invalid Response" },
1326     { 0xfffffd3b, "(-709) Insufficient Sockets" },
1327     { 0xfffffd3a, "(-710) Database Read Fail" },
1328     { 0xfffffd39, "(-711) Invalid Code Page" },
1329     { 0xfffffd38, "(-712) Invalid Escape Character" },
1330     { 0xfffffd37, "(-713) Invalid Delimiters" },
1331     { 0xfffffd36, "(-714) Not Implemented" },
1332     { 0xfffffd35, "(-715) Checksum Failure" },
1333     { 0xfffffd34, "(-716) Checksumming Not Supported" },
1334     { 0xfffffd33, "(-717) CRC Failure" },
1335     { 0xfffffd32, "(-718) Invalid Entry Handle" },
1336     { 0xfffffd31, "(-719) Invalid Value Handle" },
1337     { 0xfffffd30, "(-720) Connection Denied" },
1338     { 0xfffffd2f, "(-721) No Such Federation Link" },
1339     { 0xfffffd2e, "(-722) Operetational Schema Mismatch" },
1340     { 0xfffffd2d, "(-723) Stream Not Found" },
1341     { 0xfffffd2c, "(-724) DClient Unavailable" },
1342     { 0xfffffd2b, "(-725) MASV No Access" },
1343     { 0xfffffd2a, "(-726) MASV Invalid Request" },
1344     { 0xfffffd29, "(-727) MASV Failure" },
1345     { 0xfffffd28, "(-728) MASV Already Exists" },
1346     { 0xfffffd27, "(-729) MASV Not Found" },
1347     { 0xfffffd26, "(-730) MASV Bad Range" },
1348     { 0xfffffd25, "(-731) Value Data" },
1349     { 0xfffffd24, "(-732) Database Locked" },
1350     { 0xfffffd21, "(-735) Nothing to Abort" },
1351     { 0xfffffd20, "(-736) End of Stream" },
1352     { 0xfffffd1f, "(-737) No Such Template" },
1353     { 0xfffffd1e, "(-738) SAS Locked" },
1354     { 0xfffffd1d, "(-739) Invalid SAS Version" },
1355     { 0xfffffd1c, "(-740) SAS Already Registered" },
1356     { 0xfffffd1b, "(-741) Name Type Not Supported" },
1357     { 0xfffffd1a, "(-742) Wrong DS Version" },
1358     { 0xfffffd19, "(-743) Invalid Control Function" },
1359     { 0xfffffd18, "(-744) Invalid Control State" },
1360     { 0xfffffd17, "(-745) Cache in Use" },
1361     { 0xfffffd16, "(-746) Zero Creation Time" },
1362     { 0xfffffd15, "(-747) Would Block" },
1363     { 0xfffffd14, "(-748) Connection Timeout" },
1364     { 0xfffffd13, "(-749) Too Many Referrals" },
1365     { 0xfffffd12, "(-750) Operation Cancelled" },
1366     { 0xfffffd11, "(-751) Unknown Target" },
1367     { 0xfffffd10, "(-752) GUID Failure" },
1368     { 0xfffffd0f, "(-753) Incompatible OS" },
1369     { 0xfffffd0e, "(-754) Callback Cancel" },
1370     { 0xfffffd0d, "(-755) Invalid Synchronization Data" },
1371     { 0xfffffd0c, "(-756) Stream Exists" },
1372     { 0xfffffd0b, "(-757) Auxiliary Has Containment" },
1373     { 0xfffffd0a, "(-758) Auxiliary Not Container" },
1374     { 0xfffffd09, "(-759) Auxiliary Not Effective" },
1375     { 0xfffffd08, "(-760) Auxiliary On Alias" },
1376     { 0xfffffd07, "(-761) Have Seen State" },
1377     { 0xfffffd06, "(-762) Verb Locked" },
1378     { 0xfffffd05, "(-763) Verb Exceeds Table Length" },
1379     { 0xfffffd04, "(-764) BOF Hit" },
1380     { 0xfffffd03, "(-765) EOF Hit" },
1381     { 0xfffffd02, "(-766) Incompatible Replica Version" },
1382     { 0xfffffd01, "(-767) Query Timeout" },
1383     { 0xfffffd00, "(-768) Query Maximum Count" },
1384     { 0xfffffcff, "(-769) Duplicate Naming" },
1385     { 0xfffffcfe, "(-770) No Transaction Active" },
1386     { 0xfffffcfd, "(-771) Transaction Active" },
1387     { 0xfffffcfc, "(-772) Illegal Transaction Operation" },
1388     { 0xfffffcfb, "(-773) Iterator Syntax" },
1389     { 0xfffffcfa, "(-774) Repairing DIB" },
1390     { 0xfffffcf9, "(-775) Invalid OID Format" },
1391     { 0xfffffcf8, "(-776) Attempted to perform an NDS operation, and the DS agent on this server is closing" },
1392     { 0xfffffcf7, "(-777) Attempted to modify an object's attribute that is not stored on the sparse replica" },
1393     { 0xfffffcf6, "(-778) VpVector and VpvUser which must be correlated, are out of sync" },
1394     { 0xfffffcf5, "(-779) Error Cannot Go Remote" },
1395     { 0xfffffcf4, "(-780) Request not Supported" },
1396     { 0xfffffcf3, "(-781) Entry Not Local" },
1397     { 0xfffffcf2, "(-782) Root Unreachable" },
1398     { 0xfffffcf1, "(-783) VRDIM Not Initialized" },
1399     { 0xfffffcf0, "(-784) Wait Timeout" },
1400     { 0xfffffcef, "(-785) DIB Error" },
1401     { 0xfffffcee, "(-786) DIB IO Failure" },
1402     { 0xfffffced, "(-787) Illegal Schema Attribute" },
1403     { 0xfffffcec, "(-788) Error Schema Partition" },
1404     { 0xfffffceb, "(-789) Invalid Template" },
1405     { 0xfffffcea, "(-790) Error Opening File" },
1406     { 0xfffffce9, "(-791) Error Direct Opening File" },
1407     { 0xfffffce8, "(-792) Error Creating File" },
1408     { 0xfffffce7, "(-793) Error Direct Creating File" },
1409     { 0xfffffce6, "(-794) Error Reading File" },
1410     { 0xfffffce5, "(-795) Error Direct Reading File" },
1411     { 0xfffffce4, "(-796) Error Writing File" },
1412     { 0xfffffce3, "(-797) Error Direct Writing File" },
1413     { 0xfffffce2, "(-798) Error Positioning in File" },
1414     { 0xfffffce1, "(-799) Error Getting File Size" },
1415     { 0xffffe88f, "(-6001) Error Truncating File" },
1416     { 0xffffe88e, "(-6002) Error Parsing File Name" },
1417     { 0xffffe88d, "(-6003) Error Closing File" },
1418     { 0xffffe88c, "(-6004) Error Getting File Info" },
1419     { 0xffffe88b, "(-6005) Error Expanding File" },
1420     { 0xffffe88a, "(-6006) Error Getting Free Blocks" },
1421     { 0xffffe889, "(-6007) Error Checking File Existence" },
1422     { 0xffffe888, "(-6008) Error Deleting File" },
1423     { 0xffffe887, "(-6009) Error Renaming File" },
1424     { 0xffffe886, "(-6010) Error Initializing IO System" },
1425     { 0xffffe885, "(-6011) Error Flushing File" },
1426     { 0xffffe884, "(-6012) Error Setting Up for Read" },
1427     { 0xffffe883, "(-6013) Error Setting up for Write" },
1428     { 0xffffe882, "(-6014) Error Old View" },
1429     { 0xffffe881, "(-6015) Server in Skulk" },
1430     { 0xffffe880, "(-6016) Error Returning Partial Results" },
1431     { 0xffffe87f, "(-6017) No Such Schema" },
1432     { 0xffffe87e, "(-6018) Serial Number Mismatch" },
1433     { 0xffffe87d, "(-6019) Bad Referal Database Serial Number" },
1434     { 0xffffe87c, "(-6020) Bad Referal Serial Number" },
1435     { 0xffffe87b, "(-6021) Invalid File Sequence" },
1436     { 0xffffe87a, "(-6022) Error Referal Trans Gap" },
1437     { 0xffffe879, "(-6023) Bad Referal File Number" },
1438     { 0xffffe878, "(-6024) Referal File Not Found" },
1439     { 0xffffe877, "(-6025) Error Backup Active" },
1440     { 0xffffe876, "(-6026) Referal Device Full" },
1441     { 0xffffe875, "(-6027) Unsupported Version" },
1442     { 0xffffe874, "(-6028) Error Must Wait Checkpoint" },
1443     { 0xffffe873, "(-6029) Attribute Maintenance in Progress" },
1444     { 0xffffe872, "(-6030) Error Abort Transaction" },
1445     { 0xffff0000, "Ok" },
1446     { 0x0000, "Ok" },
1447     { 0, NULL }
1448 };
1449
1450 #define NDS_PTYPE_IPX           0x00000000
1451 #define NDS_PTYPE_IP            0x00000001
1452 #define NDS_PTYPE_SDLC          0x00000002
1453 #define NDS_PTYPE_TR_ON_ETH     0x00000003
1454 #define NDS_PTYPE_OSI           0x00000004
1455 #define NDS_PTYPE_APPLETALK     0x00000005
1456 #define NDS_PTYPE_NETBEUI       0x00000006
1457 #define NDS_PTYPE_SOCKETADDRESS 0x00000007
1458 #define NDS_PTYPE_UDP           0x00000008
1459 #define NDS_PTYPE_TCP           0x00000009
1460 #define NDS_PTYPE_UDPv6         0x0000000a
1461 #define NDS_PTYPE_TCPv6         0x0000000b
1462 #define NDS_PTYPE_INTERNAL      0x0000000c
1463 #define NDS_PTYPE_URL           0x0000000d
1464 #define NDS_PTYPE_DNS           0x0000000e
1465 #define NDS_PTYPE_CNT           0x0000000f
1466
1467 static const value_string nds_protocol_type[] = {
1468     { NDS_PTYPE_IPX,           "(IPX Protocol)" },
1469     { NDS_PTYPE_IP,            "(IP Protocol)" },
1470     { NDS_PTYPE_SDLC,          "(SDLC Protocol)" },
1471     { NDS_PTYPE_TR_ON_ETH,     "(TokenRing on Ethernet Protocol)" },
1472     { NDS_PTYPE_OSI,           "(OSI Protocol)" },
1473     { NDS_PTYPE_APPLETALK,     "(AppleTalk Protocol)" },
1474     { NDS_PTYPE_NETBEUI,       "(NetBEUI Protocol)" },
1475     { NDS_PTYPE_SOCKETADDRESS, "(Socket Address Protocol)" },
1476     { NDS_PTYPE_UDP,           "(UDP Protocol)" },
1477     { NDS_PTYPE_TCP,           "(TCP Protocol)" },
1478     { NDS_PTYPE_UDPv6,         "(UDP v6 Protocol)" },
1479     { NDS_PTYPE_TCPv6,         "(TCP v6 Protocol)" },
1480     { NDS_PTYPE_INTERNAL,      "(Internal Protocol)" },
1481     { NDS_PTYPE_URL,           "(URL Protocol)" },
1482     { NDS_PTYPE_DNS,           "(DNS Protocol)" },
1483     { NDS_PTYPE_CNT,           "(Number of protocol types defined)" },
1484     { 0, NULL }
1485 };
1486
1487
1488 static const value_string nds_syntax[] = {
1489     { 0x00000000, "Unknown Syntax" },
1490     { 0x00000001, "Distinguished Name" },
1491     { 0x00000002, "Case Sensitive Unicode String" },
1492     { 0x00000003, "Non Case Sensitive Unicode String" },
1493     { 0x00000004, "Printable String" },
1494     { 0x00000005, "Numeric String" },
1495     { 0x00000006, "Case Insensitive List" },
1496     { 0x00000007, "Boolean" },
1497     { 0x00000008, "Signed Integer" },
1498     { 0x00000009, "Binary String" },
1499     { 0x0000000a, "Telephone Number" },
1500     { 0x0000000b, "Fax Number" },
1501     { 0x0000000c, "Network Address" },
1502     { 0x0000000d, "Binary String List" },
1503     { 0x0000000e, "Email Address" },
1504     { 0x0000000f, "File System Path" },
1505     { 0x00000010, "Replica Pointer" },
1506     { 0x00000011, "Object ACL" },
1507     { 0x00000012, "Postal Address" },
1508     { 0x00000013, "Time Stamp" },
1509     { 0x00000014, "Class Name" },
1510     { 0x00000015, "Stream" },
1511     { 0x00000016, "Counter" },
1512     { 0x00000017, "Back Link" },
1513     { 0x00000018, "Time" },
1514     { 0x00000019, "Typed Name" },
1515     { 0x0000001a, "Hold" },
1516     { 0x0000001b, "Interval" },
1517     { 0, NULL }
1518 };
1519
1520 static const value_string name_space_type[] = {
1521     { 0x00000000, "DOS Name Space" },
1522     { 0x00000001, "MAC Name Space" },
1523     { 0x00000002, "NFS Name Space" },
1524     { 0x00000003, "FTAM Name Space" },
1525     { 0x00000004, "OS/2, Long Name Space" },
1526     { 0, NULL }
1527 };
1528
1529
1530 static const value_string nds_replica_state[] = {
1531     { 0x0000, "On" },
1532     { 0x0001, "New" },
1533     { 0x0002, "Dying" },
1534     { 0x0003, "Locked" },
1535     { 0x0004, "Create Master State 0" },
1536     { 0x0005, "Create Master State 1" },
1537     { 0x0006, "Transition On" },
1538     { 0x0007, "Dead Replica" },
1539     { 0x0008, "Begin Add" },
1540     { 0x000b, "Master Start" },
1541     { 0x000c, "Master Done" },
1542     { 0x0017, "Federated" },
1543     { 0x0030, "Split State 0" },
1544     { 0x0031, "Split State 1" },
1545     { 0x0040, "Join State 0" },
1546     { 0x0041, "Join State 1" },
1547     { 0x0042, "Join State 2" },
1548     { 0x0050, "Move Subtree State 0" },
1549     { 0x0051, "Move Subtree State 1" },
1550     { 0, NULL }
1551 };
1552
1553 static const value_string nds_replica_type[] = {
1554     { 0x0000, "Master" },
1555     { 0x0001, "Secondary" },
1556     { 0x0002, "Read Only" },
1557     { 0x0003, "Sub Ref" },
1558     { 0, NULL }
1559 };
1560
1561 static const value_string class_def_type[] = {
1562     { 0x0000, "Return Class Name" },
1563     { 0x0001, "Return Class Name, Flag, and Definition" },
1564     { 0x0002, "Return Class Name, Flag, Definition, and Super Class" },
1565     { 0x0003, "Return Class Name, Flag, and ASN.1 identifier" },
1566     { 0x0004, "Return Class Name, Flag, Definition, Super Class, and ACL" },
1567     { 0x0005, "Return Class Name, Flag, Creation Timestamp, Modification Timestamp, Definition, and ACL" },
1568     { 0, NULL }
1569 };
1570
1571 static const range_string nds_search_scope[] = {
1572     { 0x0000, 0x0000, "Examine the base object only" },
1573     { 0x0001, 0x0001, "Search the immediate subordinates of the base object" },
1574     { 0x0002, 0x0002, "Search the base object and all its subordinates" },
1575     { 0x0003, 0x0003, "Search the base objects and all objects in its partition (Implemented in NDS 8)" },
1576     { 0x0004, 0xFFFF, "No Search Scope Defined" },
1577     { 0, 0, NULL }
1578 };
1579
1580 static const value_string nds_verb2b_flag_vals[] = {
1581     { 0, "Request Flags (0x0000) - Retain old object name" },
1582     { 1, "Request Flags (0x0001) - Delete old object name" },
1583     { 0,  NULL }
1584 };
1585
1586 static const value_string serv_type_vals[] = {
1587     { 0, "NetWare" },
1588     { 1, "OES" },
1589     { 0,  NULL }
1590 };
1591
1592 static const value_string kernel_type_vals[] = {
1593     { 0, "NetWare" },
1594     { 1, "Linux" },
1595     { 0,  NULL }
1596 };
1597
1598 static const int * ncp_pingflags1[] = {
1599     &hf_bit1pingflags1,
1600     &hf_bit2pingflags1,
1601     &hf_bit3pingflags1,
1602     &hf_bit4pingflags1,
1603     &hf_bit5pingflags1,
1604     &hf_bit6pingflags1,
1605     &hf_bit7pingflags1,
1606     &hf_bit8pingflags1,
1607     &hf_bit9pingflags1,
1608     &hf_bit10pingflags1,
1609     &hf_bit11pingflags1,
1610     &hf_bit12pingflags1,
1611     &hf_bit13pingflags1,
1612     &hf_bit14pingflags1,
1613     &hf_bit15pingflags1,
1614     &hf_bit16pingflags1,
1615     NULL
1616 };
1617
1618 static const int * ncp_pingflags2[] = {
1619     &hf_bit1pingflags2,
1620     &hf_bit2pingflags2,
1621     &hf_bit3pingflags2,
1622     &hf_bit4pingflags2,
1623     &hf_bit5pingflags2,
1624     &hf_bit6pingflags2,
1625     &hf_bit7pingflags2,
1626     &hf_bit8pingflags2,
1627     &hf_bit9pingflags2,
1628     &hf_bit10pingflags2,
1629     &hf_bit11pingflags2,
1630     &hf_bit12pingflags2,
1631     &hf_bit13pingflags2,
1632     &hf_bit14pingflags2,
1633     &hf_bit15pingflags2,
1634     &hf_bit16pingflags2,
1635     NULL
1636 };
1637
1638 static const int * ncp_pingvflags1[] = {
1639     &hf_bit1pingvflags1,
1640     &hf_bit2pingvflags1,
1641     &hf_bit3pingvflags1,
1642     &hf_bit4pingvflags1,
1643     &hf_bit5pingvflags1,
1644     &hf_bit6pingvflags1,
1645     &hf_bit7pingvflags1,
1646     &hf_bit8pingvflags1,
1647     &hf_bit9pingvflags1,
1648     &hf_bit10pingvflags1,
1649     &hf_bit11pingvflags1,
1650     &hf_bit12pingvflags1,
1651     &hf_bit13pingvflags1,
1652     &hf_bit14pingvflags1,
1653     &hf_bit15pingvflags1,
1654     &hf_bit16pingvflags1,
1655     NULL
1656 };
1657
1658 static const int * ncp_pingpflags1[] = {
1659     &hf_bit1pingpflags1,
1660     &hf_bit2pingpflags1,
1661     &hf_bit3pingpflags1,
1662     &hf_bit4pingpflags1,
1663     &hf_bit5pingpflags1,
1664     &hf_bit6pingpflags1,
1665     &hf_bit7pingpflags1,
1666     &hf_bit8pingpflags1,
1667     &hf_bit9pingpflags1,
1668     &hf_bit10pingpflags1,
1669     &hf_bit11pingpflags1,
1670     &hf_bit12pingpflags1,
1671     &hf_bit13pingpflags1,
1672     &hf_bit14pingpflags1,
1673     &hf_bit15pingpflags1,
1674     &hf_bit16pingpflags1,
1675     NULL
1676 };
1677
1678 static const int * ndsprotflags[] = {
1679     &hf_ndsprot1flag,
1680     &hf_ndsprot2flag,
1681     &hf_ndsprot3flag,
1682     &hf_ndsprot4flag,
1683     &hf_ndsprot5flag,
1684     &hf_ndsprot6flag,
1685     &hf_ndsprot7flag,
1686     &hf_ndsprot8flag,
1687     &hf_ndsprot9flag,
1688     &hf_ndsprot10flag,
1689     &hf_ndsprot11flag,
1690     &hf_ndsprot12flag,
1691     &hf_ndsprot13flag,
1692     &hf_ndsprot14flag,
1693     &hf_ndsprot15flag,
1694     &hf_ndsprot16flag,
1695     NULL
1696 };
1697
1698 static const int * ncp_infoflagsl[] = {
1699     &hf_bit1infoflagsl,
1700     &hf_bit2infoflagsl,
1701     &hf_bit3infoflagsl,
1702     &hf_bit4infoflagsl,
1703     &hf_bit5infoflagsl,
1704     &hf_bit6infoflagsl,
1705     &hf_bit7infoflagsl,
1706     &hf_bit8infoflagsl,
1707     &hf_bit9infoflagsl,
1708     &hf_bit10infoflagsl,
1709     &hf_bit11infoflagsl,
1710     &hf_bit12infoflagsl,
1711     &hf_bit13infoflagsl,
1712     &hf_bit14infoflagsl,
1713     &hf_bit15infoflagsl,
1714     &hf_bit16infoflagsl,
1715     NULL
1716 };
1717
1718 static const int * ncp_infoflagsh[] = {
1719     &hf_bit1infoflagsh,
1720     &hf_bit2infoflagsh,
1721     &hf_bit3infoflagsh,
1722     &hf_bit4infoflagsh,
1723     &hf_bit5infoflagsh,
1724     &hf_bit6infoflagsh,
1725     &hf_bit7infoflagsh,
1726     &hf_bit8infoflagsh,
1727     &hf_bit9infoflagsh,
1728     &hf_bit10infoflagsh,
1729     &hf_bit11infoflagsh,
1730     &hf_bit12infoflagsh,
1731     &hf_bit13infoflagsh,
1732     &hf_bit14infoflagsh,
1733     &hf_bit15infoflagsh,
1734     &hf_bit16infoflagsh,
1735     NULL
1736 };
1737
1738 static const int * ncp_retinfoflagsh[] = {
1739     &hf_bit1retinfoflagsh,
1740     &hf_bit2retinfoflagsh,
1741     &hf_bit3retinfoflagsh,
1742     &hf_bit4retinfoflagsh,
1743     &hf_bit5retinfoflagsh,
1744     &hf_bit6retinfoflagsh,
1745     &hf_bit7retinfoflagsh,
1746     &hf_bit8retinfoflagsh,
1747     &hf_bit9retinfoflagsh,
1748     &hf_bit10retinfoflagsh,
1749     &hf_bit11retinfoflagsh,
1750     &hf_bit12retinfoflagsh,
1751     &hf_bit13retinfoflagsh,
1752     &hf_bit14retinfoflagsh,
1753     &hf_bit15retinfoflagsh,
1754     &hf_bit16retinfoflagsh,
1755     NULL
1756 };
1757
1758 static const int * ncp_acflags[] = {
1759     &hf_bit1acflags,
1760     &hf_bit2acflags,
1761     &hf_bit3acflags,
1762     &hf_bit4acflags,
1763     &hf_bit5acflags,
1764     &hf_bit6acflags,
1765     &hf_bit7acflags,
1766     &hf_bit8acflags,
1767     &hf_bit9acflags,
1768     &hf_bit10acflags,
1769     &hf_bit11acflags,
1770     &hf_bit12acflags,
1771     &hf_bit13acflags,
1772     &hf_bit14acflags,
1773     &hf_bit15acflags,
1774     &hf_bit16acflags,
1775     NULL
1776 };
1777
1778 static const int * ncp_eflags[] = {
1779     &hf_bit1eflags,
1780     &hf_bit2eflags,
1781     &hf_bit3eflags,
1782     &hf_bit4eflags,
1783     &hf_bit5eflags,
1784     &hf_bit6eflags,
1785     &hf_bit7eflags,
1786     &hf_bit8eflags,
1787     &hf_bit9eflags,
1788     &hf_bit10eflags,
1789     &hf_bit11eflags,
1790     &hf_bit12eflags,
1791     &hf_bit13eflags,
1792     &hf_bit14eflags,
1793     &hf_bit15eflags,
1794     &hf_bit16eflags,
1795     NULL
1796 };
1797
1798 static const int * ncp_cflags[] = {
1799     &hf_bit1cflags,
1800     &hf_bit2cflags,
1801     &hf_bit3cflags,
1802     &hf_bit4cflags,
1803     &hf_bit5cflags,
1804     &hf_bit6cflags,
1805     &hf_bit7cflags,
1806     &hf_bit8cflags,
1807     &hf_bit9cflags,
1808     &hf_bit10cflags,
1809     &hf_bit11cflags,
1810     &hf_bit12cflags,
1811     &hf_bit13cflags,
1812     &hf_bit14cflags,
1813     &hf_bit15cflags,
1814     &hf_bit16cflags,
1815     NULL
1816 };
1817
1818 static const int * ncp_lflags[] = {
1819     &hf_bit1lflags,
1820     &hf_bit2lflags,
1821     &hf_bit3lflags,
1822     &hf_bit4lflags,
1823     &hf_bit5lflags,
1824     &hf_bit6lflags,
1825     &hf_bit7lflags,
1826     &hf_bit8lflags,
1827     &hf_bit9lflags,
1828     &hf_bit10lflags,
1829     &hf_bit11lflags,
1830     &hf_bit12lflags,
1831     &hf_bit13lflags,
1832     &hf_bit14lflags,
1833     &hf_bit15lflags,
1834     &hf_bit16lflags,
1835     NULL
1836 };
1837
1838 static const int * ncp_nflags[] = {
1839     &hf_bit1nflags,
1840     &hf_bit2nflags,
1841     &hf_bit3nflags,
1842     &hf_bit4nflags,
1843     &hf_bit5nflags,
1844     &hf_bit6nflags,
1845     &hf_bit7nflags,
1846     &hf_bit8nflags,
1847     &hf_bit9nflags,
1848     &hf_bit10nflags,
1849     &hf_bit11nflags,
1850     &hf_bit12nflags,
1851     &hf_bit13nflags,
1852     &hf_bit14nflags,
1853     &hf_bit15nflags,
1854     &hf_bit16nflags,
1855     NULL
1856 };
1857
1858 static const int * ncp_rflags[] = {
1859     &hf_bit1rflags,
1860     &hf_bit2rflags,
1861     &hf_bit3rflags,
1862     &hf_bit4rflags,
1863     &hf_bit5rflags,
1864     &hf_bit6rflags,
1865     &hf_bit7rflags,
1866     &hf_bit8rflags,
1867     &hf_bit9rflags,
1868     &hf_bit10rflags,
1869     &hf_bit11rflags,
1870     &hf_bit12rflags,
1871     &hf_bit13rflags,
1872     &hf_bit14rflags,
1873     &hf_bit15rflags,
1874     &hf_bit16rflags,
1875     NULL
1876 };
1877
1878 static const int * ncp_outflags[] = {
1879     &hf_bit1outflags,
1880     &hf_bit2outflags,
1881     &hf_bit3outflags,
1882     &hf_bit4outflags,
1883     &hf_bit5outflags,
1884     &hf_bit6outflags,
1885     &hf_bit7outflags,
1886     &hf_bit8outflags,
1887     &hf_bit9outflags,
1888     &hf_bit10outflags,
1889     &hf_bit11outflags,
1890     &hf_bit12outflags,
1891     &hf_bit13outflags,
1892     &hf_bit14outflags,
1893     &hf_bit15outflags,
1894     &hf_bit16outflags,
1895     NULL
1896 };
1897
1898 static const int * ncp_siflags[] = {
1899     &hf_bit1siflags,
1900     &hf_bit2siflags,
1901     &hf_bit3siflags,
1902     &hf_bit4siflags,
1903     &hf_bit5siflags,
1904     &hf_bit6siflags,
1905     &hf_bit7siflags,
1906     &hf_bit8siflags,
1907     &hf_bit9siflags,
1908     &hf_bit10siflags,
1909     &hf_bit11siflags,
1910     &hf_bit12siflags,
1911     &hf_bit13siflags,
1912     &hf_bit14siflags,
1913     &hf_bit15siflags,
1914     &hf_bit16siflags,
1915     NULL
1916 };
1917
1918 static const int * ncp_vflags[] = {
1919     &hf_bit1vflags,
1920     &hf_bit2vflags,
1921     &hf_bit3vflags,
1922     &hf_bit4vflags,
1923     &hf_bit5vflags,
1924     &hf_bit6vflags,
1925     &hf_bit7vflags,
1926     &hf_bit8vflags,
1927     &hf_bit9vflags,
1928     &hf_bit10vflags,
1929     &hf_bit11vflags,
1930     &hf_bit12vflags,
1931     &hf_bit13vflags,
1932     &hf_bit14vflags,
1933     &hf_bit15vflags,
1934     &hf_bit16vflags,
1935     NULL
1936 };
1937
1938 static const int * nds_bitflags[] = {
1939     &hf_nds_bit1,
1940     &hf_nds_bit2,
1941     &hf_nds_bit3,
1942     &hf_nds_bit4,
1943     &hf_nds_bit5,
1944     &hf_nds_bit6,
1945     &hf_nds_bit7,
1946     &hf_nds_bit8,
1947     &hf_nds_bit9,
1948     &hf_nds_bit10,
1949     &hf_nds_bit11,
1950     &hf_nds_bit12,
1951     &hf_nds_bit13,
1952     &hf_nds_bit14,
1953     &hf_nds_bit15,
1954     &hf_nds_bit16,
1955     NULL
1956 };
1957
1958 static const int * ncp_l1flagsl[] = {
1959     &hf_bit1l1flagsl,
1960     &hf_bit2l1flagsl,
1961     &hf_bit3l1flagsl,
1962     &hf_bit4l1flagsl,
1963     &hf_bit5l1flagsl,
1964     &hf_bit6l1flagsl,
1965     &hf_bit7l1flagsl,
1966     &hf_bit8l1flagsl,
1967     &hf_bit9l1flagsl,
1968     &hf_bit10l1flagsl,
1969     &hf_bit11l1flagsl,
1970     &hf_bit12l1flagsl,
1971     &hf_bit13l1flagsl,
1972     &hf_bit14l1flagsl,
1973     &hf_bit15l1flagsl,
1974     &hf_bit16l1flagsl,
1975     NULL
1976 };
1977
1978 static const int * ncp_l1flagsh[] = {
1979     &hf_bit1l1flagsh,
1980     &hf_bit2l1flagsh,
1981     &hf_bit3l1flagsh,
1982     &hf_bit4l1flagsh,
1983     &hf_bit5l1flagsh,
1984     &hf_bit6l1flagsh,
1985     &hf_bit7l1flagsh,
1986     &hf_bit8l1flagsh,
1987     &hf_bit9l1flagsh,
1988     &hf_bit10l1flagsh,
1989     &hf_bit11l1flagsh,
1990     &hf_bit12l1flagsh,
1991     &hf_bit13l1flagsh,
1992     &hf_bit14l1flagsh,
1993     &hf_bit15l1flagsh,
1994     &hf_bit16l1flagsh,
1995     NULL
1996 };
1997
1998 static void
1999 process_ptvc_record(ptvcursor_t *ptvc, packet_info *pinfo, const ptvc_record *rec,
2000                     gboolean *req_cond_results, gboolean really_decode,
2001                     const ncp_record *ncp_rec, gboolean request);
2002
2003 /* NCP packets come in request/reply pairs. The request packets tell the type
2004  * of NCP request and give a sequence ID. The response, unfortunately, only
2005  * identifies itself via the sequence ID; you have to know what type of NCP
2006  * request the request packet contained in order to successfully parse the NCP
2007  * response. A global method for doing this does not exist in wireshark yet
2008  * (NFS also requires it), so for now the NCP section will keep its own hash
2009  * table keeping track of NCP packet types.
2010  *
2011  * We construct a conversation specified by the client and server
2012  * addresses and the connection number; the key representing the unique
2013  * NCP request then is composed of the pointer to the conversation
2014  * structure, cast to a "guint" (which may throw away the upper 32
2015  * bits of the pointer on a P64 platform, but the low-order 32 bits
2016  * are more likely to differ between conversations than the upper 32 bits),
2017  * and the sequence number.
2018  *
2019  * The value stored in the hash table is the ncp_req_hash_value pointer. This
2020  * struct tells us the NCP type and gives the ncp2222_record pointer, if
2021  * ncp_type == 0x2222.
2022  */
2023 typedef struct {
2024     conversation_t  *conversation;
2025     guint32           nw_sequence_long;
2026 } ncp_req_hash_key;
2027
2028
2029 typedef struct {
2030     guint32          nw_eid;
2031 } ncp_req_eid_hash_key;
2032
2033 typedef struct {
2034     ncp_req_eid_hash_key    *nds_eid;
2035     char                    object_name[256];
2036 } ncp_req_eid_hash_value;
2037
2038 static wmem_map_t *ncp_req_hash = NULL;
2039 static wmem_map_t *ncp_req_eid_hash = NULL;
2040
2041 /* Hash Functions */
2042 static gboolean
2043 ncp_equal(gconstpointer v, gconstpointer v2)
2044 {
2045     const ncp_req_hash_key *val1 = (const ncp_req_hash_key*)v;
2046     const ncp_req_hash_key *val2 = (const ncp_req_hash_key*)v2;
2047
2048     if (val1->conversation == val2->conversation &&
2049         val1->nw_sequence_long  == val2->nw_sequence_long ) {
2050         return TRUE;
2051     }
2052     return FALSE;
2053 }
2054
2055 static gboolean
2056 ncp_eid_equal(gconstpointer v, gconstpointer v2)
2057 {
2058     const ncp_req_eid_hash_key *val1 = (const ncp_req_eid_hash_key*)v;
2059     const ncp_req_eid_hash_key *val2 = (const ncp_req_eid_hash_key*)v2;
2060
2061     if (val1->nw_eid == val2->nw_eid ) {
2062         return TRUE;
2063     }
2064     return FALSE;
2065 }
2066
2067 static guint
2068 ncp_hash(gconstpointer v)
2069 {
2070     const ncp_req_hash_key *ncp_key = (const ncp_req_hash_key*)v;
2071     return GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence_long;
2072 }
2073
2074 static guint
2075 ncp_eid_hash(gconstpointer v)
2076 {
2077     const ncp_req_eid_hash_key *ncp_eid_key = (const ncp_req_eid_hash_key*)v;
2078     return GPOINTER_TO_UINT(ncp_eid_key->nw_eid);
2079 }
2080
2081 static void
2082 ncp_init_protocol(void)
2083 {
2084     int i;
2085
2086     for (i = 0; i < 99; i++) {
2087         frags[i].nds_frag = 0xfffffff0;
2088     }
2089 }
2090
2091 /* NCP sequence numbers are from 0 - 255. After reaching 255 the
2092  * sequence number wraps back to 0. Change nw_sequence to nw_sequence_long
2093  * and use upper bits to make sequence numbers unique. This way
2094  * future attempts to locate initiating packet will succeed.
2095  */
2096 static ncp_req_hash_value*
2097 ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence,
2098                 const ncp_record *ncp_rec, guint32 pkt_num)
2099 {
2100     ncp_req_hash_key    *request_key;
2101     ncp_req_hash_value  *request_value;
2102
2103     /* Now remember the request, so we can find it if we later
2104        a reply to it. */
2105     request_key = wmem_new(wmem_file_scope(), ncp_req_hash_key);
2106     request_key->conversation = conversation;
2107     /* Make sequence number unique */
2108     request_key->nw_sequence_long = (0x10000 + ((pkt_num/16)<<16)) | nw_sequence;
2109
2110     request_value = wmem_new0(wmem_file_scope(), ncp_req_hash_value);
2111     request_value->ncp_rec = ncp_rec;
2112     request_value->req_cond_results = NULL;
2113     request_value->req_nds_flags = 0;
2114     request_value->nds_request_verb = 0;
2115     request_value->nds_version = 0;
2116     g_strlcpy(request_value->object_name, " ", 256);
2117     request_value->nds_frag = TRUE;
2118
2119     wmem_map_insert(ncp_req_hash, request_key, request_value);
2120
2121     return request_value;
2122 }
2123
2124 static ncp_req_eid_hash_value*
2125 ncp_eid_hash_insert(guint32 nw_eid)
2126 {
2127     ncp_req_eid_hash_key    *request_eid_key;
2128     ncp_req_eid_hash_value  *request_eid_value;
2129
2130     /* Now remember the request, so we can find it if we later
2131        a reply to it. */
2132     request_eid_key = wmem_new(wmem_file_scope(), ncp_req_eid_hash_key);
2133     request_eid_key->nw_eid = nw_eid;
2134
2135     request_eid_value = wmem_new0(wmem_file_scope(), ncp_req_eid_hash_value);
2136     g_strlcpy(request_eid_value->object_name, " ", 256);
2137
2138     wmem_map_insert(ncp_req_eid_hash, request_eid_key, request_eid_value);
2139
2140     return request_eid_value;
2141 }
2142
2143 /* Returns the ncp_rec*, or NULL if not found. */
2144 static ncp_req_hash_value*
2145 ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence, guint32 pkt_num)
2146 {
2147     ncp_req_hash_key  request_key;
2148     ncp_req_hash_value *temp_value;
2149
2150     request_key.conversation = conversation;
2151     /* Find unique sequence number */
2152     request_key.nw_sequence_long = (0x10000+((pkt_num/16)<<16)) | nw_sequence;
2153
2154     /* Since masking of sequence number utilizes the packet number as
2155      * part of it's algorythm it is possible for a packet to sit right
2156      * on the boundary and fail. (depending on number of packets in trace)
2157      * Loop through all the previous sequence numbers in the hash to see
2158      * if the original request packet can be found.
2159      */
2160     temp_value = (ncp_req_hash_value *)wmem_map_lookup(ncp_req_hash, &request_key);
2161     while(!temp_value)
2162     {
2163        request_key.nw_sequence_long = request_key.nw_sequence_long-0x10000;
2164        if((request_key.nw_sequence_long & 0xffff0000) == 0){
2165             break;
2166        }
2167        temp_value = (ncp_req_hash_value *)wmem_map_lookup(ncp_req_hash, &request_key);
2168     }
2169     return temp_value;
2170 }
2171
2172 /* Returns the value_rec* for needed EID, or NULL if not found. */
2173 static ncp_req_eid_hash_value*
2174 ncp_eid_hash_lookup(conversation_t *conversation _U_, guint32 nw_eid)
2175 {
2176     ncp_req_eid_hash_key  request_eid_key;
2177
2178     request_eid_key.nw_eid = nw_eid;
2179
2180     return (ncp_req_eid_hash_value *)wmem_map_lookup(ncp_req_eid_hash, &request_eid_key);
2181 }
2182
2183 /* Does NCP func require a subfunction code? */
2184 static gboolean
2185 ncp_requires_subfunc(guint8 func)
2186 {
2187     const guint8 *ncp_func_requirement = ncp_func_requires_subfunc;
2188
2189     while (*ncp_func_requirement != 0) {
2190         if (*ncp_func_requirement == func) {
2191             return TRUE;
2192         }
2193         ncp_func_requirement++;
2194     }
2195     return FALSE;
2196 }
2197
2198 /* Does the NCP func have a length parameter? */
2199 static gboolean
2200 ncp_has_length_parameter(guint8 func)
2201 {
2202     const guint8 *ncp_func_requirement = ncp_func_has_no_length_parameter;
2203
2204     while (*ncp_func_requirement != 0) {
2205         if (*ncp_func_requirement == func) {
2206             return FALSE;
2207         }
2208         ncp_func_requirement++;
2209     }
2210     return TRUE;
2211 }
2212
2213
2214 /* Return a ncp_record* based on func and possibly subfunc */
2215 static const ncp_record *
2216 ncp_record_find(guint8 func, guint8 subfunc)
2217 {
2218     const ncp_record *ncp_rec = ncp_packets;
2219
2220     while(ncp_rec->func != 0 || ncp_rec->subfunc != 0 ||
2221           ncp_rec->name != NULL ) {
2222         if (ncp_rec->func == func) {
2223             if (ncp_rec->has_subfunc) {
2224                 if (ncp_rec->subfunc == subfunc) {
2225                     return ncp_rec;
2226                 }
2227             }
2228             else {
2229                 return ncp_rec;
2230             }
2231         }
2232         ncp_rec++;
2233     }
2234     return NULL;
2235 }
2236
2237 #define NW_UNI_MAX 1024
2238
2239 #define VTYPE_NONE                       0  /* no value */
2240 #define VTYPE_UINT8                      1
2241 #define VTYPE_UINT16                     2
2242 #define VTYPE_UINT32                     3
2243 #define VTYPE_STRING                     4
2244 #define VTYPE_BITFIELD                   5
2245 #define VTYPE_MULTIVALUE_UINT32          6
2246 #define VTYPE_BYTES                      7
2247 #define VTYPE_BOOLEAN                    8
2248 #define VTYPE_ITEM                       9
2249
2250 #define MVTYPE_ATTR_REQUEST              1
2251 #define MVTYPE_ATTR_REPLY                2
2252 #define MVTYPE_ATTR_REQUEST2             3
2253 #define MVTYPE_READ_CLASS_REQ            4
2254 #define MVTYPE_READ_REPLICAS             5
2255 #define MVTYPE_MODIFY_ATTR_REQUEST       6
2256 #define MVTYPE_ADDR_REFERRAL_REQUEST     7
2257 #define MVTYPE_ADDR_REFERRAL_REPLY       8
2258 #define MVTYPE_LOC_ADDR_REFERRAL_REPLY   9
2259 #define MVTYPE_PROC_ENTRY_SPECIFIERS    10
2260 #define MVTYPE_PRINT_TIMESTAMP          11
2261 #define MVTYPE_LIST_PARTITIONS          12
2262 #define MVTYPE_CLASS_NAMES              13
2263 #define MVTYPE_MODIFY_CLASS             14
2264 #define MVTYPE_ADD_ATTR_REQUEST         15
2265 #define MVTYPE_PROCESS_TAGS             16
2266 #define MVTYPE_PROCESS_ITERATOR         17
2267
2268 typedef struct {
2269     guint8          vtype;
2270     guint32         vvalue;
2271     const char*     vstring;
2272     const char*     vdesc;
2273     guint32         vlength;
2274     guint32         voffset;
2275     guint32         hfname;
2276     const char*     bit1;
2277     guint32         bit1hfname;
2278     const char*     bit2;
2279     guint32         bit2hfname;
2280     const char*     bit3;
2281     guint32         bit3hfname;
2282     const char*     bit4;
2283     guint32         bit4hfname;
2284     const char*     bit5;
2285     guint32         bit5hfname;
2286     const char*     bit6;
2287     guint32         bit6hfname;
2288     const char*     bit7;
2289     guint32         bit7hfname;
2290     const char*     bit8;
2291     guint32         bit8hfname;
2292     const char*     bit9;
2293     guint32         bit9hfname;
2294     const char*     bit10;
2295     guint32         bit10hfname;
2296     const char*     bit11;
2297     guint32         bit11hfname;
2298     const char*     bit12;
2299     guint32         bit12hfname;
2300     const char*     bit13;
2301     guint32         bit13hfname;
2302     const char*     bit14;
2303     guint32         bit14hfname;
2304     const char*     bit15;
2305     guint32         bit15hfname;
2306     const char*     bit16;
2307     guint32         bit16hfname;
2308     guint8          mvtype;
2309     guint32         vflags;
2310     guint32         nds_version;
2311     guint32         pflags; /* NDS Protocol Flags */
2312 } nds_val;
2313
2314 static proto_item*
2315 add_ptvc_field(packet_info* pinfo, ptvcursor_t *ptvc, const ptvc_record *rec, gboolean request, gboolean repeat, guint* ret_value)
2316 {
2317     header_field_info* hinfo = proto_registrar_get_nth(*rec->hf_ptr);
2318
2319     if (!repeat && request && rec->req_info_str)
2320         col_set_str(pinfo->cinfo, COL_INFO, "C ");
2321
2322     /* We may want integer values regardless of whether or not the value is displayed in INFO column */
2323     if (IS_FT_UINT(hinfo->type) || IS_FT_INT(hinfo->type)) {
2324         guint32 value32 = 0;
2325         guint64 value64 = 0;
2326
2327         switch(rec->length)
2328         {
2329         case 1:
2330             value32 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2331             *ret_value = value32;
2332             break;
2333         case 2:
2334             value32 = tvb_get_guint16(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2335             *ret_value = value32;
2336             break;
2337         case 3:
2338             value32 = tvb_get_guint24(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2339             *ret_value = value32;
2340             break;
2341         case 4:
2342             value32 = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2343             *ret_value = value32;
2344             break;
2345         case 5:
2346             value64 = tvb_get_guint40(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2347             break;
2348         case 6:
2349             value64 = tvb_get_guint48(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2350             break;
2351         case 7:
2352             value64 = tvb_get_guint56(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2353             break;
2354         case 8:
2355             value64 = tvb_get_guint64(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2356             break;
2357         default:
2358             DISSECTOR_ASSERT(FALSE);
2359             break;
2360         }
2361
2362         if (request && rec->req_info_str) {
2363             if (rec->length <= 4) {
2364                 col_append_fstr(pinfo->cinfo, COL_INFO,
2365                         (const gchar*)(repeat ? rec->req_info_str->repeat_string : rec->req_info_str->first_string),
2366                         value32);
2367             } else {
2368                 col_append_fstr(pinfo->cinfo, COL_INFO,
2369                         (const gchar*)(repeat ? rec->req_info_str->repeat_string : rec->req_info_str->first_string),
2370                         value64);
2371
2372             }
2373         }
2374     } else if (request && rec->req_info_str) {
2375         if (hinfo->type == FT_STRING) {
2376             col_append_fstr(pinfo->cinfo, COL_INFO,
2377                                 (const gchar*)(repeat ? rec->req_info_str->repeat_string : rec->req_info_str->first_string),
2378                                  tvb_get_string_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2379                                      ptvcursor_current_offset(ptvc), rec->length, ENC_ASCII));
2380         } else if (hinfo->type == FT_STRINGZ) {
2381             gint length;
2382             col_append_fstr(pinfo->cinfo, COL_INFO,
2383                                 (const gchar*)(repeat ? rec->req_info_str->repeat_string : rec->req_info_str->first_string),
2384                                 tvb_get_stringz_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2385                                     ptvcursor_current_offset(ptvc), &length, ENC_ASCII));
2386         } else if (hinfo->type == FT_UINT_STRING) {
2387             guint32 length = 0;
2388
2389             switch(rec->length)
2390             {
2391             case 1:
2392                 length = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2393                 break;
2394             case 2:
2395                 length = tvb_get_guint16(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2396                 break;
2397             case 3:
2398                 length = tvb_get_guint24(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2399                 break;
2400             case 4:
2401                 length = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), rec->endianness);
2402                 break;
2403             default:
2404                 DISSECTOR_ASSERT(FALSE);
2405                 break;
2406             }
2407
2408             col_append_fstr(pinfo->cinfo, COL_INFO,
2409                                 (const gchar*)(repeat ? rec->req_info_str->repeat_string : rec->req_info_str->first_string),
2410                                 tvb_get_string_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2411                                     ptvcursor_current_offset(ptvc)+rec->length, length, ENC_ASCII));
2412         } else if (hinfo->type == FT_BYTES) {
2413             col_append_fstr(pinfo->cinfo, COL_INFO,
2414                                 (const gchar*)(repeat ? rec->req_info_str->repeat_string : rec->req_info_str->first_string),
2415                                 tvb_bytes_to_str(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2416                                     ptvcursor_current_offset(ptvc), rec->length));
2417         }
2418     }
2419
2420     return ptvcursor_add(ptvc, *rec->hf_ptr,
2421                       rec->length,
2422                       rec->endianness);
2423 }
2424
2425 /*
2426  * XXX - are these just DOS-format dates and times?
2427  *
2428  * Should we put code to understand various date and time formats (UNIX,
2429  * DOS, SMB weird mutant UNIX, NT, Mac, etc. into libwireshark, and have
2430  * the "display" member of an HF_ABSOLUTE_TIME field specify whether
2431  * it's DOS date/DOS time, DOS time/DOS date, NT time, UNIX time_t,
2432  * UNIX "struct timeval", NFSv3/NFSv4 seconds/nanoseconds, Mac, etc.?
2433  *
2434  * What about hijacking the "bitmask" field to specify the precision of
2435  * the time stamp, or putting a combination of precision and format
2436  * into the "display" member?
2437  *
2438  * What about relative times?  Should they have units (seconds, milliseconds,
2439  * microseconds, nanoseconds, etc.), precision, and format in there?
2440  */
2441 static void
2442 padd_date( gchar *result, guint32 date_value )
2443 {
2444     g_snprintf( result, ITEM_LABEL_LENGTH, "%04u/%02u/%02u", ((date_value & 0xfe00) >> 9) + 1980, (date_value & 0x01e0) >> 5, date_value & 0x001f);
2445 }
2446
2447 static void
2448 padd_time( gchar *result, guint32 time_value )
2449 {
2450     g_snprintf( result, ITEM_LABEL_LENGTH, "%02u:%02u:%02u", ((time_value & 0xf800) >> 11), ((time_value & 0x07e0) >> 5), (time_value & 0x001f) * 2);
2451 }
2452
2453 /* Add a value for a ptvc_record, and process the sub-ptvc_record
2454  * that it points to. */
2455 static void
2456 process_bitfield_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
2457                                  gboolean really_decode)
2458 {
2459     proto_item          *item;
2460     proto_tree          *sub_tree;
2461     const ptvc_record   *sub_rec;
2462     int                 current_offset;
2463     gint                ett;
2464     ptvcursor_t         *sub_ptvc;
2465
2466     if (really_decode) {
2467         /* Save the current offset */
2468         current_offset = ptvcursor_current_offset(ptvc);
2469
2470         /* Add the item */
2471         item = ptvcursor_add(ptvc, *rec->hf_ptr, rec->length,
2472                              rec->endianness);
2473
2474         ett = *rec->sub_ptvc_rec->ett;
2475
2476         /* Make a new protocol sub-tree */
2477         sub_tree = proto_item_add_subtree(item, ett);
2478
2479         /* Make a new ptvcursor */
2480         sub_ptvc = ptvcursor_new(sub_tree, ptvcursor_tvbuff(ptvc),
2481                                  current_offset);
2482
2483         /* Use it */
2484         sub_rec = rec->sub_ptvc_rec->ptvc_rec;
2485         while(sub_rec->hf_ptr != NULL) {
2486             DISSECTOR_ASSERT(!sub_rec->sub_ptvc_rec);
2487             ptvcursor_add_no_advance(sub_ptvc, *sub_rec->hf_ptr,
2488                                      sub_rec->length,
2489                                      sub_rec->endianness);
2490             sub_rec++;
2491         }
2492
2493         /* Free it. */
2494         ptvcursor_free(sub_ptvc);
2495     }
2496     else {
2497         DISSECTOR_ASSERT(rec->length > 0 &&
2498                          proto_registrar_get_nth(*rec->hf_ptr)->type != FT_UINT_STRING);
2499         ptvcursor_advance(ptvc, rec->length);
2500     }
2501 }
2502
2503 /* Process a sub-ptvc_record that points to a "struct" ptvc_record. */
2504 static void
2505 process_struct_sub_ptvc_record(ptvcursor_t *ptvc, packet_info *pinfo, const ptvc_record *rec,
2506                                gboolean *req_cond_results, gboolean really_decode,
2507                                const ncp_record *ncp_rec, gboolean request)
2508 {
2509     const ptvc_record   *sub_rec;
2510     gint                ett;
2511     proto_tree          *old_tree=NULL, *new_tree;
2512     proto_item          *item=NULL;
2513     gint                offset=0;
2514
2515     /* Create a sub-proto_tree? */
2516     if (rec->sub_ptvc_rec->descr) {
2517         ett = *rec->sub_ptvc_rec->ett;
2518         old_tree = ptvcursor_tree(ptvc);
2519         offset = ptvcursor_current_offset(ptvc);
2520         new_tree = proto_tree_add_subtree(old_tree, ptvcursor_tvbuff(ptvc), offset, -1,
2521                                           ett, &item, rec->sub_ptvc_rec->descr);
2522         ptvcursor_set_tree(ptvc, new_tree);
2523     }
2524
2525     /* Get the ptvc_record for the struct and call our caller
2526      * to process it. */
2527     sub_rec = rec->sub_ptvc_rec->ptvc_rec;
2528     process_ptvc_record(ptvc, pinfo, sub_rec, req_cond_results, really_decode, ncp_rec, request);
2529
2530     /* Re-set the tree */
2531     if (rec->sub_ptvc_rec->descr) {
2532         if (ptvcursor_current_offset(ptvc) <= offset)
2533             THROW(ReportedBoundsError);
2534
2535         proto_item_set_len(item, ptvcursor_current_offset(ptvc) - offset);
2536         ptvcursor_set_tree(ptvc, old_tree);
2537     }
2538 }
2539
2540 /* Run through the table of ptvc_record's and add info to the tree. This
2541  * is the work-horse of process_ptvc_record(). */
2542 static void
2543 _process_ptvc_record(ptvcursor_t *ptvc, packet_info *pinfo, const ptvc_record *rec,
2544                      gboolean *req_cond_results, gboolean really_decode,
2545                      const ncp_record *ncp_rec, gboolean request)
2546 {
2547     guint       i, repeat_count, repeat_value;
2548
2549     if (rec->sub_ptvc_rec) {
2550         /* Repeat this? */
2551         if (rec->repeat_index >= NO_REPEAT) {
2552             if (rec->hf_ptr == PTVC_STRUCT) {
2553                 process_struct_sub_ptvc_record(ptvc, pinfo, rec,
2554                                                req_cond_results, really_decode,
2555                                                ncp_rec, request);
2556             }
2557             else {
2558                 process_bitfield_sub_ptvc_record(ptvc, rec,
2559                                                  really_decode);
2560             }
2561         }
2562         else {
2563             repeat_count = repeat_vars[rec->repeat_index];
2564             for (i = 0; i < repeat_count; i++ ) {
2565                 if (rec->hf_ptr == PTVC_STRUCT) {
2566                     process_struct_sub_ptvc_record(ptvc, pinfo, rec,
2567                                                    req_cond_results, really_decode,
2568                                                    ncp_rec, request);
2569                 }
2570                 else {
2571                     process_bitfield_sub_ptvc_record(ptvc, rec,
2572                                                      really_decode);
2573                 }
2574             }
2575         }
2576     }
2577     else {
2578         /* If we can't repeat this field, we might use it
2579          * to set a 'var'. */
2580         if (rec->repeat_index == NO_REPEAT) {
2581             if (really_decode) {
2582                 repeat_value = 0;
2583                 add_ptvc_field(pinfo, ptvc, rec, request, FALSE, &repeat_value);
2584
2585                 /* Set the value as a 'var' ? */
2586                 if (rec->var_index != NO_VAR) {
2587                     repeat_vars[rec->var_index] = repeat_value;
2588                 }
2589             }
2590             else {
2591                 /* If we don't decode the field, we
2592                  * better not use the value to set a var.
2593                  * Actually, we could, as long as we don't
2594                  * *use* that var; for now keep this assert in
2595                  * place. */
2596                 DISSECTOR_ASSERT(rec->var_index == NO_VAR);
2597
2598                 /* This had better not be variable-length,
2599                  * either. */
2600                 DISSECTOR_ASSERT(rec->length > 0 &&
2601                                  proto_registrar_get_nth(*rec->hf_ptr)->type != FT_UINT_STRING);
2602                 ptvcursor_advance(ptvc, rec->length);
2603             }
2604         }
2605         else {
2606             /* We do repeat this field. */
2607             repeat_count = repeat_vars[rec->repeat_index];
2608             if (really_decode) {
2609                 for (i = 0; i < repeat_count; i++ ) {
2610                     add_ptvc_field(pinfo, ptvc, rec, request, i != 0, &repeat_value);
2611                 }
2612             }
2613             else {
2614                 for (i = 0; i < repeat_count; i++ ) {
2615                     DISSECTOR_ASSERT(rec->length > 0 &&
2616                                      proto_registrar_get_nth(*rec->hf_ptr)->type != FT_UINT_STRING);
2617                     ptvcursor_advance(ptvc, rec->length);
2618                 }
2619             }
2620         }
2621     }
2622 }
2623
2624 /* Run through the table of ptvc_record's and add info to the tree.
2625  * Honor a request condition result. */
2626 static void
2627 process_ptvc_record(ptvcursor_t *ptvc, packet_info *pinfo, const ptvc_record *rec,
2628                     gboolean *req_cond_results, gboolean really_decode,
2629                     const ncp_record *ncp_rec, gboolean request)
2630 {
2631     gboolean decode;
2632     ptvcursor_t *expert_ptvc;
2633     proto_tree* expert_tree = ptvcursor_tree(ptvc);
2634     tvbuff_t* expert_tvb = ptvcursor_tvbuff(ptvc);
2635     gint expert_offset = ptvcursor_current_offset(ptvc);
2636
2637     while(rec->hf_ptr != NULL) {
2638         decode = really_decode;
2639         /* If we're supposed to decode, check the request condition
2640          * results to see if we should override this and *not* decode. */
2641         if (decode && req_cond_results) {
2642             if (rec->req_cond_index != NO_REQ_COND) {
2643                 if (req_cond_results[rec->req_cond_index] == FALSE) {
2644                     decode = FALSE;
2645                 }
2646             }
2647         }
2648         if (decode || ncp_rec->req_cond_size_type == REQ_COND_SIZE_CONSTANT) {
2649             _process_ptvc_record(ptvc, pinfo, rec, req_cond_results, decode, ncp_rec, request);
2650         }
2651         rec++;
2652     }
2653
2654     /* Collect any potential expert info that would have been collected over
2655        these records */
2656     if (ncp_rec->expert_handler_func)
2657     {
2658         expert_ptvc = ptvcursor_new(expert_tree, expert_tvb, expert_offset);
2659         ncp_rec->expert_handler_func(expert_ptvc, pinfo, ncp_rec, request);
2660         ptvcursor_free(expert_ptvc);
2661     }
2662 }
2663
2664
2665
2666 /* Clear the repeat_vars array. */
2667 static void
2668 clear_repeat_vars(void)
2669 {
2670     guint i;
2671
2672     for (i = 0 ; i < NUM_REPEAT_VARS; i++ ) {
2673         repeat_vars[i] = 0;
2674     }
2675 }
2676
2677
2678 /* Given an error_equivalency table and a completion code, return
2679  * the string representing the error. */
2680 static const char*
2681 ncp_error_string(const error_equivalency *errors, guint8 completion_code)
2682 {
2683
2684     while (errors->ncp_error_index != -1) {
2685         if (errors->error_in_packet == completion_code) {
2686             return ncp_errors[errors->ncp_error_index];
2687         }
2688         errors++;
2689     }
2690
2691     return "Unknown Error Code";
2692 }
2693
2694 static const ncp_record ncp1111_request =
2695 { 0x1, 0x00, NO_SUBFUNC, "Create Connection Service", NCP_GROUP_CONNECTION,
2696   NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };
2697
2698 static const ncp_record ncp5555_request =
2699 { 0x5, 0x00, NO_SUBFUNC, "Destroy Connection Service", NCP_GROUP_CONNECTION,
2700   NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };
2701
2702 static const ncp_record ncpbbbb_request =
2703 { 0xb, 0x00, NO_SUBFUNC, "Server Broadcast Message", NCP_GROUP_CONNECTION,
2704   NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };
2705
2706 static const ncp_record ncplip_echo =
2707 { 0x1f, 0x00, NO_SUBFUNC, "LIP Echo Packet", NCP_GROUP_CONNECTION,
2708   NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };
2709
2710 /* Wrapper around proto_tree_free() */
2711 static void free_proto_tree(void *tree)
2712 {
2713     if (tree) {
2714         proto_tree_free((proto_tree*) tree);
2715     }
2716 }
2717
2718 static guint32
2719 align_4(tvbuff_t *tvb, guint32 aoffset)
2720 {
2721     if(tvb_captured_length_remaining(tvb, aoffset) > 4 )
2722     {
2723         return (aoffset%4);
2724     }
2725     return 0;
2726 }
2727
2728 static const char *
2729 get_string(tvbuff_t* tvb, guint offset, guint str_length)
2730 {
2731     char *dest_buf;
2732     gint i;
2733     guint16 c_char;
2734     gint length_remaining = 0;
2735     gint max_length = (str_length < NW_UNI_MAX) ? str_length : NW_UNI_MAX;
2736
2737     length_remaining = tvb_captured_length_remaining(tvb, offset);
2738     if((gint)str_length > length_remaining)
2739     {
2740         THROW(ReportedBoundsError);
2741     }
2742
2743     if(str_length == 0)
2744     {
2745         return "";
2746     }
2747
2748     dest_buf = (char *)wmem_alloc(wmem_packet_scope(), max_length + 1);
2749     dest_buf[0] = '\0';
2750
2751     for ( i = 0; i < (gint)str_length; i++ )
2752     {
2753         c_char = tvb_get_guint8(tvb, offset );
2754         if (c_char<0x20 || c_char>0x7e)
2755         {
2756             if (c_char != 0x00)
2757             {
2758                 c_char = '.';
2759                 dest_buf[i] = c_char & 0xff;
2760             }
2761             else
2762             {
2763                 i--;
2764                 str_length--;
2765             }
2766         }
2767         else
2768         {
2769             dest_buf[i] = c_char & 0xff;
2770         }
2771         offset++;
2772         length_remaining--;
2773
2774         if(length_remaining==1)
2775         {
2776             dest_buf[i+1] = '\0';
2777             return dest_buf;
2778         }
2779         if (i >= 1023) { /* Don't process beyond the size of our variable */
2780             break;       /* If string is too long just return the first 1K. */
2781         }
2782     }
2783     if (i < 0) {
2784         i = 0;
2785     }
2786     dest_buf[i] = '\0';
2787     return dest_buf;
2788 }
2789
2790 /* Echo the NDS EID and name for NCP 22,51 replies to expert tap */
2791 static void ncp1633_reply_expert_func(ptvcursor_t *ptvc, packet_info *pinfo, const ncp_record *ncp_rec _U_, gboolean request)
2792 {
2793     if (nds_echo_eid && !request) {
2794         guint32 object_id;
2795         guint8  volume_name_len;
2796         gchar*  volume_name;
2797
2798         object_id = tvb_get_letohl(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)+126);
2799         ptvcursor_advance(ptvc, 134);
2800         volume_name_len = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2801         ptvcursor_advance(ptvc, 1);
2802         volume_name = tvb_get_string_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2803                                 ptvcursor_current_offset(ptvc), volume_name_len, ENC_ASCII);
2804
2805         expert_add_info_format(pinfo, NULL, &ei_ncp_eid,
2806                                     "EID (%08x) = %s", object_id, volume_name);
2807     }
2808 }
2809
2810 /* The following allows for specific NCP server info to be echoed to the expert tap. */
2811 static void ncp1711_reply_expert_func(ptvcursor_t *ptvc, packet_info *pinfo, const ncp_record *ncp_rec _U_, gboolean request)
2812 {
2813     if (ncp_echo_server && !request) {
2814         guint8* fsname;
2815         guint8 maj_ver, min_ver, os_lang, serv_type, kernel;
2816         guint16 prod_rev;
2817
2818         fsname = tvb_get_string_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2819                                 ptvcursor_current_offset(ptvc), 48, ENC_ASCII);
2820         ptvcursor_advance(ptvc, 48);
2821         maj_ver = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2822         ptvcursor_advance(ptvc, 1);
2823         min_ver = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2824         ptvcursor_advance(ptvc, 25); /* Skip unimportant fields */
2825         prod_rev = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2826         ptvcursor_advance(ptvc, 2);
2827         os_lang = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2828         ptvcursor_advance(ptvc, 2);
2829         serv_type = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2830         ptvcursor_advance(ptvc, 1);
2831         kernel = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2832         ptvcursor_advance(ptvc, 1);
2833
2834         expert_add_info_format(pinfo, NULL, &ei_ncp_server, "Server %s, version %d.%d, support pack %d, language %d, server type %s, kernel %s", fsname,
2835                                 maj_ver, min_ver, prod_rev, os_lang, val_to_str(serv_type & 0x01, serv_type_vals, "Unknown: %d"),
2836                                 val_to_str(kernel & 0x01, kernel_type_vals, "Unknown: %d") );
2837     }
2838 }
2839
2840 /* The following allows for Update file handle rights echoed to expert tap. */
2841 static void ncp42_request_expert_func(ptvcursor_t *ptvc, packet_info *pinfo, const ncp_record *ncp_rec _U_, gboolean request)
2842 {
2843     if (ncp_echo_file && request) {
2844         gchar* filehandle = tvb_bytes_to_str(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2845                                                 ptvcursor_current_offset(ptvc)+1, 6);
2846
2847         expert_add_info_format(pinfo, NULL, &ei_ncp_file_handle, "Close file handle %s", filehandle);
2848     }
2849 }
2850
2851 /* The following allows for oplock level 1 file opens echoed to expert tap. */
2852 static void file_rights_expert_func(ptvcursor_t *ptvc, packet_info *pinfo, const ncp_record *ncp_rec, gboolean request)
2853 {
2854     if (ncp_echo_file) {
2855         if (request) {
2856             guint8 oaction = 0, path_count = 0;
2857             guint16 rights = 0;
2858             gchar* filename = "";
2859
2860             if (ncp_rec->func == 87) {
2861                 switch(ncp_rec->subfunc)
2862                 {
2863                 case 1:
2864                 case 32:
2865                     oaction = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)+1);
2866                     ptvcursor_advance(ptvc, 12);
2867                     rights = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2868                     ptvcursor_advance(ptvc, 8);
2869                     path_count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2870                     ptvcursor_advance(ptvc, 1);
2871                     filename = tvb_get_string_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2872                                 ptvcursor_current_offset(ptvc), path_count, ENC_ASCII);
2873                     break;
2874                 case 33:
2875                 case 30:
2876                     oaction = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)+2);
2877                     ptvcursor_advance(ptvc, 16);
2878                     rights = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2879                     ptvcursor_advance(ptvc, 8);
2880                     path_count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2881                     ptvcursor_advance(ptvc, 1);
2882                     filename = tvb_get_string_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2883                                     ptvcursor_current_offset(ptvc), path_count, ENC_ASCII);
2884                     break;
2885                 }
2886             } else if (ncp_rec->func == 89) {
2887                 switch(ncp_rec->subfunc)
2888                 {
2889                 case 1:
2890                 case 32:
2891                     oaction = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)+1);
2892                     ptvcursor_advance(ptvc, 12);
2893                     rights = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2894                     ptvcursor_advance(ptvc, 14);
2895                     path_count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2896                     ptvcursor_advance(ptvc, 1);
2897                     filename = tvb_get_string_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2898                                     ptvcursor_current_offset(ptvc), path_count, ENC_ASCII);
2899                     break;
2900                 case 33:
2901                 case 30:
2902                     oaction = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)+2);
2903                     ptvcursor_advance(ptvc, 16);
2904                     rights = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2905                     ptvcursor_advance(ptvc, 14);
2906                     path_count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2907                     ptvcursor_advance(ptvc, 1);
2908                     filename = tvb_get_string_enc(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2909                                     ptvcursor_current_offset(ptvc), path_count, ENC_ASCII);
2910                     break;
2911                 }
2912             }
2913
2914             expert_add_info_format(pinfo, NULL, &ei_ncp_file_rights,
2915                                 "Op-lock open, mode %s for filename %s with rights %s",
2916                                 val_to_str(oaction & 0xeb, open_create_mode_vals, "Unknown: %d"),
2917                                 filename,
2918                                 val_to_str(rights & 0x5f, ncp_rights_vals, "Unknown: %d"));
2919         } else {
2920             if ((ncp_rec->func == 89 || ncp_rec->func == 87) && (ncp_rec->subfunc == 32 || ncp_rec->subfunc == 1)) {
2921                 guint8 oaction, oplockflg;
2922                 gchar* filehandle;
2923
2924                 filehandle = tvb_bytes_to_str(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2925                                                 ptvcursor_current_offset(ptvc), 4);
2926                 ptvcursor_advance(ptvc, 4);
2927                 oaction = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2928
2929                 if (ncp_rec->subfunc == 1) {
2930                     expert_add_info_format(pinfo, NULL, &ei_ncp_file_handle, "%s - File handle %s",
2931                                            val_to_str(oaction & 0x8f, open_create_action_vals, "Unknown: %d"),
2932                                            filehandle);
2933                 }
2934                 else
2935                 {
2936                     ptvcursor_advance(ptvc, 1);
2937                     oplockflg = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2938                     expert_add_info_format(pinfo, NULL, &ei_ncp_file_handle, "%s - File handle %s, %s",
2939                                            val_to_str(oaction & 0x8f, open_create_action_vals, "Unknown: %d"),
2940                                            filehandle,
2941                                            val_to_str(oplockflg, ncp_o_c_ret_flags_vals, "Unknown: %d"));
2942                 }
2943             }
2944         }
2945     }
2946 }
2947
2948 /* The following allows for oplock ack's and level 2 request echoed to expert tap. */
2949 static void ncp5722_request_expert_func(ptvcursor_t *ptvc, packet_info *pinfo, const ncp_record *ncp_rec _U_, gboolean request)
2950 {
2951     if (ncp_echo_file && request) {
2952         guint32 filehandle;
2953         guint8 cc_function;
2954
2955         filehandle = tvb_get_ntohl(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2956         ptvcursor_advance(ptvc, 4);
2957         cc_function = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2958
2959         expert_add_info_format(pinfo, NULL, &ei_ncp_op_lock_handle, "Op-lock on handle %08x - %s", filehandle,
2960                                 val_to_str(cc_function, ncp_cc_function_vals, "Unknown: %d"));
2961     }
2962 }
2963
2964 /* The following allows for Update file handle rights echoed to expert tap. */
2965 static void ncp572c_expert_func(ptvcursor_t *ptvc, packet_info *pinfo, const ncp_record *ncp_rec _U_, gboolean request)
2966 {
2967     if (ncp_echo_file) {
2968         gchar* filehandle;
2969
2970         if (request) {
2971             guint16 access_rights, new_rights;
2972
2973             access_rights = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)+8);
2974             ptvcursor_advance(ptvc, 10);
2975             new_rights = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc));
2976             ptvcursor_advance(ptvc, 2);
2977             filehandle = tvb_bytes_to_str(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2978                                                     ptvcursor_current_offset(ptvc), 4);
2979
2980             expert_add_info_format(pinfo, NULL, &ei_ncp_file_rights_change, "Change handle %s rights from:(%s) to:(%s)",
2981                                    filehandle,
2982                                    val_to_str(access_rights & 0x1ff, access_rights_vals, "Unknown: %d"),
2983                                    val_to_str(new_rights & 0x1ff, access_rights_vals, "Unknown: %d"));
2984
2985         } else {
2986             guint32 rights;
2987
2988             filehandle = tvb_bytes_to_str(wmem_packet_scope(), ptvcursor_tvbuff(ptvc),
2989                                                     ptvcursor_current_offset(ptvc), 4);
2990             ptvcursor_advance(ptvc, 4);
2991             rights = tvb_get_ntohl(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)+8);
2992
2993             expert_add_info_format(pinfo, NULL, &ei_ncp_effective_rights, "Handle %s effective rights:(%s)", filehandle,
2994                                     val_to_str(rights & 0x1ff, access_rights_vals, "Unknown: %d"));
2995         }
2996     }
2997 }
2998
2999 static void
3000 print_nds_values(proto_tree *vtree, packet_info* pinfo, tvbuff_t *tvb, guint32 syntax_type, nds_val *vvalues)
3001 {
3002     guint32         value1 = 0;
3003     guint32         value2 = 0;
3004     guint32         value3 = 0;
3005     guint32         value4 = 0;
3006     guint32         value5 = 0;
3007     guint32         voffset = 0, oldvoffset;
3008     guint32         icounter;
3009     guint32         number_of_values = 0;
3010     guint32         number_of_items = 0;
3011     guint32         r;
3012     proto_item      *vitem;
3013     proto_tree      *nvtree;
3014     proto_item      *aditem;
3015     proto_tree      *adtree;
3016     const char      *valuestr = NULL;
3017     gint            length_remaining;
3018     nstime_t        ns;
3019     gboolean        entry_rights = FALSE;
3020
3021     voffset = vvalues->voffset;
3022 #if 0
3023     if(tvb_get_guint8(tvb, voffset) == 0x00)
3024     {
3025         voffset = voffset+2;
3026     }
3027 #endif
3028
3029     number_of_values = tvb_get_letohl(tvb, voffset);
3030
3031     vitem = proto_tree_add_uint_format(vtree, hf_nds_uint32value, tvb, voffset,
3032                                        4, number_of_values, "Number of Values: %u", number_of_values);
3033
3034     nvtree = proto_item_add_subtree(vitem, ett_nds);
3035
3036     oldvoffset = voffset;
3037     voffset = voffset + 4;
3038
3039     for (icounter = 1 ; icounter <= number_of_values; icounter++ )
3040     {
3041         if (oldvoffset >= voffset) {
3042             proto_tree_add_expert_format(nvtree, pinfo, &ei_ncp_invalid_offset, tvb, 0, 0, "Invalid offset: %u", voffset);
3043             THROW(ReportedBoundsError);
3044         }
3045         oldvoffset = voffset;
3046         switch(syntax_type)
3047         {
3048         case 0x00000006:        /* Case Insensitive List */
3049         case 0x00000012:        /* Postal Address */
3050             voffset += align_4(tvb, voffset);
3051             voffset = voffset+4;
3052             number_of_items = tvb_get_letohl(tvb, voffset);
3053             voffset = voffset+4;
3054             for (r=1; r<=number_of_items; r++)
3055             {
3056                 value1 = tvb_get_letohl(tvb, voffset);
3057                 voffset = voffset + 4;
3058                 vvalues->vstring = get_string(tvb, voffset, value1);
3059                 proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3060                                       value1, vvalues->vstring);
3061                 voffset = voffset + value1;
3062                 voffset += align_4(tvb, voffset);
3063             }
3064             break;
3065         case 0x00000007:        /* Boolean */
3066             voffset+=4;                            /* this is always just a parameter count of 1, so ignore */
3067             value1 = tvb_get_guint8(tvb, voffset); /* Boolean value */
3068             if (value1==0)
3069             {
3070                 vvalues->vstring = "False";
3071             }
3072             else
3073             {
3074                 vvalues->vstring = "True";
3075             }
3076             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3077                                   1, vvalues->vstring);
3078             voffset=voffset+1;
3079             voffset += align_4(tvb, voffset);
3080             break;
3081         case 0x00000009:        /* Binary String */
3082             value1 = tvb_get_letohl(tvb, voffset); /* length of field */
3083             length_remaining = tvb_captured_length_remaining(tvb, voffset);
3084             if(length_remaining == -1 || value1 > (guint32) length_remaining)
3085             {
3086                 break;
3087             }
3088             voffset += 4;
3089             proto_tree_add_item(nvtree, hf_value_bytes, tvb, voffset, value1, ENC_NA);
3090             voffset += value1;
3091             voffset += (value1%2);
3092             break;
3093         case 0x0000000d:        /* Binary String List */
3094             value1 = tvb_get_letohl(tvb, voffset); /* Overall length of field list */
3095             length_remaining = tvb_captured_length_remaining(tvb, voffset);
3096             if(length_remaining == -1 || value1 > (guint32) length_remaining)
3097             {
3098                 break;
3099             }
3100             voffset += 4;
3101             tvb_ensure_bytes_exist(tvb, voffset, value1);
3102             number_of_items = tvb_get_letohl(tvb, voffset);
3103             voffset = voffset+4;
3104             for (r=1; r<=number_of_items; r++)
3105             {
3106                 value1 = tvb_get_letohl(tvb, voffset); /* length of field */
3107                 length_remaining = tvb_captured_length_remaining(tvb, voffset);
3108                 if(length_remaining == -1 || value1 > (guint32) length_remaining)
3109                 {
3110                     break;
3111                 }
3112                 voffset += 4;
3113                 proto_tree_add_item(nvtree, hf_value_bytes, tvb, voffset, value1, ENC_NA);
3114                 voffset += value1;
3115                 voffset += (value1%2);
3116             }
3117             break;
3118         case 0x00000015:        /* Stream */
3119             value1 = tvb_get_letohl(tvb, voffset); /* length of field */
3120             length_remaining = tvb_captured_length_remaining(tvb, voffset);
3121             if(length_remaining == -1 || value1 > (guint32) length_remaining)
3122             {
3123                 break;
3124             }
3125             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, 4, value1, "No value, Open stream file for data.");
3126             voffset += 4;
3127             voffset += value1;
3128             voffset += (value1%2);
3129             break;
3130         case 0x00000008:        /* Signed Integer */
3131         case 0x00000016:        /* Counter */
3132         case 0x0000001b:        /* Interval */
3133             value1 = tvb_get_letohl(tvb, voffset); /* length of field */
3134             voffset = voffset+4;
3135             value2 = tvb_get_letohl(tvb, voffset); /* Value */
3136             if (strcmp(vvalues->vstring, "zendmSearchType")==0) {
3137                 proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3138                                            value1, value2,
3139                                            "Value (%d) = %s", value2,
3140                                            val_to_str(value2, zensearchenum, "Unknown: %d"));
3141             }
3142             else
3143             {
3144                 proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3145                                            value1, value2, "Value %d", value2);
3146             }
3147             voffset = voffset+4;
3148             break;
3149         case 0x0000000b:        /* Fax Number */
3150             value1 = tvb_get_letohl(tvb, voffset); /* length of field */
3151             voffset = voffset+4;
3152             vvalues->vstring = get_string(tvb, voffset, value1);
3153             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3154                                   value1, vvalues->vstring);
3155             voffset = voffset + value1;
3156             voffset += align_4(tvb, voffset);
3157             break;
3158         case 0x0000000c:        /* Network Address */
3159             value1 = tvb_get_letohl(tvb, voffset); /* length of field */
3160             voffset = voffset + 4;
3161             value2 = tvb_get_letohl(tvb, voffset); /* type of Protocol */
3162             valuestr = val_to_str_const(value2, nds_protocol_type, "(Undefined Protocol)");
3163             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3164                                        value1, value2, valuestr, value2);
3165             voffset = voffset+4;
3166             value3 = tvb_get_letohl(tvb, voffset); /* length of address */
3167             voffset = voffset+4;
3168             switch (value2)
3169             {
3170             case NDS_PTYPE_IPX:
3171                 proto_tree_add_item(nvtree, hf_nds_net, tvb, voffset, 4, ENC_BIG_ENDIAN);
3172                 proto_tree_add_item(nvtree, hf_nds_node, tvb, voffset+4, 6, ENC_NA);
3173                 proto_tree_add_item(nvtree, hf_nds_socket, tvb, voffset+10, 2, ENC_BIG_ENDIAN);
3174                 break;
3175             case NDS_PTYPE_IP:
3176                 if (value3 > 4) {
3177                     proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, ENC_BIG_ENDIAN);
3178                     voffset += 2;
3179                 }
3180                 proto_tree_add_item(nvtree, hf_add_ref_ip, tvb, voffset, 4, ENC_BIG_ENDIAN);
3181                 break;
3182             case NDS_PTYPE_UDP:
3183                 if (value3 > 4) {
3184                     proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, ENC_BIG_ENDIAN);
3185                     voffset += 2;
3186                 }
3187                 proto_tree_add_item(nvtree, hf_add_ref_udp, tvb, voffset, 4, ENC_BIG_ENDIAN);
3188                 break;
3189             case NDS_PTYPE_TCP:
3190                 proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, ENC_BIG_ENDIAN);
3191                 proto_tree_add_item(nvtree, hf_add_ref_tcp, tvb, voffset+2, 4, ENC_BIG_ENDIAN);
3192                 break;
3193             case NDS_PTYPE_URL:
3194             case NDS_PTYPE_DNS:
3195                 vvalues->vstring = get_string(tvb, voffset, value3);
3196                 proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3197                                       value3, vvalues->vstring);
3198                 break;
3199             default:
3200                 break;
3201             }
3202             voffset = voffset + value3;
3203             voffset += align_4(tvb, voffset);
3204             break;
3205         case 0x0000000f:        /* File System Path */
3206             /*value1 = tvb_get_letohl(tvb, voffset);*/ /* length of field */
3207             voffset = voffset + 4;
3208             value2 = tvb_get_letohl(tvb, voffset); /* Name Space */
3209             valuestr = val_to_str_const(value2, name_space_type, "Unknown Name Space");
3210             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3211                                   4, valuestr);
3212             voffset = voffset+4;
3213             value3 = tvb_get_letohl(tvb, voffset); /* Length of Volume name */
3214             voffset = voffset+4;
3215             vvalues->vstring = get_string(tvb, voffset, value3);
3216             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3217                                   value3, vvalues->vstring);
3218             voffset = voffset+value3;
3219             voffset += align_4(tvb, voffset);
3220             value4 = tvb_get_letohl(tvb, voffset); /* Length of Path name */
3221             voffset = voffset+4;
3222             vvalues->vstring = get_string(tvb, voffset, value4);
3223             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3224                                   value4, vvalues->vstring);
3225             voffset = voffset+value4;
3226             voffset += align_4(tvb, voffset);
3227             break;
3228         case 0x00000010:        /* Replica Pointer */
3229             /*value1 = tvb_get_letohl(tvb, voffset);*/ /* length of field */
3230             voffset = voffset + 4;
3231             value2 = tvb_get_letohl(tvb, voffset); /* Length of Server name */
3232             voffset = voffset+4;
3233             vvalues->vstring = get_string(tvb, voffset, value2);
3234             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3235                                   value2, vvalues->vstring);
3236             voffset = voffset+value2;
3237             voffset += align_4(tvb, voffset);
3238             proto_tree_add_item(nvtree, hf_replica_type, tvb, voffset, 2, ENC_LITTLE_ENDIAN);
3239             voffset = voffset+2;
3240             proto_tree_add_item(nvtree, hf_replica_state, tvb, voffset, 2, ENC_LITTLE_ENDIAN);
3241             voffset = voffset+2;
3242             proto_tree_add_item(nvtree, hf_replica_number, tvb, voffset, 4, ENC_LITTLE_ENDIAN);
3243             voffset = voffset+4;
3244             if((vvalues->pflags & 0x8000) | (vvalues->pflags & 0x4000))
3245             {
3246                 /* If this request flag is set then this is a server. Server structures
3247                  * include the RootID as part of the replica data. */
3248                 proto_tree_add_item(nvtree, hf_nds_partition_root_id, tvb, voffset, 4, ENC_BIG_ENDIAN);
3249                 voffset += 4;
3250             }
3251             number_of_items = tvb_get_letohl(tvb, voffset);  /* Number of Addresses */
3252             aditem = proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3253                                                 4, number_of_items, "Number of Addresses: %u", number_of_items);
3254
3255             adtree = proto_item_add_subtree(aditem, ett_nds);
3256             voffset = voffset+4;
3257             for (r=1; r <= number_of_items; r++)
3258             {
3259                 /* Trap for end of packet */
3260                 if(tvb_captured_length_remaining(tvb, voffset)<12)
3261                 {
3262                     THROW(ReportedBoundsError);
3263                 }
3264                 voffset += align_4(tvb, voffset);
3265                 value4 = tvb_get_letohl(tvb, voffset); /* type of Protocol */
3266                 valuestr = val_to_str_const(value4, nds_protocol_type, "(Undefined Protocol)");
3267                 proto_tree_add_uint_format(adtree, hf_nds_uint32value, tvb, voffset,
3268                                            4, value4, valuestr, value4);
3269                 voffset = voffset+4;
3270                 value5 = tvb_get_letohl(tvb, voffset); /* length of address */
3271                 voffset = voffset+4;
3272                 switch (value4)
3273                 {
3274                 case NDS_PTYPE_IPX:
3275                     proto_tree_add_item(adtree, hf_nds_net, tvb, voffset, 4, ENC_BIG_ENDIAN);
3276                     proto_tree_add_item(adtree, hf_nds_node, tvb, voffset+4, 6, ENC_NA);
3277                     proto_tree_add_item(adtree, hf_nds_socket, tvb, voffset+10, 2, ENC_BIG_ENDIAN);
3278                     break;
3279                 case NDS_PTYPE_IP:
3280                     proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, ENC_BIG_ENDIAN);
3281                     proto_tree_add_item(adtree, hf_add_ref_ip, tvb, voffset+2, 4, ENC_BIG_ENDIAN);
3282                     break;
3283                 case NDS_PTYPE_UDP:
3284                     proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, ENC_BIG_ENDIAN);
3285                     proto_tree_add_item(adtree, hf_add_ref_udp, tvb, voffset+2, 4, ENC_BIG_ENDIAN);
3286                     break;
3287                 case NDS_PTYPE_TCP:
3288                     proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, ENC_BIG_ENDIAN);
3289                     proto_tree_add_item(adtree, hf_add_ref_tcp, tvb, voffset+2, 4, ENC_BIG_ENDIAN);
3290                     break;
3291                 case NDS_PTYPE_URL:
3292                 case NDS_PTYPE_DNS:
3293                     vvalues->vstring = get_string(tvb, voffset, value5);
3294                     proto_tree_add_string(adtree, hf_value_string, tvb, voffset,
3295                                           value5, vvalues->vstring);
3296                     break;
3297                 default:
3298                     break;
3299                 }
3300                 voffset = voffset + value5;
3301             }
3302             voffset += align_4(tvb, voffset);
3303             break;
3304         case 0x00000011:        /* Object ACL */
3305             /*value1 = tvb_get_letohl(tvb, voffset);*/ /* Length of Field */
3306             voffset = voffset + 4;
3307             value2 = tvb_get_letohl(tvb, voffset);
3308             voffset = voffset + 4;
3309             vvalues->vstring = get_string(tvb, voffset, value2); /* Unicode String */
3310             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3311                                   value2, vvalues->vstring);
3312             if (strcmp(vvalues->vstring, "[Entry Rights]")) {
3313                 entry_rights=TRUE;
3314             }
3315             else
3316             {
3317                 entry_rights=FALSE;
3318             }
3319             voffset = voffset + value2;
3320             voffset += align_4(tvb, voffset);
3321             value3 = tvb_get_letohl(tvb, voffset);
3322             voffset = voffset + 4;
3323             vvalues->vstring = get_string(tvb, voffset, value3); /* Unicode Subject Name */
3324             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3325                                   value3, vvalues->vstring);
3326             voffset = voffset + value3;
3327             voffset += align_4(tvb, voffset);
3328             /* Entry or Attribute Privileges */
3329             if (entry_rights) {
3330                 /* if Entries then use these bits */
3331                 static const int * entries[] = {
3332                     &hf_nds_compare_attributes,
3333                     &hf_nds_read_attribute,
3334                     &hf_nds_write_add_delete_attribute,
3335                     &hf_nds_add_delete_self,
3336                     &hf_nds_privilege_not_defined,
3337                     &hf_nds_supervisor,
3338                     &hf_nds_inheritance_control,
3339                     &hf_bit8vflags,
3340                     &hf_bit9vflags,
3341                     &hf_bit10vflags,
3342                     &hf_bit11vflags,
3343                     &hf_bit12vflags,
3344                     &hf_bit13vflags,
3345                     &hf_bit14vflags,
3346                     &hf_bit15vflags,
3347                     &hf_bit16vflags,
3348                     NULL
3349                 };
3350
3351                 proto_tree_add_bitmask(nvtree, tvb, voffset, hf_nds_privileges, ett_ncp, entries, ENC_LITTLE_ENDIAN);
3352             }
3353             else
3354             {
3355                 /* if attribute rights then do these bits */
3356                 static const int * rights[] = {
3357                     &hf_nds_browse_entry,
3358                     &hf_nds_add_entry,
3359                     &hf_nds_delete_entry,
3360                     &hf_nds_rename_entry,
3361                     &hf_nds_supervisor_entry,
3362                     &hf_nds_entry_privilege_not_defined,
3363                     &hf_nds_inheritance_control,
3364                     &hf_bit8vflags,
3365                     &hf_bit9vflags,
3366                     &hf_bit10vflags,
3367                     &hf_bit11vflags,
3368                     &hf_bit12vflags,
3369                     &hf_bit13vflags,
3370                     &hf_bit14vflags,
3371                     &hf_bit15vflags,
3372                     &hf_bit16vflags,
3373                     NULL
3374                 };
3375
3376                 proto_tree_add_bitmask(nvtree, tvb, voffset, hf_nds_privileges, ett_ncp, rights, ENC_LITTLE_ENDIAN);
3377             }
3378             voffset = voffset+4;
3379             voffset += align_4(tvb, voffset);
3380             break;
3381         case 0x00000013:        /* Time Stamp */
3382             value1 = tvb_get_letohl(tvb, voffset);         /* Seconds */
3383             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3384                                        4, value1, "Length of Record: %u", value1);
3385             voffset = voffset+4;
3386             ns.secs = tvb_get_letohl(tvb, voffset);
3387             ns.nsecs = 0;
3388             proto_tree_add_time_format(nvtree, hf_nds_ds_time, tvb, voffset, 4,
3389                 &ns, "Timestamp: %s", abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
3390             voffset = voffset + 4;
3391             proto_tree_add_item(nvtree, hf_nds_rnum, tvb, voffset, 2, ENC_LITTLE_ENDIAN);
3392             voffset = voffset+2;
3393             proto_tree_add_item(nvtree, hf_nds_revent, tvb, voffset, 2, ENC_LITTLE_ENDIAN);
3394             voffset = voffset+2;
3395             voffset += align_4(tvb, voffset);
3396             break;
3397         case 0x00000017:        /* Back Link */
3398             value1 = tvb_get_letohl(tvb, voffset);         /* Length */
3399             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3400                                        4, value1, "Length of Record %08x", value1);
3401             voffset = voffset+4;
3402             value2 = tvb_get_letohl(tvb, voffset);         /* Remote ID */
3403             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3404                                        4, value2, "Remote ID %08x", value2);
3405             voffset = voffset+4;
3406             value3 = tvb_get_letohl(tvb, voffset);         /* Length of string */
3407             voffset = voffset+4;
3408             vvalues->vstring = get_string(tvb, voffset, value3);
3409             proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset,
3410                                          value3, vvalues->vstring,
3411                                          "Server Distinguished Name - %s", vvalues->vstring);
3412             voffset = voffset+value3;
3413             voffset += align_4(tvb, voffset);
3414             break;
3415         case 0x00000018:        /* Time */
3416             voffset += 4; /* This is the length of the time data no need to decode, always 4 bytes */
3417             ns.secs = tvb_get_letohl(tvb, voffset);
3418             ns.nsecs = 0;
3419             proto_tree_add_time_format(nvtree, hf_nds_ds_time, tvb, voffset, 4,
3420                 &ns, "Time: %s", abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
3421             voffset = voffset + 4;
3422             break;
3423         case 0x00000019:        /* Typed Name */
3424             value1 = tvb_get_letohl(tvb, voffset);         /* Length */
3425             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3426                                        4, value1, "Length of Record %08x", value1);
3427             voffset = voffset+4;
3428             value2 = tvb_get_letohl(tvb, voffset);         /* Level */
3429             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3430                                        4, value2, "Level %d", value2);
3431             voffset = voffset+4;
3432             value3 = tvb_get_letohl(tvb, voffset);         /* Interval */
3433             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3434                                        4, value3, "Interval %d", value3);
3435             voffset = voffset+4;
3436             value4 = tvb_get_letohl(tvb, voffset);         /* Distinguished Name */
3437             voffset = voffset+4;
3438             vvalues->vstring = get_string(tvb, voffset, value4);
3439             proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset,
3440                                          value4, vvalues->vstring,
3441                                          "Distinguished Name - %s", vvalues->vstring);
3442             voffset = voffset+value4;
3443             voffset += align_4(tvb, voffset);
3444             break;
3445         case 0x0000001a:        /* Hold */
3446             value1 = tvb_get_letohl(tvb, voffset);         /* Length */
3447             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3448                                        4, value1, "Length of Record %08x", value1);
3449             voffset = voffset+4;
3450             value2 = tvb_get_letohl(tvb, voffset);         /* Amount */
3451             proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
3452                                        4, value2, "Amount %d", value2);
3453             voffset = voffset+4;
3454             value3 = tvb_get_letohl(tvb, voffset);         /* Subject */
3455             voffset = voffset+4;
3456             vvalues->vstring = get_string(tvb, voffset, value3);
3457             proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset,
3458                                          value3, vvalues->vstring,
3459                                          "Subject - %s", vvalues->vstring);
3460             voffset = voffset+value3;
3461             voffset += align_4(tvb, voffset);
3462             break;
3463         case 0x00000001:        /* Distinguished Name */
3464         case 0x00000002:        /* Case Sensitive Unicode String */
3465         case 0x00000003:        /* Non Case Sensitive Unicode String */
3466         case 0x00000004:        /* Printable String */
3467         case 0x00000005:        /* Numeric String */
3468         case 0x0000000a:        /* Telephone Number */
3469         case 0x0000000e:        /* Email Address */
3470         case 0x00000014:        /* Class Name */
3471         default:
3472             value1 = tvb_get_letohl(tvb, voffset);
3473             voffset = voffset + 4;
3474             if (strcmp(vvalues->vstring, "zendmSearchOrder")==0) {
3475                 vvalues->vstring = get_string(tvb, voffset, value1);
3476                 if (strcmp(vvalues->vstring, "0")==0) {
3477                     vvalues->vstring = "Value (0) = Object";
3478                 }
3479                 else if (strcmp(vvalues->vstring, "1")==0) {
3480                     vvalues->vstring = "Value (1) = Group";
3481                 }
3482                 else if (strcmp(vvalues->vstring, "2")==0) {
3483                     vvalues->vstring = "Value (2) = Container";
3484                 }
3485                 else if (strcmp(vvalues->vstring, "01")==0) {
3486                     vvalues->vstring = "Value (01) = Object, Group";
3487                 }
3488                 else if (strcmp(vvalues->vstring, "02")==0) {
3489                     vvalues->vstring = "Value (02) = Object, Container";
3490                 }
3491                 else if (strcmp(vvalues->vstring, "10")==0) {
3492                     vvalues->vstring = "Value (10) = Group, Object";
3493                 }
3494                 else if (strcmp(vvalues->vstring, "12")==0) {
3495                     vvalues->vstring = "Value (12) = Group, Container";
3496                 }
3497                 else if (strcmp(vvalues->vstring, "20")==0) {
3498                     vvalues->vstring = "Value (20) = Container, Object";
3499                 }
3500                 else if (strcmp(vvalues->vstring, "21")==0) {
3501                     vvalues->vstring = "Value (21) = Container, Group";
3502                 }
3503                 else if (strcmp(vvalues->vstring, "012")==0) {
3504                     vvalues->vstring = "Value (012) = Object, Group, Container";
3505                 }
3506                 else if (strcmp(vvalues->vstring, "021")==0) {
3507                     vvalues->vstring = "Value (021) = Object, Container, Group";
3508                 }
3509                 else if (strcmp(vvalues->vstring, "102")==0) {
3510                     vvalues->vstring = "Value (102) = Group, Object, Container";
3511                 }
3512                 else if (strcmp(vvalues->vstring, "120")==0) {
3513                     vvalues->vstring = "Value (120) = Group, Container, Object";
3514                 }
3515                 else if (strcmp(vvalues->vstring, "201")==0) {
3516                     vvalues->vstring = "Value (201) = Container, Object, Group";
3517                 }
3518                 else if (strcmp(vvalues->vstring, "210")==0) {
3519                     vvalues->vstring = "Value (210) = Container, Group, Object";
3520                 }
3521             }
3522             else
3523             {
3524                 vvalues->vstring = get_string(tvb, voffset, value1);
3525             }
3526             proto_tree_add_string(nvtree, hf_value_string, tvb, voffset,
3527                                   value1, vvalues->vstring);
3528             voffset = voffset + value1;
3529             voffset += align_4(tvb, voffset);
3530             break;
3531         }
3532         voffset += align_4(tvb, voffset);
3533     }
3534     vvalues->voffset=voffset;
3535     return;
3536 }
3537
3538 static guint32
3539 print_es_type(proto_tree *estree, tvbuff_t *tvb, nds_val *values, guint32 vtype, guint32 ioffset)
3540 {
3541     guint32         value1;
3542     guint32         value2;
3543     guint32         value3;
3544     guint32         value4;
3545     guint32         value5;
3546     guint32         number_of_referrals;
3547     guint32         r;
3548     guint32         i;
3549     proto_tree      *nestree;
3550     proto_item      *nesitem;
3551     proto_tree      *sub1tree;
3552     proto_item      *sub1item;
3553     proto_tree      *sub2tree;
3554     const char      *vstring="";
3555     nstime_t        ns;
3556
3557     switch (vtype)
3558     {
3559     case 0: /* No Specifier Type */
3560         /* ES Type */
3561         proto_tree_add_item(estree, hf_es_value, tvb, ioffset,
3562                             4, ENC_LITTLE_ENDIAN);
3563         ioffset = ioffset + 4;
3564         break;
3565     case 1: /* Unicode String */
3566         value1 = tvb_get_letohl(tvb, ioffset);   /* Delimiter Set */
3567         ioffset = ioffset + 4;
3568         values->vstring = get_string(tvb, ioffset, value1);
3569         proto_tree_add_string_format(estree, hf_mv_string, tvb, ioffset,
3570                                      value1, values->vstring, "Delimiter ->%s", values->vstring);
3571         ioffset=ioffset + value1;
3572         ioffset += align_4(tvb, ioffset);
3573         value2 = tvb_get_letohl(tvb, ioffset);
3574         ioffset = ioffset + 4;
3575         values->vstring = get_string(tvb, ioffset, value2);
3576         proto_tree_add_string(estree, hf_mv_string, tvb, ioffset,
3577                               value2, values->vstring);
3578         values->voffset=ioffset + value2;
3579         ioffset = values->voffset;
3580         ioffset += align_4(tvb, ioffset);
3581         break;
3582     case 2: /* Based */
3583         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
3584         vstring = val_to_str_const(value1, es_type, "No ES Type Found");
3585         nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset,
3586                                                4, vstring, "Base Context Type - %s", vstring);
3587         nestree = proto_item_add_subtree(nesitem, ett_nds);
3588         ioffset = ioffset + 4;
3589         switch (value1)
3590         {
3591         case 0: /* No Specifier Type */
3592             /* ES Type */
3593             proto_tree_add_item(nestree, hf_es_value, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
3594             ioffset = ioffset + 4;
3595             break;
3596         case 1: /* Unicode String */
3597             value2 = tvb_get_letohl(tvb, ioffset);   /* Delimiter Set */
3598             ioffset = ioffset + 4;
3599             values->vstring = get_string(tvb, ioffset, value2);
3600             proto_tree_add_string_format(nestree, hf_mv_string, tvb, ioffset,
3601                                          value2, values->vstring, "Delimiter ->%s", values->vstring);
3602             ioffset=ioffset + value2;
3603             ioffset += align_4(tvb, ioffset);
3604             value3 = tvb_get_letohl(tvb, ioffset);
3605             ioffset = ioffset + 4;
3606             values->vstring = get_string(tvb, ioffset, value3);
3607             proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset,
3608                                   value3, values->vstring);
3609             values->voffset=ioffset + value3;
3610             ioffset = values->voffset;
3611             ioffset += align_4(tvb, ioffset);
3612             break;
3613         case 2: /* Based */
3614             break;
3615         case 3: /* Hinted */
3616             break;
3617         case 4: /* Tuned */
3618             value2 = tvb_get_letohl(tvb, ioffset);   /* Count */
3619             proto_tree_add_item(nestree, hf_es_rdn_count, tvb, ioffset,
3620                                 4, ENC_LITTLE_ENDIAN);
3621             ioffset = ioffset + 4;
3622             for (r = 1 ; r <= value2; r++ )
3623             {
3624                 ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
3625                 ns.nsecs = 0;
3626                 proto_tree_add_time_format(nestree, hf_es_seconds, tvb, ioffset,
3627                                            4, &ns, "Timestamp: %s",
3628                                            abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
3629                 ioffset = ioffset + 4;
3630                 proto_tree_add_item(nestree, hf_nds_replica_num, tvb, ioffset,
3631                                     2, ENC_LITTLE_ENDIAN);
3632                 ioffset = ioffset + 2;
3633                 proto_tree_add_item(nestree, hf_nds_event_num, tvb, ioffset,
3634                                     2, ENC_LITTLE_ENDIAN);
3635                 ioffset = ioffset + 2;
3636             }
3637             value4 = tvb_get_letohl(tvb, ioffset);   /* Delimiter Set */
3638             ioffset = ioffset + 4;
3639             values->vstring = get_string(tvb, ioffset, value4);
3640             proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset,
3641                                   value4, values->vstring);
3642             ioffset=ioffset + value4;
3643             ioffset += align_4(tvb, ioffset);
3644             value5 = tvb_get_letohl(tvb, ioffset);   /* RDN */
3645             ioffset = ioffset + 4;
3646             values->vstring = get_string(tvb, ioffset, value5);
3647             proto_tree_add_string(nestree, hf_rdn_string, tvb, ioffset,
3648                                   value5, values->vstring);
3649             ioffset=ioffset + value5;
3650             ioffset += align_4(tvb, ioffset);
3651             break;
3652         case 5: /* GUID */
3653         case 6: /* ID32 */
3654         case 7: /* Count */
3655         default:
3656             /* ES Type */
3657             /* XXX: nestree rather than estree ?? */
3658             proto_tree_add_item(estree, hf_es_value, tvb, ioffset,
3659                                 4, ENC_LITTLE_ENDIAN);
3660             ioffset = ioffset + 4;
3661             break;
3662         }
3663         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
3664         vstring = val_to_str_const(value1, es_type, "No ES Type Found");
3665         nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset,
3666                                                4, vstring, "Object Name Type - %s", vstring);
3667         nestree = proto_item_add_subtree(nesitem, ett_nds);
3668         ioffset = ioffset + 4;
3669         switch (value1)
3670         {
3671         case 0: /* No Specifier Type */
3672             /* ES Type */
3673             proto_tree_add_item(nestree, hf_es_value, tvb, ioffset,
3674                                 4, ENC_LITTLE_ENDIAN);
3675             ioffset = ioffset + 4;
3676             break;
3677         case 1: /* Unicode String */
3678             value2 = tvb_get_letohl(tvb, ioffset);   /* Delimiter Set */
3679             ioffset = ioffset + 4;
3680             values->vstring = get_string(tvb, ioffset, value2);
3681             proto_tree_add_string_format(nestree, hf_mv_string, tvb, ioffset,
3682                                          value2, values->vstring, "Delimiter ->%s", values->vstring);
3683             ioffset=ioffset + value2;
3684             ioffset += align_4(tvb, ioffset);
3685             value3 = tvb_get_letohl(tvb, ioffset);
3686             ioffset = ioffset + 4;
3687             values->vstring = get_string(tvb, ioffset, value3);
3688             proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset,
3689                                   value3, values->vstring);
3690             values->voffset=ioffset + value3;
3691             ioffset = values->voffset;
3692             ioffset += align_4(tvb, ioffset);
3693             break;
3694         case 2: /* Based */
3695             break;
3696         case 3: /* Hinted */
3697             break;
3698         case 4: /* Tuned */
3699             /* Count */
3700             proto_tree_add_item_ret_uint(nestree, hf_es_rdn_count, tvb, ioffset,
3701                                 4, ENC_LITTLE_ENDIAN, &value2);
3702             ioffset = ioffset + 4;
3703             for (r = 1 ; r <= value2; r++ )
3704             {
3705                 ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
3706                 ns.nsecs = 0;
3707                 proto_tree_add_time_format(nestree, hf_es_seconds, tvb, ioffset,
3708                                            4, &ns, "Timestamp: %s",
3709                                            abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
3710                 ioffset = ioffset + 4;
3711                 proto_tree_add_item(nestree, hf_nds_replica_num, tvb, ioffset,
3712                                     2, ENC_LITTLE_ENDIAN);
3713                 ioffset = ioffset + 2;
3714                 proto_tree_add_item(nestree, hf_nds_event_num, tvb, ioffset,
3715                                     2, ENC_LITTLE_ENDIAN);
3716                 ioffset = ioffset + 2;
3717             }
3718             value4 = tvb_get_letohl(tvb, ioffset);   /* Delimiter Set */
3719             ioffset = ioffset + 4;
3720             values->vstring = get_string(tvb, ioffset, value4);
3721             proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset,
3722                                   value4, values->vstring);
3723             ioffset=ioffset + value4;
3724             ioffset += align_4(tvb, ioffset);
3725             value5 = tvb_get_letohl(tvb, ioffset);   /* RDN */
3726             ioffset = ioffset + 4;
3727             values->vstring = get_string(tvb, ioffset, value5);
3728             proto_tree_add_string(nestree, hf_rdn_string, tvb, ioffset,
3729                                   value5, values->vstring);
3730             ioffset=ioffset + value5;
3731             ioffset += align_4(tvb, ioffset);
3732             break;
3733         case 5: /* GUID */
3734         case 6: /* ID32 */
3735         case 7: /* Count */
3736         default:
3737             /* ES Type */
3738             /* XXX: nestree rather than estree ?? */
3739             proto_tree_add_item(estree, hf_es_value, tvb, ioffset,
3740                                 4, ENC_LITTLE_ENDIAN);
3741             ioffset = ioffset + 4;
3742             break;
3743         }
3744         break;
3745     case 3: /* Hinted */
3746         number_of_referrals = tvb_get_letohl(tvb, ioffset);
3747
3748         for (r = 1 ; r <= number_of_referrals; r++ )
3749         {
3750             sub1item = proto_tree_add_uint_format(estree, hf_referral_record, tvb, 6, 0,
3751                                                   r, "NDS Referral Record #%u", r);
3752             sub1tree = proto_item_add_subtree(sub1item, ett_nds);
3753
3754             proto_tree_add_item_ret_uint(sub1tree, hf_referral_addcount, tvb, ioffset, 4, ENC_LITTLE_ENDIAN, &value1);
3755
3756             ioffset = ioffset + 4;
3757             for (i = 1 ; i <= value1; i++ )
3758             {
3759                 value2 = tvb_get_letohl(tvb, ioffset);
3760                 values->vstring = val_to_str_const(value2, nds_protocol_type, "(Undefined Protocol)");
3761                 proto_tree_add_uint_format(sub1tree, hf_nds_uint32value, tvb, ioffset,
3762                                            4, value2, vstring, value2);
3763                 ioffset = ioffset+4;
3764                 value3 = tvb_get_letohl(tvb, ioffset);
3765                 ioffset = ioffset+4;
3766                 switch (value2)
3767                 {
3768                 case NDS_PTYPE_IPX:
3769                     proto_tree_add_item(sub1tree, hf_nds_net, tvb, ioffset, 4, ENC_BIG_ENDIAN);
3770                     proto_tree_add_item(sub1tree, hf_nds_node, tvb, ioffset+4, 6, ENC_NA);
3771                     proto_tree_add_item(sub1tree, hf_nds_socket, tvb, ioffset+10, 2, ENC_BIG_ENDIAN);
3772                     break;
3773                 case NDS_PTYPE_IP:
3774                     proto_tree_add_item(sub1tree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
3775                     proto_tree_add_item(sub1tree, hf_add_ref_ip, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
3776                     break;
3777                 case NDS_PTYPE_UDP:
3778                     proto_tree_add_item(sub1tree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
3779                     proto_tree_add_item(sub1tree, hf_add_ref_udp, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
3780                     break;
3781                 case NDS_PTYPE_TCP:
3782                     proto_tree_add_item(sub1tree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
3783                     proto_tree_add_item(sub1tree, hf_add_ref_tcp, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
3784                     break;
3785                 case NDS_PTYPE_URL:
3786                 case NDS_PTYPE_DNS:
3787                     values->vstring = get_string(tvb, ioffset, value3);
3788                     proto_tree_add_string(sub1tree, hf_value_string, tvb, ioffset,
3789                                           value3, values->vstring);
3790                     break;
3791                 default:
3792                     break;
3793                 }
3794                 ioffset = ioffset + value3;
3795                 ioffset += align_4(tvb, ioffset);
3796             }
3797
3798         }
3799         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
3800         vstring = val_to_str_const(value1, es_type, "No ES Type Found");
3801         nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset,
3802                                                4, vstring, "Object Name Type - %s", vstring);
3803         nestree = proto_item_add_subtree(nesitem, ett_nds);
3804         ioffset = ioffset + 4;
3805         switch (value1)
3806         {
3807         case 0: /* No Specifier Type */
3808             /* ES Type */
3809             proto_tree_add_item(nestree, hf_es_value, tvb, ioffset,
3810                                 4, ENC_LITTLE_ENDIAN);
3811             ioffset = ioffset + 4;
3812             break;
3813         case 1: /* Unicode String */
3814             value2 = tvb_get_letohl(tvb, ioffset);   /* Delimiter Set */
3815             ioffset = ioffset + 4;
3816             values->vstring = get_string(tvb, ioffset, value2);
3817             proto_tree_add_string_format(nestree, hf_mv_string, tvb, ioffset,
3818                                          value2, values->vstring, "Delimiter ->%s", values->vstring);
3819             ioffset=ioffset + value2;
3820             ioffset += align_4(tvb, ioffset);
3821             value3 = tvb_get_letohl(tvb, ioffset);
3822             ioffset = ioffset + 4;
3823             values->vstring = get_string(tvb, ioffset, value3);
3824             proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset,
3825                                   value3, values->vstring);
3826             values->voffset=ioffset + value3;
3827             ioffset = values->voffset;
3828             ioffset += align_4(tvb, ioffset);
3829             break;
3830         case 2: /* Based */
3831             break;
3832         case 3: /* Hinted */
3833             break;
3834         case 4: /* Tuned */
3835             /* Count */
3836             proto_tree_add_item_ret_uint(nestree, hf_es_rdn_count, tvb, ioffset,
3837                                 4, ENC_LITTLE_ENDIAN, &value2);
3838             ioffset = ioffset + 4;
3839             for (r = 1 ; r <= value2; r++ )
3840             {
3841                 ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
3842                 ns.nsecs = 0;
3843                 proto_tree_add_time_format(nestree, hf_es_seconds, tvb, ioffset,
3844                                            4, &ns, "Timestamp: %s",
3845                                            abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
3846                 ioffset = ioffset + 4;
3847                 proto_tree_add_item(nestree, hf_nds_replica_num, tvb, ioffset,
3848                                     2, ENC_LITTLE_ENDIAN);
3849                 ioffset = ioffset + 2;
3850                 proto_tree_add_item(nestree, hf_nds_event_num, tvb, ioffset,
3851                                     2, ENC_LITTLE_ENDIAN);
3852                 ioffset = ioffset + 2;
3853             }
3854             value4 = tvb_get_letohl(tvb, ioffset);   /* Delimiter Set */
3855             ioffset = ioffset + 4;
3856             values->vstring = get_string(tvb, ioffset, value4);
3857             proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset,
3858                                   value4, values->vstring);
3859             ioffset=ioffset + value4;
3860             ioffset += align_4(tvb, ioffset);
3861             value5 = tvb_get_letohl(tvb, ioffset);   /* RDN */
3862             ioffset = ioffset + 4;
3863             values->vstring = get_string(tvb, ioffset, value5);
3864             proto_tree_add_string(nestree, hf_rdn_string, tvb, ioffset,
3865                                   value5, values->vstring);
3866             ioffset=ioffset + value5;
3867             ioffset += align_4(tvb, ioffset);
3868             break;
3869         case 5: /* GUID */
3870         case 6: /* ID32 */
3871         case 7: /* Count */
3872         default:
3873             /* ES Type */
3874             /* XXX: nestree rather than estree ?? */
3875             proto_tree_add_item(estree, hf_es_value, tvb, ioffset,
3876                                 4, ENC_LITTLE_ENDIAN);
3877             ioffset = ioffset + 4;
3878             break;
3879         }
3880         break;
3881     case 4: /* Tuned */
3882         value1 = tvb_get_letohl(tvb, ioffset);
3883         sub1item = proto_tree_add_uint_format(estree, hf_es_rdn_count, tvb, ioffset,
3884                                               4, value1, "Number of RDN Items %u", value1);
3885         sub1tree = proto_item_add_subtree(sub1item, ett_nds);
3886         ioffset = ioffset + 4;
3887         for (r = 1 ; r <= value1; r++ )
3888         {
3889             sub2tree = proto_tree_add_subtree_format(sub1tree, tvb, ioffset, 10, ett_nds, NULL, "Item %u", r);
3890
3891             ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
3892             ns.nsecs = 0;
3893             proto_tree_add_time_format(sub2tree, hf_es_seconds, tvb, ioffset,
3894                                        4, &ns, "Timestamp: %s",
3895                                        abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
3896             ioffset = ioffset + 4;
3897             proto_tree_add_item(sub2tree, hf_nds_replica_num, tvb, ioffset,
3898                                 2, ENC_LITTLE_ENDIAN);
3899             ioffset = ioffset + 2;
3900             proto_tree_add_item(sub2tree, hf_nds_event_num, tvb, ioffset,
3901                                 2, ENC_LITTLE_ENDIAN);
3902             ioffset = ioffset + 2;
3903         }
3904         value3 = tvb_get_letohl(tvb, ioffset);   /* Delimiter Set */
3905         ioffset = ioffset + 4;
3906         values->vstring = get_string(tvb, ioffset, value3);
3907         proto_tree_add_string(sub1tree, hf_mv_string, tvb, ioffset,
3908                               value3, values->vstring);
3909         ioffset=ioffset + value3;
3910         ioffset += align_4(tvb, ioffset);
3911         value4 = tvb_get_letohl(tvb, ioffset);   /* RDN */
3912         ioffset = ioffset + 4;
3913         values->vstring = get_string(tvb, ioffset, value4);
3914         proto_tree_add_string(sub1tree, hf_rdn_string, tvb, ioffset,
3915                               value4, values->vstring);
3916         ioffset=ioffset + value4;
3917         ioffset += align_4(tvb, ioffset);
3918         break;
3919     case 5: /* GUID */
3920     case 6: /* ID32 */
3921     case 7: /* Count */
3922     default:
3923         /* ES Type */
3924         proto_tree_add_item(estree, hf_es_value, tvb, ioffset,
3925                             4, ENC_LITTLE_ENDIAN);
3926         ioffset = ioffset + 4;
3927         break;
3928     }
3929     return ioffset;
3930 }
3931
3932
3933 static void process_set_filter(proto_tree* , tvbuff_t*, packet_info*, nds_val*);
3934
3935 static void
3936 process_search_expression(proto_tree *it_tree, tvbuff_t *tvb, nds_val *values)
3937 {
3938     guint32     search_tag, ioffset;
3939     const char *search_string;
3940
3941     ioffset = values->voffset;
3942     search_tag = tvb_get_letohl(tvb, ioffset); /* Get next search operation tag */
3943     search_string = val_to_str_const(search_tag, itersearchenum, "(No Search Operation Type Found!)");
3944     proto_tree_add_uint_format(it_tree, hf_iter_search, tvb, ioffset, 4,
3945                                search_tag, "Search Operation Type: %d, (0x%04x), %s",
3946                                search_tag, search_tag, search_string);
3947     ioffset += 4;
3948     switch (search_tag)
3949     {
3950     case NDS_SEARCH_EQUAL:
3951     case NDS_SEARCH_GREATER_OR_EQUAL:
3952     case NDS_SEARCH_LESS_OR_EQUAL:
3953     case NDS_SEARCH_APPROX:
3954     case NDS_SEARCH_ATTR_FLAGS:
3955     case NDS_SEARCH_ATTR_HAS_FLAG:
3956         /* start of DCWPutAttribute */
3957         values->vvalue = tvb_get_letohl(tvb, ioffset);
3958         ioffset = ioffset + 4;
3959         values->vstring = get_string(tvb, ioffset, values->vvalue);
3960         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
3961                               values->vvalue, values->vstring);
3962         ioffset += values->vvalue;
3963         /* end of DCWPutAttribute */
3964
3965         ioffset += align_4(tvb, ioffset);
3966
3967         /* start of DCWPutValue */
3968         proto_tree_add_item(it_tree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
3969         ioffset = ioffset + 4;
3970         values->vvalue = tvb_get_letohl(tvb, ioffset);
3971         ioffset = ioffset + 4;
3972         values->vstring = get_string(tvb, ioffset, values->vvalue);
3973         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
3974                               values->vvalue, values->vstring);
3975         ioffset += values->vvalue;
3976         /* end of DCWPutValue */
3977
3978         break;
3979     case NDS_SEARCH_PRESENT:
3980         /* start of DCWPutAttribute */
3981         values->vvalue = tvb_get_letohl(tvb, ioffset);
3982         ioffset = ioffset + 4;
3983         values->vstring = get_string(tvb, ioffset, values->vvalue);
3984         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
3985                               values->vvalue, values->vstring);
3986         ioffset = ioffset + values->vvalue;
3987         /* end of DCWPutAttribute */
3988         break;
3989
3990     case NDS_SEARCH_RDN:
3991         /* print the relative distinguished name. This includes context info... */
3992 #if 0
3993         if (err = DCWPutRDN(context, cur, limit, item->data))
3994             return err;
3995 #endif
3996
3997         values->vvalue = tvb_get_letohl(tvb, ioffset);
3998         ioffset = ioffset + 4;
3999         values->vstring = get_string(tvb, ioffset, values->vvalue);
4000         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4001                               values->vvalue, values->vstring);
4002         ioffset += values->vvalue;
4003         break;
4004     case NDS_SEARCH_BASE_CLASS:
4005     case NDS_SEARCH_ENTRY_FLAGS:
4006     case NDS_SEARCH_ENTRY_HAS_FLAG:
4007     case NDS_SEARCH_VALUE_FLAGS:
4008     case NDS_SEARCH_VALUE_HAS_FLAG:
4009         /* start of DCWPutValue */
4010 #if 0
4011         proto_tree_add_item(it_tree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4012         ioffset = ioffset + 4;
4013 #endif
4014         values->vvalue = tvb_get_letohl(tvb, ioffset);
4015         ioffset = ioffset + 4;
4016         values->vstring = get_string(tvb, ioffset, values->vvalue);
4017         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4018                               values->vvalue, values->vstring);
4019         ioffset += values->vvalue;
4020         /* end of DCWPutValue */
4021         break;
4022     case DCS_VALUE_GE_WITH_ATTR:        /* Deprecated, use DS_SEARCH_VALUE_MTS_GE */
4023     case NDS_SEARCH_VALUE_MTS_GE:
4024     case NDS_SEARCH_VALUE_MTS_G:
4025     case NDS_SEARCH_VALUE_MTS_LE:
4026     case NDS_SEARCH_VALUE_MTS_L:
4027     case NDS_SEARCH_VALUE_MTS_EQ:
4028     case NDS_SEARCH_VALUE_MTS_EQ_APPROX:
4029     case NDS_SEARCH_VALUE_CTS_GE:
4030     case NDS_SEARCH_VALUE_CTS_G:
4031     case NDS_SEARCH_VALUE_CTS_LE:
4032     case NDS_SEARCH_VALUE_CTS_L:
4033     case NDS_SEARCH_VALUE_CTS_EQ:
4034     case NDS_SEARCH_VALUE_CTS_EQ_APPROX:
4035         /* start of DCWPutAttribute */
4036         values->vvalue = tvb_get_letohl(tvb, ioffset);
4037         ioffset = ioffset + 4;
4038         values->vstring = get_string(tvb, ioffset, values->vvalue);
4039         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4040                               values->vvalue, values->vstring);
4041         ioffset += values->vvalue;
4042         /* end of DCWPutAttribute */
4043
4044         ioffset += align_4(tvb, ioffset);
4045
4046         /* start of DCWPutValue */
4047         proto_tree_add_item(it_tree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4048         ioffset = ioffset + 4;
4049         values->vvalue = tvb_get_letohl(tvb, ioffset);
4050         ioffset = ioffset + 4;
4051         values->vstring = get_string(tvb, ioffset, values->vvalue);
4052         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4053                               values->vvalue, values->vstring);
4054         ioffset += values->vvalue;
4055         /* end of DCWPutValue */
4056         break;
4057     case DCS_MOD_GE_WITH_ATTR:        /* Deprecated, use DS_SEARCH_ENTRY_MTS */
4058     case NDS_SEARCH_ENTRY_MTS_GE:
4059     case NDS_SEARCH_ENTRY_MTS_G:
4060     case NDS_SEARCH_ENTRY_MTS_LE:
4061     case NDS_SEARCH_ENTRY_MTS_L:
4062     case NDS_SEARCH_ENTRY_MTS_EQ:
4063     case NDS_SEARCH_ENTRY_MTS_EQ_APPROX:
4064     case NDS_SEARCH_ENTRY_CTS_GE:
4065     case NDS_SEARCH_ENTRY_CTS_G:
4066     case NDS_SEARCH_ENTRY_CTS_LE:
4067     case NDS_SEARCH_ENTRY_CTS_L:
4068     case NDS_SEARCH_ENTRY_CTS_EQ:
4069     case NDS_SEARCH_ENTRY_CTS_EQ_APPROX:
4070         /* start of DCWPutAttribute */
4071         values->vvalue = tvb_get_letohl(tvb, ioffset);
4072         ioffset = ioffset + 4;
4073         values->vstring = get_string(tvb, ioffset, values->vvalue);
4074         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4075                               values->vvalue, values->vstring);
4076         ioffset += values->vvalue;
4077         /* end of DCWPutAttribute */
4078
4079         ioffset += align_4(tvb, ioffset);
4080
4081         /* start of DCWPutValue */
4082         proto_tree_add_item(it_tree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4083         ioffset = ioffset + 4;
4084         values->vvalue = tvb_get_letohl(tvb, ioffset);
4085         ioffset = ioffset + 4;
4086         values->vstring = get_string(tvb, ioffset, values->vvalue);
4087         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4088                               values->vvalue, values->vstring);
4089         ioffset += values->vvalue;
4090         /* end of DCWPutValue */
4091
4092         break;
4093     case NDS_SEARCH_EID:
4094     case NDS_SEARCH_ENTRY_SUBCOUNT_GE:
4095     case NDS_SEARCH_ENTRY_SUBCOUNT_G:
4096     case NDS_SEARCH_ENTRY_SUBCOUNT_LE:
4097     case NDS_SEARCH_ENTRY_SUBCOUNT_L:
4098     case NDS_SEARCH_ENTRY_SUBCOUNT_EQ:
4099         /* start of DCWPutValue */
4100         proto_tree_add_item(it_tree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4101         ioffset = ioffset + 4;
4102         values->vvalue = tvb_get_letohl(tvb, ioffset);
4103         ioffset = ioffset + 4;
4104         values->vstring = get_string(tvb, ioffset, values->vvalue);
4105         proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4106                               values->vvalue, values->vstring);
4107         ioffset += values->vvalue;
4108         /* end of DCWPutValue */
4109
4110         break;
4111
4112     default: /* Unknown Iteration search Item type */
4113         if (tvb_captured_length_remaining(tvb, ioffset) < 4) {
4114                 THROW(ReportedBoundsError);
4115         }
4116         break;
4117     }
4118     ioffset += align_4(tvb, ioffset);
4119     values->voffset = ioffset;
4120     return;
4121 }
4122
4123 static void
4124 process_search_subexpression(proto_tree *it_tree, tvbuff_t *tvb, packet_info *pinfo, nds_val *values)
4125 {
4126     proto_tree  *it_subtree, *it_subtree1;
4127     proto_item  *it_subitem;
4128     guint32     i, ioffset, number_of_items;
4129
4130     ioffset = values->voffset;
4131     if (values->vvalue != NDS_SEARCH_NOT) {
4132         number_of_items = tvb_get_letohl(tvb, ioffset);
4133         it_subitem = proto_tree_add_item(it_tree, hf_this_count, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4134         it_subtree = proto_item_add_subtree(it_subitem, ett_nds);
4135         ioffset += 4;
4136         for (i = 0; i < number_of_items; i++)
4137         {
4138             it_subtree1 = proto_tree_add_subtree_format(it_subtree, tvb, ioffset, -1, ett_nds, NULL, "Item #: %u", i+1);
4139
4140             values->voffset = ioffset;
4141             process_set_filter(it_subtree1, tvb, pinfo, values);
4142             ioffset = values->voffset;
4143
4144             if (tvb_captured_length_remaining(tvb, ioffset) < 4) {
4145                 THROW(ReportedBoundsError);
4146                 break;
4147             }
4148
4149         }
4150     }
4151     values->voffset = ioffset;
4152     return;
4153 }
4154
4155 static void
4156 process_search_match(proto_tree *it_tree, tvbuff_t *tvb, nds_val *values)
4157 {
4158     guint32     ioffset;
4159
4160     ioffset = values->voffset;
4161
4162     values->vvalue = tvb_get_letohl(tvb, ioffset);
4163     ioffset += 4;
4164     proto_tree_add_item(it_tree, hf_nds_oid, tvb, ioffset, values->vvalue, ENC_NA);
4165     ioffset += values->vvalue;
4166
4167     ioffset += align_4(tvb, ioffset);
4168
4169     proto_tree_add_item(it_tree, hf_iter_ans, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4170     ioffset += 4;
4171
4172     ioffset += align_4(tvb, ioffset);
4173
4174     /* start of DCWPutAttribute */
4175     values->vvalue = tvb_get_letohl(tvb, ioffset);
4176     ioffset = ioffset + 4;
4177     values->vstring = get_string(tvb, ioffset, values->vvalue);
4178     proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4179             values->vvalue, values->vstring);
4180     ioffset = ioffset + values->vvalue;
4181     /* end of DCWPutAttribute */
4182
4183     ioffset += align_4(tvb, ioffset);
4184
4185     /* start of DCWPutValue */
4186     proto_tree_add_item(it_tree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4187     ioffset = ioffset + 4;
4188     values->vvalue = tvb_get_letohl(tvb, ioffset);
4189     ioffset = ioffset + 4;
4190     values->vstring = get_string(tvb, ioffset, values->vvalue);
4191     proto_tree_add_string(it_tree, hf_mv_string, tvb, ioffset,
4192                           values->vvalue, values->vstring);
4193     ioffset += values->vvalue;
4194     /* end of DCWPutValue */
4195
4196     ioffset += align_4(tvb, ioffset);
4197
4198     values->voffset = ioffset;
4199     return;
4200 }
4201
4202 static void
4203 process_set_filter(proto_tree *it_tree, tvbuff_t *tvb, packet_info *pinfo, nds_val *values)
4204 {
4205     guint32     search_tag, ioffset = values->voffset;
4206     const char *search_string;
4207
4208     search_tag = tvb_get_letohl(tvb, ioffset);
4209     search_string = val_to_str_const(search_tag, itersearchenum, "(No Search Tag Found)");
4210     proto_tree_add_uint_format(it_tree, hf_iter_search, tvb, ioffset, 4,
4211         search_tag, "Type of Search: Tag = %d, (0x%04x), %s",
4212         search_tag, search_tag, search_string);
4213     ioffset += 4;
4214     values->voffset = ioffset;
4215
4216     switch (search_tag)
4217     {
4218     case NDS_SEARCH_ITEM:
4219         /* DCWPutSearchExp */
4220         process_search_expression(it_tree, tvb, values);
4221         break;
4222
4223     case NDS_SEARCH_EXTENSIBLE:
4224 #if 0
4225         err = DCWPutSearchExtMatch(context, syncFormat, cur, limit, sexp->u.extMatch);
4226 #endif
4227         process_search_match(it_tree, tvb, values);
4228         break;
4229
4230     case NDS_SEARCH_OR:
4231     case NDS_SEARCH_AND:
4232     case NDS_SEARCH_NOT:
4233         /* DCWPutSearchSubExp = process_search_subexpression */
4234         process_search_subexpression(it_tree, tvb, pinfo, values);
4235         break;
4236     default: /* Unknown Iteration search type */
4237         if (tvb_captured_length_remaining(tvb, ioffset) < 4) {
4238             THROW(ReportedBoundsError);
4239         }
4240         break;
4241     }
4242     /*ioffset = values->voffset;*/
4243     return;
4244 }
4245
4246 static void
4247 process_entry_info(proto_tree *it_tree, tvbuff_t *tvb, nds_val *values)
4248 {
4249     guint32     iter_flags, ioffset = values->voffset;
4250     nstime_t    ns;
4251
4252     values->vstring = NULL;
4253     ioffset += align_4(tvb, ioffset);
4254     iter_flags = tvb_get_letohl(tvb, ioffset);
4255
4256
4257     if (iter_flags & DSI_OUTPUT_FIELDS) { /* Output Flags */
4258         proto_tree_add_bitmask(it_tree, tvb, ioffset, hf_retinfoflagsl, ett_ncp, ncp_infoflagsl, ENC_LITTLE_ENDIAN);
4259         ioffset = ioffset+2;
4260         proto_tree_add_bitmask(it_tree, tvb, ioffset, hf_retinfoflagsh, ett_ncp, ncp_retinfoflagsh, ENC_LITTLE_ENDIAN);
4261         ioffset = ioffset+2;
4262     }
4263     if (iter_flags & DSI_ENTRY_ID) { /* Entry ID */
4264         values->vvalue = tvb_get_letohl(tvb, ioffset);
4265         proto_tree_add_uint_format(it_tree, hf_nds_eid, tvb, ioffset,
4266                 4, values->vvalue, "Entry ID 0x%08x", values->vvalue);
4267         ioffset = ioffset + 4;
4268     }
4269     if (iter_flags & DSI_ENTRY_FLAGS) { /* Entry Flags */
4270         proto_tree_add_bitmask(it_tree, tvb, ioffset, hf_eflags, ett_ncp, ncp_eflags, ENC_LITTLE_ENDIAN);
4271         ioffset = ioffset+4;
4272     }
4273     if (iter_flags & DSI_SUBORDINATE_COUNT) { /* Subordinate Count */
4274         proto_tree_add_item(it_tree, hf_sub_count, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4275         ioffset += 4;
4276     }
4277     if (iter_flags & DSI_MODIFICATION_TIME) { /* Modification Time */
4278         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
4279         ns.nsecs = 0;
4280         proto_tree_add_time_format(it_tree, hf_es_seconds, tvb, ioffset,
4281                 4, &ns, "Modification Time: %s",
4282                 abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
4283         ioffset = ioffset + 4;
4284     }
4285     if (iter_flags & DSI_MODIFICATION_TIMESTAMP) { /* Modification Timestamp */
4286         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
4287         ns.nsecs = 0;
4288         proto_tree_add_time_format(it_tree, hf_es_seconds, tvb, ioffset,
4289                 4, &ns, "Modification Timestamp: %s",
4290                 abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
4291         ioffset = ioffset + 4;
4292         proto_tree_add_item(it_tree, hf_nds_replica_num, tvb, ioffset,
4293                 2, ENC_LITTLE_ENDIAN);
4294         ioffset = ioffset + 2;
4295         proto_tree_add_item(it_tree, hf_nds_event_num, tvb, ioffset,
4296                 2, ENC_LITTLE_ENDIAN);
4297         ioffset = ioffset + 2;
4298     }
4299     if (iter_flags & DSI_CREATION_TIMESTAMP) { /* Creation Timestamp */
4300         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
4301         ns.nsecs = 0;
4302         proto_tree_add_time_format(it_tree, hf_es_seconds, tvb, ioffset,
4303                 4, &ns, "Creation Timestamp: %s",
4304                 abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
4305         ioffset = ioffset + 4;
4306         proto_tree_add_item(it_tree, hf_nds_replica_num, tvb, ioffset,
4307                 2, ENC_LITTLE_ENDIAN);
4308         ioffset = ioffset + 2;
4309         proto_tree_add_item(it_tree, hf_nds_event_num, tvb, ioffset,
4310                 2, ENC_LITTLE_ENDIAN);
4311         ioffset = ioffset + 2;
4312     }
4313     if (iter_flags & DSI_PARTITION_ROOT_ID) { /* Partition Root ID */
4314         values->vvalue = tvb_get_letohl(tvb, ioffset);
4315         proto_tree_add_uint_format(it_tree, hf_nds_local_partition, tvb, ioffset,
4316                 4, values->vvalue, "Partition Root ID %08x", values->vvalue);
4317         ioffset = ioffset + 4;
4318     }
4319     if (iter_flags & DSI_PARENT_ID) { /* Parent ID */
4320         values->vvalue = tvb_get_letohl(tvb, ioffset);
4321         proto_tree_add_uint_format(it_tree, hf_nds_local_partition, tvb, ioffset,
4322                 4, values->vvalue, "Parent ID %08x", values->vvalue);
4323         ioffset = ioffset + 4;
4324     }
4325     if (iter_flags & DSI_REVISION_COUNT) { /* Revision Count */
4326         values->vvalue = tvb_get_letohl(tvb, ioffset);
4327         proto_tree_add_uint_format(it_tree, hf_nds_local_partition, tvb, ioffset,
4328                 4, values->vvalue, "Revision count %08x", values->vvalue);
4329         ioffset = ioffset + 4;
4330     }
4331     if (iter_flags & DSI_REPLICA_TYPE) { /* Replica Type */
4332         values->vvalue = tvb_get_letohl(tvb, ioffset) & 0x00ff;
4333         proto_tree_add_uint(it_tree, hf_replica_type, tvb, ioffset, 4, values->vvalue);
4334         values->vvalue = tvb_get_letohl(tvb, ioffset) & 0xff00;
4335         proto_tree_add_uint(it_tree, hf_replica_state, tvb, ioffset, 4, values->vvalue);
4336         ioffset = ioffset + 4;
4337     }
4338     if (iter_flags & DSI_BASE_CLASS) { /* Base Class */
4339         values->vvalue = tvb_get_letohl(tvb, ioffset);         /* Length of string */
4340         ioffset = ioffset+4;
4341         values->vstring = get_string(tvb, ioffset, values->vvalue);
4342         proto_tree_add_string_format(it_tree, hf_value_string, tvb, ioffset,
4343                 values->vvalue, values->vstring,
4344                 "Base Class: - %s", values->vstring);
4345         ioffset = ioffset+values->vvalue;
4346         ioffset += align_4(tvb, ioffset);
4347     }
4348     if (iter_flags & DSI_ENTRY_RDN) { /* Relative Distinguished Name */
4349         values->vvalue = tvb_get_letohl(tvb, ioffset);         /* Length of string */
4350         ioffset = ioffset+4;
4351         values->vstring = get_string(tvb, ioffset, values->vvalue);
4352         proto_tree_add_string_format(it_tree, hf_value_string, tvb, ioffset,
4353                  values->vvalue, values->vstring,
4354                  "Relative Distinguished Name - %s", values->vstring);
4355         ioffset = ioffset+values->vvalue;
4356         ioffset += align_4(tvb, ioffset);
4357     }
4358     if (iter_flags & DSI_ENTRY_DN) { /* Distinguished Name */
4359         values->vvalue = tvb_get_letohl(tvb, ioffset);         /* Length of string */
4360         ioffset = ioffset+4;
4361         values->vstring = get_string(tvb, ioffset, values->vvalue);
4362         proto_tree_add_string_format(it_tree, hf_value_string, tvb, ioffset,
4363                  values->vvalue, values->vstring,
4364                  "Distinguished Name - %s", values->vstring);
4365         ioffset = ioffset+values->vvalue;
4366         ioffset += align_4(tvb, ioffset);
4367     }
4368     if (iter_flags & DSI_PARTITION_ROOT_DN) { /* Root Distinguished Name */
4369         values->vvalue = tvb_get_letohl(tvb, ioffset);         /* Length of string */
4370         ioffset = ioffset+4;
4371         values->vstring = get_string(tvb, ioffset, values->vvalue);
4372         proto_tree_add_string_format(it_tree, hf_value_string, tvb, ioffset,
4373                  values->vvalue, values->vstring,
4374                  "Root Distinguished Name - %s", values->vstring);
4375         ioffset = ioffset+values->vvalue;
4376         ioffset += align_4(tvb, ioffset);
4377     }
4378     if (iter_flags & DSI_PARENT_DN) { /* Parent Distinguished Name */
4379         values->vvalue = tvb_get_letohl(tvb, ioffset);         /* Length of string */
4380         ioffset = ioffset+4;
4381         values->vstring = get_string(tvb, ioffset, values->vvalue);
4382         proto_tree_add_string_format(it_tree, hf_value_string, tvb, ioffset,
4383                  values->vvalue, values->vstring,
4384                  "Parent Distinguished Name - %s", values->vstring);
4385         ioffset = ioffset+values->vvalue;
4386         ioffset += align_4(tvb, ioffset);
4387     }
4388     if (iter_flags & DSI_PURGE_TIME) { /* Purge Time */
4389         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
4390         ns.nsecs = 0;
4391         proto_tree_add_time(it_tree, hf_nds_purge, tvb, ioffset, 4, &ns);
4392         ioffset = ioffset + 4;
4393     }
4394     if (iter_flags & DSI_DEREFERENCED_BASE_CLASS) { /* Dereference Base Class */
4395         values->vvalue = tvb_get_letohl(tvb, ioffset);
4396         ioffset = ioffset + 4;
4397         values->vstring = get_string(tvb, ioffset, values->vvalue);
4398         proto_tree_add_string(it_tree, hf_deref_base, tvb, ioffset,
4399                 values->vvalue, values->vstring);
4400         ioffset = ioffset + values->vvalue;
4401     }
4402     if (iter_flags & DSI_REPLICA_NUMBER) { /* Replica Number */
4403         proto_tree_add_item_ret_uint(it_tree, hf_replica_number, tvb, ioffset,
4404                  4, ENC_LITTLE_ENDIAN, &values->vvalue);
4405         ioffset = ioffset+4;
4406     }
4407     if (iter_flags & DSI_REPLICA_STATE) { /* Replica State */
4408         values->vvalue = tvb_get_letohl(tvb, ioffset) & 0xff00;
4409         values->vstring = val_to_str_const(values->vvalue, nds_replica_state, "No Replica State Found");
4410         proto_tree_add_uint(it_tree, hf_replica_state, tvb, ioffset, 4, values->vvalue);
4411         ioffset = ioffset + 2;
4412     }
4413     if (iter_flags & DSI_FEDERATION_BOUNDARY) { /* Federation Boundary */
4414         values->vvalue = tvb_get_letohl(tvb, ioffset);
4415         proto_tree_add_uint_format(it_tree, hf_nds_uint32value, tvb, ioffset,
4416                 4, values->vvalue, "Federation Boundary %d", values->vvalue);
4417         ioffset = ioffset+4;
4418     }
4419     if (iter_flags & DSI_SCHEMA_BOUNDARY) { /* Schema Boundary */
4420         values->vvalue = tvb_get_letohl(tvb, ioffset);
4421         proto_tree_add_uint_format(it_tree, hf_nds_uint32value, tvb, ioffset,
4422                 4, values->vvalue, "Schema Boundary %d", values->vvalue);
4423         ioffset = ioffset+4;
4424     }
4425     if (iter_flags & DSI_FEDERATION_BOUNDARY_ID) { /* Federation Boundary ID */
4426         values->vvalue = tvb_get_letohl(tvb, ioffset);
4427         proto_tree_add_uint_format(it_tree, hf_nds_uint32value, tvb, ioffset,
4428                 4, values->vvalue, "Federation Boundary ID %d", values->vvalue);
4429         ioffset = ioffset+4;
4430     }
4431     if (iter_flags & DSI_SCHEMA_BOUNDARY_ID) { /* Schema Boundary ID*/
4432         values->vvalue = tvb_get_letohl(tvb, ioffset);
4433         proto_tree_add_uint_format(it_tree, hf_nds_uint32value, tvb, ioffset,
4434                 4, values->vvalue, "Schema Boundary ID %d", values->vvalue);
4435         ioffset = ioffset+4;
4436     }
4437     if (iter_flags & DSI_CUR_SUBCOUNT) { /* Current Subcount */
4438         values->vvalue = tvb_get_letohl(tvb, ioffset);
4439         proto_tree_add_uint_format(it_tree, hf_nds_uint32value, tvb, ioffset,
4440                 4, values->vvalue, "Current Subcount %d", values->vvalue);
4441         ioffset = ioffset+4;
4442     }
4443     if (iter_flags & DSI_LOCAL_ENTRY_FLAGS) { /* Local Entry Flags */
4444         proto_tree_add_bitmask(it_tree, tvb, ioffset, hf_eflags, ett_ncp, ncp_eflags, ENC_LITTLE_ENDIAN);
4445         ioffset = ioffset+4;
4446     }
4447     values->voffset = ioffset;
4448     return;
4449 }
4450
4451 static void
4452 dissect_nds_iterator(proto_tree *it_tree, tvbuff_t *tvb, packet_info *pinfo, guint32 it_verb, guint32 request_flags, guint32 ioffset, gboolean request_reply)
4453 {
4454     guint32     rcode, i, number_of_items, number_to_get;
4455     const char  *error_string;
4456     nds_val     values;
4457     proto_tree  *it_subtree, *it_subtree1;
4458     proto_item  *it_subitem;
4459     proto_item  *expert_item;
4460
4461     values.vtype = 0;
4462     values.vvalue = 0;
4463     values.vlength = 0;
4464     values.voffset = 0;
4465     values.hfname = 0;
4466     values.vdesc = "";
4467     values.vstring = NULL;
4468     values.mvtype = 0;
4469     values.vflags = 0;
4470
4471
4472     while (TRUE) {
4473         it_subitem = proto_tree_add_uint(it_tree, hf_ncp_nds_iterverb, tvb, ioffset-4, 4, it_verb);
4474
4475         it_subtree = proto_item_add_subtree(it_subitem, ett_nds);
4476
4477         if (request_reply) { /* Request packets */
4478             switch (it_verb) {
4479             case IT_ATFIRST:
4480             case IT_ATEOF:
4481             case IT_ATLAST:
4482             case IT_ATBOF:
4483             case IT_CLEAR:
4484             case IT_COPY:
4485                 break;
4486             case IT_COUNT:
4487                 proto_tree_add_item(it_subtree, hf_timelimit, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4488                 ioffset += 4;
4489                 proto_tree_add_item(it_subtree, hf_max_entries, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4490                 ioffset += 4;
4491                 proto_tree_add_item(it_subtree, hf_move_position, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4492                 ioffset += 4;
4493                 break;
4494             case IT_CREATE:
4495             case IT_CURRENT:
4496             case IT_DESTROY:
4497             case IT_DONE:
4498                 break;
4499             case IT_FIRST:
4500                 proto_tree_add_item(it_subtree, hf_timelimit, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4501                 ioffset += 4;
4502                 break;
4503             case IT_GETPOSITION:
4504             case IT_ISPOSITIONABLE:
4505                 break;
4506             case IT_LAST:
4507                 proto_tree_add_item(it_subtree, hf_timelimit, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4508                 ioffset += 4;
4509                 break;
4510             case IT_NEXT:
4511             case IT_PREV:
4512                 proto_tree_add_item(it_subtree, hf_timelimit, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4513                 ioffset += 4;
4514                 proto_tree_add_item(it_subtree, hf_num_to_get, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4515                 ioffset += 4;
4516                 break;
4517             case IT_POSITION:
4518                 proto_tree_add_item(it_subtree, hf_iter_position, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4519                 ioffset += 4;
4520                 proto_tree_add_item(it_subtree, hf_timelimit, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4521                 ioffset += 4;
4522                 break;
4523             case IT_POSITION_IT:
4524                 proto_tree_add_item(it_subtree, hf_iter_other, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4525                 ioffset += 4;
4526                 break;
4527             case IT_SETINDEX:
4528                 proto_tree_add_item(it_subtree, hf_nds_number_of_items, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4529                 number_of_items = tvb_get_letohl(tvb, ioffset);
4530                 ioffset += 4;
4531                 for (i=0; i < number_of_items; i++) {
4532                     /* Process the attribute tag */
4533 #if 0
4534                     proto_tree_add_item(it_subtree, hf_nds_tag_string, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4535 #endif
4536                     proto_tree_add_item(it_subtree, hf_iter_index, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4537                     ioffset = ioffset + 4;
4538
4539                     /* start of DCWPutAttribute */
4540 #if 0
4541                     values.vvalue = tvb_get_letohl(tvb, ioffset);
4542                     ioffset = ioffset + 4;
4543                     values.vstring = get_string(tvb, ioffset, values.vvalue);
4544                     proto_tree_add_string(it_subtree, hf_mv_string, tvb, ioffset,
4545                             values.vvalue, values.vstring);
4546                     ioffset = ioffset + values.vvalue;
4547 #endif
4548                     /* end of DCWPutAttribute */
4549
4550 #if 0
4551                     ioffset += align_4(tvb, ioffset);
4552 #endif
4553                     if (tvb_captured_length_remaining(tvb, ioffset) < 4) {
4554                         THROW(ReportedBoundsError);
4555                         return;
4556                     }
4557                 }
4558                 break;
4559             case IT_SETFILTER:
4560
4561                 values.voffset = ioffset;
4562
4563                 /* DCWPutSearchExp  = process_set_filter() */
4564                 process_set_filter(it_subtree, tvb, pinfo, &values);
4565
4566                 ioffset = values.voffset;
4567                 ioffset += align_4(tvb, ioffset);
4568                 break;
4569             case IT_SKIP:
4570                 proto_tree_add_item(it_subtree, hf_timelimit, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4571                 ioffset += 4;
4572                 proto_tree_add_item(it_subtree, hf_num_to_skip, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4573                 ioffset += 4;
4574                 break;
4575             case IT_TYPEDOWN:
4576                 proto_tree_add_item(it_subtree, hf_num_to_get, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4577                 number_to_get = tvb_get_letohl(tvb, ioffset);
4578                 ioffset += 4;
4579                 if (number_to_get == 0) {
4580                     proto_tree_add_item(it_tree, hf_nds_tag_string, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4581                     ioffset = ioffset + 4;
4582
4583                 }
4584                 values.vvalue = tvb_get_letohl(tvb, ioffset);
4585                 ioffset = ioffset + 4;
4586                 values.vstring = get_string(tvb, ioffset, values.vvalue);
4587                 proto_tree_add_string(it_subtree, hf_mv_string, tvb, ioffset,
4588                         values.vvalue, values.vstring);
4589                 ioffset = ioffset + values.vvalue;
4590                 ioffset += align_4(tvb, ioffset);
4591                 break;
4592             default:
4593                 if (tvb_captured_length_remaining(tvb, ioffset) < 4) {
4594                     THROW(ReportedBoundsError);
4595                 }
4596                 return;
4597             }
4598         }
4599         else    /* Reply Packets */
4600         {                                           /* All replies include a completion code first */
4601             expert_item = proto_tree_add_item_ret_uint(it_subtree, hf_iter_verb_completion_code, tvb, ioffset,
4602                     4, ENC_LITTLE_ENDIAN, &rcode);
4603             error_string = val_to_str_const(rcode, nds_reply_errors, "Unknown Interation Verb Completion Code");
4604
4605             if (rcode != 0 && ncp_echo_err) {
4606                 expert_add_info_format(pinfo, expert_item, &ei_iter_verb_completion_code, "Iteration Verb Error: 0x%08x %s", rcode, error_string);
4607             }
4608             ioffset += 4;
4609
4610             switch (it_verb) {
4611             case IT_ATFIRST:
4612             case IT_ATEOF:
4613             case IT_ATLAST:
4614             case IT_ATBOF:
4615                 proto_tree_add_item(it_subtree, hf_iter_ans, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4616                 ioffset += 4;
4617                 break;
4618             case IT_CLEAR:
4619                 break;
4620             case IT_COPY:
4621                 proto_tree_add_item(it_subtree, hf_iter_copy, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4622                 ioffset += 4;
4623                 break;
4624             case IT_COUNT:
4625                 proto_tree_add_item(it_subtree, hf_this_count, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4626                 ioffset += 4;
4627                 break;
4628             case IT_CREATE:
4629                 proto_tree_add_item(it_subtree, hf_nds_iterator, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4630                 ioffset += 4;
4631                 break;
4632             case IT_CURRENT:
4633             case IT_NEXT:
4634             case IT_PREV:
4635             case IT_FIRST:
4636             case IT_LAST:
4637                 proto_tree_add_item(it_subtree, hf_nds_info_type, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4638                 ioffset = ioffset + 4;
4639                 proto_tree_add_item(it_subtree, hf_data_size, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4640                 ioffset += 4;
4641                 number_of_items = tvb_get_letohl(tvb, ioffset);
4642                 proto_tree_add_item(it_subtree, hf_this_count, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4643                 ioffset += 4;
4644                 for (i = 0; i < number_of_items; i++)
4645                 {
4646                     it_subtree1 = proto_tree_add_subtree_format(it_subtree, tvb, ioffset, -1, ett_nds, NULL, "Item #: %u", i+1);
4647
4648                     ioffset += align_4(tvb, ioffset);
4649
4650                     /* Start WGetAndBufferEntryInfo = process_entry_info() */
4651                     values.voffset = ioffset;
4652                     values.vflags = request_flags;
4653                     process_entry_info(it_subtree1, tvb, &values);
4654                     ioffset = values.voffset;
4655                     /* End WGetAndBufferEntryInfo */
4656
4657                     ioffset += align_4(tvb, ioffset);
4658
4659                     /* WGetReadBuffer - This seems to be a count and then size field (2 * guint32) */
4660                     /* For now we will just skip this offset. NEED TO ADD LOGIC TO HANDLE */
4661                     ioffset += 8;
4662
4663                     if (tvb_captured_length_remaining(tvb, ioffset) < 4) {
4664                         break;
4665                     }
4666                 }
4667                 break;
4668             case IT_DESTROY:
4669             case IT_DONE:
4670                 break;
4671             case IT_GETPOSITION:
4672                 proto_tree_add_item(it_subtree, hf_iter_position, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4673                 ioffset += 4;
4674                 break;
4675             case IT_ISPOSITIONABLE:
4676                 proto_tree_add_item(it_subtree, hf_positionable, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4677                 ioffset += 4;
4678                 break;
4679             case IT_POSITION:
4680             case IT_POSITION_IT:
4681             case IT_SETFILTER:
4682             case IT_TYPEDOWN:
4683                 break;
4684             case IT_SETINDEX:
4685                 proto_tree_add_item(it_subtree, hf_iter_index, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4686                 ioffset += 4;
4687                 break;
4688             case IT_SKIP:
4689                 proto_tree_add_item(it_subtree, hf_num_skipped, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4690                 ioffset += 4;
4691                 break;
4692             default:
4693                 if (tvb_captured_length_remaining(tvb, ioffset) < 4) {
4694                     THROW(ReportedBoundsError);
4695                 }
4696                 return;
4697             }
4698         }
4699         it_verb = tvb_get_letohl(tvb, ioffset);
4700         ioffset += 4;
4701         if (it_verb == IT_DONE || tvb_captured_length_remaining(tvb, ioffset) < 4) {
4702             proto_tree_add_uint(it_tree, hf_ncp_nds_iterverb, tvb, ioffset-4, 4, it_verb);
4703             break;
4704         }
4705     }
4706     return;
4707 }
4708
4709
4710 static void
4711 process_multivalues(proto_tree *ncp_tree, tvbuff_t *tvb, packet_info *pinfo, nds_val *values)
4712 {
4713     guint32         i;
4714     guint32         r;
4715     guint32         ioffset = 0, oldioffset;
4716     guint32         value1 = 0;
4717     guint32         value2 = 0;
4718     guint8          value3 = 0;
4719     guint32         value4 = 0;
4720     gint            value5 = 0;
4721     guint32         value6 = 0;
4722     guint32         value7 = 0;
4723     const char      *valuestr = "";
4724     proto_tree      *ntree;
4725     proto_tree      *atree;
4726     proto_item      *nitem;
4727     proto_item      *aitem;
4728     guint32         number_of_referrals = 0;
4729     proto_tree      *estree;
4730     proto_item      *esitem;
4731     guint32         bvalue=0;
4732     nds_val         temp_values;
4733     proto_tree      *sub1tree;
4734     proto_item      *sub1item;
4735     proto_tree      *sub2tree;
4736     proto_item      *sub2item;
4737     gint            length_remaining;
4738     nstime_t        ns;
4739
4740     mv_resolve_name_string[0] = '\0';
4741     values->vstring = "";
4742
4743     /* Is the value passed a string or UINT32? */
4744     if(values->mvtype != MVTYPE_LIST_PARTITIONS && values->mvtype != MVTYPE_PROCESS_TAGS)
4745     {
4746         nitem = proto_tree_add_uint_format(ncp_tree, values->hfname, tvb, values->voffset+ioffset,
4747                                            values->vlength, values->vvalue, values->vdesc, values->vvalue);
4748     }
4749     else
4750     {
4751         nitem = proto_tree_add_string_format(ncp_tree, values->hfname, tvb, values->voffset+ioffset,
4752                                              values->vlength, values->vdesc, "%s", values->vdesc);
4753     }
4754     ioffset = (values->voffset+4);
4755
4756     ntree = proto_item_add_subtree(nitem, ett_nds);
4757
4758     switch (values->mvtype)
4759     {
4760     case MVTYPE_ATTR_REQUEST:   /* Attribute Request */
4761         for (i = 1 ; i <= values->vvalue; i++ )
4762         {
4763             ioffset += align_4(tvb, ioffset);
4764             value1 = tvb_get_letohl(tvb, ioffset);
4765             ioffset = ioffset + 4;
4766             values->vstring = get_string(tvb, ioffset, value1);
4767             proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
4768                                   value1, values->vstring);
4769             ioffset = ioffset + value1;
4770         }
4771         break;
4772
4773     case MVTYPE_ATTR_REPLY:     /* Attribute Reply */
4774         switch(values->vflags)
4775         {
4776         case 0:
4777             for (i = 1 ; i <= values->vvalue; i++ )
4778             {
4779                 ioffset += align_4(tvb, ioffset);
4780                 value1 = tvb_get_letohl(tvb, ioffset);
4781                 ioffset = ioffset + 4;
4782                 values->vstring = get_string(tvb, ioffset, value1);
4783                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
4784                                       value1, values->vstring);
4785                 ioffset = ioffset + value1;
4786             }
4787             break;
4788         case 1:
4789             for (i = 1 ; i <= values->vvalue; i++ )
4790             {
4791                 proto_tree_add_item(ntree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4792                 ioffset = ioffset + 4;
4793                 value2 = tvb_get_letohl(tvb, ioffset);
4794                 ioffset = ioffset + 4;
4795                 values->vstring = get_string(tvb, ioffset, value2);
4796                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
4797                                       value2, values->vstring);
4798                 ioffset += value2;
4799                 ioffset += align_4(tvb, ioffset);
4800                 values->voffset = ioffset;
4801
4802                 print_nds_values(ntree, pinfo, tvb, value1, values);
4803                 ioffset = values->voffset;
4804             }
4805             break;
4806         case 2:
4807             for (i = 1 ; i <= values->vvalue; i++ )
4808             {
4809                 proto_tree_add_item(ntree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4810                 ioffset = ioffset + 4;
4811                 value2 = tvb_get_letohl(tvb, ioffset);
4812                 ioffset = ioffset + 4;
4813                 values->vstring = get_string(tvb, ioffset, value2);
4814                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
4815                                       value2, values->vstring);
4816                 values->voffset=ioffset + value2;
4817                 ioffset += value2;
4818                 ioffset += align_4(tvb, ioffset);
4819                 value3 = tvb_get_letohl(tvb, ioffset);
4820
4821                 proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, 4,
4822                                            value3, "Number of Values - %u", value3);
4823
4824                 ioffset = ioffset + 4;
4825                 for (r = 1 ; r <= value3; r++ )
4826                 {
4827                     ioffset += 4;   /* Length = 4 */
4828                     proto_tree_add_item(ntree, hf_nds_privileges, tvb, ioffset,
4829                                         values->vlength, ENC_LITTLE_ENDIAN);
4830
4831                     ioffset = ioffset+4;
4832                 }
4833             }
4834             break;
4835         case 3:
4836             for (i = 1 ; i <= values->vvalue; i++ )
4837             {
4838                 proto_tree_add_item(ntree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4839                 ioffset = ioffset + 4;
4840                 value2 = tvb_get_letohl(tvb, ioffset);
4841                 ioffset = ioffset + 4;
4842                 values->vstring = get_string(tvb, ioffset, value2);
4843                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
4844                                       value2, values->vstring);
4845                 ioffset = ioffset + value2;
4846                 ioffset += align_4(tvb, ioffset);
4847                 value3 = tvb_get_letohl(tvb, ioffset);
4848
4849                 aitem = proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, 4,
4850                                                    value3, "Number of Values - %u", value3);
4851
4852                 atree = proto_item_add_subtree(aitem, ett_nds);
4853
4854                 ioffset = ioffset + 4;
4855                 for (r = 1 ; r <= value3; r++ )
4856                 {
4857                     ioffset += align_4(tvb, ioffset);
4858                     proto_tree_add_bitmask(atree, tvb, ioffset, hf_vflags, ett_ncp, ncp_vflags, ENC_LITTLE_ENDIAN);
4859                     ioffset = ioffset + 4;
4860                     ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
4861                     ns.nsecs = 0;
4862                     proto_tree_add_time_format(atree, hf_es_seconds, tvb, ioffset,
4863                                                4, &ns, "Timestamp: %s",
4864                                                abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
4865                     ioffset = ioffset + 4;
4866                     proto_tree_add_item(atree, hf_nds_replica_num, tvb, ioffset,
4867                                         2, ENC_LITTLE_ENDIAN);
4868                     ioffset = ioffset + 2;
4869                     proto_tree_add_item(atree, hf_nds_event_num, tvb, ioffset,
4870                                         2, ENC_LITTLE_ENDIAN);
4871                     ioffset = ioffset + 2;
4872                     value5 = tvb_get_letohl(tvb, ioffset); /* length of field */
4873                     if(value5 > tvb_captured_length_remaining(tvb, ioffset))
4874                     {
4875                         break;
4876                     }
4877                     ioffset += 4;
4878                     proto_tree_add_item(atree, hf_value_bytes, tvb, ioffset, value5, ENC_NA);
4879                     ioffset += value5;
4880                     ioffset += (value5%2);
4881                 }
4882             }
4883             break;
4884         case 4:
4885             for (i = 1 ; i <= values->vvalue; i++ )
4886             {
4887                 proto_tree_add_item(ntree, hf_nds_syntax, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
4888                 ioffset = ioffset + 4;
4889                 value2 = tvb_get_letohl(tvb, ioffset);
4890                 ioffset = ioffset + 4;
4891                 values->vstring = get_string(tvb, ioffset, value2);
4892                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
4893                                       value2, values->vstring);
4894                 ioffset = ioffset + value2;
4895                 value3 = tvb_get_letohl(tvb, ioffset);
4896
4897                 proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, 4,
4898                                            value3, "Number of Values - %u", value3);
4899
4900                 ioffset = ioffset + 4;
4901                 for (r = 1 ; r <= value3; r++ )
4902                 {
4903                     ioffset += align_4(tvb, ioffset);
4904                     proto_tree_add_bitmask(ntree, tvb, ioffset, hf_vflags, ett_ncp, ncp_vflags, ENC_LITTLE_ENDIAN);
4905                     ioffset = ioffset + 4;
4906                     ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
4907                     ns.nsecs = 0;
4908                     proto_tree_add_time_format(ntree, hf_es_seconds, tvb, ioffset,
4909                                                4, &ns, "Creation Time: %s",
4910                                                abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
4911                     ioffset = ioffset + 4;
4912                     proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset,
4913                                         2, ENC_LITTLE_ENDIAN);
4914                     ioffset = ioffset + 2;
4915                     proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset,
4916                                         2, ENC_LITTLE_ENDIAN);
4917                     ioffset = ioffset + 2;
4918                     proto_tree_add_item(ntree, hf_nds_value_len, tvb, ioffset,
4919                                         4, ENC_LITTLE_ENDIAN);
4920                     ioffset = ioffset + 4;
4921                 }
4922             }
4923             break;
4924         default:
4925             break;
4926         }
4927         break;
4928
4929     case MVTYPE_ATTR_REQUEST2:    /* Attribute Request */
4930         oldioffset = 0;
4931         for (i = 1 ; i <= values->vvalue; i++ )
4932         {
4933             if (oldioffset >= ioffset) {
4934                 proto_tree_add_expert_format(ntree, pinfo, &ei_ncp_invalid_offset, tvb, 0, 0, "Invalid offset: %u", ioffset);
4935                 THROW(ReportedBoundsError);
4936             }
4937             oldioffset = ioffset;
4938             ioffset += align_4(tvb, ioffset);
4939             value1 = tvb_get_letohl(tvb, ioffset);
4940             proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset,
4941                                        4, value1, "Value %d", value1);
4942             ioffset = ioffset + value1;
4943         }
4944         break;
4945
4946     case MVTYPE_ADD_ATTR_REQUEST: /* Add Attribute Request */
4947         for (i = 1 ; i <= values->vvalue; i++ )
4948         {
4949             value1 = tvb_get_letohl(tvb, ioffset);
4950             ioffset = ioffset + 4;
4951             values->vstring = get_string(tvb, ioffset, value1);
4952             proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
4953                                   value1, values->vstring);
4954             ioffset = ioffset + value1;
4955             ioffset += align_4(tvb, ioffset);
4956             values->voffset = ioffset;
4957             print_nds_values(ntree, pinfo, tvb, 9, values);
4958             ioffset = values->voffset;
4959         }
4960         break;
4961
4962     case MVTYPE_READ_CLASS_REQ:   /* Read Class Request */
4963         for (i = 1 ; i <= values->vvalue; i++ )
4964         {
4965             ioffset += align_4(tvb, ioffset);
4966             value1 = tvb_get_letohl(tvb, ioffset);
4967             ioffset = ioffset + 4;
4968             values->vstring = get_string(tvb, ioffset, value1);
4969             proto_tree_add_string(ntree, hf_nds_base, tvb, ioffset,
4970                                   value1, values->vstring);
4971             values->mvtype = MVTYPE_ATTR_REQUEST;
4972             ioffset = ioffset + value1;
4973         }
4974         break;
4975
4976     case MVTYPE_READ_REPLICAS:    /* Read Replicas */
4977         for (i = 1 ; i <= values->vvalue; i++ )
4978         {
4979             bvalue = 0x00000001;
4980
4981             for (r = 0 ; r < 9; r++ )
4982             {
4983                 if (values->vflags & bvalue)
4984                 {
4985                     switch(bvalue)
4986                     {
4987                     case 0x00000001:                /*p3values.bit1 = "Output Flags"*/
4988                         proto_tree_add_bitmask(ntree, tvb, ioffset, hf_outflags, ett_ncp, ncp_outflags, ENC_LITTLE_ENDIAN);
4989                         ioffset = ioffset + 4;
4990                         break;
4991                     case 0x00000002:                /*p3values.bit2 = "Entry ID"*/
4992                         value1 = tvb_get_letohl(tvb, ioffset);
4993                         proto_tree_add_uint_format(ntree, hf_nds_eid, tvb, ioffset,
4994                                                    4, value1, "Entry ID %08x", value1);
4995                         ioffset = ioffset + 4;
4996                         break;
4997                     case 0x00000004:                /*p3values.bit3 = "Replica State"*/
4998                         proto_tree_add_item_ret_uint(ntree, hf_replica_state, tvb, ioffset,
4999                                               4, ENC_LITTLE_ENDIAN, &value1);
5000                         ioffset = ioffset + 4;
5001                         break;
5002                     case 0x0000008:                 /*p3values.bit4 = "Modification Timestamp"*/
5003                         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5004                         ns.nsecs = 0;
5005                         proto_tree_add_time_format(ntree, hf_es_seconds, tvb, ioffset,
5006                                                    4, &ns, "Modification Timestamp: %s",
5007                                                    abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5008                         ioffset = ioffset + 4;
5009                         proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset,
5010                                             2, ENC_LITTLE_ENDIAN);
5011                         ioffset = ioffset + 2;
5012                         proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset,
5013                                             2, ENC_LITTLE_ENDIAN);
5014                         ioffset = ioffset + 2;
5015                         break;
5016                     case 0x00000010:                /*p3values.bit5 = "Purge Time"*/
5017                         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5018                         ns.nsecs = 0;
5019                         proto_tree_add_time(ntree, hf_nds_purge, tvb, ioffset, 4, &ns);
5020                         ioffset = ioffset + 4;
5021                         break;
5022                     case 0x00000020:                /*p3values.bit6 = "Local Partition ID"*/
5023                         proto_tree_add_item(ntree, hf_nds_local_partition, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
5024                         ioffset = ioffset + 4;
5025                         break;
5026                     case 0x00000040:                /*p3values.bit7 = "Distinguished Name"*/
5027                         value1 = tvb_get_letohl(tvb, ioffset);
5028                         ioffset = ioffset + 4;
5029                         temp_values.vstring = get_string(tvb, ioffset, value1);
5030                         proto_tree_add_string(ntree, hf_nds_name, tvb, ioffset,
5031                                               value1, temp_values.vstring);
5032                         ioffset = ioffset + value1;
5033                         break;
5034                     case 0x00000080:                /*p3values.bit8 = "Replica Type & State"*/
5035                         value1 = tvb_get_letohl(tvb, ioffset);
5036                         value2 = value1 & 0x00ff;
5037                         proto_tree_add_uint(ntree, hf_replica_type, tvb, ioffset, 4, value2);
5038                         value3 = value1 & 0xff00;
5039                         proto_tree_add_uint(ntree, hf_replica_state, tvb, ioffset, 4, value3);
5040                         ioffset = ioffset + 4;
5041                         break;
5042                     case 0x00000100:                /*p3values.bit9 = "Partition Busy"*/
5043                         value1 = tvb_get_letohs(tvb, ioffset);
5044                         proto_tree_add_boolean(ntree, hf_partition_busy, tvb, ioffset, 4, value1);
5045                         ioffset += 4;
5046                         break;
5047                     default:
5048                         break;
5049                     }
5050                 }
5051                 bvalue = bvalue*2;
5052                 ioffset += align_4(tvb, ioffset);
5053                 if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5054                 {
5055                     break;
5056                 }
5057             }
5058             if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5059             {
5060                 break;
5061             }
5062         }
5063         break;
5064
5065     case MVTYPE_MODIFY_ATTR_REQUEST: /* Modify Attribute Request */
5066         for (i = 0 ; i < values->vvalue; i++ )
5067         {
5068             ioffset += align_4(tvb, ioffset);
5069             value1 = tvb_get_letohl(tvb, ioffset);
5070             valuestr = val_to_str_const(value1, nds_kind_of_changes, "(Kind Change Not Found)");
5071             proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset,
5072                                        values->vlength, value1, valuestr, value1);
5073             ioffset = ioffset+4;
5074             value2 = tvb_get_letohl(tvb, ioffset);
5075             ioffset = ioffset + 4;
5076             temp_values.vstring = get_string(tvb, ioffset, value2);   /* Name of Attribute */
5077             proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
5078                                   value2, temp_values.vstring);
5079             ioffset = ioffset + value2;
5080             ioffset += align_4(tvb, ioffset);
5081             if(value1 != 1 && value1 != 6)
5082             {
5083                 values->voffset = ioffset;
5084                 /* XX: Is values.vstring set properly at this point ?? */
5085                 print_nds_values(ntree, pinfo, tvb, 9, values);
5086                 ioffset = values->voffset;
5087             }
5088         }
5089         break;
5090
5091     case MVTYPE_ADDR_REFERRAL_REQUEST: /* Address Referral Request */
5092         for (i = 0 ; i < values->vvalue; i++ )
5093         {
5094             value1 = tvb_get_letohl(tvb, ioffset);
5095             valuestr = val_to_str_const(value1, nds_protocol_type, "(Undefined Protocol)");
5096             proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset,
5097                                        values->vlength, value1, valuestr, value1);
5098             ioffset = ioffset+4;
5099         }
5100         break;
5101
5102     case MVTYPE_ADDR_REFERRAL_REPLY: /* Address Referral Reply */
5103         number_of_referrals = values->vvalue;
5104
5105         for (r = 1 ; r <= number_of_referrals; r++ )
5106         {
5107             aitem = proto_tree_add_uint_format(ntree, hf_referral_record, tvb, 6, 0,
5108                                                r, "NDS Referral Record #%u", r);
5109             atree = proto_item_add_subtree(aitem, ett_nds);
5110
5111             proto_tree_add_item_ret_uint(atree, hf_referral_addcount, tvb, ioffset, 4, ENC_LITTLE_ENDIAN, &value1);
5112
5113             ioffset = ioffset + 4;
5114             for (i = 1 ; i <= value1; i++ )
5115             {
5116                 value2 = tvb_get_letohl(tvb, ioffset);
5117                 valuestr = val_to_str_const(value2, nds_protocol_type, "(Undefined Protocol)");
5118                 proto_tree_add_uint_format(atree, hf_nds_uint32value, tvb, ioffset,
5119                                            values->vlength, value2, valuestr, value2);
5120                 ioffset = ioffset+4;
5121                 value3 = tvb_get_letohl(tvb, ioffset);
5122                 ioffset = ioffset+4;
5123                 switch (value2)
5124                 {
5125                 case NDS_PTYPE_IPX:
5126                     proto_tree_add_item(atree, hf_nds_net, tvb, ioffset, 4, ENC_BIG_ENDIAN);
5127                     proto_tree_add_item(atree, hf_nds_node, tvb, ioffset+4, 6, ENC_NA);
5128                     proto_tree_add_item(atree, hf_nds_socket, tvb, ioffset+10, 2, ENC_BIG_ENDIAN);
5129                     break;
5130                 case NDS_PTYPE_IP:
5131                     proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
5132                     proto_tree_add_item(atree, hf_add_ref_ip, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
5133                     break;
5134                 case NDS_PTYPE_UDP:
5135                     proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
5136                     proto_tree_add_item(atree, hf_add_ref_udp, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
5137                     break;
5138                 case NDS_PTYPE_TCP:
5139                     proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
5140                     proto_tree_add_item(atree, hf_add_ref_tcp, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
5141                     break;
5142                 case NDS_PTYPE_URL:
5143                 case NDS_PTYPE_DNS:
5144                     values->vstring = get_string(tvb, ioffset, value3);
5145                     proto_tree_add_string(atree, hf_value_string, tvb, ioffset,
5146                                           value3, values->vstring);
5147                     break;
5148                 default:
5149                     break;
5150                 }
5151                 ioffset = ioffset + value3;
5152                 ioffset += align_4(tvb, ioffset);
5153             }
5154
5155         }
5156         break;
5157
5158     case MVTYPE_LOC_ADDR_REFERRAL_REPLY: /* Local Address Referral Reply */
5159         number_of_referrals = values->vvalue;
5160
5161         for (r = 1 ; r <= number_of_referrals; r++ )
5162         {
5163             aitem = proto_tree_add_uint_format(ntree, hf_referral_record, tvb, 6, 0,
5164                                                r, "NDS Referral Record #%u", r);
5165             atree = proto_item_add_subtree(aitem, ett_nds);
5166
5167             value2 = tvb_get_letohl(tvb, ioffset);
5168             valuestr = val_to_str_const(value2, nds_protocol_type, "(Undefined Protocol)");
5169             proto_tree_add_uint_format(atree, hf_nds_uint32value, tvb, ioffset,
5170                                        values->vlength, value2, valuestr, value2);
5171             ioffset = ioffset+4;
5172             value3 = tvb_get_letohl(tvb, ioffset);
5173             ioffset = ioffset+4;
5174
5175             switch (value2)
5176             {
5177             case NDS_PTYPE_IPX:
5178                 proto_tree_add_item(atree, hf_nds_net, tvb, ioffset, 4, ENC_BIG_ENDIAN);
5179                 proto_tree_add_item(atree, hf_nds_node, tvb, ioffset+4, 6, ENC_NA);
5180                 proto_tree_add_item(atree, hf_nds_socket, tvb, ioffset+10, 2, ENC_BIG_ENDIAN);
5181                 break;
5182             case NDS_PTYPE_IP:
5183                 proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
5184                 proto_tree_add_item(atree, hf_add_ref_ip, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
5185                 break;
5186             case NDS_PTYPE_UDP:
5187                 proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
5188                 proto_tree_add_item(atree, hf_add_ref_udp, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
5189                 break;
5190             case NDS_PTYPE_TCP:
5191                 proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, ENC_BIG_ENDIAN);
5192                 proto_tree_add_item(atree, hf_add_ref_tcp, tvb, ioffset+2, 4, ENC_BIG_ENDIAN);
5193                 break;
5194             case NDS_PTYPE_URL:
5195             case NDS_PTYPE_DNS:
5196                 values->vstring = get_string(tvb, ioffset, value3);
5197                 proto_tree_add_string(atree, hf_value_string, tvb, ioffset,
5198                                       value3, values->vstring);
5199                 break;
5200             default:
5201                 break;
5202             }
5203             ioffset = ioffset + value3;
5204             ioffset += align_4(tvb, ioffset);
5205         }
5206         break;
5207
5208     case MVTYPE_PROC_ENTRY_SPECIFIERS: /* Process Entry Specifiers */
5209         value2 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
5210         values->vstring = val_to_str_const(value2, es_type, "No ES Type Found");
5211         esitem = proto_tree_add_string_format(ntree, hf_es_type, tvb, ioffset,
5212                                               4, values->vstring, "Output Entry Specifier - %s", values->vstring);
5213         estree = proto_item_add_subtree(esitem, ett_nds);
5214         ioffset = ioffset + 4;
5215         ioffset = print_es_type(estree, tvb, values, value2, ioffset);
5216         value3 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
5217         values->vstring = val_to_str_const(value3, es_type, "No ES Type Found");
5218         esitem = proto_tree_add_string_format(ntree, hf_es_type, tvb, ioffset,
5219                                               4, values->vstring, "Input Entry Specifier - %s", values->vstring);
5220         estree = proto_item_add_subtree(esitem, ett_nds);
5221         ioffset = ioffset + 4;
5222         ioffset = print_es_type(estree, tvb, values, value3, ioffset);
5223         /* values.vstring is being overwritten. So store the resolve name to a global value */
5224         g_strlcpy(mv_resolve_name_string, values->vstring, 128);
5225         value4 = tvb_get_letohl(tvb, ioffset);
5226         aitem = proto_tree_add_uint_format(ntree, hf_referral_record, tvb, ioffset, 4,
5227                                            value4, "Referral Protocols - %u", value4);
5228         atree = proto_item_add_subtree(aitem, ett_nds);
5229         ioffset += 4;
5230         for (i = 0 ; i < value4; i++ )
5231         {
5232             value5 = tvb_get_letohl(tvb, ioffset);
5233             valuestr = val_to_str_const(value5, nds_protocol_type, "(Undefined Protocol)");
5234             proto_tree_add_string_format(atree, hf_value_string, tvb, ioffset,
5235                                          4, valuestr, "Protocol -> %s", valuestr);
5236             ioffset = ioffset+4;
5237         }
5238         value6 = tvb_get_letohl(tvb, ioffset);
5239         aitem = proto_tree_add_uint_format(ntree, hf_referral_record, tvb, ioffset, 4,
5240                                            value6, "Tree Walking Protocols - %u", value6);
5241         atree = proto_item_add_subtree(aitem, ett_nds);
5242         ioffset += 4;
5243         for (i = 0 ; i < value6; i++ )
5244         {
5245             value7 = tvb_get_letohl(tvb, ioffset);
5246             valuestr = val_to_str_const(value7, nds_protocol_type, "(Undefined Protocol)");
5247             proto_tree_add_string_format(atree, hf_value_string, tvb, ioffset,
5248                                          4, valuestr, "Protocol -> %s", valuestr);
5249             ioffset = ioffset+4;
5250         }
5251         values->vstring = " ";
5252         break;
5253
5254     case MVTYPE_PRINT_TIMESTAMP:  /* Print Timestamp */
5255         proto_tree_add_item(ncp_tree, hf_nds_replica_num, tvb, ioffset,
5256                             2, ENC_LITTLE_ENDIAN);
5257         ioffset = ioffset + 2;
5258         proto_tree_add_item(ncp_tree, hf_nds_event_num, tvb, ioffset,
5259                             2, ENC_LITTLE_ENDIAN);
5260         ioffset = ioffset + 2;
5261         /* fall through */
5262
5263     case MVTYPE_LIST_PARTITIONS:  /* List Partitions */
5264         number_of_referrals = values->vvalue;
5265         /* A bad packet could put us in a tight loop so trap for anything
5266          * over 256 referrals.
5267          */
5268         if (number_of_referrals > 256) {
5269             proto_tree_add_expert_format(ntree, pinfo, &ei_ncp_invalid_offset, tvb, 0, 0, "Bad referal at offset: %u", ioffset);
5270             THROW(ReportedBoundsError);
5271             break;
5272         }
5273         for (i = 0; i < number_of_referrals; i++)
5274         {
5275             bvalue = 0x00000001;
5276
5277             for (r = 0 ; r < 32; r++ )
5278             {
5279                 /*oldioffset = ioffset;*/
5280                 if (values->vflags & bvalue)
5281                 {
5282                     switch(bvalue)
5283                     {
5284                     case 0x00000001:                /* Information Flags */
5285                         proto_tree_add_bitmask(ncp_tree, tvb, ioffset, hf_infoflagsl, ett_ncp, ncp_infoflagsl, ENC_LITTLE_ENDIAN);
5286                         ioffset += 2;
5287                         proto_tree_add_bitmask(ncp_tree, tvb, ioffset, hf_infoflagsh, ett_ncp, ncp_infoflagsh, ENC_LITTLE_ENDIAN);
5288                         ioffset += 2;
5289                         break;
5290                     case 0x00000002:                /* Entry ID */
5291                         value1 = tvb_get_letohl(tvb, ioffset);
5292                         proto_tree_add_uint_format(ntree, hf_nds_eid, tvb, ioffset,
5293                                                    4, value1, "Entry ID %08x", value1);
5294                         ioffset = ioffset + 4;
5295                         break;
5296                     case 0x00000004:                /* Entry Flags */
5297                         proto_tree_add_bitmask(ncp_tree, tvb, ioffset, hf_eflags, ett_ncp, ncp_eflags, ENC_LITTLE_ENDIAN);
5298                         ioffset = ioffset+4;
5299                         break;
5300                     case 0x0000008:                 /* Subordinate Count */
5301                         value1 = tvb_get_letohl(tvb, ioffset);
5302                         proto_tree_add_uint_format(ntree, hf_sub_count, tvb, ioffset,
5303                                                    4, value1, "Subordinate Count %u", value1);
5304                         ioffset = ioffset + 4;
5305                         break;
5306                     case 0x0000010:                 /* Modification Time */
5307                         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5308                         ns.nsecs = 0;
5309                         proto_tree_add_time_format(ntree, hf_es_seconds, tvb, ioffset,
5310                                                    4, &ns, "Modification Time: %s",
5311                                                    abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5312                         ioffset = ioffset + 4;
5313                         break;
5314                     case 0x0000020:                 /* Modification Timestamp */
5315                         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5316                         ns.nsecs = 0;
5317                         proto_tree_add_time_format(ntree, hf_es_seconds, tvb, ioffset,
5318                                                    4, &ns, "Modification Timestamp: %s",
5319                                                    abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5320                         ioffset = ioffset + 4;
5321                         proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset,
5322                                             2, ENC_LITTLE_ENDIAN);
5323                         ioffset = ioffset + 2;
5324                         proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset,
5325                                             2, ENC_LITTLE_ENDIAN);
5326                         ioffset = ioffset + 2;
5327                         break;
5328                     case 0x0000040:                 /* Creation Timestamp */
5329                         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5330                         ns.nsecs = 0;
5331                         proto_tree_add_time_format(ntree, hf_es_seconds, tvb, ioffset,
5332                                                    4, &ns, "Creation Timestamp: %s",
5333                                                    abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5334                         ioffset = ioffset + 4;
5335                         proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset,
5336                                             2, ENC_LITTLE_ENDIAN);
5337                         ioffset = ioffset + 2;
5338                         proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset,
5339                                             2, ENC_LITTLE_ENDIAN);
5340                         ioffset = ioffset + 2;
5341                         break;
5342                     case 0x00000080:                /* Partition Root ID */
5343                         value1 = tvb_get_letohl(tvb, ioffset);
5344                         proto_tree_add_uint_format(ntree, hf_nds_partition_root_id, tvb, ioffset,
5345                                                    4, value1, "Partition Root ID %08x", value1);
5346                         ioffset = ioffset + 4;
5347                         break;
5348                     case 0x00000100:                /* Parent ID */
5349                         proto_tree_add_item(ntree, hf_nds_parent, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
5350                         ioffset = ioffset + 4;
5351                         break;
5352                     case 0x00000200:                /* Revision Count */
5353                         proto_tree_add_item(ntree, hf_nds_revision, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
5354                         ioffset = ioffset + 4;
5355                         break;
5356                     case 0x00000400:                /* Replica Type & State */
5357                         value1 = tvb_get_letohl(tvb, ioffset);
5358                         value2 = value1 & 0x00ff;
5359                         proto_tree_add_uint(ntree, hf_replica_type, tvb, ioffset, 4, value2);
5360                         value3 = value1 & 0xff00;
5361                         proto_tree_add_uint(ntree, hf_replica_state, tvb, ioffset, 4, value3);
5362                         ioffset = ioffset + 4;
5363                         break;
5364                     case 0x00000800:                /* Base Class */
5365                         value1 = tvb_get_letohl(tvb, ioffset);
5366                         ioffset = ioffset + 4;
5367                         temp_values.vstring = get_string(tvb, ioffset, value1);
5368                         proto_tree_add_string(ntree, hf_nds_base, tvb, ioffset,
5369                                               value1, temp_values.vstring);
5370                         ioffset = ioffset + value1;
5371                         break;
5372                     case 0x00001000:                /* Relative Distinguished Name */
5373                         value1 = tvb_get_letohl(tvb, ioffset);
5374                         ioffset = ioffset + 4;
5375                         temp_values.vstring = get_string(tvb, ioffset, value1);
5376                         proto_tree_add_string(ntree, hf_nds_relative_dn, tvb, ioffset,
5377                                               value1, temp_values.vstring);
5378                         ioffset = ioffset + value1;
5379                         break;
5380                     case 0x00002000:                /* Distinguished Name */
5381                         value1 = tvb_get_letohl(tvb, ioffset);
5382                         ioffset = ioffset + 4;
5383                         temp_values.vstring = get_string(tvb, ioffset, value1);
5384                         proto_tree_add_string(ntree, hf_nds_name, tvb, ioffset,
5385                                               value1, temp_values.vstring);
5386                         ioffset = ioffset + value1;
5387                         break;
5388                     case 0x00004000:                /* Root Distinguished Name */
5389                         value1 = tvb_get_letohl(tvb, ioffset);
5390                         ioffset = ioffset + 4;
5391                         temp_values.vstring = get_string(tvb, ioffset, value1);
5392                         proto_tree_add_string(ntree, hf_nds_name, tvb, ioffset,
5393                                               value1, temp_values.vstring);
5394                         ioffset = ioffset + value1;
5395                         break;
5396                     case 0x00008000:                /* Parent Distinguished Name */
5397                         value1 = tvb_get_letohl(tvb, ioffset);
5398                         ioffset = ioffset + 4;
5399                         temp_values.vstring = get_string(tvb, ioffset, value1);
5400                         proto_tree_add_string(ntree, hf_nds_name, tvb, ioffset,
5401                                               value1, temp_values.vstring);
5402                         ioffset = ioffset + value1;
5403                         break;
5404                     case 0x00010000:                /* Purge Time */
5405                         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5406                         ns.nsecs = 0;
5407                         proto_tree_add_time_format(ntree, hf_es_seconds, tvb, ioffset,
5408                                                    4, &ns, "Purge Time: %s",
5409                                                    abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5410                         ioffset = ioffset + 4;
5411                         break;
5412                     case 0x00020000:                /* Dereference Base Class */
5413                         value1 = tvb_get_letohl(tvb, ioffset);
5414                         ioffset = ioffset + 4;
5415                         temp_values.vstring = get_string(tvb, ioffset, value1);
5416                         proto_tree_add_string(ntree, hf_deref_base, tvb, ioffset,
5417                                               value1, temp_values.vstring);
5418                         ioffset = ioffset + value1;
5419                         break;
5420                     default:
5421                         break;
5422
5423                     }
5424                     ioffset += align_4(tvb, ioffset);
5425                 }
5426                 bvalue = bvalue*2;
5427                 /* We could loop forever so check to see if bvalue has wrapped to 0.
5428                  * if so then just abort loop.
5429                  */
5430                 if (bvalue==0) {
5431                     break;
5432                 }
5433                 if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5434                 {
5435                     break;
5436                 }
5437             }
5438             if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5439             {
5440                 break;
5441             }
5442         }
5443         break;
5444
5445     case MVTYPE_CLASS_NAMES:      /* Class Names */
5446         number_of_referrals = values->vvalue;
5447         for (i = 0; i < number_of_referrals; i++)
5448         {
5449             ioffset += align_4(tvb, ioffset);
5450             value1 = tvb_get_letohl(tvb, ioffset);
5451             ioffset = ioffset + 4;
5452             temp_values.vstring = get_string(tvb, ioffset, value1);
5453             sub1item = proto_tree_add_string(ntree, hf_nds_base_class, tvb, ioffset,
5454                                              value1, temp_values.vstring);
5455             sub1tree = proto_item_add_subtree(sub1item, ett_nds);
5456             ioffset = ioffset + value1;
5457             ioffset += align_4(tvb, ioffset);
5458             if(values->vflags != 0)
5459             {
5460                 proto_tree_add_bitmask(sub1tree, tvb, ioffset, hf_cflags, ett_ncp, ncp_cflags, ENC_LITTLE_ENDIAN);
5461                 ioffset = ioffset+4;
5462                 if(values->vflags != 5)
5463                 {
5464                     value1 = tvb_get_letohl(tvb, ioffset); /* length of field */
5465                     length_remaining = tvb_captured_length_remaining(tvb, ioffset);
5466                     if(length_remaining == -1 || value1 > (guint32) length_remaining)
5467                     {
5468                         break;
5469                     }
5470                     ioffset += 4;
5471                     proto_tree_add_item(sub1tree, hf_nds_asn1, tvb, ioffset, value1, ENC_NA);
5472                     ioffset += value1;
5473                     ioffset += (value1%2);
5474                 }
5475                 if(values->vflags == 1 || values->vflags == 2 || values->vflags == 4)
5476                 {
5477                     value1 = tvb_get_letohl(tvb, ioffset);  /* Super Classes */
5478                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5479                                                           4, value1, "Super Classes %u", value1);
5480                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5481                     ioffset = ioffset + 4;
5482                     for (r = 0; r < value1; r++)
5483                     {
5484                         value2 = tvb_get_letohl(tvb, ioffset);
5485                         ioffset = ioffset + 4;
5486                         temp_values.vstring = get_string(tvb, ioffset, value2);
5487                         proto_tree_add_string(sub2tree, hf_nds_super, tvb, ioffset,
5488                                               value2, temp_values.vstring);
5489                         ioffset = ioffset + value2;
5490                         ioffset += align_4(tvb, ioffset);
5491                     }
5492                     value1 = tvb_get_letohl(tvb, ioffset);  /* Containment Classes */
5493                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5494                                                           4, value1, "Containment Classes %u", value1);
5495                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5496                     ioffset = ioffset + 4;
5497                     for (r = 0; r < value1; r++)
5498                     {
5499                         value2 = tvb_get_letohl(tvb, ioffset);
5500                         ioffset = ioffset + 4;
5501                         temp_values.vstring = get_string(tvb, ioffset, value2);
5502                         proto_tree_add_string(sub2tree, hf_nds_base_class, tvb, ioffset,
5503                                               value2, temp_values.vstring);
5504                         ioffset = ioffset + value2;
5505                         ioffset += align_4(tvb, ioffset);
5506                     }
5507                     value1 = tvb_get_letohl(tvb, ioffset);  /* Naming Attributes */
5508                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5509                                                           4, value1, "Naming Attributes %u", value1);
5510                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5511                     ioffset = ioffset + 4;
5512                     for (r = 0; r < value1; r++)
5513                     {
5514                         value2 = tvb_get_letohl(tvb, ioffset);
5515                         ioffset = ioffset + 4;
5516                         temp_values.vstring = get_string(tvb, ioffset, value2);
5517                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5518                                               value2, temp_values.vstring);
5519                         ioffset = ioffset + value2;
5520                         ioffset += align_4(tvb, ioffset);
5521                     }
5522                     value1 = tvb_get_letohl(tvb, ioffset);  /* Mandatory Attributes */
5523                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5524                                                           4, value1, "Mandatory Attributes %u", value1);
5525                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5526                     ioffset = ioffset + 4;
5527                     for (r = 0; r < value1; r++)
5528                     {
5529                         value2 = tvb_get_letohl(tvb, ioffset);
5530                         ioffset = ioffset + 4;
5531                         temp_values.vstring = get_string(tvb, ioffset, value2);
5532                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5533                                               value2, temp_values.vstring);
5534                         ioffset = ioffset + value2;
5535                         ioffset += align_4(tvb, ioffset);
5536                     }
5537                     value1 = tvb_get_letohl(tvb, ioffset);  /* Optional Attributes */
5538                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5539                                                           4, value1, "Optional Attributes %u", value1);
5540                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5541                     ioffset = ioffset + 4;
5542                     for (r = 0; r < value1; r++)
5543                     {
5544                         ioffset += align_4(tvb, ioffset);
5545                         value2 = tvb_get_letohl(tvb, ioffset);
5546                         ioffset = ioffset + 4;
5547                         temp_values.vstring = get_string(tvb, ioffset, value2);
5548                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5549                                               value2, temp_values.vstring);
5550                         ioffset = ioffset + value2;
5551                         if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5552                         {
5553                             break;
5554                         }
5555                     }
5556                 }
5557 #if 0
5558                 if(values->vflags == 2 || values->vflags == 4)   /* Class Definitions of Super Classes */
5559 #endif
5560                 if(values->vflags == 4)   /* Class Definitions of Super Classes */
5561                 {
5562                     value1 = tvb_get_letohl(tvb, ioffset);  /* Containment Classes */
5563                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5564                                                           4, value1, "Containment Classes %u", value1);
5565                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5566                     ioffset = ioffset + 4;
5567                     for (r = 0; r < value1; r++)
5568                     {
5569                         value2 = tvb_get_letohl(tvb, ioffset);
5570                         ioffset = ioffset + 4;
5571                         temp_values.vstring = get_string(tvb, ioffset, value2);
5572                         proto_tree_add_string(sub2tree, hf_nds_base_class, tvb, ioffset,
5573                                               value2, temp_values.vstring);
5574                         ioffset = ioffset + value2;
5575                         ioffset += align_4(tvb, ioffset);
5576                     }
5577                     value1 = tvb_get_letohl(tvb, ioffset);  /* Naming Attributes */
5578                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5579                                                           4, value1, "Naming Attributes %u", value1);
5580                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5581                     ioffset = ioffset + 4;
5582                     for (r = 0; r < value1; r++)
5583                     {
5584                         value2 = tvb_get_letohl(tvb, ioffset);
5585                         ioffset = ioffset + 4;
5586                         temp_values.vstring = get_string(tvb, ioffset, value2);
5587                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5588                                               value2, temp_values.vstring);
5589                         ioffset = ioffset + value2;
5590                         ioffset += align_4(tvb, ioffset);
5591                     }
5592                     value1 = tvb_get_letohl(tvb, ioffset);  /* Mandatory Attributes */
5593                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5594                                                           4, value1, "Mandatory Attributes %u", value1);
5595                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5596                     ioffset = ioffset + 4;
5597                     for (r = 0; r < value1; r++)
5598                     {
5599                         value2 = tvb_get_letohl(tvb, ioffset);
5600                         ioffset = ioffset + 4;
5601                         temp_values.vstring = get_string(tvb, ioffset, value2);
5602                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5603                                               value2, temp_values.vstring);
5604                         ioffset = ioffset + value2;
5605                         ioffset += align_4(tvb, ioffset);
5606                     }
5607                     value1 = tvb_get_letohl(tvb, ioffset);  /* Optional Attributes */
5608                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5609                                                           4, value1, "Optional Attributes %u", value1);
5610                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5611                     ioffset = ioffset + 4;
5612                     for (r = 0; r < value1; r++)
5613                     {
5614                         value2 = tvb_get_letohl(tvb, ioffset);
5615                         ioffset = ioffset + 4;
5616                         temp_values.vstring = get_string(tvb, ioffset, value2);
5617                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5618                                               value2, temp_values.vstring);
5619                         ioffset = ioffset + value2;
5620                         ioffset += align_4(tvb, ioffset);
5621                     }
5622                     value1 = tvb_get_letohl(tvb, ioffset);    /* Default ACL */
5623                     proto_tree_add_uint_format(sub1tree, hf_nds_eid, tvb, ioffset,
5624                                                4, value1, "Default ACL %08x", value1);
5625                     ioffset = ioffset + 4;
5626                     if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5627                     {
5628                         break;
5629                     }
5630                 }
5631                 if(values->vflags == 5)   /* Base Class Definitions */
5632                 {
5633                     ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5634                     ns.nsecs = 0;
5635                     proto_tree_add_time_format(sub1tree, hf_es_seconds, tvb, ioffset,
5636                                                4, &ns, "Creation Timestamp: %s",
5637                                                abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5638                     ioffset = ioffset + 4;
5639                     proto_tree_add_item(sub1tree, hf_nds_replica_num, tvb, ioffset,
5640                                         2, ENC_LITTLE_ENDIAN);
5641                     ioffset = ioffset + 2;
5642                     proto_tree_add_item(sub1tree, hf_nds_event_num, tvb, ioffset,
5643                                         2, ENC_LITTLE_ENDIAN);
5644                     ioffset = ioffset + 2;
5645                     ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5646                     ns.nsecs = 0;
5647                     proto_tree_add_time_format(sub1tree, hf_es_seconds, tvb, ioffset,
5648                                                4, &ns, "Modification Timestamp: %s",
5649                                                abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5650                     ioffset = ioffset + 4;
5651                     proto_tree_add_item(sub1tree, hf_nds_replica_num, tvb, ioffset,
5652                                         2, ENC_LITTLE_ENDIAN);
5653                     ioffset = ioffset + 2;
5654                     proto_tree_add_item(sub1tree, hf_nds_event_num, tvb, ioffset,
5655                                         2, ENC_LITTLE_ENDIAN);
5656                     ioffset = ioffset + 2;
5657                     /* Class Definition */
5658                     value1 = tvb_get_letohl(tvb, ioffset);  /* Super Classes */
5659                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5660                                                           4, value1, "Super Classes %u", value1);
5661                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5662                     ioffset = ioffset + 4;
5663                     for (r = 0; r < value1; r++)
5664                     {
5665                         value2 = tvb_get_letohl(tvb, ioffset);
5666                         ioffset = ioffset + 4;
5667                         temp_values.vstring = get_string(tvb, ioffset, value2);
5668                         proto_tree_add_string(sub2tree, hf_nds_super, tvb, ioffset,
5669                                               value2, temp_values.vstring);
5670                         ioffset = ioffset + value2;
5671                         ioffset += align_4(tvb, ioffset);
5672                     }
5673                     value1 = tvb_get_letohl(tvb, ioffset);  /* Containment Classes */
5674                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5675                                                           4, value1, "Containment Classes %u", value1);
5676                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5677                     ioffset = ioffset + 4;
5678                     for (r = 0; r < value1; r++)
5679                     {
5680                         value2 = tvb_get_letohl(tvb, ioffset);
5681                         ioffset = ioffset + 4;
5682                         temp_values.vstring = get_string(tvb, ioffset, value2);
5683                         proto_tree_add_string(sub2tree, hf_nds_base_class, tvb, ioffset,
5684                                               value2, temp_values.vstring);
5685                         ioffset = ioffset + value2;
5686                         ioffset += align_4(tvb, ioffset);
5687                     }
5688                     value1 = tvb_get_letohl(tvb, ioffset);  /* Naming Attributes */
5689                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5690                                                           4, value1, "Naming Attributes %u", value1);
5691                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5692                     ioffset = ioffset + 4;
5693                     for (r = 0; r < value1; r++)
5694                     {
5695                         value2 = tvb_get_letohl(tvb, ioffset);
5696                         ioffset = ioffset + 4;
5697                         temp_values.vstring = get_string(tvb, ioffset, value2);
5698                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5699                                               value2, temp_values.vstring);
5700                         ioffset = ioffset + value2;
5701                         ioffset += align_4(tvb, ioffset);
5702                     }
5703                     value1 = tvb_get_letohl(tvb, ioffset);  /* Mandatory Attributes */
5704                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5705                                                           4, value1, "Mandatory Attributes %u", value1);
5706                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5707                     ioffset = ioffset + 4;
5708                     for (r = 0; r < value1; r++)
5709                     {
5710                         value2 = tvb_get_letohl(tvb, ioffset);
5711                         ioffset = ioffset + 4;
5712                         temp_values.vstring = get_string(tvb, ioffset, value2);
5713                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5714                                               value2, temp_values.vstring);
5715                         ioffset = ioffset + value2;
5716                         ioffset += align_4(tvb, ioffset);
5717                     }
5718                     value1 = tvb_get_letohl(tvb, ioffset);  /* Optional Attributes */
5719                     sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_number_of_items, tvb, ioffset,
5720                                                           4, value1, "Optional Attributes %u", value1);
5721                     sub2tree = proto_item_add_subtree(sub2item, ett_nds);
5722                     ioffset = ioffset + 4;
5723                     for (r = 0; r < value1; r++)
5724                     {
5725                         value2 = tvb_get_letohl(tvb, ioffset);
5726                         ioffset = ioffset + 4;
5727                         temp_values.vstring = get_string(tvb, ioffset, value2);
5728                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5729                                               value2, temp_values.vstring);
5730                         ioffset = ioffset + value2;
5731                         ioffset += align_4(tvb, ioffset);
5732                     }
5733                     value1 = tvb_get_letohl(tvb, ioffset);    /* Default ACL */
5734                     proto_tree_add_uint_format(sub1tree, hf_nds_eid, tvb, ioffset,
5735                                                4, value1, "Default ACL %08x", value1);
5736                     ioffset = ioffset + 4;
5737                     if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5738                     {
5739                         break;
5740                     }
5741                 }
5742             }
5743         }
5744         break;
5745
5746     case MVTYPE_MODIFY_CLASS:     /* Modify Class */
5747         for (i = 1 ; i <= values->vvalue; i++ )   /* Attribute Names to add*/
5748         {
5749             ioffset += align_4(tvb, ioffset);
5750             value1 = tvb_get_letohl(tvb, ioffset);
5751             ioffset = ioffset + 4;
5752             values->vstring = get_string(tvb, ioffset, value1);
5753             proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
5754                                   value1, values->vstring);
5755             ioffset = ioffset + value1;
5756         }
5757         if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5758         {
5759             break;
5760         }
5761         ioffset += align_4(tvb, ioffset);
5762         proto_tree_add_item_ret_uint(ntree, hf_nds_att_del, tvb, ioffset, 4, ENC_LITTLE_ENDIAN, &value1);
5763         ioffset = ioffset + 4;
5764         for (i = 1 ; i <= value1; i++ )   /* Attribute Names to delete*/
5765         {
5766             ioffset += align_4(tvb, ioffset);
5767             value2 = tvb_get_letohl(tvb, ioffset);
5768             ioffset = ioffset + 4;
5769             values->vstring = get_string(tvb, ioffset, value2);
5770             proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
5771                                   value2, values->vstring);
5772             ioffset = ioffset + value2;
5773         }
5774         if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5775         {
5776             break;
5777         }
5778         ioffset += align_4(tvb, ioffset);
5779         proto_tree_add_item_ret_uint(ntree, hf_nds_acl_add, tvb, ioffset, 4, ENC_LITTLE_ENDIAN, &value1);
5780         ioffset = ioffset + 4;
5781         for (i = 1 ; i <= value1; i++ )   /* ACL templates to add*/
5782         {
5783             ioffset += align_4(tvb, ioffset);
5784             value2 = tvb_get_letohl(tvb, ioffset);  /* Attribute Name */
5785             ioffset = ioffset + 4;
5786             values->vstring = get_string(tvb, ioffset, value2);
5787             proto_tree_add_string(ntree, hf_nds_attribute_dn, tvb, ioffset,
5788                                   value2, values->vstring);
5789             ioffset = ioffset + value2;
5790             ioffset += align_4(tvb, ioffset);
5791             value2 = tvb_get_letohl(tvb, ioffset);  /* DN of Trustee */
5792             ioffset = ioffset + 4;
5793             values->vstring = get_string(tvb, ioffset, value2);
5794             proto_tree_add_string(ntree, hf_nds_trustee_dn, tvb, ioffset,
5795                                   value2, values->vstring);
5796             ioffset = ioffset + value2;
5797             ioffset += align_4(tvb, ioffset);
5798             proto_tree_add_item(ntree, hf_nds_privileges, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
5799             ioffset = ioffset + 4;
5800         }
5801         if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5802         {
5803             break;
5804         }
5805         ioffset += align_4(tvb, ioffset);
5806         proto_tree_add_item_ret_uint(ntree, hf_nds_acl_del, tvb, ioffset,
5807                                    4, ENC_LITTLE_ENDIAN, &value1);
5808         ioffset = ioffset + 4;
5809         for (i = 1 ; i <= value1; i++ )   /* ACL templates to delete*/
5810         {
5811             ioffset += align_4(tvb, ioffset);
5812             value2 = tvb_get_letohl(tvb, ioffset);  /* Attribute Name */
5813             ioffset = ioffset + 4;
5814             values->vstring = get_string(tvb, ioffset, value2);
5815             proto_tree_add_string(ntree, hf_nds_attribute_dn, tvb, ioffset,
5816                                   value2, values->vstring);
5817             ioffset = ioffset + value2;
5818             ioffset += align_4(tvb, ioffset);
5819             value2 = tvb_get_letohl(tvb, ioffset);  /* DN of Trustee */
5820             ioffset = ioffset + 4;
5821             values->vstring = get_string(tvb, ioffset, value2);
5822             proto_tree_add_string(ntree, hf_nds_trustee_dn, tvb, ioffset,
5823                                   value2, values->vstring);
5824             ioffset = ioffset + value2;
5825             ioffset += align_4(tvb, ioffset);
5826             value1 = tvb_get_letohl(tvb, ioffset);  /* Privileges */
5827             proto_tree_add_item(ntree, hf_nds_privileges, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
5828             ioffset = ioffset + 4;
5829         }
5830         break;
5831
5832     case MVTYPE_PROCESS_TAGS: /* Process tags and paths depending on name type returned. */
5833         switch (values->vflags) {
5834
5835         case 8:  /* Tuned Name */
5836             proto_tree_add_item(ntree, hf_nds_tune_mark, tvb, ioffset, 2, ENC_BIG_ENDIAN);
5837             ioffset += 2;
5838             value1 = tvb_get_letohs(tvb, ioffset);
5839             valuestr = val_to_str_const(value1, nds_tuned_tags, "(Undefined Tuned Name Tag)");
5840             proto_tree_add_string_format(ntree, hf_value_string, tvb, ioffset,
5841                                          2, valuestr, "Tuned Name Tag -> %s", valuestr);
5842             ioffset += 2;
5843             ioffset += align_4(tvb, ioffset);
5844             if (value1 == 0) { /* RDN Hint - really just returns the dist name + timestamp info */
5845                 value2 = tvb_get_letohl(tvb, ioffset);  /* Distinguished Name Len, String[len]*/
5846                 ioffset = ioffset + 4;
5847                 values->vstring = get_string(tvb, ioffset, value2);
5848                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
5849                                       value2, values->vstring);
5850                 ioffset += value2;
5851                 ioffset += align_4(tvb, ioffset);
5852                 ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5853                 ns.nsecs = 0;
5854                 proto_tree_add_time_format(ntree, hf_es_seconds, tvb, ioffset,
5855                                            4, &ns, "Creation Timestamp: %s",
5856                                            abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5857                 ioffset += 4;
5858                 proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset,
5859                                     2, ENC_LITTLE_ENDIAN);
5860                 ioffset = ioffset + 2;
5861                 proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset,
5862                                     2, ENC_LITTLE_ENDIAN);
5863                 ioffset = ioffset + 2;
5864             }
5865             else /* Process the full RDN history including ancestors */
5866             {
5867                 value1 = tvb_get_letohl(tvb, ioffset);
5868                 sub1item = proto_tree_add_uint_format(ntree, hf_nds_acl_del, tvb, ioffset,
5869                                                       4, value1, "Number of RDN Items %u", value1);
5870                 sub1tree = proto_item_add_subtree(sub1item, ett_nds);
5871                 ioffset = ioffset + 4;
5872                 for (i=1; i <= value1; i++) {
5873                     sub2tree = proto_tree_add_subtree_format(sub1tree, tvb, ioffset, 0, ett_nds, NULL, "Item %u", i);
5874                     ioffset += align_4(tvb, ioffset);
5875
5876                     value5 = tvb_get_letohl(tvb, ioffset);
5877                     valuestr = val_to_str_const(value5, nds_tuned_item_tags, "(Undefined Tuned Name Tag)");
5878                     if (value5 == 0) { /* Items are timestamp + Distinguished name (0 value == one entry)*/
5879                         proto_tree_add_string_format(sub2tree, hf_value_string, tvb, ioffset,
5880                                                      4, valuestr, "Item Tag -> %s", valuestr);
5881                         ioffset += 4;
5882                         ns.secs = tvb_get_letohl(tvb, ioffset);   /* Seconds */
5883                         ns.nsecs = 0;
5884                         proto_tree_add_time_format(sub2tree, hf_es_seconds, tvb, ioffset,
5885                                                    4, &ns, "Timestamp: %s",
5886                                                    abs_time_secs_to_str(wmem_packet_scope(), ns.secs, ABSOLUTE_TIME_LOCAL, TRUE));
5887                         ioffset += 4;
5888                         proto_tree_add_item(sub2tree, hf_nds_replica_num, tvb, ioffset,
5889                                             2, ENC_LITTLE_ENDIAN);
5890                         ioffset = ioffset + 2;
5891                         proto_tree_add_item(sub2tree, hf_nds_event_num, tvb, ioffset,
5892                                             2, ENC_LITTLE_ENDIAN);
5893                         ioffset = ioffset + 2;
5894                         value2 = tvb_get_letohl(tvb, ioffset);  /* Distinguished Name Len, String[len]*/
5895                         ioffset = ioffset + 4;
5896                         values->vstring = get_string(tvb, ioffset, value2);
5897                         proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset,
5898                                               value2, values->vstring);
5899                         ioffset += value2;
5900                     }
5901                     /* XXX: What if "multiple items" ?                 */
5902                     /*      What if "Undefined ... " ?                 */
5903                     /*      For now: we'll just keep on walking...     */
5904                     /*      Presumably we'll get a ReportedBoundsError */
5905                     /*       pretty quickly.                           */
5906                     else   /* Undefined or "multiple items" ... */
5907                     {
5908                         ioffset += 4;
5909                     }
5910                 } /* for */
5911             } /* else */
5912             values->voffset=ioffset;
5913             break;
5914         default: /* All other name types are just a string */
5915             values->vstring = get_string(tvb, ioffset, values->vlength);
5916             proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset,
5917                                   values->vlength, values->vstring);
5918             values->voffset=ioffset + values->vlength;
5919             /*ioffset = values->voffset;
5920             ioffset += align_4(tvb, ioffset);*/
5921             break;
5922         } /* switch (values->vflags) */
5923         break;
5924
5925     case MVTYPE_PROCESS_ITERATOR: /* Process Iterator subverbs. */
5926         proto_tree_add_item(ntree, hf_nds_info_type, tvb, ioffset, 4, ENC_LITTLE_ENDIAN);
5927         ioffset += 4;
5928         value5 = tvb_get_letohl(tvb, ioffset);
5929         proto_tree_add_bitmask(ncp_tree, tvb, ioffset, hf_infoflagsl, ett_ncp, ncp_infoflagsl, ENC_LITTLE_ENDIAN);
5930         ioffset += 2;
5931         proto_tree_add_bitmask(ncp_tree, tvb, ioffset, hf_infoflagsh, ett_ncp, ncp_infoflagsh, ENC_LITTLE_ENDIAN);
5932         ioffset += 2;
5933         proto_tree_add_item(ntree, hf_nds_time_filter, tvb, ioffset, 4, ENC_BIG_ENDIAN);
5934         ioffset += 4;
5935         proto_tree_add_item(ntree, hf_nds_all_attr, tvb, ioffset, 4, ENC_BIG_ENDIAN);
5936         ioffset += 4;
5937         value2 = tvb_get_letohl(tvb, ioffset);
5938         sub1item = proto_tree_add_uint_format(ntree, hf_nds_number_of_items, tvb, ioffset,
5939                                               4, value2, "Number of Attributes %u", value2);
5940         sub1tree = proto_item_add_subtree(sub1item, ett_nds);
5941         ioffset += 4;
5942         for (i=1; i<=value2; i++) {
5943             sub2tree = proto_tree_add_subtree_format(sub1tree, tvb, ioffset, 0, ett_nds, NULL, "Attribute %u", i);
5944             ioffset += align_4(tvb, ioffset);
5945             value3 = tvb_get_letohl(tvb, ioffset);  /* Attribute Name */
5946             ioffset = ioffset + 4;
5947             values->vstring = get_string(tvb, ioffset, value3);
5948             proto_tree_add_string(sub2tree, hf_nds_attribute_dn, tvb, ioffset,
5949                                   value3, values->vstring);
5950             ioffset = ioffset + value3;
5951
5952             if(tvb_captured_length_remaining(tvb, ioffset) < 4 )
5953             {
5954                 break;
5955             }
5956         }
5957         ioffset += align_4(tvb, ioffset);
5958         value4 = tvb_get_letohl(tvb, ioffset);
5959         values->vstring = val_to_str_const(value4, iterator_subverbs, "(No Iteration Verb Found)");
5960         ioffset += 4;
5961         dissect_nds_iterator(ntree, tvb, pinfo, value4, value5, ioffset, TRUE);
5962
5963         values->vstring = wmem_strdup_printf(wmem_packet_scope(), "(%s)", values->vstring);
5964         break;
5965
5966     default:
5967         break;
5968     }
5969 }
5970
5971 static void
5972 dissect_ncp_89_6_request(tvbuff_t *tvb, proto_tree *volatile ncp_tree, guint32 offset)
5973 {
5974     guint32 string_len, datatype, count, i;
5975
5976     datatype = tvb_get_letohl(tvb, offset);
5977     proto_tree_add_item(ncp_tree, hf_ncp_data_type_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5978     offset += 1;
5979     proto_tree_add_item(ncp_tree, hf_ncp_reserved5, tvb, offset, 5, ENC_NA);
5980     offset += 5;
5981     count = tvb_get_guint8(tvb, offset);
5982     proto_tree_add_item(ncp_tree, hf_ncp_path_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5983     offset += 1;
5984     for (i=0; i < count; i++) {
5985         if (datatype == 0) {
5986             string_len = (tvb_get_guint8(tvb, offset))+1;
5987             proto_tree_add_item(ncp_tree, hf_ncp_directory_path, tvb, offset+1, string_len-1, ENC_ASCII|ENC_NA);
5988         }
5989         else
5990         {
5991             string_len = (tvb_get_letohs(tvb, offset))+2;
5992             proto_tree_add_item(ncp_tree, hf_ncp_directory_path, tvb, offset+2, string_len-2, ENC_ASCII|ENC_NA);
5993         }
5994         offset += string_len;
5995         if(tvb_captured_length_remaining(tvb, offset) < 4 )
5996         {
5997             break;
5998         }
5999     }
6000 }
6001
6002
6003 static void
6004 dissect_ncp_123_11_reply(tvbuff_t *tvb, proto_tree *volatile ncp_tree, ncp_req_hash_value *request_value)
6005 {
6006     int string_len, loffset;
6007
6008     loffset = 76;
6009     if (request_value->length == 7) {
6010         /* Undocumented, if request value length is 7 then the reply is offset by 8 bytes.
6011          * Unknown what these 8 bytes represent */
6012         loffset += 8;
6013     }
6014     string_len = tvb_get_guint8(tvb, loffset);
6015     proto_tree_add_item(ncp_tree, hf_ncp_file_name_12, tvb, loffset+1, string_len, ENC_ASCII|ENC_NA);
6016     loffset += string_len+1;
6017     string_len = tvb_get_guint8(tvb, loffset);
6018     proto_tree_add_item(ncp_tree, hf_ncp_name12, tvb, loffset+1, string_len, ENC_ASCII|ENC_NA);
6019     loffset += string_len+1;
6020     string_len = tvb_get_guint8(tvb, loffset);
6021     proto_tree_add_item(ncp_tree, hf_ncp_copyright, tvb, loffset+1, string_len, ENC_ASCII|ENC_NA);
6022 }
6023
6024 static void
6025 dissect_ncp_123_17_reply(tvbuff_t *tvb, packet_info* pinfo, proto_tree *volatile ncp_tree)
6026 {
6027     proto_tree              *atree;
6028     proto_item              *aitem;
6029     guint32 loffset, number_of_items, addr_type;
6030     guint16 x;
6031
6032     number_of_items = tvb_get_letohl(tvb, 36);
6033     proto_tree_add_item(ncp_tree, hf_ncp_items_in_packet, tvb, 36, 4, ENC_LITTLE_ENDIAN);
6034     loffset = 40;
6035     for (x = 1; x <= number_of_items; x++)
6036     {
6037         atree = proto_tree_add_subtree_format(ncp_tree, tvb, loffset, -1, ett_ncp, &aitem, "Network Address - %u", x);
6038
6039         addr_type = tvb_get_guint8(tvb, loffset);
6040         proto_tree_add_item(atree, hf_ncp_transport_type, tvb, loffset, 1, ENC_LITTLE_ENDIAN);
6041         /* The address type is one byte of a 4 byte value. The next 4 bytes are
6042          * the length of the address. Since we already know the length based upon
6043          * the type of address, we can skip this value. So set the offset accourdingly */
6044         loffset += 8;
6045
6046         switch (addr_type)
6047         {
6048         case 1:
6049             proto_tree_add_item(atree, hf_nds_net, tvb, loffset, 4, ENC_BIG_ENDIAN);
6050             proto_tree_add_item(atree, hf_nds_node, tvb, loffset+4, 6, ENC_NA);
6051             proto_tree_add_item(atree, hf_nds_socket, tvb, loffset+10, 2, ENC_BIG_ENDIAN);
6052             loffset += 12;
6053             break;
6054         case 5:
6055             proto_tree_add_item(atree, hf_nds_port, tvb, loffset, 2, ENC_BIG_ENDIAN);
6056             proto_tree_add_item(atree, hf_add_ref_udp, tvb, loffset+2, 4, ENC_BIG_ENDIAN);
6057             loffset += 6;
6058             break;
6059         case 6:
6060             proto_tree_add_item(atree, hf_nds_port, tvb, loffset, 2, ENC_BIG_ENDIAN);
6061             proto_tree_add_item(atree, hf_add_ref_tcp, tvb, loffset+2, 4, ENC_BIG_ENDIAN);
6062             loffset += 6;
6063             break;
6064         default:
6065             expert_add_info(pinfo, aitem, &ei_ncp_address_type);
6066             /* unknown type so read the length field and then
6067              * just skip the record and move on to the next */
6068             loffset += tvb_get_letohl(tvb, loffset - 4);
6069             break;
6070         }
6071         proto_item_set_end(aitem, tvb, loffset);
6072         if(tvb_captured_length_remaining(tvb, loffset) < 4 )
6073         {
6074             break;
6075         }
6076     }
6077 }
6078
6079 static void
6080 dissect_ncp_87_72_reply(tvbuff_t *tvb, proto_tree *volatile ncp_tree)
6081 {
6082     proto_tree_add_item(ncp_tree, hf_ncp_bytes_actually_trans_64, tvb, tvb_captured_length_remaining(tvb, 0)-4, 4, ENC_BIG_ENDIAN);
6083 }
6084
6085 static void
6086 dissect_ncp_23_26_reply(tvbuff_t *tvb, proto_tree *volatile ncp_tree)
6087 {
6088     /* For an IP-only server, the 4-byte IP address is placed into the 4-byte NetworkAddress
6089      * field of the NetworkAddressStruct, while the NetworkNodeAddress and NetworkSocket
6090      * fields are left blank. */
6091     if (tvb_get_letohl(tvb, 12)==0) {
6092         /* IP Address */
6093         proto_tree_add_item(ncp_tree, hf_ncp_ip_address, tvb, 8, 4, ENC_BIG_ENDIAN);
6094     }
6095     else
6096     {
6097         /* IPX Address */
6098         proto_tree_add_item(ncp_tree, hf_nds_net, tvb, 8, 4, ENC_BIG_ENDIAN);
6099         proto_tree_add_item(ncp_tree, hf_nds_node, tvb, 12, 6, ENC_NA);
6100         proto_tree_add_item(ncp_tree, hf_nds_socket, tvb, 18, 2, ENC_BIG_ENDIAN);
6101     }
6102     proto_tree_add_item(ncp_tree, hf_ncp_connection_type, tvb, 20, 1, ENC_NA);
6103 }
6104
6105 /*
6106  * XXX - this actually handles both 89 3 and 89 20.
6107  * It should also probably handle 87 3 and 87 20.
6108  */
6109 static void
6110 dissect_ncp_8x20req(tvbuff_t *tvb, proto_tree *volatile ncp_tree, guint32 offset, guint func)
6111 {
6112     guint32 string_len, str_length, buffer_offset;
6113     gint i;
6114     guint8 c_char;
6115     wmem_strbuf_t *string_buf;
6116     gint length_remaining = 0;
6117
6118     length_remaining = tvb_captured_length_remaining(tvb, offset);
6119     /*
6120      * XXX - the Novell documentation for function code 89 (0x59) says
6121      * that the length is 1 byte if the data format byte is 0 for ASCII
6122      * and 2 bytes if the data format byte is 1 for UTF-8.
6123      *
6124      * The documentation for function code 87 (0x57) says it's always
6125      * 1 byte - and that there's no data format byte.
6126      */
6127     if (func == 0x57)
6128     {
6129         string_len = tvb_get_guint8(tvb, offset);
6130         str_length = tvb_get_guint8(tvb, offset);
6131     }
6132     else
6133     {
6134         string_len = tvb_get_letohs(tvb, offset);
6135         str_length = tvb_get_letohs(tvb, offset);
6136     }
6137
6138     if((gint)str_length > length_remaining)
6139     {
6140         THROW(ReportedBoundsError);
6141     }
6142
6143     string_buf = wmem_strbuf_new(wmem_packet_scope(), NULL);
6144     offset++;
6145     buffer_offset = offset;
6146
6147     /*
6148      * XXX - should this treat ASCII and UTF-8 differently?
6149      */
6150     for ( i = 0; i <= (gint)str_length; i++ )
6151     {
6152         c_char = tvb_get_guint8(tvb, buffer_offset );
6153         if (c_char<0x20 || c_char>0x7e)
6154         {
6155             /* Not printable ASCII */
6156             if (c_char == 0xff)
6157             {
6158                 /*
6159                  * 0xff is not a valid ASCII character and is not
6160                  * part of a valid UTF-8 octet sequence.
6161                  *
6162                  * What is the significance of 0xbf, 0xaa, and 0xae
6163                  * here?
6164                  *
6165                  * Will these show up in UTF-8 strings?
6166                  */
6167                 buffer_offset++;
6168                 length_remaining--;
6169                 c_char = tvb_get_guint8(tvb, buffer_offset);
6170                 if (c_char == '?')
6171                 {
6172                     wmem_strbuf_append_c(string_buf, '?');
6173                     proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "Wildcard Question");
6174                 }
6175                 else if (c_char == '*')
6176                 {
6177                     wmem_strbuf_append_c(string_buf, '*');
6178                     proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "Wildcard Asterisk");
6179                 }
6180                 else if (c_char == 0xbf)
6181                 {
6182                     /*
6183                      * For what it's worth, in ISO 8859-1, 0xbf is a
6184                      * Spanish-style upside-down question mark.
6185                      */
6186                     wmem_strbuf_append_c(string_buf, '?');
6187                     proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "DOS Wildcard Question");
6188                 }
6189                 else if (c_char == 0xaa)
6190                 {
6191                     /*
6192                      * But, in 8859-1, this is a feminine ordinal indicator
6193                      * (underlined subscripted "a").
6194                      */
6195                     c_char = '*';
6196                     wmem_strbuf_append_c(string_buf, c_char);
6197                     proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "DOS Wildcard Asterisk");
6198                 }
6199                 else if (c_char == 0xae)
6200                 {
6201                     /*
6202                      * And this is a registered trademark symbol.
6203                      */
6204                     wmem_strbuf_append_c(string_buf, '.');
6205                     proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "DOS Wildcard Period");
6206                 }
6207                 else
6208                 {
6209                     wmem_strbuf_append_c(string_buf, '.');
6210                 }
6211             }
6212             else if (c_char == 0xef)
6213             {
6214                 /*
6215                  * XXX - if these 3-character sequences are considered
6216                  * as UTF-8 sequences, they map to characters in the
6217                  * private use range from f87b to f87f.
6218                  *
6219                  * Is that what's happening here?
6220                  *
6221                  * If so, will these show up in ASCII strings?
6222                  */
6223                 buffer_offset++;
6224                 length_remaining--;
6225                 c_char = tvb_get_guint8(tvb, buffer_offset);
6226                 if (c_char == 0xa3)
6227                 {
6228                     buffer_offset++;
6229                     length_remaining--;
6230                     c_char = tvb_get_guint8(tvb, buffer_offset);
6231                     if (c_char == 0xbb)
6232                     {
6233                         wmem_strbuf_append_c(string_buf, '?');
6234                         proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "Wildcard Question");
6235                     }
6236                     else if (c_char == 0xbc)
6237                     {
6238                         wmem_strbuf_append_c(string_buf, '*');
6239                         proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "Wildcard Asterisk");
6240                     }
6241                     else if (c_char == 0xbd)
6242                     {
6243                         c_char = '?';
6244                         wmem_strbuf_append_c(string_buf, c_char);
6245                         proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "DOS Wildcard Question");
6246                     }
6247                     else if (c_char == 0xbe)
6248                     {
6249                         wmem_strbuf_append_c(string_buf, '*');
6250                         proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "DOS Wildcard Asterisk");
6251                     }
6252                     else if (c_char == 0xbf)
6253                     {
6254                         wmem_strbuf_append_c(string_buf, '.');
6255                         proto_tree_add_uint_format_value(ncp_tree, hf_search_modifier, tvb, buffer_offset-1, 2, c_char, "DOS Wildcard Period");
6256                     }
6257                 }
6258             }
6259             else
6260             {
6261                 if (c_char != 0x00)
6262                 {
6263                     wmem_strbuf_append_c(string_buf, '.');
6264                 }
6265                 else
6266                 {
6267                     i--;
6268                     str_length--;
6269                     offset++;
6270                 }
6271             }
6272         }
6273         else
6274         {
6275             /* printable ASCII */
6276             wmem_strbuf_append_c(string_buf, c_char);
6277         }
6278         buffer_offset++;
6279         length_remaining--;
6280
6281         if(length_remaining==1)
6282         {
6283             break;
6284         }
6285         if (i >= 1023) { /* Don't process beyond the size of our variable */
6286             break;       /* If string is too long just return the first 1K. */
6287         }
6288     }
6289
6290     proto_tree_add_string(ncp_tree, hf_search_pattern, tvb, offset, string_len, wmem_strbuf_get_str(string_buf));
6291 }
6292
6293 static void
6294 dissect_ncp_8x20reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *volatile ncp_tree,
6295                       const ncp_record *ncp_rec, ncp_req_hash_value *request_value)
6296 {
6297     guint16             x;
6298     guint32             loffset, number_of_items, str_length;
6299     ptvcursor_t         *ptvc = NULL;
6300     proto_tree          *atree, *btree;
6301     proto_item          *aitem, *bitem;
6302
6303     if ((request_value->req_mask ==0) & (request_value->req_mask_ext == 0))
6304     {
6305         return;
6306     }
6307     atree = proto_tree_add_subtree(ncp_tree, tvb, 8, 9, ett_ncp, &aitem, "Search Sequence");
6308
6309     proto_tree_add_item(atree, hf_ncp_volume_number, tvb, 8, 1, ENC_LITTLE_ENDIAN);
6310     proto_tree_add_item(atree, hf_ncp_directory_entry_number, tvb, 9, 4, ENC_LITTLE_ENDIAN);
6311     proto_tree_add_item(atree, hf_ncp_sequence_number, tvb, 13, 4, ENC_LITTLE_ENDIAN);
6312
6313     proto_tree_add_item(ncp_tree, hf_ncp_more_flag, tvb, 17, 1, ENC_LITTLE_ENDIAN);
6314     number_of_items = tvb_get_letohs(tvb, 18);
6315     proto_tree_add_item(ncp_tree, hf_ncp_info_count, tvb, 18, 2, ENC_LITTLE_ENDIAN);
6316     loffset = 20;
6317     for (x = 1; x <= number_of_items; x++ )
6318     {
6319         atree = proto_tree_add_subtree_format(ncp_tree, tvb, loffset, -1, ett_ncp, &aitem, "Information Item %u", x);
6320
6321         /* Data Stream Space Allocated */
6322         if (request_value->req_mask & 0x0002) {
6323             proto_tree_add_item(atree, hf_ncp_data_stream_space_alloc, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6324             loffset += 4;
6325         }
6326         else
6327         {
6328             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6329                 loffset += 4;
6330             }
6331         }
6332         /* Attributes */
6333         if (request_value->req_mask & 0x0004) {
6334             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Attributes");
6335
6336             ptvc = ptvcursor_new(btree, tvb, loffset);
6337             process_ptvc_record(ptvc, pinfo, ptvc_struct_attributes_struct,
6338                     NULL, TRUE, ncp_rec, FALSE);
6339             ptvcursor_free(ptvc);
6340             loffset += 6;
6341             proto_item_set_end(bitem, tvb, loffset);
6342         }
6343         else
6344         {
6345             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6346                 loffset += 6;
6347             }
6348         }
6349         /* Data Stream Size */
6350         if (request_value->req_mask & 0x0008) {
6351             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Data Stream Size");
6352
6353             proto_tree_add_item(btree, hf_ncp_data_stream_size, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6354             loffset += 4;
6355             proto_item_set_end(bitem, tvb, loffset);
6356         }
6357         else
6358         {
6359             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6360                 loffset += 4;
6361             }
6362         }
6363         /* Total Stream Size */
6364         if (request_value->req_mask & 0x0010) {
6365             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Total Stream Size");
6366
6367             proto_tree_add_item(btree, hf_ncp_ttl_ds_disk_space_alloc, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6368             proto_tree_add_item(btree, hf_ncp_number_of_data_streams, tvb, loffset+4, 2, ENC_LITTLE_ENDIAN);
6369             loffset += 6;
6370             proto_item_set_end(bitem, tvb, loffset);
6371         }
6372         else
6373         {
6374             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6375                 loffset += 6;
6376             }
6377         }
6378         /* Extended Attributes oldstyle location*/
6379         if (request_value->req_mask & 0x0020 && !ncp_newstyle) {
6380             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Extended Attributes");
6381             ptvc = ptvcursor_new(btree, tvb, loffset);
6382             process_ptvc_record(ptvc, pinfo, ptvc_struct_ea_info_struct,
6383                     NULL, TRUE, ncp_rec, FALSE);
6384             ptvcursor_free(ptvc);
6385             loffset += 12;
6386             proto_item_set_end(bitem, tvb, loffset);
6387         }
6388         else
6389         {
6390             if ((request_value->req_mask_ext & 0x8000)==FALSE && !ncp_newstyle) {
6391                 loffset += 12;
6392             }
6393         }
6394         /* Extended Attributes new style location*/
6395         if (request_value->req_mask & 0x0020 && ncp_newstyle) {
6396             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Extended Attributes");
6397
6398             ptvc = ptvcursor_new(btree, tvb, loffset);
6399             process_ptvc_record(ptvc, pinfo, ptvc_struct_ea_info_struct,
6400                     NULL, TRUE, ncp_rec, FALSE);
6401             ptvcursor_free(ptvc);
6402             loffset += 12;
6403             proto_item_set_end(bitem, tvb, loffset);
6404         }
6405         else
6406         {
6407             if ((request_value->req_mask_ext & 0x8000)==FALSE && ncp_newstyle) {
6408                 loffset += 12;
6409             }
6410         }
6411         /* Archive Information */
6412         if (request_value->req_mask & 0x0040) {
6413             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Archive");
6414             ptvc = ptvcursor_new(btree, tvb, loffset);
6415             process_ptvc_record(ptvc, pinfo, ptvc_struct_archive_info_struct,
6416                     NULL, TRUE, ncp_rec, FALSE);
6417             ptvcursor_free(ptvc);
6418             loffset += 8;
6419             proto_item_set_end(bitem, tvb, loffset);
6420         }
6421         else
6422         {
6423             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6424                 loffset += 8;
6425             }
6426         }
6427         /* Modification Information */
6428         if (request_value->req_mask & 0x0080) {
6429             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Modification");
6430
6431             ptvc = ptvcursor_new(btree, tvb, loffset);
6432             process_ptvc_record(ptvc, pinfo, ptvc_struct_modify_info_struct,
6433                     NULL, TRUE, ncp_rec, FALSE);
6434             ptvcursor_free(ptvc);
6435             loffset += 10;
6436             proto_item_set_end(bitem, tvb, loffset);
6437         }
6438         else
6439         {
6440             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6441                 loffset += 10;
6442             }
6443         }
6444         /* Creation Information old style location */
6445         if (request_value->req_mask & 0x0100 && !ncp_newstyle) {
6446             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Creation");
6447             ptvc = ptvcursor_new(btree, tvb, loffset);
6448             process_ptvc_record(ptvc, pinfo, ptvc_struct_creation_info_struct,
6449                     NULL, TRUE, ncp_rec, FALSE);
6450             ptvcursor_free(ptvc);
6451             loffset += 8;
6452             proto_item_set_end(bitem, tvb, loffset);
6453         }
6454         else
6455         {
6456             if ((request_value->req_mask_ext & 0x8000)==FALSE && !ncp_newstyle) {
6457                 loffset += 8;
6458             }
6459         }
6460         /* Creation Information new style location */
6461         if (request_value->req_mask & 0x0100 && ncp_newstyle) {
6462             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Creation");
6463             ptvc = ptvcursor_new(btree, tvb, loffset);
6464             process_ptvc_record(ptvc, pinfo, ptvc_struct_creation_info_struct,
6465                     NULL, TRUE, ncp_rec, FALSE);
6466             ptvcursor_free(ptvc);
6467             loffset += 8;
6468             proto_item_set_end(bitem, tvb, loffset);
6469         }
6470         else
6471         {
6472             if ((request_value->req_mask_ext & 0x8000)==FALSE && ncp_newstyle) {
6473                 loffset += 8;
6474             }
6475         }
6476         /* Name Space Information */
6477         if (request_value->req_mask & 0x0200) {
6478             proto_tree_add_item(atree, hf_ncp_creator_name_space_number, tvb, loffset, 1, ENC_LITTLE_ENDIAN);
6479             loffset += 4;
6480         }
6481         else
6482         {
6483             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6484                 loffset += 4;
6485             }
6486         }
6487         /* Directory Entry */
6488         if (request_value->req_mask & 0x0400) {
6489             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Directory Entry");
6490             ptvc = ptvcursor_new(btree, tvb, loffset);
6491             process_ptvc_record(ptvc, pinfo, ptvc_struct_dir_entry_struct,
6492                     NULL, TRUE, ncp_rec, FALSE);
6493             ptvcursor_free(ptvc);
6494             loffset += 12;
6495             proto_item_set_end(bitem, tvb, loffset);
6496         }
6497         else
6498         {
6499             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6500                 loffset += 12;
6501             }
6502         }
6503         /* Rights Information */
6504         if (request_value->req_mask & 0x0800) {
6505             ptvc = ptvcursor_new(atree, tvb, loffset);
6506             process_ptvc_record(ptvc, pinfo, ptvc_struct_rights_info_struct,
6507                     NULL, TRUE, ncp_rec, FALSE);
6508             ptvcursor_free(ptvc);
6509             loffset += 2;
6510         }
6511         else
6512         {
6513             if ((request_value->req_mask_ext & 0x8000)==FALSE) {
6514                 loffset += 2;
6515             }
6516         }
6517         /* Return ID Information */
6518         if (request_value->req_mask & 0x1000) {
6519             proto_tree_add_item(atree, hf_ncp_curr_ref_id, tvb, loffset, 2, ENC_LITTLE_ENDIAN);
6520             loffset += 2;
6521         }
6522         /* Return Name Space Attributes Information */
6523         if (request_value->req_mask & 0x2000) {
6524             proto_tree_add_item(atree, hf_ncp_attr_def_32, tvb, loffset, 1, ENC_LITTLE_ENDIAN);
6525             loffset += 4;
6526         }
6527         /* Return Actual Information */
6528         if (request_value->req_mask & 0x4000) {
6529             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Actual");
6530
6531             proto_tree_add_item(btree, hf_ncp_data_stream_num_long, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6532             proto_tree_add_item(btree, hf_ncp_data_stream_fat_blks, tvb, loffset+4, 4, ENC_LITTLE_ENDIAN);
6533             loffset += 8;
6534             proto_item_set_end(bitem, tvb, loffset);
6535         }
6536         /* Return Logical Information */
6537         if (request_value->req_mask & 0x8000) {
6538             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Logical");
6539             proto_tree_add_item(btree, hf_ncp_number_of_data_streams_long, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6540             number_of_items = tvb_get_letohs(tvb, loffset);
6541             loffset += 4;
6542             for (x = 1; x <= number_of_items; x++ )
6543             {
6544                 proto_tree_add_item(btree, hf_ncp_data_stream_num_long, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6545                 proto_tree_add_item(btree, hf_ncp_data_stream_size, tvb, loffset+4, 4, ENC_LITTLE_ENDIAN);
6546                 loffset += 8;
6547             }
6548             proto_item_set_end(bitem, tvb, loffset);
6549         }
6550         /* Last Update */
6551         if (request_value->req_mask_ext & 0x0001 && ncp_newstyle) {
6552             proto_tree_add_item(atree, hf_ncp_sec_rel_to_y2k, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6553             loffset += 4;
6554         }
6555         /* Dos Name */
6556         if (request_value->req_mask_ext & 0x0002 && ncp_newstyle) {
6557             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "DOS Name");
6558
6559             if (ncp_rec->func == 0x57) {
6560                 str_length = tvb_get_guint8(tvb, loffset);
6561                 loffset += 1;
6562             }
6563             else
6564             {
6565                 str_length = tvb_get_letohs(tvb, loffset);
6566                 loffset += 2;
6567             }
6568             proto_tree_add_item(btree, hf_ncp_file_name_12, tvb, loffset, str_length, ENC_ASCII|ENC_NA);
6569             loffset += str_length;
6570             proto_item_set_end(bitem, tvb, loffset);
6571         }
6572         /* Flush Time */
6573         if (request_value->req_mask_ext & 0x0004 && ncp_newstyle) {
6574             ptvc = ptvcursor_new(atree, tvb, loffset);
6575             process_ptvc_record(ptvc, pinfo, ptvc_struct_flush_time_struct,
6576                     NULL, TRUE, ncp_rec, FALSE);
6577             ptvcursor_free(ptvc);
6578             loffset += 4;
6579         }
6580         /* Parental */
6581         if (request_value->req_mask_ext & 0x0008 && ncp_newstyle) {
6582             proto_tree_add_item(atree, hf_ncp_parent_base_id, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6583             loffset += 4;
6584         }
6585         /* MAC finder */
6586         if (request_value->req_mask_ext & 0x0010 && ncp_newstyle) {
6587             proto_tree_add_item(atree, hf_ncp_mac_finder_info, tvb, loffset, 32, ENC_NA);
6588             loffset += 32;
6589         }
6590         /* Sibling */
6591         if (request_value->req_mask_ext & 0x0020 && ncp_newstyle) {
6592             proto_tree_add_item(atree, hf_ncp_sibling_count, tvb, loffset, 4, ENC_LITTLE_ENDIAN);
6593             loffset += 4;
6594         }
6595         /* Effective */
6596         if (request_value->req_mask_ext & 0x0040 && ncp_newstyle) {
6597             proto_tree_add_item(atree, hf_ncp_effective_rights, tvb, loffset, 1, ENC_LITTLE_ENDIAN);
6598             loffset += 4;
6599         }
6600         /* MAC Date */
6601         if (request_value->req_mask_ext & 0x0080 && ncp_newstyle) {
6602             btree = proto_tree_add_subtree(atree, tvb, loffset, -1, ett_ncp, &bitem, "Mac Date");
6603
6604             ptvc = ptvcursor_new(btree, tvb, loffset);
6605             process_ptvc_record(ptvc, pinfo, ptvc_struct_mac_time_struct,
6606                     NULL, TRUE, ncp_rec, FALSE);
6607             ptvcursor_free(ptvc);
6608             loffset += 8;
6609             proto_item_set_end(bitem, tvb, loffset);
6610         }
6611         /* Last Access */
6612         if (request_value->req_mask_ext & 0x0100 && ncp_newstyle) {
6613             ptvc = ptvcursor_new(atree, tvb, loffset);
6614             process_ptvc_record(ptvc, pinfo, ptvc_struct_last_access_time_struct,
6615                     NULL, TRUE, ncp_rec, FALSE);
6616             ptvcursor_free(ptvc);
6617             loffset += 2;
6618         }
6619         /* 64 bit file sizes */
6620         if (request_value->req_mask_ext & 0x0400 && ncp_newstyle) {
6621             proto_tree_add_item(atree, hf_ncp_f_size_64bit, tvb, loffset, 8, ENC_LITTLE_ENDIAN);
6622             loffset += 8;
6623         }
6624         /* We always return the file name */
6625         if (ncp_rec->func == 0x57) {
6626             str_length = tvb_get_guint8(tvb, loffset);
6627             loffset += 1;
6628         }
6629         else
6630         {
6631             str_length = tvb_get_letohs(tvb, loffset);
6632             loffset += 2;
6633         }
6634         proto_tree_add_item(atree, hf_ncp_file_name_12, tvb, loffset, str_length, ENC_UTF_8);
6635         loffset += str_length;
6636
6637         proto_item_set_end(aitem, tvb, loffset);
6638
6639         if(tvb_captured_length_remaining(tvb, loffset) < 4 )
6640         {
6641                 break;
6642         }
6643     }
6644 }
6645
6646 static void
6647 dissect_ncp_123_62_reply(tvbuff_t *tvb, proto_tree *volatile ncp_tree)
6648 {
6649     guint8 cmd_type;
6650     guint8* param_string;
6651     gint ret_len;
6652
6653     cmd_type = tvb_get_guint8(tvb, 8+16);
6654     param_string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, 8+24, &ret_len, ENC_ASCII);
6655
6656     switch (cmd_type) {
6657     case 0:   /* { 0x00, "Numeric Value" }, */
6658     case 2:   /* { 0x02, "Ticks Value" },   */
6659     case 4:   /* { 0x04, "Time Value" },    */
6660     case 6:   /* { 0x06, "Trigger Value" }, */
6661     case 7:   /* { 0x07, "Numeric Value" }, */
6662         proto_tree_add_item(ncp_tree, hf_srvr_param_number, tvb, 37+(gint)strlen(param_string), 4, ENC_LITTLE_ENDIAN);
6663         break;
6664     case 1:   /* { 0x01, "Boolean Value" }, */
6665         proto_tree_add_item(ncp_tree, hf_srvr_param_boolean, tvb, 37+(gint)strlen(param_string), 1, ENC_LITTLE_ENDIAN);
6666         break;
6667     case 5:   /* { 0x05, "String Value" },  */
6668         proto_tree_add_item(ncp_tree, hf_srvr_param_string, tvb, 37+(gint)strlen(param_string), -1, ENC_ASCII|ENC_NA);
6669         break;
6670     default:
6671         break;
6672     }
6673 }
6674
6675 /*
6676  * Defrag logic
6677  *
6678  * NDS fragment not being set to 0xffffffff indicates we are inside or at the
6679  * beginning of a fragment. But when the end of the fragment
6680  * is encounterd the flag is set to 0xffffffff. So we must mark what the
6681  * frame number is of the end fragment so that we will be
6682  * able to redissect if the user clicks on the packet
6683  * or resorts/filters the trace.
6684  *
6685  * Once we are certain that we are in a fragment sequence
6686  * then we can just process each fragment in this conversation
6687  * until we reach the fragment == 0xffffffff packet.
6688  *
6689  * We will be able to easily determine if a conversation is a fragment
6690  * with the exception of the last packet in the fragment. So remember
6691  * the last fragment packet number.
6692  *
6693  * Also the NDS dissection requires the values of NDS Verb, Version, and Flags.
6694  * Without these values being remembered from the first request packet then
6695  * we will be unable to dissect the reply packet. For this reason we remember
6696  * these values on the first fragment and then populate the values in the final
6697  * fragment. We only do this on the first dissection.
6698  */
6699 void
6700 nds_defrag(tvbuff_t *tvb, packet_info *pinfo, guint32 nw_connection, guint8 sequence, guint16 type, proto_tree *tree, struct novell_tap *ncp_tap)
6701 {
6702     int                 i, frag_count=0;
6703     guint               len=0;
6704     guint32             tid = 1;
6705     tvbuff_t            *frag_tvb = NULL;
6706     fragment_head       *fd_head;
6707     ncp_req_hash_value  *request_value = NULL;
6708     conversation_t      *conversation;
6709     guint32             nds_frag;
6710
6711     for (i = 0; i < 99; i++) {
6712         if (!frags[i].nds_fragmented)
6713         {
6714             frags[i].nds_frag = 0xfffffff0;
6715         }
6716     }
6717     /* Check to see if defragmentation is enabeled in the dissector */
6718     if (!nds_defragment) {
6719         dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6720         return;
6721     }
6722     /* Has this already been dissected? */
6723     if (!pinfo->fd->visited) {
6724         /* Find the conversation whence the request would have come. */
6725         conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
6726                                          ENDPOINT_NCP, nw_connection, nw_connection, 0);
6727         if (conversation != NULL) {
6728             /* find the record telling us the request made that caused
6729                this reply */
6730             request_value = ncp_hash_lookup(conversation, sequence, pinfo->num);
6731             if (!request_value) {
6732                 dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6733                 return;
6734             }
6735             p_add_proto_data(wmem_file_scope(), pinfo, proto_ncp, 0, (void*) request_value);
6736         }
6737         /* else... we haven't seen an NCP Request for that conversation and sequence. */
6738         else
6739             {
6740                 dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6741                 return;
6742             }
6743     }
6744     else {
6745         request_value = (ncp_req_hash_value *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ncp, 0);
6746         if (!request_value) {
6747                 dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6748                 return;
6749         }
6750     }
6751     /* Validate that this is an NDS packet */
6752     /* If this isn't an NDS packet then just return */
6753     if (!request_value->ncp_rec ||
6754         request_value->ncp_rec->func!=104 || request_value->ncp_rec->subfunc!=2) {
6755         dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6756         return;
6757     }
6758     /* Check to see if there is at least enough packet info to get the fragment flag */
6759     if (tvb_reported_length_remaining(tvb, 12) < 4) {
6760         dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6761         return;
6762     }
6763     /* Get the fragment flag */
6764     nds_frag = tvb_get_letohl(tvb, 12);
6765
6766     /* Now we need to find if this is a new fragment or already one defined. */
6767     /* We currently limit the maximum number of simultaneous fragments to 100. */
6768     for (i=0; i<100; i++)
6769     {
6770         if (frags[i].nds_frag == nds_frag || frags[i].nds_frag == 0xfffffff0)
6771         {
6772             if (frags[i].nds_frag == 0xfffffff0)
6773                 {
6774                     frags[i].nds_length = 0;
6775                     frags[i].nds_frag = nds_frag;
6776                     frags[i].nds_fragmented = TRUE;
6777                     frags[i].sequence = 0;
6778                 }
6779             break;
6780         }
6781     }
6782     if (i > 99)
6783         return;
6784
6785     frag_count = i;
6786
6787     /* is this the end of an existing fragment or just another reply */
6788     if (nds_frag == 0xffffffff && request_value->nds_frag_num == 0xffffffff)
6789     {
6790         dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6791         return;
6792     }
6793
6794     /* Now we process the fragments */
6795     if (request_value->nds_frag || (request_value->nds_end_frag == pinfo->num))
6796     {
6797         /* Check to see of this is a fragment. If so then mark as a fragment. */
6798         if (frags[frag_count].nds_frag==0xffffffff) {
6799             request_value->nds_frag = FALSE;
6800             /* nds_length of 0 means start of fragment */
6801             frags[frag_count].nds_length = 0;
6802         }
6803         else
6804         {
6805             if (frags[frag_count].nds_length == 0)
6806             {
6807                 frags[frag_count].nds_length = tvb_get_letohl(tvb, 0);
6808             }
6809         }
6810         /*
6811          * Fragment
6812          *
6813          */
6814         tid = (pinfo->srcport+pinfo->destport);
6815         len = tvb_reported_length(tvb);
6816         if (len > 0 && tvb_bytes_exist(tvb, 0, len))
6817         {
6818             if (frags[frag_count].nds_length > len)
6819             {
6820                 /* This is the first fragment so remember the verb, version, and flags. */
6821                 frags[frag_count].nds_frag_verb = request_value->nds_request_verb;
6822                 frags[frag_count].nds_frag_version = request_value->nds_version;
6823                 frags[frag_count].nds_frag_flags = request_value->req_nds_flags;
6824                 frags[frag_count].nds_frag_prot_flags = request_value->req_nds_prot_flags;
6825                 fd_head = fragment_add_seq_next(&nds_reassembly_table, tvb, 0, pinfo, tid, NULL, len, request_value->nds_frag);
6826                 frags[frag_count].sequence = sequence;
6827                 frags[frag_count].nds_length = 1;
6828             }
6829             else
6830             {
6831                 /* Subsequent fragments should be offset by 16 since we do not need */
6832                 /* the additional fragment handle and size fields in our composite data */
6833                 /* Also do not add retransmitted packets, just mark and return */
6834                 if (!pinfo->fd->visited)
6835                 {
6836                     if (sequence != frags[frag_count].sequence) {
6837                         fd_head = fragment_add_seq_next(&nds_reassembly_table, tvb, 16, pinfo, tid, NULL, len-16, request_value->nds_frag);
6838                         frags[frag_count].sequence = sequence;
6839                     }
6840                     else
6841                     {
6842                         col_add_fstr(pinfo->cinfo, COL_INFO, "[Retransmitted NDS Fragment 0x%08x]", frags[frag_count].nds_frag);
6843                         return;
6844                     }
6845                 }
6846                 else
6847                 {
6848                     fd_head = fragment_add_seq_next(&nds_reassembly_table, tvb, 16, pinfo, tid, NULL, len-16, request_value->nds_frag);
6849                     frags[frag_count].sequence = sequence;
6850                 }
6851             }
6852             if (fd_head != NULL)
6853             {
6854                 /* Is this the last fragment? nds_frag will indicate */
6855                 if (fd_head->next != NULL && !request_value->nds_frag)
6856                 {
6857                     frag_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
6858                     add_new_data_source(pinfo,
6859                                         frag_tvb,
6860                                         "Reassembled NDS");
6861                     /* Show all fragments. */
6862                     if (tree)
6863                     {
6864                         proto_item *frag_tree_item;
6865                         show_fragment_seq_tree(fd_head,
6866                                                &nds_frag_items,
6867                                                tree, pinfo,
6868                                                frag_tvb, &frag_tree_item);
6869                         tid++;
6870                     }
6871
6872                     if (!pinfo->fd->visited)
6873                     {
6874                         /* Now we need to find the original fragment number. */
6875                         /* Get the fragment flag */
6876                         nds_frag = tvb_get_letohl(frag_tvb, 12);
6877                         for (i=0; i<100; i++)
6878                         {
6879                             if (frags[i].nds_frag == nds_frag)
6880                             {
6881                                 break;
6882                             }
6883                         }
6884                         if (i > 99)
6885                             return;
6886                         if (frags[i].nds_frag == 0xffffffff)
6887                         {
6888                             /* Error can't find fragment */
6889                             /*DISSECTOR_ASSERT(0);*/
6890                         }
6891                         frag_count = i;
6892                         /* Remember this fragment information so we can dissect.
6893                          * Only do this on the first dissection. After the first
6894                          * dissection we will just read the memory values.
6895                          */
6896                         request_value->nds_end_frag = pinfo->num;
6897                         request_value->nds_request_verb = frags[frag_count].nds_frag_verb;
6898                         request_value->nds_version = frags[frag_count].nds_frag_version;
6899                         request_value->req_nds_flags = frags[frag_count].nds_frag_flags;
6900                         request_value->req_nds_prot_flags = frags[frag_count].nds_frag_prot_flags;
6901                     }
6902
6903                 }
6904                 else
6905                 {
6906                     /* This is either a beggining or middle fragment on second dissection */
6907                     frag_tvb = tvb_new_subset_remaining(tvb, 0);
6908                     if (request_value->nds_frag)
6909                     {
6910                       col_add_fstr(pinfo->cinfo, COL_INFO, "[NDS Fragment 0x%08x]", frags[frag_count].nds_frag);
6911                     }
6912                 }
6913             }
6914             else
6915             {
6916                 /* Fragment from first pass of dissection */
6917                 if (request_value->nds_frag)
6918                 {
6919                    col_add_fstr(pinfo->cinfo, COL_INFO, "[NDS Fragment 0x%08x]", frags[frag_count].nds_frag);
6920                 }
6921
6922                 frag_tvb = NULL;
6923             }
6924         }
6925         else
6926         {
6927             /*
6928              * There are no bytes so Dissect this
6929              */
6930             frag_tvb = tvb_new_subset_remaining(tvb, 0);
6931         }
6932         if (frag_tvb == NULL)
6933         {
6934             /* This is a fragment packet */
6935             frag_tvb = tvb_new_subset_remaining(tvb, 0);
6936             nds_data_handle = find_dissector("data");
6937             call_dissector(nds_data_handle, frag_tvb, pinfo, tree);
6938         }
6939         else
6940         {
6941             /* This is the end fragment so dissect */
6942             if (!request_value->nds_frag) {
6943                 frags[frag_count].nds_length = 0;
6944                 dissect_ncp_reply(frag_tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6945             }
6946         }
6947     }
6948     else
6949     {
6950         /* This is not any fragment packet */
6951         request_value->nds_frag = FALSE;
6952         /* Trap for retransmitted end fragment */
6953         if (request_value->nds_end_frag < pinfo->num) {
6954             col_add_fstr(pinfo->cinfo, COL_INFO, "[Retransmitted end of NDS Fragment 0x%08x, see packet #%d for details.]", request_value->nds_frag_num, request_value->nds_end_frag);
6955         }
6956         else
6957         {
6958             dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree, ncp_tap);
6959         }
6960     }
6961 }
6962
6963 static gboolean ncp2222_dfilters_compiled = FALSE;
6964
6965 static void
6966 ncp2222_compile_dfilters(void)
6967 {
6968     int i;
6969     gchar *err_msg;
6970
6971     for (i = 0; i < NUM_REQ_CONDS; i++) {
6972         if (!dfilter_compile((const gchar*)req_conds[i].dfilter_text,
6973                              &req_conds[i].dfilter, &err_msg)) {
6974             g_error("NCP dissector failed to compile dfilter \"%s\": %s\n",
6975                       req_conds[i].dfilter_text, err_msg);
6976             g_free(err_msg);
6977             g_assert_not_reached();
6978         }
6979     }
6980 }
6981
6982 void
6983 dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
6984                 guint32 nw_connection, guint8 sequence,
6985                 guint16 type, gboolean is_lip_echo_allocate_slot,
6986                 proto_tree *volatile ncp_tree)
6987 {
6988     volatile guint8         func=0;
6989     volatile guint8         subfunc = 0;
6990     gboolean                requires_subfunc = FALSE;
6991     gboolean                has_length = FALSE;
6992     ncp_req_hash_value      *volatile request_value = NULL;
6993     const ncp_record        *volatile ncp_rec = NULL;
6994     conversation_t          *conversation;
6995     ptvcursor_t             *volatile ptvc = NULL;
6996     proto_tree              *temp_tree = NULL;
6997     volatile gboolean       run_req_cond = FALSE;
6998     volatile unsigned long  exception_code;
6999     const char              *volatile message;
7000     proto_item              *ti;
7001
7002
7003     /* We're dissecting an ncp2222 request; Compile the dfilters (if not yet done). */
7004     /* XXX: We do this here rather than at "post-registration" (as previouly done)  */
7005     /*      so compiling over 100 dfilters is done only if needed (thus avoiding    */
7006     /*      compiling the dfilters each time Wireshark is started.                  */
7007     if (! ncp2222_dfilters_compiled) {
7008         ncp2222_compile_dfilters();
7009         ncp2222_dfilters_compiled = TRUE;
7010     }
7011
7012     /* Determine which ncp_record to use. */
7013     switch (type) {
7014     case NCP_ALLOCATE_SLOT:
7015         if (is_lip_echo_allocate_slot) {
7016             ncp_rec = &ncplip_echo;
7017         } else {
7018             ncp_rec = &ncp1111_request;
7019             if (ncp_echo_conn) {
7020                 expert_add_info(pinfo, NULL, &ei_ncp_connection_request);
7021             }
7022         }
7023         break;
7024     case NCP_SERVICE_REQUEST:
7025         func = tvb_get_guint8(tvb, 6);
7026         requires_subfunc = ncp_requires_subfunc(func);
7027         has_length = ncp_has_length_parameter(func);
7028         if (requires_subfunc) {
7029             if (has_length) {
7030                 subfunc = tvb_get_guint8(tvb, 9);
7031             }
7032             else {
7033                 subfunc = tvb_get_guint8(tvb, 7);
7034             }
7035         }
7036         ncp_rec = ncp_record_find(func, subfunc);
7037         break;
7038     case NCP_DEALLOCATE_SLOT:
7039         ncp_rec = &ncp5555_request;
7040         if (ncp_echo_conn) {
7041             expert_add_info_format(pinfo, NULL, &ei_ncp_destroy_connection, "Destroy Connection %u Request", nw_connection);
7042         }
7043         break;
7044     case NCP_BROADCAST_SLOT:
7045         ncp_rec = &ncpbbbb_request;
7046         break;
7047     case NCP_LIP_ECHO:
7048         ncp_rec = &ncplip_echo;
7049         break;
7050     default:
7051         ncp_rec = NULL;
7052         break;
7053     }
7054
7055     /* Fill in the INFO column. */
7056     if (ncp_rec) {
7057         col_add_fstr(pinfo->cinfo, COL_INFO, "C %s", ncp_rec->name);
7058     }
7059     else {
7060         if (requires_subfunc) {
7061             col_add_fstr(pinfo->cinfo, COL_INFO,
7062                             "C Unknown Function %u %u (0x%02X/0x%02x)",
7063                             func, subfunc, func, subfunc);
7064             return;
7065         }
7066         else {
7067             col_add_fstr(pinfo->cinfo, COL_INFO,
7068                             "C Unknown Function %u (0x%02x)",
7069                             func, func);
7070             return;
7071         }
7072     }
7073
7074     if (!pinfo->fd->visited) {
7075         /* This is the first time we've looked at this packet.
7076            Keep track of the address and connection whence the request
7077            came, and the address and connection to which the request
7078            is being sent, so that we can match up calls with replies.
7079            (We don't include the sequence number, as we may want
7080            to have all packets over the same connection treated
7081            as being part of a single conversation so that we can
7082            let the user select that conversation to be displayed.) */
7083         conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
7084                                          ENDPOINT_NCP, nw_connection, nw_connection, 0);
7085
7086         if (conversation == NULL) {
7087             /* It's not part of any conversation - create a new one. */
7088             conversation = conversation_new(pinfo->num, &pinfo->src, &pinfo->dst,
7089                                             ENDPOINT_NCP, nw_connection, nw_connection, 0);
7090         }
7091         request_value = ncp_hash_insert(conversation, sequence, ncp_rec, pinfo->num);
7092         request_value->req_frame_num = pinfo->num;
7093         request_value->req_frame_time = pinfo->abs_ts;
7094
7095         /* If this is the first time we're examining the packet,
7096          * check to see if this NCP type uses a "request condition".
7097          * If so, we have to build a proto_tree because request conditions
7098          * use display filters to work, and without a proto_tree,
7099          * display filters can't possibly work. */
7100         if (ncp_rec) {
7101             if (ncp_rec->req_cond_indexes) {
7102                 run_req_cond = TRUE;
7103             }
7104         }
7105     }
7106
7107     /* If we have to handle a request condition, or have to
7108        add to the Info column, we need to construct a protocol
7109        tree.  If we already have a proto_tree, then wonderful.
7110        If we don't, we need to build one. */
7111     if (run_req_cond && !ncp_tree) {
7112         temp_tree = proto_tree_create_root(pinfo);
7113         proto_tree_set_visible(temp_tree, FALSE);
7114         ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, ENC_NA);
7115         ncp_tree = proto_item_add_subtree(ti, ett_ncp);
7116     }
7117
7118     if (ncp_tree) {
7119         /* If the dissection throws an exception, be sure to free
7120          * the temporary proto_tree that was created. Because of the
7121          * way the CLEANUP_PUSH macro works, we can't put it in an 'if'
7122          * block; it has to be in the same scope as the terminating
7123          * CLEANUP_POP or CLEANUP_POP_AND_ALLOC. So, we always
7124          * call CLEANUP_POP and friends, but the value of temp_tree is
7125          * NULL if no cleanup is needed, and non-null if cleanup is needed. */
7126         CLEANUP_PUSH_PFX(xx,free_proto_tree, temp_tree);
7127
7128 #ifdef FAKE_TREE_IS_VISIBLE
7129         PTREE_DATA(ncp_tree)->visible=1;
7130 #endif
7131
7132         /* Before the dissection, if we're saving data for a request
7133          * condition, we have to prime the proto tree using the
7134          * dfilter information */
7135         if (run_req_cond) {
7136             const int *needed;
7137             dfilter_t *dfilter;
7138
7139             needed = ncp_rec->req_cond_indexes;
7140
7141             while (*needed != -1) {
7142                 dfilter = req_conds[*needed].dfilter;
7143                 /* Prime the proto_tree with "interesting fields". */
7144                 dfilter_prime_proto_tree(dfilter, ncp_tree);
7145                 needed++;
7146             }
7147         }
7148
7149         switch (type) {
7150         case NCP_BROADCAST_SLOT:
7151             ; /* nothing */
7152             break;
7153
7154         case NCP_SERVICE_REQUEST:
7155             proto_tree_add_uint_format_value(ncp_tree, hf_ncp_func, tvb, 6, 1,
7156                                        func, "%u (0x%02X), %s",
7157                                        func, func, ncp_rec ? ncp_rec->name : "Unknown");
7158             break;
7159
7160         default:
7161             ; /* nothing */
7162             break;
7163         }
7164         if (request_value) {
7165             request_value->length = 0;
7166         }
7167         if (requires_subfunc) {
7168             if (has_length) {
7169                 if (request_value && func==123) {
7170                     request_value->length = tvb_get_ntohs(tvb, 7);
7171                 }
7172                 proto_tree_add_item(ncp_tree, hf_ncp_length, tvb, 7,
7173                                     2, ENC_BIG_ENDIAN);
7174                 proto_tree_add_uint(ncp_tree, hf_ncp_subfunc, tvb, 9, 1, subfunc);
7175                 ptvc = ptvcursor_new(ncp_tree, tvb, 10);
7176             }
7177             else {
7178                 proto_tree_add_uint(ncp_tree, hf_ncp_subfunc, tvb, 7, 1, subfunc);
7179                 ptvc = ptvcursor_new(ncp_tree, tvb, 8);
7180             }
7181         }
7182         else {
7183             ptvc = ptvcursor_new(ncp_tree, tvb, 7);
7184         }
7185
7186         /* The group is not part of the packet, but it's useful
7187          * information to display anyway. Put it in the tree for filtering and tap use*/
7188         if (ncp_rec) {
7189             ti = proto_tree_add_uint_format_value(ncp_tree, hf_ncp_group, tvb, 0, 0, ncp_rec->group, "%s", ncp_groups[ncp_rec->group]);
7190             proto_item_set_generated(ti);
7191         }
7192
7193         exception_code = 0;
7194         message = NULL;
7195         if (ncp_rec && ncp_rec->request_ptvc) {
7196             clear_repeat_vars();
7197             /*
7198              * We need to remember the results even if we
7199              * throw an exception dissecting this request,
7200              * so that we can properly dissect the reply.
7201              * We catch any exceptions thrown when
7202              * dissecting the request, and re-throw them
7203              * after saving the results of any conditional
7204              * tests.
7205              */
7206             TRY {
7207                 process_ptvc_record(ptvc, pinfo, ncp_rec->request_ptvc, NULL, TRUE, ncp_rec, TRUE);
7208             } CATCH_ALL {
7209                 exception_code = EXCEPT_CODE;
7210                 message = GET_MESSAGE;
7211             }
7212             ENDTRY;
7213         }
7214         ptvcursor_free(ptvc);
7215
7216         /* Now that the dissection is done, do we need to run
7217          * some display filters on the resulting tree in order
7218          * to save results for "request conditions" ? */
7219         if (run_req_cond) {
7220             const int   *needed;
7221             gboolean    *results;
7222             dfilter_t   *dfilter;
7223
7224             results = (gboolean *)wmem_alloc0(wmem_file_scope(), sizeof(gboolean)*NUM_REQ_CONDS);
7225             needed = ncp_rec->req_cond_indexes;
7226
7227             while (*needed != -1) {
7228                 /* ncp_tree is not a root proto_tree, but
7229                  * dfilters will still work on it. */
7230                 dfilter = req_conds[*needed].dfilter;
7231                 results[*needed] = dfilter_apply(dfilter, ncp_tree);
7232                 needed++;
7233             }
7234
7235             /* Save the results so the reply packet dissection
7236              * get to them. */
7237             request_value->req_cond_results = results;
7238         }
7239
7240         if (!request_value)
7241         {
7242              conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
7243                                                  ENDPOINT_NCP, nw_connection, nw_connection, 0);
7244              if (conversation != NULL) {
7245                  /* find the record telling us the request made that caused
7246                     this reply */
7247                  request_value = ncp_hash_lookup(conversation, sequence, pinfo->num);
7248               }
7249         }
7250         /* SecretStore packets are dessected in packet-ncp-sss.c */
7251         if (func == 0x5c && ncp_tree) {
7252             dissect_sss_request(tvb, pinfo, ncp_tree, request_value);
7253         }
7254         /* NMAS packets are dessected in packet-ncp-nmas.c */
7255         if (func == 0x5e && ncp_tree) {
7256             dissect_nmas_request(tvb, pinfo, ncp_tree, request_value);
7257         }
7258
7259         /* Store NCP request specific flags for manual dissection */
7260         if ((func == 0x57 || func == 0x59) && subfunc == 0x14 && ncp_tree && request_value) {
7261             request_value->req_mask = tvb_get_letohs(tvb, 8+4);
7262             request_value->req_mask_ext = tvb_get_letohs(tvb, 8+6);
7263         }
7264         /* NCP function 89/6 passes either ASCII or UTF8 data */
7265         /* Decode manually since it is not possible to SREC the request */
7266         /* packets from the python code */
7267         if (func == 0x59 && subfunc == 0x6) {
7268             dissect_ncp_89_6_request(tvb, ncp_tree, 22);
7269         }
7270         /*
7271          * Need to parse for Novell specific wildcard values in Search
7272          * Pattern, decode this ncp (89)/20 and (89)/03 req manually here.
7273          *
7274          * XXX - do 0x57/87 and 0x59/89 both have this?  87 doesn't
7275          * appear to have the ASCII/UTF-8 data type field.
7276          */
7277         if (ncp_rec->func == 0x59 && (ncp_rec->subfunc == 0x14 || ncp_rec->subfunc == 0x03)) {
7278             if (ncp_rec->subfunc == 0x03)
7279             {
7280                  dissect_ncp_8x20req(tvb, ncp_tree, 26, ncp_rec->func);
7281             }
7282 /*if (ncp_rec->func == 0x57)
7283 {
7284             dissect_ncp_8x20req(tvb, ncp_tree, 27, ncp_rec->func);
7285 }*/
7286             else
7287             {
7288                 dissect_ncp_8x20req(tvb, ncp_tree, 28, ncp_rec->func);
7289             }
7290         }
7291         /* Free the temporary proto_tree */
7292         CLEANUP_CALL_AND_POP_PFX(xx);
7293
7294         /* Re-throw any exception. */
7295         if (exception_code != 0)
7296             THROW_MESSAGE(exception_code, message);
7297     }
7298 }
7299
7300 static void
7301 dissect_nds_ping_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
7302                        proto_tree *ncp_tree, ncp_req_hash_value *request_value)
7303 {
7304     guint8     ping_version;
7305     guint32    nds_string_len;
7306     guint32    nds_offset;
7307     guint32    bvalue;
7308     guint32    nds_flags;
7309     int        i;
7310     nstime_t   ns;
7311
7312     ping_version = tvb_get_guint8(tvb, 8);
7313     proto_tree_add_item(ncp_tree, hf_ping_version, tvb, 8, 1, ENC_NA);
7314     if (ping_version == 9) {
7315         nds_string_len = tvb_get_ntohl(tvb, 9);
7316         nds_offset = nds_string_len+16;
7317         proto_tree_add_item(ncp_tree, hf_nds_tree_name, tvb, 16, nds_string_len, ENC_ASCII|ENC_NA);
7318         proto_tree_add_item(ncp_tree, hf_nds_reply_depth, tvb, nds_offset, 4, ENC_BIG_ENDIAN);
7319         proto_tree_add_item(ncp_tree, hf_nds_reply_rev, tvb, (nds_offset+4), 4, ENC_BIG_ENDIAN);
7320         proto_tree_add_item(ncp_tree, hf_nds_reply_flags, tvb, (nds_offset+8), 4, ENC_LITTLE_ENDIAN);
7321     }
7322     else {
7323         nds_offset = 12;
7324         nds_flags = request_value->req_nds_flags;
7325         bvalue = 0x00000001;
7326
7327         for (i = 0 ; i < 32; i++ ) {
7328             if (nds_flags & bvalue)
7329             {
7330                 switch(bvalue)
7331                 {
7332                 case 0x00000001:   /* Supported Fields */
7333                     proto_tree_add_bitmask(ncp_tree, tvb, nds_offset, hf_pingflags1, ett_ncp, ncp_pingflags1, ENC_LITTLE_ENDIAN);
7334                     nds_offset += 2;
7335                     proto_tree_add_bitmask(ncp_tree, tvb, nds_offset, hf_pingflags2, ett_ncp, ncp_pingflags2, ENC_LITTLE_ENDIAN);
7336                     nds_offset += 2;
7337                     break;
7338                 case 0x00000002:
7339                     proto_tree_add_item(ncp_tree, hf_nds_reply_depth, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7340                     nds_offset += 4;
7341                     break;
7342                 case 0x00000004:
7343                     proto_tree_add_item(ncp_tree, hf_nds_reply_rev, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7344                     nds_offset += 4;
7345                     break;
7346                 case 0x00000008:
7347                     proto_tree_add_bitmask(ncp_tree, tvb, nds_offset, hf_pingpflags1, ett_ncp, ncp_pingpflags1, ENC_LITTLE_ENDIAN);
7348                     nds_offset += 4;
7349                     break;
7350                 case 0x00000010:
7351                     proto_tree_add_bitmask(ncp_tree, tvb, nds_offset, hf_pingvflags1, ett_ncp, ncp_pingvflags1, ENC_LITTLE_ENDIAN);
7352                     nds_offset += 4;
7353                     break;
7354                 case 0x00000020:
7355                     proto_tree_add_item(ncp_tree, hf_nds_letter_ver, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7356                     nds_offset += 4;
7357                     break;
7358                 case 0x00000040:
7359                     proto_tree_add_item(ncp_tree, hf_nds_os_majver, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7360                     nds_offset += 4;
7361                     proto_tree_add_item(ncp_tree, hf_nds_os_minver, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7362                     nds_offset += 4;
7363                     proto_tree_add_item(ncp_tree, hf_ncp_os_revision, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7364                     nds_offset += 4;
7365                     break;
7366                 case 0x00000100:
7367                     proto_tree_add_item(ncp_tree, hf_nds_lic_flags, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7368                     nds_offset += 4;
7369                     break;
7370                 case 0x00000200:
7371                     ns.secs = tvb_get_letohl(tvb, nds_offset);
7372                     ns.nsecs = 0;
7373                     proto_tree_add_time(ncp_tree, hf_nds_ds_time, tvb, nds_offset, 4, &ns);
7374                     nds_offset += 4;
7375                     break;
7376                 case 0x00000400:
7377                     ns.secs = tvb_get_letohl(tvb, nds_offset);
7378                     ns.nsecs = 0;
7379                     proto_tree_add_time(ncp_tree, hf_nds_svr_time, tvb, nds_offset, 4, &ns);
7380                     nds_offset += 4;
7381                     break;
7382                 case 0x00000800:
7383                     ns.secs = tvb_get_letohl(tvb, nds_offset);
7384                     ns.nsecs = 0;
7385                     proto_tree_add_time(ncp_tree, hf_nds_crt_time, tvb, nds_offset, 4, &ns);
7386                     nds_offset += 4;
7387                     break;
7388                 case 0x00010000:
7389                     if(tvb_get_guint8(tvb, nds_offset) == 0x00)
7390                     {
7391                         nds_offset += 2;
7392                     }
7393                     nds_string_len = tvb_get_letohl(tvb, nds_offset);
7394                     nds_offset += 4;
7395                     proto_tree_add_item(ncp_tree, hf_sap_name, tvb, nds_offset, nds_string_len, ENC_ASCII|ENC_NA);
7396                     nds_offset += nds_string_len;
7397                     nds_offset += align_4(tvb, nds_offset);
7398                     break;
7399                 case 0x00020000:
7400                     if(tvb_get_guint8(tvb, nds_offset) == 0x00)
7401                     {
7402                         nds_offset += 2;
7403                     }
7404                     nds_string_len = tvb_get_letohl(tvb, nds_offset);
7405                     nds_offset += 4;
7406                     proto_tree_add_item(ncp_tree, hf_nds_tree_name, tvb, nds_offset, nds_string_len, ENC_ASCII|ENC_NA);
7407                     nds_offset += nds_string_len;
7408                     nds_offset += align_4(tvb, nds_offset);
7409                     break;
7410                 case 0x00040000:
7411                     if(tvb_get_guint8(tvb, nds_offset) == 0x00)
7412                     {
7413                         nds_offset += 2;
7414                     }
7415                     nds_string_len = tvb_get_letohl(tvb, nds_offset);
7416                     nds_offset += 4;
7417                     proto_tree_add_item(ncp_tree, hf_os_name, tvb, nds_offset, nds_string_len, ENC_ASCII|ENC_NA);
7418                     nds_offset += nds_string_len;
7419                     nds_offset += align_4(tvb, nds_offset);
7420                     break;
7421                 case 0x00080000:
7422                     if(tvb_get_guint8(tvb, nds_offset) == 0x00)
7423                     {
7424                         nds_offset += 2;
7425                     }
7426                     nds_string_len = tvb_get_letohl(tvb, nds_offset);
7427                     nds_offset += 4;
7428                     proto_tree_add_item(ncp_tree, hf_hardware_name, tvb, nds_offset, nds_string_len, ENC_ASCII|ENC_NA);
7429                     nds_offset += nds_string_len;
7430                     nds_offset += align_4(tvb, nds_offset);
7431                     break;
7432                 case 0x00100000:
7433                     if(tvb_get_guint8(tvb, nds_offset) == 0x00)
7434                     {
7435                         nds_offset += 2;
7436                     }
7437                     nds_string_len = tvb_get_letohl(tvb, nds_offset);
7438                     nds_offset += 4;
7439                     proto_tree_add_item(ncp_tree, hf_vendor_name, tvb, nds_offset, nds_string_len, ENC_ASCII|ENC_NA);
7440                     nds_offset += nds_string_len;
7441                     nds_offset += align_4(tvb, nds_offset);
7442                     break;
7443                 default:
7444                     break;
7445                 }
7446             }
7447             bvalue = bvalue*2;
7448         }
7449     }
7450 }
7451
7452 static void
7453 dissect_nds_reply(tvbuff_t *tvb, packet_info *pinfo,
7454                   proto_tree *ncp_tree, guint32 nds_error_code,
7455                   const char *nds_error_string, ncp_req_hash_value *request_value,
7456                   conversation_t *conversation)
7457 {
7458     guint32                         nds_offset;
7459     proto_item                      *expert_item;
7460     const char                      *verb_string;
7461     gboolean                        resolve_eid=FALSE;
7462     guint32                         global_eid=0;
7463     gboolean                        add_eid = FALSE;
7464     char                            *global_object_name = NULL;
7465     ncp_req_eid_hash_value          *request_eid_value = NULL;
7466     nds_val                         temp_value;
7467
7468     nds_offset = 8;
7469
7470     proto_tree_add_item(ncp_tree, hf_ncp_fragment_size, tvb, nds_offset,
7471                         4, ENC_LITTLE_ENDIAN);
7472     nds_offset += 4;
7473     proto_tree_add_item(ncp_tree, hf_ncp_fragment_handle, tvb, nds_offset,
7474                         4, ENC_LITTLE_ENDIAN);
7475     nds_offset += 4;
7476     /*
7477      * Is the possibly-reassembled reply large enough to have a completion
7478      * code?  (We can't check the fragment size as this might just be the
7479      * last fragment.)
7480      */
7481     if (tvb_reported_length_remaining(tvb, nds_offset) >= 4)
7482     {
7483         /* Yes - process the completion code. */
7484         expert_item = proto_tree_add_uint_format(ncp_tree, hf_nds_reply_error, tvb, nds_offset,
7485                                                  4, nds_error_code, "NDS Completion Code: 0x%08x, %s",
7486                                                  nds_error_code, nds_error_string);
7487
7488         if (nds_error_code != 0 && ncp_echo_err) {
7489             expert_add_info_format(pinfo, expert_item, &ei_nds_reply_error, "NDS Error: 0x%08x %s", nds_error_code, nds_error_string);
7490         }
7491     }
7492
7493     if ((request_value == NULL) || (nds_error_code != 0))
7494         return;
7495
7496     nds_offset = 20;
7497     verb_string = val_to_str_const(request_value->nds_request_verb,
7498                                     ncp_nds_verb_vals, "Continuation Fragment");
7499     if(request_value->req_nds_prot_flags & 0x4000)
7500     {
7501         /* CRC is included in the NDS header so justify the offset */
7502         proto_tree_add_item(ncp_tree, hf_nds_crc, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7503         nds_offset += 4;
7504     }
7505
7506     if(request_value->nds_request_verb != 0)
7507     {
7508         proto_tree_add_uint_format_value(ncp_tree,
7509                                     hf_ncp_nds_verb, tvb, 6, 0,
7510                                     request_value->nds_request_verb,
7511                                     "%d, %s",
7512                                     request_value->nds_request_verb, verb_string);
7513     }
7514
7515     memset(&temp_value, 0, sizeof(temp_value));
7516     switch (request_value->nds_request_verb)
7517     {
7518     case 0x01:
7519         proto_tree_add_item_ret_uint(ncp_tree, hf_nds_tag_string, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN, &temp_value.vvalue);
7520         nds_offset += 4;
7521
7522         switch(temp_value.vvalue)
7523         {
7524         case NDS_TAG_NO_SUCH_ENTRY:
7525             break;
7526         case NDS_TAG_LOCAL_ENTRY:
7527             proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN, &global_eid);
7528             add_eid = TRUE;
7529             resolve_eid = TRUE;
7530             global_object_name = request_value->object_name;
7531             nds_offset += 4;
7532
7533             temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7534             temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7535             temp_value.vdesc = "Referral Records: %u";
7536             temp_value.vlength = 4;
7537             temp_value.voffset = nds_offset;
7538             temp_value.hfname = hf_nds_referrals;
7539             temp_value.mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY;
7540             process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7541             break;
7542         case NDS_TAG_REMOTE_ENTRY:
7543             nds_offset += 4;   /* GUINT32 reserved field */
7544             proto_tree_add_item(ncp_tree, hf_nds_eid, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7545             nds_offset += 4;
7546             temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7547             temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7548             temp_value.vdesc = "Referral Records: %u";
7549             temp_value.vlength = 4;
7550             temp_value.voffset = nds_offset;
7551             temp_value.hfname = hf_nds_referrals;
7552             temp_value.mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY;
7553             process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7554             break;
7555         case NDS_TAG_ALIAS_ENTRY:
7556             temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7557             if (temp_value.vvalue == 0x00)
7558                 break;
7559
7560             temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, nds_offset+4, temp_value.vvalue, ENC_UTF_16|ENC_LITTLE_ENDIAN);
7561             proto_tree_add_string_format(ncp_tree, hf_nds_name, tvb, nds_offset, 4+temp_value.vvalue, temp_value.vstring, "Alias Name: %s", temp_value.vstring);
7562             break;
7563         case NDS_TAG_REFERRAL_INFORMATION:
7564             temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7565             proto_tree_add_uint_format(ncp_tree, hf_nds_eid, tvb, nds_offset, 4, temp_value.vvalue, "Distance Object is From Root: 0x%08x", temp_value.vvalue);
7566             nds_offset += 4;
7567
7568             temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7569             temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7570             temp_value.vdesc = "Referral Records: %u";
7571             temp_value.vlength = 4;
7572             temp_value.voffset = nds_offset;
7573             temp_value.hfname = hf_nds_referrals;
7574             temp_value.mvtype = MVTYPE_ADDR_REFERRAL_REPLY;
7575             process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7576             break;
7577         case NDS_TAG_ENTRY_AND_REFERRALS:
7578             proto_tree_add_item(ncp_tree, hf_nds_result_flags, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7579             nds_offset += 4;
7580             proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN, &global_eid);
7581             add_eid = TRUE;
7582             resolve_eid = TRUE;
7583             global_object_name = request_value->object_name;
7584             nds_offset += 4;
7585
7586             temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7587             temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7588             temp_value.vdesc = "Referral Records: %u";
7589             temp_value.vlength = 4;
7590             temp_value.voffset = nds_offset;
7591             temp_value.hfname = hf_nds_referrals;
7592             temp_value.mvtype = MVTYPE_ADDR_REFERRAL_REPLY;
7593             process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7594             break;
7595         default:
7596             break;
7597         }
7598         break;
7599     case 0x02:
7600         nds_offset -= 4;
7601         temp_value.vvalue = 1;
7602         temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7603         temp_value.vdesc = "Entry Information";
7604         temp_value.vlength = 0;
7605         temp_value.voffset = nds_offset;
7606         temp_value.hfname = hf_nds_name;
7607         temp_value.mvtype = MVTYPE_LIST_PARTITIONS;
7608         temp_value.vflags = request_value->req_nds_flags;
7609         process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7610         break;
7611     case 0x03:
7612         proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7613         nds_offset += 4;
7614         proto_tree_add_item(ncp_tree, hf_nds_info_type, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7615         nds_offset += 4;
7616
7617         temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7618         temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7619         temp_value.vdesc = "Number of Attributes: %u";
7620         temp_value.vlength = 4;
7621         temp_value.voffset = nds_offset;
7622         temp_value.hfname = hf_nds_attr;
7623         temp_value.mvtype = MVTYPE_ATTR_REPLY;
7624         temp_value.vflags = request_value->req_nds_flags;
7625         temp_value.nds_version = request_value->nds_version;
7626         temp_value.pflags = request_value->req_nds_prot_flags;
7627         process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7628         break;
7629     case 0x04:
7630         temp_value.vvalue = tvb_get_guint8(tvb, nds_offset);
7631         if (temp_value.vvalue == 0)
7632         {
7633             proto_tree_add_uint_format_value(ncp_tree, hf_nds_compare_results, tvb, nds_offset, 1, temp_value.vvalue, "Did Not Match");
7634         }
7635         else
7636         {
7637             proto_tree_add_uint_format_value(ncp_tree, hf_nds_compare_results, tvb, nds_offset, 1, temp_value.vvalue, "Matched");
7638         }
7639         break;
7640     case 0x05:
7641         proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7642         nds_offset += 4;
7643
7644         temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7645         temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7646         temp_value.vdesc = "Entry Information";
7647         temp_value.vlength = 0;
7648         temp_value.voffset = nds_offset;
7649         temp_value.hfname = hf_nds_name;
7650         temp_value.mvtype = MVTYPE_LIST_PARTITIONS;
7651         temp_value.vflags = request_value->req_nds_flags;
7652         process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7653         break;
7654     case 0x06:
7655     case 0x07:
7656     case 0x08:
7657     case 0x09:
7658     case 0x0a:
7659     case 0x0b:
7660     case 0x0c:
7661     case 0x0d:
7662     case 0x0e:
7663         break;
7664     case 0x0f:
7665         proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7666         nds_offset += 4;
7667         proto_tree_add_item(ncp_tree, hf_nds_class_def_type, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7668         nds_offset += 4;
7669
7670         temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7671         temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7672         temp_value.vdesc = "Class Definitions %u";
7673         temp_value.vlength = 0;
7674         temp_value.voffset = nds_offset;
7675         temp_value.hfname = hf_nds_classes;
7676         temp_value.mvtype = MVTYPE_CLASS_NAMES;
7677         temp_value.vflags = request_value->req_nds_flags;
7678         process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7679         break;
7680     case 0x10:
7681     case 0x11:
7682         break;
7683     case 0x12:
7684         proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7685         nds_offset += 4;
7686
7687         temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7688         temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7689         temp_value.vdesc = "Classes: %u";
7690         temp_value.vlength = 4;
7691         temp_value.voffset = nds_offset;
7692         temp_value.mvtype = MVTYPE_READ_CLASS_REQ;
7693         temp_value.hfname= hf_nds_classes;
7694         process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7695         break;
7696     case 0x13:
7697         proto_tree_add_item(ncp_tree, hf_nds_privileges, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7698         break;
7699     case 0x14:
7700     case 0x15:
7701         break;
7702     case 0x16:
7703         proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7704         nds_offset += 4;
7705
7706         temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7707         if (temp_value.vvalue == 0)
7708             break;
7709
7710         temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, nds_offset+4, temp_value.vvalue, ENC_UTF_16|ENC_LITTLE_ENDIAN);
7711         proto_tree_add_string_format(ncp_tree, hf_nds_name, tvb, nds_offset, 4+temp_value.vvalue, temp_value.vstring, "Server Distinguished Name: %s", temp_value.vstring);
7712         nds_offset += 4+temp_value.vvalue;
7713         nds_offset += align_4(tvb, nds_offset);
7714
7715         temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7716         temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7717         temp_value.vdesc = "Replicas: %u";
7718         temp_value.vlength = 4;
7719         temp_value.voffset = nds_offset;
7720         temp_value.hfname = hf_nds_replicas;
7721         temp_value.mvtype = MVTYPE_READ_REPLICAS;
7722         temp_value.bit1 = "Output Flags";
7723         temp_value.bit2 = "Entry ID";
7724         temp_value.bit3 = "Replica State";
7725         temp_value.bit4 = "Modification Timestamp";
7726         temp_value.bit5 = "Purge Time";
7727         temp_value.bit6 = "Local Partition ID";
7728         temp_value.bit7 = "Distinguished Name";
7729         temp_value.bit8 = "Replica Type";
7730         temp_value.bit9 = "Partition Busy";
7731         temp_value.vflags = request_value->req_nds_flags;
7732         process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7733         break;
7734     case 0x17:
7735     case 0x18:
7736     case 0x19:
7737     case 0x1a:
7738         break;
7739     case 0x1b:
7740         proto_tree_add_item(ncp_tree, hf_nds_file_handle, tvb, nds_offset, 4, ENC_BIG_ENDIAN);
7741         nds_offset += 4;
7742         proto_tree_add_item(ncp_tree, hf_nds_file_size, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7743         break;
7744     case 0x1c:
7745     case 0x1d:
7746     case 0x1e:
7747     case 0x1f:
7748     case 0x20:
7749     case 0x21:
7750     case 0x22:
7751     case 0x23:
7752     case 0x24:
7753     case 0x25:
7754     case 0x26:
7755     case 0x27:
7756     case 0x28:
7757     case 0x29:
7758     case 0x2a:
7759     case 0x2b:
7760     case 0x2c:
7761     case 0x2d:
7762     case 0x2e:
7763     case 0x2f:
7764     case 0x30:
7765     case 0x31:
7766     case 0x32:
7767     case 0x33:
7768     case 0x34:
7769         break;
7770     case 0x35:
7771         temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7772         temp_value.vdesc = "Server Name";
7773         temp_value.mvtype = MVTYPE_PROCESS_TAGS;
7774         temp_value.vflags = request_value->req_nds_flags;
7775         temp_value.hfname = hf_nds_svr_dst_name;
7776         temp_value.vlength = tvb_get_letohl(tvb, nds_offset);
7777         if (temp_value.vlength == 0x00)
7778             break;
7779
7780         temp_value.voffset = nds_offset;
7781         process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7782         nds_offset += temp_value.vlength + 4;
7783         nds_offset += align_4(tvb, nds_offset);
7784
7785         temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7786         temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
7787         temp_value.vdesc = "Referral Records: %u";
7788         temp_value.vlength = 4;
7789         temp_value.voffset = nds_offset;
7790         temp_value.hfname = hf_nds_referrals;
7791         temp_value.mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY;
7792         process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
7793         break;
7794     case 0x36:
7795     case 0x37:
7796     case 0x38:
7797         break;
7798     case 0x39:
7799         proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN, &global_eid);
7800         add_eid = TRUE;
7801         resolve_eid = TRUE;
7802         global_object_name = request_value->object_name;
7803         break;
7804     case 0x3a:
7805     case 0x3b:
7806     case 0x3c:
7807     case 0x3d:
7808     case 0x3e:
7809     case 0x3f:
7810     case 0x40:
7811     case 0x41:
7812     case 0x42:
7813     case 0x43:
7814     case 0x44:
7815     case 0x45:
7816     case 0x46:
7817     case 0x47:
7818     case 0x48:
7819     case 0x49:
7820     case 0x4a:
7821     case 0x4b:
7822     case 0x4c:
7823     case 0x4d:
7824         break;
7825     case 0x6e:
7826         proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN);
7827         nds_offset += 4;
7828         expert_item = proto_tree_add_item_ret_uint(ncp_tree, hf_iter_completion_code, tvb, nds_offset, 4, ENC_LITTLE_ENDIAN, &temp_value.vvalue);
7829         nds_offset += 4;
7830
7831         if (temp_value.vvalue != 0 && ncp_echo_err) {
7832             expert_add_info_format(pinfo, expert_item, &ei_nds_iteration, "NDS Iteration Error: 0x%08x %s",
7833                                     temp_value.vvalue, val_to_str(temp_value.vvalue, nds_reply_errors, "Unknown: %d"));
7834         }
7835         temp_value.vvalue = tvb_get_letohl(tvb, nds_offset);
7836         temp_value.vtype = VTYPE_ITEM;
7837         temp_value.vlength = 4;
7838         temp_value.voffset = nds_offset;
7839         temp_value.mvtype = MVTYPE_PROCESS_ITERATOR;
7840         temp_value.hfname = hf_ncp_nds_iterverb;
7841         dissect_nds_iterator(ncp_tree, tvb, pinfo, temp_value.vvalue, 0, nds_offset, FALSE);
7842         break;
7843     default:
7844         break;
7845     }
7846     /* NDS Entry ID's (EID) is identified in the reply
7847         * packet of an NDS resolve name. We need to store
7848         * this EID and its associated name into our hash
7849         * so that we can resolve the name for other NDS
7850         * requests. */
7851     if (!pinfo->fd->visited) {
7852         if(add_eid)
7853         {
7854             request_eid_value = ncp_eid_hash_lookup(conversation, global_eid);
7855             if (!request_eid_value) {
7856                 request_eid_value = ncp_eid_hash_insert(global_eid);
7857                 if (global_object_name != NULL)
7858                     g_strlcpy(request_eid_value->object_name, global_object_name, 256);
7859                 else
7860                     request_eid_value->object_name[0] = '\0';
7861             }
7862         }
7863     }
7864     /* Echo EID data to expert Chat window */
7865     if (add_eid && nds_echo_eid) {
7866         expert_add_info_format(pinfo, NULL, &ei_ncp_eid,
7867                                 "EID (%08x) = %s", global_eid, global_object_name);
7868     }
7869     /* For NDS requests with just an EID, resolve name
7870         * from hash table. */
7871     if(resolve_eid)
7872     {
7873         request_eid_value = ncp_eid_hash_lookup(conversation, global_eid);
7874         if (request_eid_value) {
7875             proto_tree_add_string_format(ncp_tree,
7876                                             hf_nds_name, tvb, 6, 0,
7877                                             request_eid_value->object_name,
7878                                             "NDS Name for EID - %s",
7879                                             request_eid_value->object_name);
7880         }
7881     }
7882 }
7883
7884 void
7885 dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo,
7886                   guint32 nw_connection, guint8 sequence, guint16 type,
7887                   proto_tree *ncp_tree, struct novell_tap *ncp_tap)
7888 {
7889     conversation_t      *conversation = NULL;
7890     ncp_req_hash_value  *request_value = NULL;
7891     const ncp_record    *ncp_rec = NULL;
7892     gboolean            *req_cond_results;
7893     guint8               completion_code=0;
7894     ptvcursor_t         *ptvc = NULL;
7895     const char          *error_string;
7896     guint32              nds_offset = 0;
7897     guint32              nds_error_code = 0;
7898     /*guint32              nds_reply_buffer = 0;*/
7899     const char          *nds_error_string = NULL;
7900     /*guint32              nds_frag=0;*/
7901     proto_item          *expert_item;
7902     guint8               conn_stat;
7903
7904
7905 #ifdef FAKE_TREE_IS_VISIBLE
7906     if (ncp_tree) {
7907         PTREE_DATA(ncp_tree)->visible=1;
7908     }
7909 #endif
7910
7911     if (!pinfo->fd->visited) {
7912         /* Find the conversation whence the request would have come. */
7913         conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
7914                                          ENDPOINT_NCP, nw_connection, nw_connection, 0);
7915         if (conversation != NULL) {
7916             /* find the record telling us the request made that caused
7917                this reply */
7918             request_value = ncp_hash_lookup(conversation, sequence, pinfo->num);
7919             if (request_value) {
7920                 ncp_rec = request_value->ncp_rec;
7921             }
7922             p_add_proto_data(wmem_file_scope(), pinfo, proto_ncp, 0, (void*) request_value);
7923         }
7924         /* else... we haven't seen an NCP Request for that conversation
7925            and sequence.
7926            Create Service request packets do not contain nw_connection.
7927            The initial value is set to 65535 or 0. The reply packet has the
7928            valid connection. So, we can't find the request packet in
7929            our conversation list. To trap for this we can just perform
7930            the search again with 65535 to see if we can locate the
7931            proper request packet. */
7932         else {
7933             conversation = find_conversation(pinfo->num,
7934                                              &pinfo->src, &pinfo->dst, ENDPOINT_NCP, 65535, 65535, 0);
7935             if (conversation != NULL) {
7936                 /* find the record telling us the request made
7937                    that caused this reply */
7938                 request_value = ncp_hash_lookup(conversation,
7939                                                 sequence, pinfo->num);
7940                 if (request_value) {
7941                     ncp_rec = request_value->ncp_rec;
7942                 }
7943                 p_add_proto_data(wmem_file_scope(), pinfo, proto_ncp, 0,
7944                                  (void*) request_value);
7945             }
7946             else {
7947                 conversation = find_conversation(pinfo->num,
7948                                                  &pinfo->src, &pinfo->dst, ENDPOINT_NCP, 0, 0, 0);
7949                 if (conversation != NULL) {
7950                     /* find the record telling us the request made
7951                        that caused this reply */
7952                     request_value = ncp_hash_lookup(conversation,
7953                                                     sequence, pinfo->num);
7954                     if (request_value) {
7955                         ncp_rec = request_value->ncp_rec;
7956                     }
7957                     p_add_proto_data(wmem_file_scope(), pinfo, proto_ncp, 0,
7958                                      (void*) request_value);
7959                 }
7960                 /* else... we haven't seen an NCP Request for that
7961                    conversation and sequence. */
7962             }
7963         }
7964     }
7965     else {
7966         /*request_value = p_get_proto_data(wmem_file_scope(), pinfo, proto_ncp);*/
7967         conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
7968                                          ENDPOINT_NCP, nw_connection, nw_connection, 0);
7969         if (conversation != NULL) {
7970
7971              request_value = ncp_hash_lookup(conversation,
7972                                sequence, pinfo->num);
7973         }
7974         if (request_value) {
7975             ncp_rec = request_value->ncp_rec;
7976         }
7977     }
7978
7979     /*
7980      * Tap the packet before the dissectors are called so we
7981      * still get the tap listener called even if there is an
7982      * exception.
7983      */
7984     tap_queue_packet(ncp_tap->stat, pinfo, request_value);
7985
7986     if (ncp_rec && ncp_rec->func==0x68 &&
7987         (ncp_rec->subfunc==0x02 || ncp_rec->subfunc==0x01)) {
7988         col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDS");
7989     }
7990
7991     /* A completion code of 0 always means OK. Non-zero means failure,
7992      * but each non-zero value has a different meaning. And the same value
7993      * can have different meanings, depending on the ncp.func (and ncp.subfunc)
7994      * value. */
7995     completion_code = tvb_get_guint8(tvb, 6);
7996     if (completion_code == 0) {
7997         if(type == NCP_POSITIVE_ACK)
7998         {
7999             error_string = "Server Busy, Request Being Processed";
8000         }
8001         else
8002         {
8003             error_string = "OK";
8004         }
8005     } else {
8006         if (ncp_rec && ncp_rec->errors) {
8007             error_string = ncp_error_string(ncp_rec->errors, completion_code);
8008         }
8009         else {
8010             error_string = "Original Request Packet not Found";
8011         }
8012     }
8013     if (type == NCP_SERVICE_REPLY && ncp_rec && ncp_rec->func==0x68 &&
8014         ncp_rec->subfunc==0x02 && (tvb_reported_length_remaining(tvb, 8) >= 8))
8015     {
8016         nds_offset = 8;
8017         /*nds_reply_buffer = tvb_get_letohl(tvb, nds_offset);*/
8018         nds_offset += 4;
8019         /*nds_frag = tvb_get_letohl(tvb, nds_offset);*/
8020         nds_offset += 4;
8021         /*
8022          * Is the possibly-reassembled reply large enough to have
8023          * a completion code?  (We can't check the fragment size
8024          * as this might just be the last fragment.)
8025          */
8026         if (tvb_reported_length_remaining(tvb, nds_offset) >= 4)
8027         {
8028             /* Yes - process the completion code. */
8029             nds_error_code = tvb_get_letohl(tvb, nds_offset);
8030             nds_error_string = val_to_str_const(nds_error_code, nds_reply_errors, "NDS Error - No Definition Found");
8031         }
8032     }
8033     col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
8034                     type == NCP_SERVICE_REPLY ? "R" : "ACK",
8035                     nds_error_string ? nds_error_string : error_string);
8036
8037     if (ncp_tree) {
8038
8039         if (request_value) {
8040             nstime_t ns;
8041
8042             proto_tree_add_uint(ncp_tree, hf_ncp_req_frame_num, tvb, 0, 0,
8043                                 request_value->req_frame_num);
8044             nstime_delta(&ns, &pinfo->abs_ts, &request_value->req_frame_time);
8045             proto_tree_add_time(ncp_tree, hf_ncp_req_frame_time, tvb, 0, 0, &ns);
8046         }
8047
8048         /* Put the func (and maybe subfunc) from the request packet
8049          * in the proto tree, but hidden. That way filters on ncp.func
8050          * or ncp.subfunc will find both the requests and the replies.
8051          */
8052         if (ncp_rec) {
8053             proto_tree_add_uint_format_value(ncp_tree, hf_ncp_func, tvb, 6, 0,
8054                                        ncp_rec->func, "%u (0x%02X), %s",
8055                                        ncp_rec->func, ncp_rec->func, ncp_rec->name);
8056             if (ncp_requires_subfunc(ncp_rec->func)) {
8057                 proto_tree_add_uint(ncp_tree, hf_ncp_subfunc, tvb, 6, 0, ncp_rec->subfunc);
8058             }
8059         }
8060     }
8061
8062     expert_item = proto_tree_add_uint_format_value(ncp_tree, hf_ncp_completion_code, tvb, 6, 1,
8063                                              completion_code, "%d (0x89%02x), %s",
8064                                              completion_code, completion_code, error_string);
8065     if ((completion_code != 0 || type == NCP_POSITIVE_ACK) && ncp_echo_err) {
8066         expert_add_info_format(pinfo, expert_item, &ei_ncp_completion_code,
8067                                "Error: %d (0x89%02x) %s", completion_code,
8068                                completion_code, error_string);
8069     }
8070
8071     conn_stat = tvb_get_guint8(tvb, 7);
8072     expert_item = proto_tree_add_item(ncp_tree, hf_ncp_connection_status, tvb,
8073                                       7, 1, ENC_NA);
8074     if (conn_stat != 0 && conn_stat != 0x40 ) {
8075         col_set_str(pinfo->cinfo, COL_INFO,
8076                     "Error: Bad Connection Status");
8077         if (ncp_echo_err) {
8078             expert_add_info(pinfo, expert_item, &ei_ncp_connection_status);
8079         }
8080         return;
8081     }
8082     /*
8083      * Unless this is a successful reply, that's all there
8084      * is to parse.
8085      */
8086     if (type != NCP_SERVICE_REPLY || completion_code != 0)
8087         return;
8088
8089     if (ncp_rec) {
8090         /* Dissect SSS Reply packets */
8091         if (ncp_rec->func == 0x5c && request_value)
8092         {
8093             dissect_sss_reply(tvb, pinfo, ncp_tree, ncp_rec->subfunc, request_value);
8094         }
8095         /* Dissect NMAS Reply packets */
8096         if (ncp_rec->func == 0x5e && request_value)
8097         {
8098             dissect_nmas_reply(tvb, pinfo, ncp_tree, ncp_rec->func, ncp_rec->subfunc, request_value);
8099         }
8100         /* Dissect NDS Ping packets */
8101         if (ncp_rec->func == 0x68 && ncp_rec->subfunc == 0x01)
8102         {
8103             dissect_nds_ping_reply(tvb, pinfo, ncp_tree,
8104                                    request_value);
8105         }
8106         /* Dissect NDS Reply packets */
8107         if (ncp_rec->func == 0x68 && ncp_rec->subfunc == 0x02)
8108         {
8109             dissect_nds_reply(tvb, pinfo, ncp_tree, nds_error_code,
8110                               nds_error_string, request_value, conversation);
8111         }
8112         /* Due to lack of group repeat fields in reply structure, decode this ncp 87/20 reply manually here. */
8113         if ((ncp_rec->func == 0x57 || ncp_rec->func == 0x59) && ncp_rec->subfunc == 0x14) {
8114             dissect_ncp_8x20reply(tvb, pinfo, ncp_tree, ncp_rec, request_value);
8115         }
8116         if (ncp_rec->func == 5 && ncp_echo_conn) {
8117             expert_add_info(pinfo, NULL, &ei_ncp_connection_destroyed);
8118         }
8119         if (ncp_rec->reply_ptvc) {
8120             /* If we're not building a protocol tree, quit;
8121              * "process_ptvc_record()" assumes we're building
8122              * a protocol tree, and we don't support putting
8123              * stuff in the Info column in replies, and no
8124              * state information is currently updated for
8125              * replies by "process_ptvc_record()", so we
8126              * can't, and don't have a reason to, dissect
8127              * any further if we're not building a protocol
8128              * tree. */
8129             if (!ncp_tree)
8130                 return;
8131
8132             /* If a non-zero completion code was found, it is
8133              * legal to not have any fields, even if the packet
8134              * type is defined as having fields.
8135              *
8136              * XXX - we already know that the completion code
8137              * is 0, as we checked it above.  Is there any
8138              * reason why we'd want to do a full dissection
8139              * if the completion code isn't 0? */
8140             if (completion_code != 0 && tvb_captured_length(tvb) == 8) {
8141                 return;
8142             }
8143
8144             /* Any request condition results? */
8145             if (request_value) {
8146                 req_cond_results = request_value->req_cond_results;
8147             }
8148             else {
8149                 req_cond_results = NULL;
8150             }
8151             clear_repeat_vars();
8152             ptvc = ptvcursor_new(ncp_tree, tvb, 8);
8153             process_ptvc_record(ptvc, pinfo, ncp_rec->reply_ptvc,
8154                                 req_cond_results, TRUE, ncp_rec, FALSE);
8155             ptvcursor_free(ptvc);
8156
8157             /* Process ncp 123/17 address records manually to format correctly. */
8158             if (ncp_rec->func == 0x7b && ncp_rec->subfunc == 0x11) {
8159                 dissect_ncp_123_17_reply(tvb, pinfo, ncp_tree);
8160             }
8161             /* Process ncp 123/11 NLM names manually to format correctly. */
8162             if (ncp_rec->func == 0x7b && ncp_rec->subfunc == 0x0b && request_value) {
8163                 dissect_ncp_123_11_reply(tvb, ncp_tree, request_value);
8164             }
8165             /* Process ncp 123/62 server set parameter values manually to format correctly. */
8166             if (ncp_rec->func == 0x7b && ncp_rec->subfunc == 0x3e) {
8167                 dissect_ncp_123_62_reply(tvb, ncp_tree);
8168             }
8169             /* Process ncp 23/26 address records manually to format correctly. */
8170             if (ncp_rec->func == 0x17 && ncp_rec->subfunc == 0x1a) {
8171                 dissect_ncp_23_26_reply(tvb, ncp_tree);
8172             }
8173             /* Process ncp 87/72 bytes transferred value. */
8174             if (ncp_rec->func == 0x57 && ncp_rec->subfunc == 0x48) {
8175                 dissect_ncp_87_72_reply(tvb, ncp_tree);
8176             }
8177
8178         }
8179     } else {
8180         if (tvb_reported_length(tvb) > 8) {
8181             expert_item = proto_tree_add_item(ncp_tree, hf_no_request_record_found, tvb, 8, -1, ENC_NA);
8182             if (ncp_echo_err) {
8183                 expert_add_info(pinfo, expert_item, &ei_ncp_no_request_record_found);
8184             }
8185         }
8186     }
8187 }
8188
8189 void
8190 dissect_nds_request(tvbuff_t *tvb, packet_info *pinfo,
8191                     guint32 nw_connection, guint8 sequence,
8192                     guint16 type, proto_tree *ncp_tree)
8193 {
8194     guint8                   func, subfunc;
8195     ncp_req_hash_value      *request_value = NULL;
8196     ncp_req_eid_hash_value  *request_eid_value = NULL;
8197     const ncp_record        *ncp_rec = NULL;
8198     conversation_t          *conversation;
8199     ptvcursor_t             *ptvc = NULL;
8200     proto_tree              *temp_tree = NULL;
8201     gboolean                 run_req_cond = FALSE;
8202     guint8                   nds_verb = 0;
8203     const char              *verb_string = "";
8204     guint32                  nds_frag = 0;
8205     guint8                   nds_version = 0;
8206     guint32                  foffset = 0;
8207     const char*              global_object_name = NULL;
8208     guint32                  global_eid=0;
8209     gboolean                 resolve_eid=FALSE;
8210     guint32                  global_flags=0, nds_prot_flags=0;
8211     guint32                  version, value1;
8212     nds_val                  temp_value;
8213
8214     func = tvb_get_guint8(tvb, 6);
8215     subfunc = tvb_get_guint8(tvb, 7);
8216
8217     ncp_rec = ncp_record_find(func, subfunc);
8218     if (ncp_rec) {
8219         col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDS");
8220     } else {
8221         col_add_fstr(pinfo->cinfo, COL_INFO,
8222                         "C Unknown Function %d (0x%02x)",
8223                         func, func);
8224     }
8225
8226     /* Check to see if this is a fragment packet */
8227     nds_frag = tvb_get_letohl(tvb, 8);
8228
8229     /* Keep track of the address and connection whence the request
8230        came, and the address and connection to which the request
8231        is being sent, so that we can match up calls with replies.
8232        (We don't include the sequence number, as we may want
8233        to have all packets over the same connection treated
8234        as being part of a single conversation so that we can
8235        let the user select that conversation to be displayed.) */
8236
8237     conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
8238                                      ENDPOINT_NCP, nw_connection, nw_connection, 0);
8239     if (conversation == NULL) {
8240         /* It's not part of any conversation - create a new one. */
8241         conversation = conversation_new(pinfo->num, &pinfo->src, &pinfo->dst,
8242                                         ENDPOINT_NCP, nw_connection, nw_connection, 0);
8243     }
8244
8245     if (!pinfo->fd->visited) {
8246         request_value = ncp_hash_insert(conversation, sequence, ncp_rec, pinfo->num);
8247         request_value->req_frame_num = pinfo->num;
8248         request_value->req_frame_time=pinfo->abs_ts;
8249
8250         /* If this is the first time we're examining the packet,
8251          * check to see if this NCP type uses a "request condition".
8252          * If so, we have to build a proto_tree because request conditions
8253          * use display filters to work, and without a proto_tree,
8254          * display filters can't possibly work. If we already have
8255          * a proto_tree, then wonderful. If we don't, we need to build
8256          * one. */
8257         if (ncp_rec && !ncp_tree) {
8258             run_req_cond = TRUE;
8259         }
8260         /* Keep track of the Fragment number in the request for defrag logic */
8261         request_value->nds_frag_num = nds_frag;
8262     }
8263
8264     /* If we have to handle a request condition, or have to
8265        add to the Info column, we need to construct a protocol
8266        tree.  If we already have a proto_tree, then wonderful.
8267        If we don't, we need to build one. */
8268     if (run_req_cond && !ncp_tree) {
8269         proto_item *ti;
8270
8271         temp_tree = proto_tree_create_root(pinfo);
8272         proto_tree_set_visible(temp_tree, FALSE);
8273         ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, ENC_NA);
8274         ncp_tree = proto_item_add_subtree(ti, ett_ncp);
8275     }
8276
8277     /* Get NDS Verb */
8278     if (nds_frag == 0xffffffff) {
8279         /* First fragment or only fragment. */
8280         nds_verb = tvb_get_guint8(tvb, 24);
8281         if (nds_verb == 0xfe)
8282         {
8283             nds_version = nds_verb;
8284             nds_verb = tvb_get_guint8(tvb, 32);
8285             foffset = 36;
8286         }
8287         else
8288         {
8289             nds_version = 0;
8290             foffset = 28;
8291         }
8292         if (type == NCP_SERVICE_REQUEST) {
8293             proto_tree_add_item(ncp_tree, hf_nds_buffer_size, tvb, foffset,
8294                                 4, ENC_LITTLE_ENDIAN);
8295         }
8296         foffset = foffset+4;
8297         verb_string = val_to_str_const(nds_verb, ncp_nds_verb_vals,
8298                                        "Continuation Fragment");
8299
8300         if (ncp_rec)
8301             col_add_fstr(pinfo->cinfo, COL_INFO, "C NDS %s", verb_string);
8302     } else {
8303         if (ncp_rec)
8304             col_add_fstr(pinfo->cinfo, COL_INFO, "C Continue NDS Fragment 0x%08x", nds_frag);
8305     }
8306
8307     if (ncp_tree) {
8308         /* If the dissection throws an exception, be sure to free
8309          * the temporary proto_tree that was created. Because of the
8310          * way the CLEANUP_PUSH macro works, we can't put it in an 'if'
8311          * block; it has to be in the same scope as the terminating
8312          * CLEANUP_POP or CLEANUP_POP_AND_ALLOC. So, we always
8313          * call CLEANUP_POP and friends, but the value of temp_tree is
8314          * NULL if no cleanup is needed, and non-null if cleanup is needed.
8315          */
8316         CLEANUP_PUSH(free_proto_tree, temp_tree);
8317
8318 #ifdef FAKE_TREE_IS_VISIBLE
8319         PTREE_DATA(ncp_tree)->visible=1;
8320 #endif
8321
8322     if (type == NCP_SERVICE_REQUEST) {
8323         memset(&temp_value, 0, sizeof(temp_value));
8324         request_value = ncp_hash_lookup(conversation, sequence, pinfo->num);
8325
8326         if (ncp_rec && ncp_rec->request_ptvc)
8327         {
8328             ptvc = ptvcursor_new(ncp_tree, tvb, 7);
8329             clear_repeat_vars();
8330             process_ptvc_record(ptvc, pinfo, ncp_rec->request_ptvc, NULL, TRUE, ncp_rec, TRUE);
8331             ptvcursor_free(ptvc);
8332         }
8333         if (ncp_tree) {
8334             proto_tree_add_uint_format_value(ncp_tree, hf_ncp_func, tvb, 6, 1,
8335                                        func, "%d (0x%02X), %s",
8336                                        func, func, ncp_rec ? ncp_rec->name : "Unknown");
8337
8338             proto_tree_add_uint(ncp_tree, hf_ncp_subfunc, tvb, 7, 1, subfunc);
8339
8340             proto_tree_add_uint(ncp_tree, hf_ncp_fragment_handle, tvb, 8, 4,
8341                                 nds_frag);
8342         }
8343
8344         if (nds_frag == 0xffffffff) {
8345
8346             if (ncp_tree) {
8347                 proto_tree_add_item(ncp_tree, hf_ncp_fragment_size, tvb, 12, 4, ENC_LITTLE_ENDIAN);
8348
8349                 proto_tree_add_item(ncp_tree, hf_ncp_message_size, tvb, 16, 4, ENC_LITTLE_ENDIAN);
8350                 nds_prot_flags=tvb_get_letohs(tvb, 22);
8351                 proto_tree_add_bitmask(ncp_tree, tvb, 22, hf_ncp_nds_flag, ett_ncp, ndsprotflags, ENC_LITTLE_ENDIAN);
8352
8353                 if (nds_version == 0) {
8354                     proto_tree_add_uint_format_value(ncp_tree, hf_ncp_nds_verb, tvb, 24, 4,
8355                                             nds_verb, "%d, (0x%02x), %s",
8356                                             nds_verb, nds_verb, verb_string);
8357                 }
8358                 else {
8359                     proto_tree_add_uint_format_value(ncp_tree, hf_ncp_nds_verb, tvb, 32, 4,
8360                                             nds_verb, "%d, (0x%02x), %s",
8361                                             nds_verb, nds_verb, verb_string);
8362                 }
8363             }
8364
8365             switch(nds_verb) {
8366
8367             case 0x01:
8368                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8369                 foffset += 4;
8370                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_nds_nflags, ett_ncp, ncp_nflags, ENC_LITTLE_ENDIAN);
8371                 foffset += 4;
8372
8373                 if (version == 0 || version == 1)
8374                 {
8375                     proto_tree_add_item(ncp_tree, hf_nds_scope, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8376                     foffset += 4;
8377                     value1 = tvb_get_letohl(tvb, foffset);
8378                     if (value1 == 0)
8379                         break;
8380
8381                     global_object_name = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8382                     proto_tree_add_string(ncp_tree, hf_nds_name, tvb, foffset, 4+value1, global_object_name);
8383                     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", global_object_name);
8384                     foffset += 4+value1;
8385                     foffset += align_4(tvb, foffset);
8386
8387                     temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8388                     temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8389                     temp_value.vdesc = "Communications Transports: %u";
8390                     temp_value.vlength = 4;
8391                     temp_value.hfname= hf_nds_comm_trans;
8392                     temp_value.voffset = foffset;
8393                     temp_value.mvtype = MVTYPE_ADDR_REFERRAL_REQUEST;
8394                     process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8395                     foffset = foffset + (temp_value.vvalue * 4) + 4;
8396
8397                     temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8398                     temp_value.vdesc = "Tree Walker Transport Type: %u";
8399                     temp_value.hfname= hf_nds_tree_trans;
8400                     temp_value.voffset = foffset;
8401                     process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8402                 }
8403                 else
8404                 {
8405                     proto_tree_add_item(ncp_tree, hf_min_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8406                     foffset += 4;
8407
8408                     temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8409                     temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8410                     temp_value.vdesc = "Number of Versions to Include: %u";
8411                     temp_value.vlength = 4;
8412                     temp_value.mvtype = MVTYPE_ATTR_REQUEST2;
8413                     temp_value.voffset = foffset;
8414                     temp_value.hfname= hf_nds_ver_include;
8415                     process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8416                     foffset += (temp_value.vvalue * 4) + 4;
8417
8418                     temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8419                     temp_value.vdesc = "Number of Versions to Exclude: %u";
8420                     temp_value.hfname= hf_nds_ver_exclude;
8421                     temp_value.voffset = foffset;
8422                     process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8423                     foffset += (temp_value.vvalue * 4) + 4;
8424
8425                     proto_tree_add_item(ncp_tree, hf_nds_dn_output_type, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8426                     foffset += 4;
8427                     proto_tree_add_item(ncp_tree, hf_nds_nested_output_type, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8428                     foffset += 4;
8429
8430                     value1 = tvb_get_letohl(tvb, foffset);
8431                     global_object_name = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8432                     proto_tree_add_string(ncp_tree, hf_nds_output_delimiter, tvb, foffset, 4+value1, global_object_name);
8433                     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", global_object_name);
8434                     foffset += 4+value1;
8435                     foffset += align_4(tvb, foffset);
8436
8437                     temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8438                     temp_value.vdesc = "Size of Entry Specifier: %u";
8439                     temp_value.mvtype = MVTYPE_PROC_ENTRY_SPECIFIERS;
8440                     temp_value.hfname= hf_nds_output_entry_specifier;
8441                     temp_value.voffset = foffset;
8442                     process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8443                 }
8444                 break;
8445             case 0x02:
8446                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8447                 foffset += 4;
8448                 switch(version)
8449                 {
8450                 case 0:
8451                     proto_tree_add_item(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8452                     break;
8453                 case 1:
8454                     proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_nds_rflags, ett_ncp, ncp_rflags, ENC_LITTLE_ENDIAN);
8455                     value1 = tvb_get_letohl(tvb, foffset);
8456
8457                     if ((value1 & 0xf000) == 0xc000)
8458                     {
8459                         proto_tree_add_string(ncp_tree, hf_nds_name_type, tvb, 0, 0, "Partial");
8460                     }
8461                     else
8462                     {
8463                         proto_tree_add_string(ncp_tree, hf_nds_name_type, tvb, 0, 0, "Full");
8464                     }
8465                     foffset += 4;
8466
8467                     proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8468                     resolve_eid = TRUE;
8469                     break;
8470                 case 2:
8471                     proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_nds_rflags, ett_ncp, ncp_rflags, ENC_LITTLE_ENDIAN);
8472                     value1 = tvb_get_letohl(tvb, foffset);
8473                     if ((value1 & 0xf000) == 0xc000)
8474                     {
8475                         proto_tree_add_string(ncp_tree, hf_nds_name_type, tvb, 0, 0, "Return Partition Name");
8476                     }
8477                     else
8478                     {
8479                         proto_tree_add_string(ncp_tree, hf_nds_name_type, tvb, 0, 0, "Return Full Name");
8480                     }
8481                     foffset += 4;
8482                     proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_retinfoflagsl, ett_ncp, ncp_infoflagsl, ENC_LITTLE_ENDIAN);
8483                     global_flags = tvb_get_letohl(tvb, foffset);
8484                     foffset += 2;
8485                     proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_retinfoflagsh, ett_ncp, ncp_infoflagsh, ENC_LITTLE_ENDIAN);
8486                     foffset += 2;
8487
8488                     proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8489                     resolve_eid = TRUE;
8490                     break;
8491                 default:
8492                     break;
8493                 }
8494                 break;
8495
8496             case 0x03:
8497                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8498                 foffset += 4;
8499
8500                 if (version == 0)
8501                 {
8502                     proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8503                     foffset += 4;
8504                     proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8505                     resolve_eid = TRUE;
8506                     foffset += 4;
8507                     proto_tree_add_item_ret_uint(ncp_tree, hf_nds_info_type, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_flags);
8508                     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", rval_to_str_const(global_flags, nds_info_type, "No Info Type Set"));
8509
8510                     foffset += 4;
8511                     proto_tree_add_item(ncp_tree, hf_nds_all_attr, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8512                     foffset += 4;
8513
8514                     temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8515                     temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8516                     temp_value.vdesc = "Attributes: %u";
8517                     temp_value.vlength = 4;
8518                     temp_value.voffset = foffset;
8519                     temp_value.mvtype = MVTYPE_ATTR_REQUEST;
8520                     temp_value.hfname= hf_nds_attr;
8521                     process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8522                     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", temp_value.vstring);
8523                 }
8524                 else
8525                 {
8526                     proto_tree_add_item(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8527                     foffset += 4;
8528                     proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8529                     foffset += 4;
8530                     proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8531                     resolve_eid = TRUE;
8532                     foffset += 4;
8533                     proto_tree_add_item_ret_uint(ncp_tree, hf_nds_info_type, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_flags);
8534                     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", rval_to_str_const(global_flags, nds_info_type, "No Info Type Set"));
8535                     foffset += 4;
8536                     proto_tree_add_item(ncp_tree, hf_nds_all_attr, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8537                     foffset += 4;
8538
8539                     temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8540                     temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8541                     temp_value.vdesc = "Attributes: %u";
8542                     temp_value.vlength = 4;
8543                     temp_value.voffset = foffset;
8544                     temp_value.mvtype = MVTYPE_ATTR_REQUEST;
8545                     temp_value.hfname= hf_nds_attr;
8546                     process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8547                     col_append_fstr(pinfo->cinfo, COL_INFO, " %s", temp_value.vstring);
8548                }
8549                break;
8550             case 0x04:
8551                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8552                 foffset += 4;
8553
8554                 if (version == 1)
8555                 {
8556                     /* Version 1 specifies for this offset value to always be a value of 1*/
8557                     /* No need to display to user */
8558                     foffset += 4;
8559                 }
8560
8561                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8562                 resolve_eid = TRUE;
8563                 foffset += 4;
8564
8565                 foffset += 4;       /* Attribute Count = 1 */
8566
8567                 value1 = tvb_get_letohl(tvb, foffset);
8568                 if (value1 == 0)
8569                     break;
8570
8571                 global_object_name = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8572                 proto_tree_add_string_format(ncp_tree, hf_nds_name, tvb, foffset, 4+value1, global_object_name, "Attribute Name Being Compared: %s", global_object_name);
8573                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", global_object_name);
8574                 foffset += 4+value1;
8575                 foffset += align_4(tvb, foffset);
8576
8577                 foffset += 4;       /* Attribute Count = 1 */
8578
8579                 value1 = tvb_get_letohl(tvb, foffset);
8580                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8581                 proto_tree_add_string_format(ncp_tree, hf_value_string, tvb, foffset, 4+value1, temp_value.vstring, "Attribute Value: %s", temp_value.vstring);
8582                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", temp_value.vstring);
8583                 break;
8584             case 0x05:
8585                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8586                 foffset += 4;
8587                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_nds_rflags, ett_ncp, ncp_lflags, ENC_LITTLE_ENDIAN);
8588                 foffset += 2;
8589                 proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8590                 foffset += 4;
8591                 proto_tree_add_item(ncp_tree, hf_nds_parent, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8592                 foffset += 4;
8593                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_retinfoflagsl, ett_ncp, ncp_infoflagsl, ENC_LITTLE_ENDIAN);
8594                 foffset += 2;
8595                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_retinfoflagsh, ett_ncp, ncp_infoflagsh, ENC_LITTLE_ENDIAN);
8596                 foffset += 2;
8597
8598                 value1 = tvb_get_letohl(tvb, foffset);
8599                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8600                 proto_tree_add_string(ncp_tree, hf_nds_name_filter, tvb, foffset, 4+value1, temp_value.vstring);
8601                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", temp_value.vstring);
8602                 foffset += 4+value1;
8603                 if (version == 0)
8604                     break;
8605
8606                 foffset += align_4(tvb, foffset);
8607
8608                 value1 = tvb_get_letohl(tvb, foffset);
8609                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8610                 proto_tree_add_string(ncp_tree, hf_nds_class_filter, tvb, foffset, 4+value1, temp_value.vstring);
8611                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", temp_value.vstring);
8612                 foffset += 4+value1;
8613                 if (version == 1)
8614                     break;
8615
8616                 foffset += align_4(tvb, foffset);
8617
8618                 temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8619                 temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8620                 temp_value.vdesc = "Seconds: %u";
8621                 temp_value.vlength = 4;
8622                 temp_value.mvtype = MVTYPE_PRINT_TIMESTAMP;
8623                 temp_value.hfname= hf_nds_time_filter;
8624                 temp_value.voffset = foffset;
8625                 process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8626                 break;
8627             case 0x06:
8628                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8629                 foffset += 4;
8630                 proto_tree_add_item(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8631                 foffset += 4;
8632                 proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8633                 foffset += 4;
8634                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8635                 resolve_eid = FALSE;
8636                 foffset += 4;
8637                 proto_tree_add_item(ncp_tree, hf_nds_search_scope, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8638                 foffset += 4;
8639                 proto_tree_add_item(ncp_tree, hf_nds_num_objects, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8640                 foffset += 4;
8641                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_siflags, ett_ncp, ncp_siflags, ENC_LITTLE_ENDIAN);
8642                 foffset += 4;
8643
8644                 if (version != 2)
8645                 {
8646                     proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_retinfoflagsl, ett_ncp, ncp_infoflagsl, ENC_LITTLE_ENDIAN);
8647                     foffset += 2;
8648                     proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_retinfoflagsh, ett_ncp, ncp_infoflagsh, ENC_LITTLE_ENDIAN);
8649                 }
8650                 break;
8651             case 0x07:
8652                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8653                 foffset += 4;
8654                 proto_tree_add_item(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8655                 foffset += 4;
8656                 if (version != 0)
8657                 {
8658                     proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8659                     foffset += 4;
8660                 }
8661
8662                 global_eid = tvb_get_letohl(tvb, foffset);
8663                 proto_tree_add_uint_format(ncp_tree, hf_nds_eid, tvb, foffset, 4, global_eid, "Parent Entry ID: 0x%08x", global_eid);
8664                 resolve_eid = FALSE;
8665                 foffset += 4;
8666
8667                 value1 = tvb_get_letohl(tvb, foffset);
8668                 if (value1 == 0)
8669                     break;
8670                 global_object_name = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8671                 proto_tree_add_string(ncp_tree, hf_nds_relative_dn, tvb, foffset, 4+value1, global_object_name);
8672                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", global_object_name);
8673                 foffset += 4+value1;
8674                 foffset += align_4(tvb, foffset);
8675
8676                 temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8677                 temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8678                 temp_value.vstring = "";
8679                 temp_value.vdesc = "Attributes: %u";
8680                 temp_value.vlength = 4;
8681                 temp_value.voffset = foffset;
8682                 temp_value.mvtype = MVTYPE_ADD_ATTR_REQUEST;
8683                 temp_value.hfname= hf_nds_attr;
8684                 process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8685                 break;
8686             case 0x08:
8687                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8688                 foffset += 4;
8689                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8690                 resolve_eid = TRUE;
8691                 break;
8692
8693             case 0x09:
8694                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8695                 foffset += 4;
8696
8697                 if (version != 0)
8698                 {
8699                     proto_tree_add_item(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8700                     foffset += 4;
8701                 }
8702
8703                 proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8704                 foffset += 4;
8705                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8706                 resolve_eid = TRUE;
8707                 foffset += 4;
8708
8709                 temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8710                 temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8711                 temp_value.vstring = "";
8712                 temp_value.vdesc = "Number of Attributes to Change %u";
8713                 temp_value.vlength = 4;
8714                 temp_value.mvtype = MVTYPE_MODIFY_ATTR_REQUEST;
8715                 temp_value.hfname= hf_nds_number_of_changes;
8716                 temp_value.voffset = foffset;
8717                 process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8718                 break;
8719             case 0x0a:
8720                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8721                 foffset += 4;
8722
8723                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8724                 resolve_eid = TRUE;
8725                 foffset += 4;
8726
8727                 proto_tree_add_item(ncp_tree, hf_nds_keep, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8728                 foffset += 4;
8729                 foffset += align_4(tvb, foffset);
8730
8731                 value1 = tvb_get_letohl(tvb, foffset);
8732                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8733                 proto_tree_add_string(ncp_tree, hf_nds_new_rdn, tvb, foffset, 4+value1, temp_value.vstring);
8734                 break;
8735
8736             case 0x0b:
8737                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8738                 foffset += 4;
8739                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_nds_acflags, ett_ncp, ncp_acflags, ENC_LITTLE_ENDIAN);
8740                 foffset += 4;
8741
8742                 value1 = tvb_get_letohl(tvb, foffset);
8743                 if (value1 == 0)
8744                     break;
8745                 global_object_name = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8746                 proto_tree_add_string_format(ncp_tree, hf_nds_relative_dn, tvb, foffset, 4+value1, global_object_name, "Attribute Name: %s", global_object_name);
8747                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", global_object_name);
8748                 foffset += 4+value1;
8749                 foffset += align_4(tvb, foffset);
8750
8751                 proto_tree_add_item(ncp_tree, hf_nds_syntax, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8752                 foffset += 4;
8753                 proto_tree_add_item(ncp_tree, hf_nds_lower, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8754                 foffset += 4;
8755                 proto_tree_add_item(ncp_tree, hf_nds_upper, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8756                 foffset += 4;
8757                 value1 = tvb_get_letohl(tvb, foffset);
8758                 foffset += 4;
8759                 proto_tree_add_item(ncp_tree, hf_nds_asn1, tvb, foffset, value1, ENC_NA);
8760                 break;
8761             case 0x0c: /* Not Defined */
8762                 break;
8763             case 0x0d:
8764                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8765                 foffset += 4;
8766
8767                 value1 = tvb_get_letohl(tvb, foffset);
8768                 if (value1 == 0)
8769                     break;
8770
8771                 global_object_name = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8772                 proto_tree_add_string(ncp_tree, hf_nds_attribute_dn, tvb, foffset, 4+value1, global_object_name);
8773                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", global_object_name);
8774                 break;
8775             case 0x0e: /* Not Defined */
8776                 break;
8777             case 0x0f:
8778                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8779                 foffset += 4;
8780                 proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8781                 foffset += 4;
8782                 proto_tree_add_item(ncp_tree, hf_nds_class_def_type, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8783                 foffset += 4;
8784                 value1 = tvb_get_letohl(tvb, foffset);
8785                 if (value1 == 0)
8786                 {
8787                     proto_tree_add_uint_format_value(ncp_tree, hf_nds_return_all_classes, tvb, foffset, 4, value1, "Do Not Return All Classes");
8788                 }
8789                 else
8790                 {
8791                     proto_tree_add_uint_format_value(ncp_tree, hf_nds_return_all_classes, tvb, foffset, 4, value1, "Return All Classes");
8792                 }
8793                 foffset += 4;
8794                 foffset += align_4(tvb, foffset);
8795
8796                 temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8797                 temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8798                 temp_value.vdesc = "Classes: %u";
8799                 temp_value.vlength = 4;
8800                 temp_value.mvtype = MVTYPE_READ_CLASS_REQ;
8801                 temp_value.hfname= hf_nds_classes;
8802                 temp_value.voffset = foffset;
8803                 process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
8804                 break;
8805             case 0x10:
8806                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8807                 foffset += 4;
8808
8809                 value1 = tvb_get_letohl(tvb, foffset);
8810                 if (value1 == 0)
8811                     break;
8812
8813                 global_object_name = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8814                 proto_tree_add_string_format(ncp_tree, hf_nds_base_class, tvb, foffset, 4+value1, global_object_name, "Class Name: %s", global_object_name);
8815                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", global_object_name);
8816                 foffset += 4+value1;
8817                 foffset += align_4(tvb, foffset);
8818
8819                 temp_value.vvalue = tvb_get_letohl(tvb, foffset);
8820                 temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
8821                 temp_value.vdesc = "Number of Attributes to Add: %u";
8822                 temp_value.vlength = 4;
8823                 temp_value.voffset = foffset;
8824                 temp_value.mvtype = MVTYPE_MODIFY_CLASS;
8825                 temp_value.hfname= hf_nds_att_add;
8826                 break;
8827             case 0x11:
8828                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8829                 foffset += 4;
8830
8831                 value1 = tvb_get_letohl(tvb, foffset);
8832                 if (value1 == 0)
8833                     break;
8834
8835                 global_object_name = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8836                 proto_tree_add_string_format(ncp_tree, hf_nds_base, tvb, foffset, 4+value1, global_object_name, "Class Name: %s", global_object_name);
8837                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", global_object_name);
8838                 break;
8839             case 0x12:
8840                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8841                 foffset += 4;
8842                 proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8843                 foffset += 4;
8844                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8845                 resolve_eid = TRUE;
8846                 break;
8847             case 0x13:
8848                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8849                 foffset += 4;
8850                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8851                 resolve_eid = TRUE;
8852                 foffset += 4;
8853
8854                 value1 = tvb_get_letohl(tvb, foffset);
8855                 if (value1 == 0)
8856                     break;
8857
8858                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8859                 proto_tree_add_string_format(ncp_tree, hf_nds_name, tvb, foffset, 4+value1, temp_value.vstring, "Trustee Name: %s", temp_value.vstring);
8860                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", temp_value.vstring);
8861                 foffset += 4+value1;
8862                 foffset += align_4(tvb, foffset);
8863
8864                 value1 = tvb_get_letohl(tvb, foffset);
8865                 if (value1 == 0)
8866                     break;
8867
8868                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8869                 proto_tree_add_string_format(ncp_tree, hf_nds_name, tvb, foffset, 4+value1, temp_value.vstring, "Attribute to be Checked: %s", temp_value.vstring);
8870                 foffset += 4+value1;
8871                 foffset += align_4(tvb, foffset);
8872
8873                 if(version != 0)
8874                 {
8875                     value1 = tvb_get_letohl(tvb, foffset);
8876                     if (value1 == 0)
8877                         break;
8878
8879                     temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8880                     proto_tree_add_string_format(ncp_tree, hf_nds_name, tvb, foffset, 4+value1, temp_value.vstring, "Security Equivalence: %s", temp_value.vstring);
8881                     col_append_fstr(pinfo->cinfo, COL_INFO, " %s", temp_value.vstring);
8882                 }
8883                 break;
8884             case 0x14: /* Not Defined */
8885             case 0x15:
8886                 break;
8887             case 0x16:
8888                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8889                 foffset += 4;
8890                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_nds_rflags, ett_ncp, nds_bitflags, ENC_LITTLE_ENDIAN);
8891                 foffset += 2;
8892                 proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8893                 foffset += 4;
8894
8895                 if(version == 0)
8896                 {
8897                     global_flags = 0x000000c0;
8898                     break;
8899                 }
8900
8901                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_l1flagsl, ett_ncp, ncp_l1flagsl, ENC_LITTLE_ENDIAN);
8902                 global_flags = tvb_get_letohs(tvb, foffset);
8903                 foffset += 2;
8904                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_l1flagsh, ett_ncp, ncp_l1flagsh, ENC_LITTLE_ENDIAN);
8905                 foffset += 2;
8906
8907                 if(version == 1)
8908                     break;
8909
8910                 proto_tree_add_item(ncp_tree, hf_nds_partition_root_id, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8911                 break;
8912             case 0x17:
8913                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8914                 foffset += 4;
8915                 value1 = tvb_get_letohl(tvb, foffset);
8916                 proto_tree_add_uint_format(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, value1, "Flags: 0x%08x", value1);
8917                 foffset += 4;
8918                 proto_tree_add_item(ncp_tree, hf_nds_new_part_id, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8919                 break;
8920             case 0x18:
8921                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8922                 foffset += 4;
8923                 value1 = tvb_get_letohl(tvb, foffset);
8924                 proto_tree_add_uint_format(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, value1, "Flags: 0x%08x", value1);
8925                 foffset += 4;
8926                 proto_tree_add_item(ncp_tree, hf_nds_child_part_id, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8927                 break;
8928             case 0x19:
8929                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8930                 foffset += 4;
8931                 value1 = tvb_get_letohl(tvb, foffset);
8932                 proto_tree_add_uint_format(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, value1, "Flags: 0x%08x", value1);
8933                 foffset += 4;
8934                 proto_tree_add_item(ncp_tree, hf_nds_master_part_id, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8935                 foffset += 4;
8936                 proto_tree_add_item(ncp_tree, hf_replica_type, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8937                 foffset += 4;
8938
8939                 value1 = tvb_get_letohl(tvb, foffset);
8940                 if (value1 == 0)
8941                     break;
8942
8943                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8944                 proto_tree_add_string(ncp_tree, hf_nds_target_name, tvb, foffset, 4+value1, temp_value.vstring);
8945                 break;
8946             case 0x1a: /* Not Defined */
8947                 break;
8948             case 0x1b:
8949                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8950                 foffset += 4;
8951                 proto_tree_add_item(ncp_tree, hf_nds_stream_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8952                 foffset += 4;
8953                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8954                 resolve_eid = TRUE;
8955                 foffset += 4;
8956
8957                 value1 = tvb_get_letohl(tvb, foffset);
8958                 if (value1 == 0)
8959                     break;
8960
8961                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8962                 proto_tree_add_string(ncp_tree, hf_nds_stream_name, tvb, foffset, 4+value1, temp_value.vstring);
8963                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", temp_value.vstring);
8964                 break;
8965             case 0x1c: /* Not Defined */
8966             case 0x1d:
8967             case 0x1e:
8968             case 0x1f:
8969             case 0x20:
8970             case 0x21:
8971             case 0x22:
8972             case 0x23:
8973             case 0x24:
8974             case 0x25:
8975                 break;
8976             case 0x26:
8977                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &version);
8978                 foffset += 4;
8979                 value1 = tvb_get_letohl(tvb, foffset);
8980                 proto_tree_add_uint_format(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, value1, "Flags: 0x%08x", value1);
8981                 foffset += 4;
8982                 proto_tree_add_item(ncp_tree, hf_nds_time_delay, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
8983                 foffset += 4;
8984
8985                 if(version == 0)
8986                 {
8987                     value1 = tvb_get_letohl(tvb, foffset);
8988                     if (value1 == 0)
8989                         break;
8990
8991                     temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
8992                     proto_tree_add_string(ncp_tree, hf_nds_root_name, tvb, foffset, 4+value1, temp_value.vstring);
8993                     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", temp_value.vstring);
8994                 }
8995                 else
8996                 {
8997                     global_eid = tvb_get_letohl(tvb, foffset);
8998                     proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
8999                     resolve_eid = TRUE;
9000                 }
9001                 break;
9002             case 0x27: /* Not Defined */
9003             case 0x28:
9004             case 0x29:
9005                 break;
9006             case 0x2a:
9007                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9008                 foffset += 4;
9009                 value1 = tvb_get_letohl(tvb, foffset);
9010                 proto_tree_add_uint_format(ncp_tree, hf_nds_req_flags, tvb, foffset, 4, value1, "Flags: 0x%08x", value1);
9011                 foffset += 4;
9012                 global_eid = tvb_get_letohl(tvb, foffset);
9013                 proto_tree_add_uint_format(ncp_tree, hf_nds_ver, tvb, foffset, 4, global_eid, "Destination Parent Entry ID: 0x%08x", global_eid);
9014                 resolve_eid = TRUE;
9015                 foffset += 4;
9016
9017                 value1 = tvb_get_letohl(tvb, foffset);
9018                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
9019                 proto_tree_add_string(ncp_tree, hf_nds_new_rdn, tvb, foffset, 4+value1, temp_value.vstring);
9020                 foffset += (4+value1);
9021                 foffset += align_4(tvb, foffset);
9022
9023                 value1 = tvb_get_letohl(tvb, foffset);
9024                 if (value1 == 0)
9025                     break;
9026                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
9027                 proto_tree_add_string(ncp_tree, hf_nds_target_name, tvb, foffset, 4+value1, temp_value.vstring);
9028                 break;
9029             case 0x2b:
9030                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9031                 foffset += 4;
9032                 proto_tree_add_item(ncp_tree, hf_nds_verb2b_req_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9033                 foffset += 4;
9034                 global_eid = tvb_get_letohl(tvb, foffset);
9035                 proto_tree_add_uint_format(ncp_tree, hf_nds_ver, tvb, foffset, 4, global_eid, "Source Entry ID: 0x%08x", global_eid);
9036                 resolve_eid = TRUE;
9037                 foffset += 4;
9038                 value1 = tvb_get_letohl(tvb, foffset);
9039                 proto_tree_add_uint_format(ncp_tree, hf_nds_ver, tvb, foffset, 4, value1, "Destination Parent Entry ID: 0x%08x", value1);
9040                 foffset += 4;
9041                 value1 = tvb_get_letohl(tvb, foffset);
9042                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
9043                 proto_tree_add_string(ncp_tree, hf_nds_new_rdn, tvb, foffset, 4+value1, temp_value.vstring);
9044                 foffset += (4+value1);
9045                 foffset += align_4(tvb, foffset);
9046                 value1 = tvb_get_letohl(tvb, foffset);
9047                 if (value1 == 0)
9048                     break;
9049                 temp_value.vstring = tvb_get_string_enc(wmem_packet_scope(), tvb, foffset+4, value1, ENC_UTF_16|ENC_LITTLE_ENDIAN);
9050                 proto_tree_add_string(ncp_tree, hf_nds_target_name, tvb, foffset, 4+value1, temp_value.vstring);
9051                 break;
9052             case 0x2c: /* Not Defined */
9053             case 0x2d:
9054             case 0x2e:
9055             case 0x2f:
9056             case 0x30:
9057             case 0x31:
9058                 break;
9059             case 0x32:
9060                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9061                 foffset += 4;
9062                 proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9063                 foffset += 4;
9064                 value1 = tvb_get_letohl(tvb, foffset);
9065                 temp_value.vstring = val_to_str_const(value1, ncp_nds_verb_vals, "(No Verb Found)");
9066                 proto_tree_add_string_format(ncp_tree, hf_mv_string, tvb, foffset, 4+value1, temp_value.vstring, "NDS Verb: %s", temp_value.vstring);
9067             break;
9068             case 0x33: /* Not Defined */
9069             case 0x34:
9070                 break;
9071             case 0x35:
9072                 if (nds_version != 0)
9073                 {
9074                     proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9075                     foffset += 4;
9076                     proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_nds_rflags, ett_ncp, ncp_rflags, ENC_LITTLE_ENDIAN);
9077                     global_flags = tvb_get_letohl(tvb, foffset);
9078                 }
9079                 break;
9080             case 0x36: /* Not Defined */
9081             case 0x37:
9082             case 0x38:
9083                 break;
9084             case 0x39:
9085                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9086                 foffset += 4;
9087                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
9088                 resolve_eid = TRUE;
9089                 break;
9090             case 0x3a:
9091                 proto_tree_add_item(ncp_tree, hf_nds_buffer_size, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9092                 foffset += 4;
9093                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9094                 foffset += 4;
9095                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
9096                 resolve_eid = TRUE;
9097                 break;
9098             case 0x3b:
9099                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9100                 foffset += 4;
9101                 proto_tree_add_item_ret_uint(ncp_tree, hf_nds_eid, tvb, foffset, 4, ENC_LITTLE_ENDIAN, &global_eid);
9102                 resolve_eid = TRUE;
9103                 break;
9104             case 0x3c: /* Not Defined */
9105             case 0x3d:
9106             case 0x3e:
9107             case 0x3f:
9108             case 0x40:
9109             case 0x41:
9110             case 0x42:
9111             case 0x43:
9112             case 0x44:
9113             case 0x45:
9114             case 0x46:
9115             case 0x47:
9116             case 0x48:
9117             case 0x49:
9118             case 0x4a:
9119             case 0x4b:
9120             case 0x4c:
9121             case 0x4d:
9122                 break;
9123             case 0x6e:
9124                 proto_tree_add_item(ncp_tree, hf_nds_ver, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9125                 foffset += 4;
9126                 proto_tree_add_bitmask(ncp_tree, tvb, foffset, hf_nds_rflags, ett_ncp, ncp_rflags, ENC_LITTLE_ENDIAN);
9127                 global_flags = tvb_get_letohl(tvb, foffset);
9128                 foffset += 4;
9129                 proto_tree_add_item(ncp_tree, hf_nds_iteration, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9130                 foffset += 4;
9131                 global_eid = tvb_get_letohl(tvb, foffset);
9132                 proto_tree_add_uint_format(ncp_tree, hf_nds_eid, tvb, foffset, 4, global_eid, "Base Entry ID: 0x%08x", global_eid);
9133                 resolve_eid = TRUE;
9134                 foffset += 4;
9135                 proto_tree_add_item(ncp_tree, hf_nds_scope, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
9136                 foffset += 4;
9137
9138                 temp_value.vvalue = tvb_get_letohl(tvb, foffset);
9139                 temp_value.vtype = VTYPE_MULTIVALUE_UINT32;
9140                 temp_value.vdesc = "Iterator: 0x%08x";
9141                 temp_value.vlength = 4;
9142                 temp_value.voffset = foffset;
9143                 temp_value.hfname= hf_nds_iterator;
9144                 temp_value.mvtype = MVTYPE_PROCESS_ITERATOR;
9145                 process_multivalues(ncp_tree, tvb, pinfo, &temp_value);
9146                 col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", temp_value.vstring);
9147                 break;
9148             default: /* Not Defined */
9149                 break;
9150             }
9151         }
9152
9153         /* For NDS requests with just an EID, resolve name from hash table. */
9154         request_eid_value = ncp_eid_hash_lookup(conversation, global_eid);
9155         if(resolve_eid) {
9156             if (request_eid_value) {
9157                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Object Name - %s", request_eid_value->object_name);
9158             }
9159         }
9160         if (request_value)
9161         {
9162             request_value->nds_request_verb = nds_verb;
9163             request_value->nds_version = nds_version;
9164             if (global_object_name)
9165                 g_strlcpy(request_value->object_name, global_object_name, 256);
9166             else
9167                 request_value->object_name[0] = '\0';
9168             request_value->req_nds_flags = global_flags;
9169             request_value->req_nds_prot_flags = nds_prot_flags;
9170         }
9171     }
9172
9173         /* Free the temporary proto_tree */
9174         CLEANUP_CALL_AND_POP;
9175     }
9176 }
9177
9178 /*
9179  * XXX - this duplicates stuff in "dissect_ncp_request()"; could
9180  * "dissect_ncp_request()" not just call "dissect_ping_req()" if
9181  * the operation is an NCP ping, and "dissect_ping_req()" just dissect
9182  * ping portion?
9183  */
9184 void
9185 dissect_ping_req(tvbuff_t *tvb, packet_info *pinfo,
9186                  guint32 nw_connection, guint8 sequence,
9187                  guint16 type, proto_tree *ncp_tree)
9188 {
9189     guint8               func, subfunc = 0;
9190     ncp_req_hash_value  *request_value = NULL;
9191     const ncp_record    *ncp_rec = NULL;
9192     conversation_t      *conversation;
9193     ptvcursor_t         *ptvc = NULL;
9194     proto_tree          *temp_tree = NULL;
9195     gint                 length_remaining = 0;
9196     guint32              nds_flags;
9197     guint32              ping_version;
9198
9199 #ifdef FAKE_TREE_IS_VISIBLE
9200     if (ncp_tree) {
9201         PTREE_DATA(ncp_tree)->visible=1;
9202     }
9203 #endif
9204
9205     func = tvb_get_guint8(tvb, 6);
9206     subfunc = tvb_get_guint8(tvb, 7);
9207
9208     ncp_rec = ncp_record_find(func, subfunc);
9209
9210     /* Fill in the INFO column. */
9211     if (ncp_rec)
9212     {
9213         col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDS");
9214
9215         col_set_str(pinfo->cinfo, COL_INFO, "C Ping for NDS");
9216
9217     }
9218     if (!pinfo->fd->visited)
9219     {
9220
9221         /* This is the first time we've looked at this packet.
9222            Keep track of the address and connection whence the request
9223            came, and the address and connection to which the request
9224            is being sent, so that we can match up calls with replies.
9225            (We don't include the sequence number, as we may want
9226            to have all packets over the same connection treated
9227            as being part of a single conversation so that we can
9228            let the user select that conversation to be displayed.) */
9229
9230         conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
9231                                          ENDPOINT_NCP, nw_connection, nw_connection, 0);
9232
9233         if (conversation == NULL)
9234         {
9235             /* It's not part of any conversation - create a new one. */
9236             conversation = conversation_new(pinfo->num, &pinfo->src, &pinfo->dst,
9237                                             ENDPOINT_NCP, nw_connection, nw_connection, 0);
9238         }
9239
9240         request_value = ncp_hash_insert(conversation, sequence, ncp_rec, pinfo->num);
9241         request_value->req_frame_num = pinfo->num;
9242         request_value->req_frame_time=pinfo->abs_ts;
9243
9244         /* If this is the first time we're examining the packet,
9245          * check to see if this NCP type uses a "request condition".
9246          * If so, we have to build a proto_tree because request conditions
9247          * use display filters to work, and without a proto_tree,
9248          * display filters can't possibly work. If we already have
9249          * a proto_tree, then wonderful. If we don't, we need to build
9250          * one. */
9251         if (ncp_rec && !ncp_tree) {
9252             proto_item *ti;
9253
9254             temp_tree = proto_tree_create_root(pinfo);
9255             proto_tree_set_visible(temp_tree, FALSE);
9256             ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, ENC_NA);
9257             ncp_tree = proto_item_add_subtree(ti, ett_ncp);
9258         }
9259     }
9260
9261     if (ncp_tree) {
9262         /* If the dissection throws an exception, be sure to free
9263          * the temporary proto_tree that was created. Because of the
9264          * way the CLEANUP_PUSH macro works, we can't put it in an 'if'
9265          * block; it has to be in the same scope as the terminating
9266          * CLEANUP_POP or CLEANUP_POP_AND_ALLOC. So, we always
9267          * call CLEANUP_POP and friends, but the value of temp_tree is
9268          * NULL if no cleanup is needed, and non-null if cleanup is needed.
9269          */
9270         CLEANUP_PUSH(free_proto_tree, temp_tree);
9271
9272         switch (type) {
9273
9274         case NCP_BROADCAST_SLOT:
9275             ; /* nothing */
9276             break;
9277
9278         case NCP_SERVICE_REQUEST:
9279             proto_tree_add_uint_format_value(ncp_tree, hf_ncp_func, tvb, 6, 1,
9280                                        func, "%u (0x%02X), %s",
9281                                        func, func, ncp_rec ? ncp_rec->name : "Unknown");
9282
9283             proto_tree_add_uint(ncp_tree, hf_ncp_subfunc, tvb, 7, 1, subfunc);
9284
9285             length_remaining = tvb_reported_length_remaining(tvb, 8);
9286
9287             if (length_remaining >= 8) {
9288                 proto_item *pi;
9289
9290                 ping_version = tvb_get_letohl(tvb, 8);
9291                 proto_tree_add_uint(ncp_tree, hf_nds_ping_version, tvb, 8,
9292                                     4, ping_version);
9293                 nds_flags = tvb_get_letohl(tvb, 12);
9294                 if (request_value){
9295                     request_value->nds_request_verb = 0xf0;
9296                     request_value->req_nds_flags = nds_flags;
9297                 }
9298
9299                 pi = proto_tree_add_uint(ncp_tree, hf_ncp_nds_verb, tvb, 0, 0, 240);
9300                 proto_item_set_hidden(pi);
9301
9302                 proto_tree_add_bitmask(ncp_tree, tvb, 12, hf_pingflags1, ett_ncp, ncp_pingflags1, ENC_LITTLE_ENDIAN);
9303                 proto_tree_add_bitmask(ncp_tree, tvb, 14, hf_pingflags2, ett_ncp, ncp_pingflags2, ENC_LITTLE_ENDIAN);
9304             }
9305             break;
9306
9307         default:
9308             ; /* nothing */
9309             break;
9310         }
9311         ptvc = ptvcursor_new(ncp_tree, tvb, 7);
9312         if (ncp_rec && ncp_rec->request_ptvc) {
9313             clear_repeat_vars();
9314             process_ptvc_record(ptvc, pinfo, ncp_rec->request_ptvc, NULL, TRUE, ncp_rec, TRUE);
9315         }
9316         ptvcursor_free(ptvc);
9317
9318         /* Free the temporary proto_tree */
9319         CLEANUP_CALL_AND_POP;
9320     }
9321 }
9322
9323 /*
9324  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
9325  *
9326  * Local variables:
9327  * c-basic-offset: 4
9328  * tab-width: 4
9329  * indent-tabs-mode: nil
9330  * End:
9331  *
9332  * vi: set shiftwidth=4 tabstop=4 expandtab filetype=c:
9333  * :indentSize=4:tabSize=4:noTabs=true:
9334  */