Set the svn:eol-style property on all text files to "native", so that
[obnox/wireshark/wip.git] / packet-ncp2222.inc
1 /* packet-ncp2222.inc
2  *
3  * Routines for NetWare Core Protocol. This C code gets #include'd
4  * into packet-ncp2222.c, which is generated from ncp2222.py. It's
5  * #include'd instead of being in a separate compilation unit so
6  * that all the data tables in packet-ncp2222.c can remain static.
7  *
8  * Gilbert Ramirez <gram@alumni.rice.edu>
9  * Modified to decode NDS packets by Greg Morris <gmorris@novell.com>
10  *
11  * Portions Copyright (c) Gilbert Ramirez 2000-2002
12  * Portions Copyright (c) Novell, Inc. 2000-2003
13  *
14  * $Id$
15  *
16  * Ethereal - Network traffic analyzer
17  * By Gerald Combs <gerald@ethereal.com>
18  * Copyright 2000 Gerald Combs
19  *
20  * This program is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU General Public License
22  * as published by the Free Software Foundation; either version 2
23  * of the License, or (at your option) any later version.
24  * 
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  * GNU General Public License for more details.
29  * 
30  * You should have received a copy of the GNU General Public License
31  * along with this program; if not, write to the Free Software
32  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
33  */
34
35 #define NCP_PACKET_INIT_COUNT   200
36 #define PROTO_LENGTH_UNTIL_END -1
37
38 gboolean        nds_defragment = TRUE;
39
40 typedef struct {
41         guint32         nds_frag_verb;
42         guint32         nds_frag_version;
43         guint32         nds_frag_flags;
44         guint32         nds_length;
45         guint32         nds_frag;
46         gboolean        nds_fragmented;
47 } frag_info;        
48
49 frag_info           frags[100];
50
51 const fragment_items nds_frag_items = {
52         &ett_nds_segment,
53         &ett_nds_segments,
54         &hf_nds_segments,
55         &hf_nds_segment,
56         &hf_nds_segment_overlap,
57         &hf_nds_segment_overlap_conflict,
58         &hf_nds_segment_multiple_tails,
59         &hf_nds_segment_too_long_segment,
60         &hf_nds_segment_error,
61         NULL,
62         "segments"
63 };
64
65 static const value_string nds_tags[] = {
66         { 0x00000000, "No Such Entry" },
67         { 0x00000001, "Local Entry" },
68         { 0x00000002, "Remote Entry" },
69         { 0x00000003, "Alias Entry" },
70         { 0x00000004, "Referral Information" },
71         { 0x00000006, "Entry and Referrals" },
72         { 0,    NULL }
73 };
74
75 static const value_string nds_info_type[] = {
76         { 0x00000000, "Attribute Names Only / " },
77         { 0x00000001, "Attribute Name & Value / " },
78         { 0x00000002, "Effective Privileges / " },
79         { 0x00000003, "Value Information / " },
80         { 0x00000004, "Abbreviated Value / " },
81         { 0,    NULL }
82 };
83
84 static const value_string nds_kind_of_changes[] = {
85         { 0x00000000, "Add Attribute" },
86         { 0x00000001, "Remove Attribute" },
87         { 0x00000002, "Add Value" },
88         { 0x00000003, "Remove Value" },
89         { 0x00000004, "Add Additional Value" },
90         { 0x00000005, "Overwrite Value" },
91         { 0x00000006, "Clear Attribute" },
92         { 0x00000007, "Clear Value" },
93         { 0,    NULL }
94 };
95
96 static const value_string es_type[] = {
97         { 0x00000000, "No type is specified" },
98         { 0x00000001, "Unicode string" },
99         { 0x00000002, "Partial name" },
100         { 0x00000003, "Referrals" },
101         { 0x00000004, "Tuned name" },
102         { 0x00000005, "GUID attribute" },
103         { 0x00000006, "Local entry ID" },
104         { 0x00000007, "Number of defined entry specifiers" },
105         { 0,    NULL }
106 };
107
108 static const value_string nds_protocol_type[] = {
109         { 0x00000000, "(IPX Protocol)" },
110         { 0x00000001, "(IP Protocol)" },
111         { 0x00000002, "(SDLC Protocol)" },
112         { 0x00000003, "(TokenRing on Ethernet Protocol)" },
113         { 0x00000004, "(OSI Protocol)" },
114         { 0x00000005, "(AppleTalk Protocol)" },
115         { 0x00000006, "(NetBEUI Protocol)" },
116         { 0x00000007, "(Socket Address Protocol)" },
117         { 0x00000008, "(UDP Protocol)" },
118         { 0x00000009, "(TCP Protocol)" },
119         { 0x0000000a, "(UDP v6 Protocol)" },
120         { 0x0000000b, "(TCP v6 Protocol)" },
121         { 0x0000000c, "(Internal Protocol)" },
122         { 0x0000000d, "(URL Protocol)" },
123         { 0,    NULL }
124 };
125
126
127 static const value_string nds_syntax[] = {
128         { 0x00000000, "Unknown Syntax" },
129         { 0x00000001, "Distinguished Name" },
130         { 0x00000002, "Case Sensitive Unicode String" },
131         { 0x00000003, "Non Case Sensitive Unicode String" },
132         { 0x00000004, "Printable String" },
133         { 0x00000005, "Numeric String" },
134         { 0x00000006, "Case Insensitive List" },
135         { 0x00000007, "Boolean" },
136         { 0x00000008, "Signed Integer" },
137         { 0x00000009, "Binary String" },
138         { 0x0000000a, "Telephone Number" },
139         { 0x0000000b, "Fax Number" },
140         { 0x0000000c, "Network Address" },
141         { 0x0000000d, "Binary String List" },
142         { 0x0000000e, "Email Address" },
143         { 0x0000000f, "File System Path" },
144         { 0x00000010, "Replica Pointer" },
145         { 0x00000011, "Object ACL" },
146         { 0x00000012, "Postal Address" },
147         { 0x00000013, "Time Stamp" },
148         { 0x00000014, "Class Name" },
149         { 0x00000015, "Stream" },
150         { 0x00000016, "Counter" },
151         { 0x00000017, "Back Link" },
152         { 0x00000018, "Time" },
153         { 0x00000019, "Typed Name" },
154         { 0x0000001a, "Hold" },
155         { 0x0000001b, "Interval" },
156         { 0,    NULL }
157 };
158
159 static const value_string name_space_type[] = {
160         { 0x00000000, "DOS Name Space" },
161         { 0x00000001, "MAC Name Space" },
162         { 0x00000002, "NFS Name Space" },
163         { 0x00000003, "FTAM Name Space" },
164         { 0x00000004, "OS/2, Long Name Space" },
165         { 0,    NULL }
166 };
167
168                               
169 static const value_string nds_replica_state[] = {
170         { 0x0000, "On" },
171         { 0x0001, "New" },
172         { 0x0002, "Dying" },
173         { 0x0003, "Locked" },
174         { 0x0004, "Create Master State 0" },
175         { 0x0005, "Create Master State 1" },
176         { 0x0006, "Transition On" },
177         { 0x0007, "Dead Replica" },
178         { 0x0008, "Begin Add" },
179         { 0x000b, "Master Start" },
180         { 0x000c, "Master Done" },
181         { 0x0017, "Federated" },
182         { 0x0030, "Split State 0" },
183         { 0x0031, "Split State 1" },
184         { 0x0040, "Join State 0" },
185         { 0x0041, "Join State 1" },
186         { 0x0042, "Join State 2" },
187         { 0x0050, "Move Subtree State 0" },
188         { 0x0051, "Move Subtree State 1" },
189         { 0,    NULL }
190 };
191
192 static const value_string nds_replica_type[] = {
193         { 0x0000, "Master" },
194         { 0x0001, "Secondary" },
195         { 0x0002, "Read Only" },
196         { 0x0003, "Sub Ref" },
197         { 0,    NULL }
198 };
199
200 static const value_string class_def_type[] = {
201         { 0x0000, "Return Class Name" },
202         { 0x0001, "Return Class Name, Flag, and Definition" },
203         { 0x0002, "Return Class Name, Flag, Definition, and Super Class" },
204         { 0x0003, "Return Class Name, Flag, and ASN.1 identifier" },
205         { 0x0004, "Return Class Name, Flag, Definition, Super Class, and ACL" },
206         { 0x0005, "Return Class Name, Flag, Creation Timestamp, Modification Timestamp, Definition, and ACL" },
207         { 0,    NULL }
208 };
209
210 static const value_string nds_search_scope[] = {
211         { 0x0000, "Examine the base object only" },
212         { 0x0001, "Search the immediate subordinates of the base object" },
213         { 0x0002, "Search the base object and all its subordinates" },
214         { 0x0003, "Search the base objects and all objects in its partition (Implemented in NDS 8)" },
215         { 0,    NULL }
216 };
217
218 static const value_string nds_reply_errors[] = {
219         { 0xffffffff, "(-1) Insufficient Space" },
220         { 0xffffff89, "(-119) Buffer too Small" },
221         { 0xffffff88, "(-120) RR Volume Flag Not Set" },
222         { 0xffffff87, "(-121) No Items Found" },
223         { 0xffffff86, "(-122) Connection Already Temporary" },
224         { 0xffffff85, "(-123) Connection Already Logged In" },
225         { 0xffffff84, "(-124) Connection Not Authenticated" },
226         { 0xffffff83, "(-125) Connection Not Logged In" },
227         { 0xffffff82, "(-126) NCP Boundary Check Failed" },
228         { 0xffffff81, "(-127) Lock Waiting" },
229         { 0xffffff80, "(-128) Lock Fail" },
230         { 0xffffff7f, "(-129) Out of Handles" },
231         { 0xffffff7e, "(-130) No Open Privilege" },
232         { 0xffffff7d, "(-131) Hard IO Error" },
233         { 0xffffff7c, "(-132) No Create Privilege" },
234         { 0xffffff7b, "(-133) No Create Delete Privilege" },
235         { 0xffffff7a, "(-134) Create Duplicate When Read Only" },
236         { 0xffffff79, "(-135) Create File with Invalid Name" },
237         { 0xffffff78, "(-136) Invalid File Handle" },
238         { 0xffffff77, "(-137) No Search Privilege"   },
239         { 0xffffff76, "(-138) No Delete Privilege" },
240         { 0xffffff75, "(-139) No Rename Privilege" },
241         { 0xffffff74, "(-140) No Set Privilege" },
242         { 0xffffff73, "(-141) Some File in Use" },
243         { 0xffffff72, "(-142) All File in Use" },
244         { 0xffffff71, "(-143) Some Read Only" },
245         { 0xffffff70, "(-144) All Read Only" },
246         { 0xffffff6f, "(-145) Some names Exist" },
247         { 0xffffff6e, "(-146) All Names Exist" },
248         { 0xffffff6d, "(-147) No Read Privilege" },
249         { 0xffffff6c, "(-148) No Write Privilege" },
250         { 0xffffff6b, "(-149) File Detached" },
251         { 0xffffff6a, "(-150) No Alloc Space/Target Not a Subdirectory/Insuffficient Memory" },
252         { 0xffffff69, "(-151) No Spool Space" },
253         { 0xffffff68, "(-152) Invalid Volume" },
254         { 0xffffff67, "(-153) Directory Full" },
255         { 0xffffff66, "(-154) Rename Across Volume" },
256         { 0xffffff65, "(-155) Bad Directory Handle" },
257         { 0xffffff64, "(-156) Invalid Path/No Such Extension" },
258         { 0xffffff63, "(-157) No Directory Handles" },
259         { 0xffffff62, "(-158) Bad File Name" },
260         { 0xffffff61, "(-159) Directory Active" },
261         { 0xffffff60, "(-160) Directory Not Empty" },
262         { 0xffffff5f, "(-161) Directory IO Error" },
263         { 0xffffff5e, "(-162) IO Locked" },
264         { 0xffffff5d, "(-163) Transaction Restarted" },
265         { 0xffffff5c, "(-164) Rename Directory Invalid" },
266         { 0xffffff5b, "(-165) Invalid Open/Create Mode" },
267         { 0xffffff5a, "(-166) Already in Use" },
268         { 0xffffff59, "(-167) Invalid Resource Tag" },
269         { 0xffffff58, "(-168) Access Denied" },
270         { 0xffffff44, "(-188) Login Signing Required" },
271         { 0xffffff43, "(-189) Login Encryption Required" },
272         { 0xffffff42, "(-190) Invalid Data Stream" },
273         { 0xffffff41, "(-191) Invalid Name Space" },
274         { 0xffffff40, "(-192) No Accounting Privileges" },
275         { 0xffffff3f, "(-193) No Account Balance" },
276         { 0xffffff3e, "(-194) Credit Limit Exceeded" },
277         { 0xffffff3d, "(-195) Too Many Holds" },
278         { 0xffffff3c, "(-196) Accounting Disabled" },
279         { 0xffffff3b, "(-197) Intruder Login Lockout" },
280         { 0xffffff3a, "(-198) No Console Rights" },
281         { 0xffffff30, "(-208) Queue IO Failure" },
282         { 0xffffff2f, "(-209) No Queue" },
283         { 0xffffff2e, "(-210) No Queue Server" },
284         { 0xffffff2d, "(-211) No Queue Rights" },
285         { 0xffffff2c, "(-212) Queue Full" },
286         { 0xffffff2b, "(-213) No Queue Job" },
287         { 0xffffff2a, "(-214) No Queue Job Rights/Unencrypted Not Allowed" },
288         { 0xffffff29, "(-215) Queue In Service/Duplicate Password" },
289         { 0xffffff28, "(-216) Queue Not Active/Password Too Short" },
290         { 0xffffff27, "(-217) Queue Station Not Server/Maximum Logins Exceeded" },
291         { 0xffffff26, "(-218) Queue Halted/Bad Login Time" },
292         { 0xffffff25, "(-219) Queue Maximum Servers/Node Address Violation" },
293         { 0xffffff24, "(-220) Login Account Expired" },
294         { 0xffffff22, "(-222) Bad Password" },
295         { 0xffffff21, "(-223) Password Expired" },
296         { 0xffffff20, "(-224) No Login Connection Available" },
297         { 0xffffff18, "(-232) Write to Group Property" },
298         { 0xffffff17, "(-233) Member Already Exists" },
299         { 0xffffff16, "(-234) No Such Member" },
300         { 0xffffff15, "(-235) Property Not Group" },
301         { 0xffffff14, "(-236) No Such Value Set" },
302         { 0xffffff13, "(-237) Property Already Exists" },
303         { 0xffffff12, "(-238) Object Already Exists" },
304         { 0xffffff11, "(-239) Illegal Name" },
305         { 0xffffff10, "(-240) Illegal Wildcard" },
306         { 0xffffff0f, "(-241) Bindery Security" },
307         { 0xffffff0e, "(-242) No Object Read Rights" },
308         { 0xffffff0d, "(-243) No Object Rename Rights" },
309         { 0xffffff0c, "(-244) No Object Delete Rights" },
310         { 0xffffff0b, "(-245) No Object Create Rights" },
311         { 0xffffff0a, "(-246) No Property Delete Rights" },
312         { 0xffffff09, "(-247) No Property Create Rigths" },
313         { 0xffffff08, "(-248) No Property Write Rights" },
314         { 0xffffff07, "(-249) No Propery Read Rights" },
315         { 0xffffff06, "(-250) Temp Remap" },
316         { 0xffffff05, "(-251) Unknown Request/No Such Property" },
317         { 0xffffff04, "(-252) Message Queue Full/Target Already Has Message/No Such Object" },
318         { 0xffffff03, "(-253) Bad Station Number" },
319         { 0xffffff02, "(-254) Bindery Locked/Directory Locked/Spool Delete/Trustee not Found/Timeout" },
320         { 0xffffff01, "(-255) Hard Failure" },
321         { 0xfffffed3, "(-301) Not Enough Memory" },
322         { 0xfffffed2, "(-302) Bad Key" },
323         { 0xfffffed1, "(-303) Bad Context" },
324         { 0xfffffed0, "(-304) Buffer Full" },
325         { 0xfffffecf, "(-305) List Empty" },
326         { 0xfffffece, "(-306) Bad Syntax"   },
327         { 0xfffffecd, "(-307) Buffer Empty" },
328         { 0xfffffecc, "(-308) Bad Verb" },
329         { 0xfffffecb, "(-309) Expected Identifier" },
330         { 0xfffffeca, "(-310) Expected Equals" },
331         { 0xfffffec9, "(-311) Attribute Type Expected" },
332         { 0xfffffec8, "(-312) Attribute Type Not Expected" },
333         { 0xfffffec7, "(-313) Filter Tree Empty" },
334         { 0xfffffec6, "(-314) Invalid Object Name" },
335         { 0xfffffec5, "(-315) Expected RDN Delimiter" },
336         { 0xfffffec4, "(-316) Too Many Tokens" },
337         { 0xfffffec3, "(-317) Inconsistent MultiAVA" },
338         { 0xfffffec2, "(-318) Country Name Too Long" },
339         { 0xfffffec1, "(-319) Internal Error" },
340         { 0xfffffec0, "(-320) Can't Add Root" },
341         { 0xfffffebf, "(-321) Unable to Attach" },
342         { 0xfffffebe, "(-322) Invalid Iteration Handle" },
343         { 0xfffffebd, "(-323) Buffer Zero Length" },
344         { 0xfffffebc, "(-324) Invalid Replica Type" },
345         { 0xfffffebb, "(-325) Invalid Attribute Syntax" },
346         { 0xfffffeba, "(-326) Invalid Filter Syntax" },
347         { 0xfffffeb8, "(-328) Unicode Error during Context Creation" },
348         { 0xfffffeb7, "(-329) Invalid Union Tag" },
349         { 0xfffffeb6, "(-330) Invalid Server Response" },
350         { 0xfffffeb5, "(-331) Null Pointer" },
351         { 0xfffffeb4, "(-332) No Server Found" },
352         { 0xfffffeb3, "(-333) No Connection" },
353         { 0xfffffeb2, "(-334) RDN Too Long" },
354         { 0xfffffeb1, "(-335) Duplicate Type" },
355         { 0xfffffeb0, "(-336) Data Store Failure" },
356         { 0xfffffeaf, "(-337) Not Logged In" },
357         { 0xfffffeae, "(-338) Invalid Password Characters" },
358         { 0xfffffead, "(-339) Failed Server Authentication" },
359         { 0xfffffeac, "(-340) Transport Failed" },
360         { 0xfffffeab, "(-341) No Such Syntax" },
361         { 0xfffffeaa, "(-342) Invalid DS Name" },
362         { 0xfffffea9, "(-343) Attribute Name Too Long" },
363         { 0xfffffea8, "(-344) Invalid TDS" },
364         { 0xfffffea7, "(-345) Invalid DS Version" },
365         { 0xfffffea6, "(-346) Unicode Translation" },
366         { 0xfffffea5, "(-347) Schema Name Too Long" },
367         { 0xfffffea4, "(-348) Unicode File Not Found" },
368         { 0xfffffea3, "(-349) Unicode Already Loaded" },
369         { 0xfffffea2, "(-350) Not Context Owner" },
370         { 0xfffffea1, "(-351) Attempt to Authenticate" },
371         { 0xfffffea0, "(-352) No Writable Replicas" },
372         { 0xfffffe9f, "(-353) DN Too Long" },
373         { 0xfffffe9e, "(-354) Rename Not Allowed" },
374         { 0xfffffe9d, "(-355) Not NDS for NT" },
375         { 0xfffffe9c, "(-356) NDS for NT - No Domain" },
376         { 0xfffffe9b, "(-357) NDS for NT - Sync Disabled" },
377         { 0xfffffe9a, "(-358) Iterator Invalid Handle" },
378         { 0xfffffe99, "(-359) Iterator Invalid Position" },
379         { 0xfffffe98, "(-360) Iterator Invalid Search Data" },
380         { 0xfffffe97, "(-361) Iterator Invalid Scope" },
381         { 0xfffffda7, "(-601) No Such Entry" },
382         { 0xfffffda6, "(-602) No Such Value" },
383         { 0xfffffda5, "(-603) No Such Attribute" },
384         { 0xfffffda4, "(-604) No Such Class" },
385         { 0xfffffda3, "(-605) No Such Partition" },
386         { 0xfffffda2, "(-606) Entry Already Exists" },
387         { 0xfffffda1, "(-607) Not Effective Class" },
388         { 0xfffffda0, "(-608) Illegal Attribute" },
389         { 0xfffffd9f, "(-609) Missing Mandatory" },
390         { 0xfffffd9e, "(-610) Illegal DS Name" },
391         { 0xfffffd9d, "(-611) Illegal Containment" },
392         { 0xfffffd9c, "(-612) Can't Have Multiple Values" },
393         { 0xfffffd9b, "(-613) Syntax Violation" },
394         { 0xfffffd9a, "(-614) Duplicate Value" },
395         { 0xfffffd99, "(-615) Attribute Already Exists" },
396         { 0xfffffd98, "(-616) Maximum Entries Exist" },
397         { 0xfffffd97, "(-617) Database Format" },
398         { 0xfffffd96, "(-618) Inconsistent Database" },
399         { 0xfffffd95, "(-619) Invalid Comparison" },
400         { 0xfffffd94, "(-620) Comparison Failed" },
401         { 0xfffffd93, "(-621) Transaction Tracking Disabled" },
402         { 0xfffffd92, "(-622) Invalid Transport" },
403         { 0xfffffd91, "(-623) Syntax Invalid in Name" },
404         { 0xfffffd90, "(-624) Replica Already Exists" },
405         { 0xfffffd8f, "(-625) Transport Failure" },
406         { 0xfffffd8e, "(-626) All Referrals Failed" },
407         { 0xfffffd8d, "(-627) Can't Remove Naming Value" },
408         { 0xfffffd8c, "(-628) Object Class Violation" },
409         { 0xfffffd8b, "(-629) Entry is Not Leaf" },
410         { 0xfffffd8a, "(-630) Different Tree" },
411         { 0xfffffd89, "(-631) Illegal Replica Type" },
412         { 0xfffffd88, "(-632) System Failure" },
413         { 0xfffffd87, "(-633) Invalid Entry for Root" },
414         { 0xfffffd86, "(-634) No Referrals" },
415         { 0xfffffd85, "(-635) Remote Failure" },
416         { 0xfffffd84, "(-636) Unreachable Server" },
417         { 0xfffffd83, "(-637) Previous Move in Progress" },
418         { 0xfffffd82, "(-638) No Character Mapping" },
419         { 0xfffffd81, "(-639) Incomplete Authentication" },
420         { 0xfffffd80, "(-640) Invalid Certificate" },
421         { 0xfffffd7f, "(-641) Invalid Request" },
422         { 0xfffffd7e, "(-642) Invalid Iteration" },
423         { 0xfffffd7d, "(-643) Schema is Non-removable" },
424         { 0xfffffd7c, "(-644) Schema is in Use" },
425         { 0xfffffd7b, "(-645) Class Already Exists" },
426         { 0xfffffd7a, "(-646) Bad Naming Attributes" },
427         { 0xfffffd79, "(-647) Not Root Partition" },
428         { 0xfffffd78, "(-648) Insufficient Stack" },
429         { 0xfffffd77, "(-649) Insufficient Buffer" },
430         { 0xfffffd76, "(-650) Ambiguous Containment" },
431         { 0xfffffd75, "(-651) Ambiguous Naming" },
432         { 0xfffffd74, "(-652) Duplicate Mandatory" },
433         { 0xfffffd73, "(-653) Duplicate Optional" },
434         { 0xfffffd72, "(-654) Partition Busy" },
435         { 0xfffffd71, "(-655) Multiple Replicas" },
436         { 0xfffffd70, "(-656) Crucial Replica" },
437         { 0xfffffd6f, "(-657) Schema Sync in Progress" },
438         { 0xfffffd6e, "(-658) Skulk in Progress" },
439         { 0xfffffd6d, "(-659) Time Not Synchronized" },
440         { 0xfffffd6c, "(-660) Record in Use" },
441         { 0xfffffd6b, "(-661) DS Volume Not Mounted" },
442         { 0xfffffd6a, "(-662) DS Volume IO Failure" },
443         { 0xfffffd69, "(-663) DS Locked" },
444         { 0xfffffd68, "(-664) Old Epoch" },
445         { 0xfffffd67, "(-665) New Epoch" },
446         { 0xfffffd66, "(-666) Incompatible DS Version" },
447         { 0xfffffd65, "(-667) Partition Root" },
448         { 0xfffffd64, "(-668) Entry Not Container" },
449         { 0xfffffd63, "(-669) Failed Authentication" },
450         { 0xfffffd62, "(-670) Invalid Context" },
451         { 0xfffffd61, "(-671) No Such Parent" },
452         { 0xfffffd60, "(-672) No Access" },
453         { 0xfffffd5f, "(-673) Replica Not On" },
454         { 0xfffffd5e, "(-674) Invalid Name Service" },
455         { 0xfffffd5d, "(-675) Invalid Task" },
456         { 0xfffffd5c, "(-676) Invalide Connection Handle" },
457         { 0xfffffd5b, "(-677) Invalid Identity" },
458         { 0xfffffd5a, "(-678) Duplicate ACL" },
459         { 0xfffffd59, "(-679) Partition Already Exists" },
460         { 0xfffffd58, "(-680) Transport Modified" },
461         { 0xfffffd57, "(-681) Alias of an Alias" },
462         { 0xfffffd56, "(-682) Auditing Failed" },
463         { 0xfffffd55, "(-683) Invalid API Version" },
464         { 0xfffffd54, "(-684) Secure NCP Violation" },
465         { 0xfffffd53, "(-685) Move in Progress" },
466         { 0xfffffd52, "(-686) Not a Leaf Partition" },
467         { 0xfffffd51, "(-687) Cannot Abort" },
468         { 0xfffffd50, "(-688) Cache Overflow" },
469         { 0xfffffd4f, "(-689) Invalid Subordinate Count" },
470         { 0xfffffd4e, "(-690) Invalid RDN" },
471         { 0xfffffd4d, "(-691) Modification Time Not Current" },
472         { 0xfffffd4c, "(-692) Incorrect Base Class" },
473         { 0xfffffd4b, "(-693) Missing Reference" },
474         { 0xfffffd4a, "(-694) Lost Entry" },
475         { 0xfffffd49, "(-695) Agent Already Registered" },
476         { 0xfffffd48, "(-696) DS Loader Busy" },
477         { 0xfffffd47, "(-697) DS Cannot Reload" },
478         { 0xfffffd46, "(-698) Replica in Skulk" },
479         { 0xfffffd45, "(-699) Fatal" },
480         { 0xfffffd44, "(-700) Obsolete API" },
481         { 0xfffffd43, "(-701) Synchronization Disabled" },
482         { 0xfffffd42, "(-702) Invalid Parameter" },
483         { 0xfffffd41, "(-703) Duplicate Template" },
484         { 0xfffffd40, "(-704) No Master Replica" },
485         { 0xfffffd3f, "(-705) Duplicate Containment" },
486         { 0xfffffd3e, "(-706) Not a Sibling" },
487         { 0xfffffd3d, "(-707) Invalid Signature" },
488         { 0xfffffd3c, "(-708) Invalid Response" },
489         { 0xfffffd3b, "(-709) Insufficient Sockets" },
490         { 0xfffffd3a, "(-710) Database Read Fail" },
491         { 0xfffffd39, "(-711) Invalid Code Page" },
492         { 0xfffffd38, "(-712) Invalid Escape Character" },
493         { 0xfffffd37, "(-713) Invalide Delimiters" },
494         { 0xfffffd36, "(-714) Not Implemented" },
495         { 0xfffffd35, "(-715) Checksum Failure" },
496         { 0xfffffd34, "(-716) Checksumming Not Supported" },
497         { 0xfffffd33, "(-717) CRC Failure" },
498         { 0xfffffd32, "(-718) Invalid Entry Handle" },
499         { 0xfffffd31, "(-719) Invalid Value Handle" },
500         { 0xfffffd30, "(-720) Connection Denied" },
501         { 0xfffffd2f, "(-721) No Such Federation Link" },
502         { 0xfffffd2e, "(-722) Operetational Schema Mismatch" },
503         { 0xfffffd2d, "(-723) Stream Not Found" },
504         { 0xfffffd2c, "(-724) DClient Unavailable" },
505         { 0xfffffd2b, "(-725) MASV No Access" },
506         { 0xfffffd2a, "(-726) MASV Invalid Request" },
507         { 0xfffffd29, "(-727) MASV Failure" },
508         { 0xfffffd28, "(-728) MASV Already Exists" },
509         { 0xfffffd27, "(-729) MASV Not Found" },
510         { 0xfffffd26, "(-730) MASV Bad Range" },
511         { 0xfffffd25, "(-731) Value Data" },
512         { 0xfffffd24, "(-732) Database Locked" },
513         { 0xfffffd21, "(-735) Nothing to Abort" },
514         { 0xfffffd20, "(-736) End of Stream" },
515         { 0xfffffd1f, "(-737) No Such Template" },
516         { 0xfffffd1e, "(-738) SAS Locked" },
517         { 0xfffffd1d, "(-739) Invalid SAS Version" },
518         { 0xfffffd1c, "(-740) SAS Already Registered" },
519         { 0xfffffd1b, "(-741) Name Type Not Supported" },
520         { 0xfffffd1a, "(-742) Wrong DS Version" },
521         { 0xfffffd19, "(-743) Invalid Control Function" },
522         { 0xfffffd18, "(-744) Invalid Control State" },
523         { 0xfffffd17, "(-745) Cache in Use" },
524         { 0xfffffd16, "(-746) Zero Creation Time" },
525         { 0xfffffd15, "(-747) Would Block" },
526         { 0xfffffd14, "(-748) Connection Timeout" },
527         { 0xfffffd13, "(-749) Too Many Referrals" },
528         { 0xfffffd12, "(-750) Operation Cancelled" },
529         { 0xfffffd11, "(-751) Unknown Target" },
530         { 0xfffffd10, "(-752) GUID Failure" },
531         { 0xfffffd0f, "(-753) Incompatible OS" },
532         { 0xfffffd0e, "(-754) Callback Cancel" },
533         { 0xfffffd0d, "(-755) Invalid Synchronization Data" },
534         { 0xfffffd0c, "(-756) Stream Exists" },
535         { 0xfffffd0b, "(-757) Auxiliary Has Containment" },
536         { 0xfffffd0a, "(-758) Auxiliary Not Container" },
537         { 0xfffffd09, "(-759) Auxiliary Not Effective" },
538         { 0xfffffd08, "(-760) Auxiliary On Alias" },
539         { 0xfffffd07, "(-761) Have Seen State" },
540         { 0xfffffd06, "(-762) Verb Locked" },
541         { 0xfffffd05, "(-763) Verb Exceeds Table Length" },
542         { 0xfffffd04, "(-764) BOF Hit" },
543         { 0xfffffd03, "(-765) EOF Hit" },
544         { 0xfffffd02, "(-766) Incompatible Replica Version" },
545         { 0xfffffd01, "(-767) Query Timeout" },
546         { 0xfffffd00, "(-768) Query Maximum Count" },
547         { 0xfffffcff, "(-769) Duplicate Naming" },
548         { 0xfffffcfe, "(-770) No Transaction Active" },
549         { 0xfffffcfd, "(-771) Transaction Active" },
550         { 0xfffffcfc, "(-772) Illegal Transaction Operation" },
551         { 0xfffffcfb, "(-773) Iterator Syntax" },
552         { 0xfffffcfa, "(-774) Repairing DIB" },
553         { 0xfffffcf9, "(-775) Invalid OID Format" },
554         { 0xfffffcf8, "(-776) Attempted to perform an NDS operation, and the DS agent on this server is closing" },
555         { 0xfffffcf7, "(-777) Attempted to modify an object's attribute that is not stored on the sparse replica" },
556         { 0xfffffcf6, "(-778) VpVector and VpvUser which must be correlated, are out of sync" },
557         { 0xfffffcf5, "(-779) Error Cannot Go Remote" },
558         { 0xfffffcf4, "(-780) Request not Supported" },
559         { 0xfffffcf3, "(-781) Entry Not Local" },
560         { 0xfffffcf2, "(-782) Root Unreachable" },
561         { 0xfffffcf1, "(-783) VRDIM Not Initialized" },
562         { 0xfffffcf0, "(-784) Wait Timeout" },
563         { 0xfffffcef, "(-785) DIB Error" },
564         { 0xfffffcee, "(-786) DIB IO Failure" },
565         { 0xfffffced, "(-787) Illegal Schema Attribute" },
566         { 0xfffffcec, "(-788) Error Schema Partition" },
567         { 0xfffffceb, "(-789) Invalid Template" },
568         { 0xfffffcea, "(-790) Error Opening File" },
569         { 0xfffffce9, "(-791) Error Direct Opening File" },
570         { 0xfffffce8, "(-792) Error Creating File" },
571         { 0xfffffce7, "(-793) Error Direct Creating File" },
572         { 0xfffffce6, "(-794) Error Reading File" },
573         { 0xfffffce5, "(-795) Error Direct Reading File" },
574         { 0xfffffce4, "(-796) Error Writing File" },
575         { 0xfffffce3, "(-797) Error Direct Writing File" },
576         { 0xfffffce2, "(-798) Error Positioning in File" },
577         { 0xfffffce1, "(-799) Error Getting File Size" },
578         { 0xffffe88f, "(-6001) Error Truncating File" },
579         { 0xffffe88e, "(-6002) Error Parsing File Name" },
580         { 0xffffe88d, "(-6003) Error Closing File" },
581         { 0xffffe88c, "(-6004) Error Getting File Info" },
582         { 0xffffe88b, "(-6005) Error Expanding File" },
583         { 0xffffe88a, "(-6006) Error Getting Free Blocks" },
584         { 0xffffe889, "(-6007) Error Checking File Existence" },
585         { 0xffffe888, "(-6008) Error Deleting File" },
586         { 0xffffe887, "(-6009) Error Renaming File" },
587         { 0xffffe886, "(-6010) Error Initializing IO System" },
588         { 0xffffe885, "(-6011) Error Flushing File" },
589         { 0xffffe884, "(-6012) Error Setting Up for Read" },
590         { 0xffffe883, "(-6013) Error Setting up for Write" },
591         { 0xffffe882, "(-6014) Error Old View" },
592         { 0xffffe881, "(-6015) Server in Skulk" },
593         { 0xffffe880, "(-6016) Error Returning Partial Results" },
594         { 0xffffe87f, "(-6017) No Such Schema" },
595         { 0xffffe87e, "(-6018) Serial Number Mismatch" },
596         { 0xffffe87d, "(-6019) Bad Referal Database Serial Number" },
597         { 0xffffe87c, "(-6020) Bad Referal Serial Number" },
598         { 0xffffe87b, "(-6021) Invalid File Sequence" },
599         { 0xffffe87a, "(-6022) Error Referal Trans Gap" },
600         { 0xffffe879, "(-6023) Bad Referal File Number" },
601         { 0xffffe878, "(-6024) Referal File Not Found" },
602         { 0xffffe877, "(-6025) Error Backup Active" },
603         { 0xffffe876, "(-6026) Referal Device Full" },
604         { 0xffffe875, "(-6027) Unsupported Version" },
605         { 0xffffe874, "(-6028) Error Must Wait Checkpoint" },
606         { 0xffffe873, "(-6029) Attribute Maintenance in Progress" },
607         { 0xffffe872, "(-6030) Error Abort Transaction" },
608         { 0xffff0000, "Ok" },
609         { 0x0000, "Ok" },
610         { 0,    NULL }
611 };
612
613
614 static void
615 process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
616                 int *req_cond_results, gboolean really_decode,
617                 const ncp_record *ncp_rec);
618
619 /* NCP packets come in request/reply pairs. The request packets tell the type
620  * of NCP request and give a sequence ID. The response, unfortunately, only
621  * identifies itself via the sequence ID; you have to know what type of NCP
622  * request the request packet contained in order to successfully parse the NCP
623  * response. A global method for doing this does not exist in ethereal yet
624  * (NFS also requires it), so for now the NCP section will keep its own hash
625  * table keeping track of NCP packet types.
626  *
627  * We construct a conversation specified by the client and server
628  * addresses and the connection number; the key representing the unique
629  * NCP request then is composed of the pointer to the conversation
630  * structure, cast to a "guint" (which may throw away the upper 32
631  * bits of the pointer on a P64 platform, but the low-order 32 bits
632  * are more likely to differ between conversations than the upper 32 bits),
633  * and the sequence number.
634  *
635  * The value stored in the hash table is the ncp_req_hash_value pointer. This
636  * struct tells us the NCP type and gives the ncp2222_record pointer, if
637  * ncp_type == 0x2222.
638  */
639 typedef struct {
640         conversation_t  *conversation;
641         guint8          nw_sequence;
642 } ncp_req_hash_key;
643
644
645 typedef struct {
646         guint32         nw_eid;
647 } ncp_req_eid_hash_key;
648
649 typedef struct {
650         char                    object_name[256];
651         char                    *object_class;
652 } ncp_req_eid_hash_value;
653
654 static GHashTable *ncp_req_hash = NULL;
655 static GHashTable *ncp_req_eid_hash = NULL;
656 static GMemChunk *ncp_req_eid_hash_keys = NULL;
657 static GMemChunk *ncp_req_eid_hash_values = NULL;
658 static GMemChunk *ncp_req_hash_keys = NULL;
659 static GMemChunk *ncp_req_hash_values = NULL;
660
661 /* Hash Functions */
662 gint
663 ncp_equal(gconstpointer v, gconstpointer v2)
664 {
665         const ncp_req_hash_key  *val1 = (const ncp_req_hash_key*)v;
666         const ncp_req_hash_key  *val2 = (const ncp_req_hash_key*)v2;
667
668         if (val1->conversation == val2->conversation &&
669             val1->nw_sequence  == val2->nw_sequence ) {
670                 return 1;
671         }
672         return 0;
673 }
674
675 gint
676 ncp_eid_equal(gconstpointer v, gconstpointer v2)
677 {
678         const ncp_req_eid_hash_key      *val1 = (const ncp_req_eid_hash_key*)v;
679         const ncp_req_eid_hash_key      *val2 = (const ncp_req_eid_hash_key*)v2;
680
681         if (val1->nw_eid == val2->nw_eid ) {
682                 return 1;
683         }
684         return 0;
685 }
686
687 guint
688 ncp_hash(gconstpointer v)
689 {
690         const ncp_req_hash_key  *ncp_key = (const ncp_req_hash_key*)v;
691         return GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence;
692 }
693
694 guint
695 ncp_eid_hash(gconstpointer v)
696 {
697         const ncp_req_eid_hash_key      *ncp_eid_key = (const ncp_req_eid_hash_key*)v;
698         return GPOINTER_TO_UINT(ncp_eid_key->nw_eid);
699 }
700
701 /* Frees memory used by the ncp_req_hash_value's */
702 static void
703 ncp_req_hash_cleanup(gpointer key _U_, gpointer value, gpointer user_data _U_)
704 {
705         ncp_req_hash_value      *request_value = (ncp_req_hash_value*) value;
706
707         if (request_value->req_cond_results) {
708                 g_free(request_value->req_cond_results);
709         }
710 }
711
712 /* Frees memory used by the ncp_req_hash_value's */
713 static void
714 ncp_req_eid_hash_cleanup(gpointer key _U_, gpointer value, gpointer user_data _U_)
715 {
716         ncp_req_eid_hash_value  *request_eid_value = (ncp_req_eid_hash_value*) value;
717
718         if (request_eid_value->object_class) {
719                 g_free(request_eid_value->object_name);
720         }
721 }
722
723 /* Initializes the hash table and the mem_chunk area each time a new
724  * file is loaded or re-loaded in ethereal */
725 static void
726 ncp_init_protocol(void)
727 {
728         /* fragment */
729         fragment_table_init(&nds_fragment_table);
730         reassembled_table_init(&nds_reassembled_table);
731         
732         if (ncp_req_hash) {
733                 g_hash_table_foreach(ncp_req_hash, ncp_req_hash_cleanup, NULL);
734                 g_hash_table_destroy(ncp_req_hash);
735         }
736         if (ncp_req_eid_hash) {
737                 g_hash_table_foreach(ncp_req_eid_hash, ncp_req_eid_hash_cleanup, NULL);
738                 g_hash_table_destroy(ncp_req_eid_hash);
739         }
740         if (ncp_req_hash_keys)
741                 g_mem_chunk_destroy(ncp_req_hash_keys);
742         if (ncp_req_hash_values)
743                 g_mem_chunk_destroy(ncp_req_hash_values);
744         if (ncp_req_eid_hash_keys)
745                 g_mem_chunk_destroy(ncp_req_eid_hash_keys);
746         if (ncp_req_eid_hash_values)
747                 g_mem_chunk_destroy(ncp_req_eid_hash_values);
748
749         ncp_req_hash = g_hash_table_new(ncp_hash, ncp_equal);
750         ncp_req_eid_hash = g_hash_table_new(ncp_eid_hash, ncp_eid_equal);
751         ncp_req_hash_keys = g_mem_chunk_new("ncp_req_hash_keys",
752                         sizeof(ncp_req_hash_key),
753                         NCP_PACKET_INIT_COUNT * sizeof(ncp_req_hash_key),
754                         G_ALLOC_ONLY);
755         ncp_req_hash_values = g_mem_chunk_new("ncp_req_hash_values",
756                         sizeof(ncp_req_hash_value),
757                         NCP_PACKET_INIT_COUNT * sizeof(ncp_req_hash_value),
758                         G_ALLOC_ONLY);
759         ncp_req_eid_hash_keys = g_mem_chunk_new("ncp_req_eid_hash_keys",
760                         sizeof(ncp_req_eid_hash_key),
761                         NCP_PACKET_INIT_COUNT * sizeof(ncp_req_eid_hash_key),
762                         G_ALLOC_ONLY);
763         ncp_req_eid_hash_values = g_mem_chunk_new("ncp_req_eid_hash_values",
764                         sizeof(ncp_req_eid_hash_value),
765                         NCP_PACKET_INIT_COUNT * sizeof(ncp_req_eid_hash_value),
766                         G_ALLOC_ONLY);
767 }
768
769 /* After the sequential run, we don't need the ncp_request hash and keys
770  * anymore; the lookups have already been done and the vital info
771  * saved in the reply-packets' private_data in the frame_data struct. */
772 static void
773 ncp_postseq_cleanup(void)
774 {
775         if (ncp_req_hash) {
776                 /* Destroy the hash, but don't clean up request_condition data. */
777                 /*g_hash_table_destroy(ncp_req_hash);
778                 ncp_req_hash = NULL;*/
779         }
780         if (ncp_req_hash_keys) {
781                 /*g_mem_chunk_destroy(ncp_req_hash_keys);
782                 ncp_req_hash_keys = NULL;*/
783         }
784         /* Don't free the ncp_req_hash_values or EID_hash_table, as they're
785          * needed during random-access processing of the proto_tree.*/
786 }
787
788 ncp_req_hash_value*
789 ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence,
790                 const ncp_record *ncp_rec)
791 {
792         ncp_req_hash_key                *request_key;
793         ncp_req_hash_value              *request_value;
794
795         /* Now remember the request, so we can find it if we later
796            a reply to it. */
797         request_key = g_mem_chunk_alloc(ncp_req_hash_keys);
798         request_key->conversation = conversation;
799         request_key->nw_sequence = nw_sequence;
800
801         request_value = g_mem_chunk_alloc(ncp_req_hash_values);
802         request_value->ncp_rec = ncp_rec;
803         request_value->req_cond_results = NULL;
804         request_value->req_nds_flags = 0;
805         request_value->nds_request_verb = 0;
806         request_value->nds_version = 0;
807         strcpy(request_value->object_name, " ");
808         request_value->nds_frag = TRUE;
809         
810         g_hash_table_insert(ncp_req_hash, request_key, request_value);
811
812         return request_value;
813 }
814
815 ncp_req_eid_hash_value*
816 ncp_eid_hash_insert(guint32 nw_eid)
817 {
818         ncp_req_eid_hash_key            *request_eid_key;
819         ncp_req_eid_hash_value          *request_eid_value;
820
821         /* Now remember the request, so we can find it if we later
822            a reply to it. */
823         request_eid_key = g_mem_chunk_alloc(ncp_req_eid_hash_keys);
824         request_eid_key->nw_eid = nw_eid;
825
826         request_eid_value = g_mem_chunk_alloc(ncp_req_eid_hash_values);
827         strcpy(request_eid_value->object_name, " ");
828         request_eid_value->object_class = NULL;
829         
830         g_hash_table_insert(ncp_req_eid_hash, request_eid_key, request_eid_value);
831
832         return request_eid_value;
833 }
834
835 /* Returns the ncp_rec*, or NULL if not found. */
836 ncp_req_hash_value*
837 ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence)
838 {
839         ncp_req_hash_key                request_key;
840
841         request_key.conversation = conversation;
842         request_key.nw_sequence = nw_sequence;
843
844         return g_hash_table_lookup(ncp_req_hash, &request_key);
845 }
846
847 /* Returns the value_rec* for needed EID, or NULL if not found. */
848 ncp_req_eid_hash_value*
849 ncp_eid_hash_lookup(conversation_t *conversation _U_, guint32 nw_eid)
850 {
851         ncp_req_eid_hash_key            request_eid_key;
852
853         request_eid_key.nw_eid = nw_eid;
854
855         return g_hash_table_lookup(ncp_req_eid_hash, &request_eid_key);
856 }
857
858 /* Does NCP func require a subfunction code? */
859 static gboolean
860 ncp_requires_subfunc(guint8 func)
861 {
862         const guint8 *ncp_func_requirement = ncp_func_requires_subfunc;
863
864         while (*ncp_func_requirement != 0) {
865                 if (*ncp_func_requirement == func) {
866                         return TRUE;
867                 }
868                 ncp_func_requirement++;
869         }
870         return FALSE;
871 }
872
873 /* Does the NCP func have a length parameter? */
874 static gboolean
875 ncp_has_length_parameter(guint8 func)
876 {
877         const guint8 *ncp_func_requirement = ncp_func_has_no_length_parameter;
878
879         while (*ncp_func_requirement != 0) {
880                 if (*ncp_func_requirement == func) {
881                         return FALSE;
882                 }
883                 ncp_func_requirement++;
884         }
885         return TRUE;
886 }
887                 
888
889 /* Return a ncp_record* based on func and possibly subfunc */
890 static const ncp_record *
891 ncp_record_find(guint8 func, guint8 subfunc)
892 {
893         const ncp_record *ncp_rec = ncp_packets;
894
895         while(ncp_rec->func != 0 || ncp_rec->subfunc != 0 ||
896                 ncp_rec->name != NULL ) {
897                 if (ncp_rec->func == func) {
898                         if (ncp_rec->has_subfunc) {
899                                 if (ncp_rec->subfunc == subfunc) {
900                                         return ncp_rec;
901                                 }
902                         }
903                         else {
904                                 return ncp_rec;
905                         }
906                 }
907                 ncp_rec++;
908         }
909         return NULL;
910 }
911
912
913 /* Given a proto_item*, assume it contains an integer value
914  * and return a guint from it. */
915 guint
916 get_item_value(proto_item *item)
917 {
918         return fvalue_get_integer(&PITEM_FINFO(item)->value);
919 }
920
921
922 char *
923 get_item_string(proto_item *item)
924 {
925         return fvalue_get(&PITEM_FINFO(item)->value);
926 }
927
928 char *
929 get_item_name(proto_item *item)
930 {
931         return PITEM_FINFO(item)->hfinfo->name;
932 }
933
934
935 typedef proto_item* (*padd_func_t)(ptvcursor_t*, const ptvc_record*);
936
937 /*
938  * XXX - are these just DOS-format dates and times?
939  *
940  * Should we put code to understand various date and time formats (UNIX,
941  * DOS, SMB weird mutant UNIX, NT, Mac, etc. into libethereal, and have
942  * the "display" member of an HF_ABSOLUTE_TIME field specify whether
943  * it's DOS date/DOS time, DOS time/DOS date, NT time, UNIX time_t,
944  * UNIX "struct timeval", NFSv3/NFSv4 seconds/nanoseconds, Mac, etc.?
945  *
946  * What about hijacking the "bitmask" field to specify the precision of
947  * the time stamp, or putting a combination of precision and format
948  * into the "display" member?
949  *
950  * What about relative times?  Should they have units (seconds, milliseconds,
951  * microseconds, nanoseconds, etc.), precision, and format in there?
952  */
953 typedef struct {
954         guint   year;
955         guint   month;
956         guint   day;
957 } nw_date_t;
958
959 typedef struct {
960         guint   hour;
961         guint   minute;
962         guint   second;
963 } nw_time_t;
964
965 typedef struct {
966         char   buffer[1024];
967 } nw_uni_t;
968
969 #define VTYPE_NONE              0       /* no value */
970 #define VTYPE_UINT8             1
971 #define VTYPE_UINT16            2
972 #define VTYPE_UINT32            3
973 #define VTYPE_STRING            4
974 #define VTYPE_BITFIELD          5
975 #define VTYPE_MULTIVALUE_UINT32 6
976 #define VTYPE_BYTES             7
977 #define VTYPE_BOOLEAN           8
978
979 #define MVTYPE_ATTR_REQUEST             1
980 #define MVTYPE_ATTR_REPLY               2
981 #define MVTYPE_ATTR_REQUEST2            3       /* XXX - how does this differ from 1? */
982 #define MVTYPE_READ_CLASS_REQ           4
983 #define MVTYPE_READ_REPLICAS            5
984 #define MVTYPE_MODIFY_ATTR_REQUEST      6
985 #define MVTYPE_ADDR_REFERRAL_REQUEST    7
986 #define MVTYPE_ADDR_REFERRAL_REPLY      8
987 #define MVTYPE_LOC_ADDR_REFERRAL_REPLY  9
988 #define MVTYPE_PROC_ENTRY_SPECIFIERS    10
989 #define MVTYPE_PRINT_TIMESTAMP          11
990 #define MVTYPE_LIST_PARTITIONS          12
991 #define MVTYPE_CLASS_NAMES              13
992 #define MVTYPE_MODIFY_CLASS             14
993 #define MVTYPE_ADD_ATTR_REQUEST         15
994
995 typedef struct {
996         guint8          vtype;
997         guint32         vvalue;
998         char*           vstring;
999         char*           vdesc;
1000         guint32         vlength;
1001         guint32         voffset;
1002         guint32         hfname;
1003         char*           bit1;
1004         guint32         bit1hfname;
1005         char*           bit2;
1006         guint32         bit2hfname;
1007         char*           bit3;
1008         guint32         bit3hfname;
1009         char*           bit4;
1010         guint32         bit4hfname;
1011         char*           bit5;
1012         guint32         bit5hfname;
1013         char*           bit6;
1014         guint32         bit6hfname;
1015         char*           bit7;
1016         guint32         bit7hfname;
1017         char*           bit8;
1018         guint32         bit8hfname;
1019         char*           bit9;
1020         guint32         bit9hfname;
1021         char*           bit10;
1022         guint32         bit10hfname;
1023         char*           bit11;
1024         guint32         bit11hfname;
1025         char*           bit12;
1026         guint32         bit12hfname;
1027         char*           bit13;
1028         guint32         bit13hfname;
1029         char*           bit14;
1030         guint32         bit14hfname;
1031         char*           bit15;
1032         guint32         bit15hfname;
1033         char*           bit16;
1034         guint32         bit16hfname;
1035         guint8          mvtype;
1036         guint32         vflags;
1037         guint32         nds_version;
1038 } nds_val;        
1039         
1040
1041 /* Given an integer, fill in a nw_date_t struct. */
1042 static void
1043 uint_to_nwdate(guint data, nw_date_t *nwdate)
1044 {
1045         nwdate->day   =  data & 0x001f;
1046         nwdate->month = (data & 0x01e0) >> 5;
1047         nwdate->year  = ((data & 0xfe00) >> 9) + 1980;
1048 }
1049
1050 /* Given an integer, fill in a nw_time_t struct. */
1051 static void
1052 uint_to_nwtime(guint data, nw_time_t *nwtime)
1053 {
1054         /* 2-second resolution */
1055         nwtime->second = (data & 0x001f) * 2;
1056         nwtime->minute = ((data & 0x07e0) >> 5);
1057         nwtime->hour   = ((data & 0xf800) >> 11);
1058 }
1059
1060 char *
1061 unicode_to_string(char * data, guint32 length)
1062 {
1063         guint32 i;
1064         guint16 character;
1065         int     offset = 0;
1066         char *  buffer = "";
1067         
1068         if (data[1] == 0x00){
1069
1070                 for (i = 0; i < length; i++) {
1071                         character = data[offset];
1072                         buffer[i] = character & 0xff;
1073                         offset += 2;
1074                 }
1075         }
1076         else
1077         {        
1078                 buffer = data;
1079         }        
1080         return buffer;
1081 }
1082
1083 static proto_item*
1084 padd_normal(ptvcursor_t *ptvc, const ptvc_record *rec)
1085 {
1086         return 
1087         ptvcursor_add(ptvc, *rec->hf_ptr,
1088                 rec->length, rec->endianness);
1089 }
1090
1091
1092 static proto_item*
1093 padd_date(ptvcursor_t *ptvc, const ptvc_record *rec)
1094 {
1095         proto_item      *item;
1096         nw_date_t       nw_date;
1097         gint            offset;
1098
1099         offset = ptvcursor_current_offset(ptvc);
1100
1101         item = ptvcursor_add(ptvc, *rec->hf_ptr,
1102                 rec->length, rec->endianness);
1103
1104         uint_to_nwdate(get_item_value(item), &nw_date);
1105         
1106         proto_item_set_text(item, get_item_name(item)); 
1107         proto_item_append_text(item, ": %04u/%02u/%02u",
1108                         nw_date.year, nw_date.month, nw_date.day);
1109         return item;
1110 }
1111
1112 static proto_item*
1113 padd_time(ptvcursor_t *ptvc, const ptvc_record *rec)
1114 {
1115         proto_item      *item;
1116         nw_time_t       nw_time;
1117         gint            offset;
1118
1119         offset = ptvcursor_current_offset(ptvc);
1120
1121         item = ptvcursor_add(ptvc, *rec->hf_ptr,
1122                 rec->length, rec->endianness);
1123
1124         uint_to_nwtime(get_item_value(item), &nw_time);
1125         
1126         proto_item_set_text(item, get_item_name(item)); 
1127         proto_item_append_text(item, ": %02u:%02u:%02u",
1128                         nw_time.hour, nw_time.minute, nw_time.second);
1129         return item;
1130 }
1131
1132
1133 /* Convert a string from little-endian unicode to ascii.  At the moment we
1134    fake it by taking every odd byte.  )-:  The caller must free the
1135    result returned. */
1136 static proto_item*
1137 padd_uni(ptvcursor_t *ptvc, const ptvc_record *rec)
1138 {
1139         proto_item      *item;
1140         nw_uni_t        nw_uni;
1141         guint            offset;
1142         
1143         strcpy(nw_uni.buffer, "");
1144         offset = ptvcursor_current_offset(ptvc);
1145
1146         item = ptvcursor_add(ptvc, *rec->hf_ptr,
1147                 rec->length, rec->endianness);
1148
1149         proto_item_set_text(item, get_item_name(item)); 
1150         proto_item_append_text(item, " %s",
1151                         nw_uni.buffer);
1152                                 
1153         return item;
1154
1155
1156 /* Add a value for a ptvc_record, and process the sub-ptvc_record
1157  * that it points to. */
1158 static void
1159 process_bitfield_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
1160                 gboolean really_decode)
1161 {
1162         proto_item              *item;
1163         proto_tree              *sub_tree;
1164         const ptvc_record       *sub_rec;
1165         int                     current_offset;
1166         gint                    ett;
1167         ptvcursor_t             *sub_ptvc;
1168
1169         if (really_decode) {
1170                 /* Save the current offset */
1171                 current_offset = ptvcursor_current_offset(ptvc);
1172
1173                 /* Add the item */
1174                 item = ptvcursor_add(ptvc, *rec->hf_ptr, rec->length,
1175                                 rec->endianness);
1176
1177                 ett = *rec->sub_ptvc_rec->ett;
1178
1179                 /* Make a new protocol sub-tree */
1180                 sub_tree = proto_item_add_subtree(item, ett);
1181
1182                 /* Make a new ptvcursor */
1183                 sub_ptvc = ptvcursor_new(sub_tree, ptvcursor_tvbuff(ptvc),
1184                                 current_offset);
1185
1186                 /* Use it */
1187                 sub_rec = rec->sub_ptvc_rec->ptvc_rec;
1188                 while(sub_rec->hf_ptr != NULL) {
1189                         g_assert(!sub_rec->sub_ptvc_rec);
1190                         ptvcursor_add_no_advance(sub_ptvc, *sub_rec->hf_ptr,
1191                                         sub_rec->length, sub_rec->endianness);
1192                         sub_rec++;
1193                 }
1194
1195                 /* Free it. */
1196                 ptvcursor_free(sub_ptvc);
1197         }
1198         else {
1199                 ptvcursor_advance(ptvc, rec->length);
1200         }
1201 }
1202
1203 /* Process a sub-ptvc_record that points to a "struct" ptvc_record. */
1204 static void
1205 process_struct_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
1206                 int *req_cond_results, gboolean really_decode,
1207                 const ncp_record *ncp_rec)
1208 {
1209         const ptvc_record       *sub_rec;
1210         gint                    ett;
1211         proto_tree              *old_tree=NULL, *new_tree;
1212         proto_item              *item=NULL;
1213         gint                    offset=0;
1214
1215         /* Create a sub-proto_tree? */
1216         if (rec->sub_ptvc_rec->descr) {
1217                 ett = *rec->sub_ptvc_rec->ett;
1218                 old_tree = ptvcursor_tree(ptvc);
1219                 offset = ptvcursor_current_offset(ptvc);
1220                 item = proto_tree_add_text(old_tree, ptvcursor_tvbuff(ptvc),
1221                                 offset, PROTO_LENGTH_UNTIL_END,
1222                                 rec->sub_ptvc_rec->descr);
1223                 new_tree = proto_item_add_subtree(item, ett);
1224                 ptvcursor_set_tree(ptvc, new_tree);
1225         }
1226
1227         /* Get the ptvc_record for the struct and call our caller
1228          * to process it. */
1229         sub_rec = rec->sub_ptvc_rec->ptvc_rec;
1230         process_ptvc_record(ptvc, sub_rec, req_cond_results, really_decode, ncp_rec);
1231
1232         /* Re-set the tree */
1233         if (rec->sub_ptvc_rec->descr) {
1234                 proto_item_set_len(item, ptvcursor_current_offset(ptvc) - offset);
1235                 ptvcursor_set_tree(ptvc, old_tree);
1236         }
1237 }
1238
1239 /* Run through the table of ptvc_record's and add info to the tree. This
1240  * is the work-horse of process_ptvc_record(). */
1241 static void
1242 _process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
1243                 int *req_cond_results, gboolean really_decode,
1244                 const ncp_record *ncp_rec)
1245 {
1246         proto_item      *item;
1247         guint           i, repeat_count;
1248         padd_func_t     func = NULL;
1249
1250         if (rec->sub_ptvc_rec) {
1251                 /* Repeat this? */
1252                 if (rec->repeat_index == NO_REPEAT) {
1253                         if (rec->hf_ptr == PTVC_STRUCT) {
1254                                 process_struct_sub_ptvc_record(ptvc, rec,
1255                                                 req_cond_results, really_decode,
1256                                                 ncp_rec);
1257                         }
1258                         else {
1259                                 process_bitfield_sub_ptvc_record(ptvc, rec,
1260                                                 really_decode);
1261                         }
1262                 }
1263                 else {
1264                         repeat_count = repeat_vars[rec->repeat_index];
1265                         for (i = 0; i < repeat_count; i++ ) {
1266                                 if (rec->hf_ptr == PTVC_STRUCT) {
1267                                         process_struct_sub_ptvc_record(ptvc, rec,
1268                                                 req_cond_results, really_decode,
1269                                                 ncp_rec);
1270                                 }
1271                                 else {
1272                                         process_bitfield_sub_ptvc_record(ptvc, rec,
1273                                                         really_decode);
1274                                 }
1275                         }
1276                 }
1277         }
1278         else {
1279                 /* If we can't repeat this field, we might use it
1280                  * to set a 'var'. */
1281                 if (rec->repeat_index == NO_REPEAT) {
1282                         if (really_decode) {
1283                                 /* Handle any special formatting. */
1284                                 switch(rec->special_fmt) {
1285                                         case NCP_FMT_NONE:
1286                                                 func = padd_normal;
1287                                                 break;
1288                                         case NCP_FMT_NW_DATE:
1289                                                 func = padd_date;
1290                                                 break;
1291                                         case NCP_FMT_NW_TIME:
1292                                                 func = padd_time;
1293                                                 break;
1294                                         case NCP_FMT_UNICODE:
1295                                                 func = padd_uni;
1296                                                 break;        
1297                                         default:
1298                                                 g_assert_not_reached();
1299                                 }
1300                                 item = func(ptvc, rec);
1301
1302                                 /* Set the value as a 'var' ? */
1303                                 if (rec->var_index != NO_VAR) {
1304                                         repeat_vars[rec->var_index] = get_item_value(item);
1305                                 }
1306                         }
1307                         else {
1308                                 /* If we don't decode the field, we
1309                                  * better not use the value to set a var.
1310                                  * Actually, we could, as long as we don't
1311                                  * *use* that var; for now keep this assert in
1312                                  * place. */
1313                                 g_assert(rec->var_index == NO_VAR);
1314                                 ptvcursor_advance(ptvc, rec->length);
1315                         }
1316                 }
1317                 else {
1318                         /* We do repeat this field. */
1319                         repeat_count = repeat_vars[rec->repeat_index];
1320                         if (really_decode) {
1321                                 /* Handle any special formatting. */
1322                                 switch(rec->special_fmt) {
1323                                         case NCP_FMT_NONE:
1324                                                 func = padd_normal;
1325                                                 break;
1326                                         case NCP_FMT_NW_DATE:
1327                                                 func = padd_date;
1328                                                 break;
1329                                         case NCP_FMT_NW_TIME:
1330                                                 func = padd_time;
1331                                                 break;
1332                                         case NCP_FMT_UNICODE:
1333                                                 func = padd_uni;
1334                                                 break;        
1335                                         default:
1336                                                 g_assert_not_reached();
1337                                 }
1338                                 for (i = 0; i < repeat_count; i++ ) {
1339                                         func(ptvc, rec);
1340                                 }
1341                         }
1342                         else {
1343                                 for (i = 0; i < repeat_count; i++ ) {
1344                                         ptvcursor_advance(ptvc, rec->length);
1345                                 }
1346                         }
1347                 }
1348         }
1349 }
1350
1351 /* Run through the table of ptvc_record's and add info to the tree.
1352  * Honor a request condition result. */
1353 static void
1354 process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec,
1355                 int *req_cond_results, gboolean really_decode,
1356                 const ncp_record *ncp_rec)
1357 {
1358         gboolean decode;
1359
1360         while(rec->hf_ptr != NULL) {
1361                 decode = really_decode;
1362                 /* If we're supposed to decode, check the request condition
1363                  * results to see if we should override this and *not* decode. */
1364                 if (decode && req_cond_results) {
1365                         if (rec->req_cond_index != NO_REQ_COND) {
1366                                 if (req_cond_results[rec->req_cond_index] == FALSE) {
1367                                         decode = FALSE;
1368                                 }
1369                         }
1370                 }
1371                 if (decode || ncp_rec->req_cond_size_type == REQ_COND_SIZE_CONSTANT) {
1372                         _process_ptvc_record(ptvc, rec, req_cond_results, decode, ncp_rec);
1373                 }
1374                 rec++;
1375         }
1376 }
1377
1378
1379
1380 /* Clear the repeat_vars array. */
1381 static void
1382 clear_repeat_vars(void)
1383 {
1384         guint i;
1385
1386         for (i = 0 ; i < NUM_REPEAT_VARS; i++ ) {
1387                 repeat_vars[i] = 0;
1388         }
1389 }
1390
1391
1392 /* Given an error_equivalency table and a completion code, return
1393  * the string representing the error. */
1394 static const char*
1395 ncp_error_string(const error_equivalency *errors, guint8 completion_code)
1396 {
1397         while (errors->ncp_error_index != -1) {
1398                 if (errors->error_in_packet == completion_code) {
1399                         return ncp_errors[errors->ncp_error_index];
1400                 }
1401                 errors++;
1402         }
1403
1404         return "Unknown Error Code";
1405 }
1406
1407 static const ncp_record ncp1111_request =
1408         { 0x01, 0x00, NO_SUBFUNC, "Create Connection Service", NCP_GROUP_CONNECTION,
1409                 NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };
1410
1411 static const ncp_record ncp5555_request =
1412         { 0x01, 0x00, NO_SUBFUNC, "Destroy Connection Service", NCP_GROUP_CONNECTION,
1413                 NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };
1414
1415 static const ncp_record ncpbbbb_request =
1416         { 0x01, 0x00, NO_SUBFUNC, "Server Broadcast Message", NCP_GROUP_CONNECTION,
1417                 NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };                
1418
1419 static const ncp_record ncplip_echo =
1420         { 0x01, 0x00, NO_SUBFUNC, "LIP Echo Packet", NCP_GROUP_CONNECTION,
1421                 NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL };
1422
1423 /* Wrapper around proto_tree_free() */
1424 void free_proto_tree(void *tree)
1425 {
1426         if (tree) {
1427                 proto_tree_free((proto_tree*) tree);
1428         }
1429 }
1430
1431 static guint32
1432 align_4(tvbuff_t *tvb, guint32 aoffset)
1433 {
1434        if(tvb_length_remaining(tvb, aoffset) > 4 )
1435        {
1436                 return (aoffset%4);
1437        }
1438        return 0;
1439 }
1440        
1441 static void
1442 get_string(tvbuff_t* tvb, guint offset, guint str_length, char *dest_buf)
1443 {
1444         guint32 i;
1445         guint16 c_char;
1446         guint32 length_remaining = 0;
1447
1448         length_remaining = tvb_length_remaining(tvb, offset);
1449         if(str_length > length_remaining || str_length > 1024)  
1450         {
1451                 strcpy(dest_buf, "String too long to process");
1452                 return;
1453         }
1454         dest_buf[0] = '\0';        
1455         if(str_length == 0)
1456         {
1457                 return;
1458         }
1459         for ( i = 0; i < str_length; i++ )
1460         {
1461                 c_char = tvb_get_guint8(tvb, offset );
1462                 if (c_char<0x20 || c_char>0x7e)
1463                 {
1464                         if (c_char != 0x00)
1465                         { 
1466                                 c_char = '.';
1467                                 dest_buf[i] = c_char & 0xff;
1468                         }
1469                         else
1470                         {
1471                                 i--;
1472                                 str_length--;
1473                         }
1474                 }
1475                 else
1476                 {
1477                         dest_buf[i] = c_char & 0xff;
1478                 }
1479                 offset++;
1480                 length_remaining--;
1481                 
1482                 if(length_remaining==1)
1483                 {
1484                         dest_buf[i+1] = '\0';
1485                         return;
1486                 }        
1487         }
1488         dest_buf[i] = '\0';
1489         return;
1490 }
1491
1492 static void
1493 uni_to_string(char * data, guint32 str_length, char *dest_buf)
1494 {
1495         guint32 i;
1496         guint16 c_char;
1497         guint32 length_remaining = 0;
1498
1499         length_remaining = str_length;
1500         dest_buf[0] = '\0';        
1501         if(str_length == 0)
1502         {
1503                 return;
1504         }
1505         for ( i = 0; i < str_length; i++ )
1506         {
1507                 c_char = data[i];
1508                 if (c_char<0x20 || c_char>0x7e)
1509                 {
1510                         if (c_char != 0x00)
1511                         { 
1512                                 c_char = '.';
1513                                 dest_buf[i] = c_char & 0xff;
1514                         }
1515                         else
1516                         {
1517                                 i--;
1518                                 str_length--;
1519                         }
1520                 }
1521                 else
1522                 {
1523                         dest_buf[i] = c_char & 0xff;
1524                 }
1525                 length_remaining--;
1526                 
1527                 if(length_remaining==0)
1528                 {
1529                         dest_buf[i+1] = '\0';
1530                         return;
1531                 }        
1532         }
1533         dest_buf[i] = '\0';
1534         return;
1535 }
1536
1537 /*************************************
1538 * Return based on % format in request
1539 * %d = integer in decimal format = 0
1540 * %x = integer in hex format = 1
1541 * %s = string = 2
1542 **************************************/  
1543 int
1544 get_info_type(const gchar* check_string)
1545 {
1546         guint length;
1547         guint i;
1548         char char_val;
1549         
1550         length =  strlen(check_string);
1551         
1552         for (i = 0 ; i < length-1 ; i++ ) {
1553                 char_val = check_string[i+1];
1554                 if (check_string[i] == 0x25 && check_string[i+1] == 0x64) {   /* %d Digits*/
1555                         return 0;
1556                 } 
1557                 if ( check_string[i] == 0x78 && check_string[i+1] == 0x25 && check_string[i+2] == 0x73) {  /* x%s Bytes*/
1558                         return 1;
1559                 }
1560         }
1561         return 2; /* Normal String */
1562 }                
1563
1564 static void
1565 process_bitfield(proto_tree *ncp_tree, tvbuff_t *tvb, nds_val *values)
1566 {
1567         gchar                   flags_str[512];
1568         gchar                   *sep;
1569         proto_item              *tinew;
1570         proto_tree              *flags_tree;
1571         guint32                 i;
1572         guint32                 bvalue = 0;
1573
1574         bvalue = 0x00000001;
1575         flags_str[0]='\0';
1576         sep="";
1577         for (i = 0 ; i < (values->vlength*8); i++ ) {
1578                 if (values->vvalue & bvalue) 
1579                 {
1580                         strcat(flags_str, sep);
1581                         switch(bvalue){
1582                                 case 0x00000001:
1583                                         strcat(flags_str, values->bit1);
1584                                         break;
1585                                 case 0x00000002:        
1586                                         strcat(flags_str, values->bit2);
1587                                         break;
1588                                 case 0x00000004:        
1589                                         strcat(flags_str, values->bit3);
1590                                         break;
1591                                 case 0x00000008:        
1592                                         strcat(flags_str, values->bit4);
1593                                         break;
1594                                 case 0x00000010:        
1595                                         strcat(flags_str, values->bit5);
1596                                         break;
1597                                 case 0x00000020:        
1598                                         strcat(flags_str, values->bit6);
1599                                         break;
1600                                 case 0x00000040:        
1601                                         strcat(flags_str, values->bit7);
1602                                         break;
1603                                 case 0x00000080:        
1604                                         strcat(flags_str, values->bit8);
1605                                         break;
1606                                 case 0x00000100:        
1607                                         strcat(flags_str, values->bit9);
1608                                         break;
1609                                 case 0x00000200:        
1610                                         strcat(flags_str, values->bit10);
1611                                         break;
1612                                 case 0x00000400:        
1613                                         strcat(flags_str, values->bit11);
1614                                         break;
1615                                 case 0x00000800:        
1616                                         strcat(flags_str, values->bit12);
1617                                         break;
1618                                 case 0x00001000:        
1619                                         strcat(flags_str, values->bit13);
1620                                         break;
1621                                 case 0x00002000:        
1622                                         strcat(flags_str, values->bit14);
1623                                         break;
1624                                 case 0x00004000:        
1625                                         strcat(flags_str, values->bit15);
1626                                         break;
1627                                 case 0x00008000:        
1628                                         strcat(flags_str, values->bit16);
1629                                         break;
1630                                 default:
1631                                         break;
1632                         }                
1633                         sep = ", ";
1634                 }
1635                 bvalue = bvalue*2;
1636         }
1637         if(values->vlength==4)
1638         {
1639                 tinew = proto_tree_add_uint_format(ncp_tree, values->hfname,
1640                         tvb, values->voffset, values->vlength, values->vvalue, "%s 0x%08x",
1641                         values->vdesc, values->vvalue);
1642         }
1643         else
1644         {                
1645                 tinew = proto_tree_add_uint_format(ncp_tree, values->hfname,
1646                         tvb, values->voffset, values->vlength, values->vvalue, "%s 0x%04x",
1647                         values->vdesc, values->vvalue);
1648         }
1649         if (flags_str[0] != '\0')
1650                 proto_item_append_text(tinew, " - (%s)", flags_str);
1651                                                         
1652         flags_tree = proto_item_add_subtree(tinew, ett_nds);
1653                                                 
1654         bvalue = 0x00000001;
1655                 
1656         for (i = 0 ; i < (values->vlength*8); i++ ) {
1657                 if (values->vvalue & bvalue) 
1658                 {
1659                         switch(bvalue)
1660                         {
1661                                 case 0x00000001:
1662                                         proto_tree_add_item(flags_tree, values->bit1hfname, tvb, values->voffset, values->vlength, TRUE);
1663                                         break;
1664                                 case 0x00000002:
1665                                         proto_tree_add_item(flags_tree, values->bit2hfname, tvb, values->voffset, values->vlength, TRUE);
1666                                         break;
1667                                 case 0x00000004:
1668                                         proto_tree_add_item(flags_tree, values->bit3hfname, tvb, values->voffset, values->vlength, TRUE);
1669                                         break;
1670                                 case 0x00000008:
1671                                         proto_tree_add_item(flags_tree, values->bit4hfname, tvb, values->voffset, values->vlength, TRUE);
1672                                         break;
1673                                 case 0x00000010:
1674                                         proto_tree_add_item(flags_tree, values->bit5hfname, tvb, values->voffset, values->vlength, TRUE);
1675                                         break;
1676                                 case 0x00000020:
1677                                         proto_tree_add_item(flags_tree, values->bit6hfname, tvb, values->voffset, values->vlength, TRUE);
1678                                         break;
1679                                 case 0x00000040:
1680                                         proto_tree_add_item(flags_tree, values->bit7hfname, tvb, values->voffset, values->vlength, TRUE);
1681                                         break;
1682                                 case 0x00000080:
1683                                         proto_tree_add_item(flags_tree, values->bit8hfname, tvb, values->voffset, values->vlength, TRUE);
1684                                         break;
1685                                 case 0x00000100:
1686                                         proto_tree_add_item(flags_tree, values->bit9hfname, tvb, values->voffset, values->vlength, TRUE);
1687                                         break;
1688                                 case 0x00000200:
1689                                         proto_tree_add_item(flags_tree, values->bit10hfname, tvb, values->voffset, values->vlength, TRUE);
1690                                         break;
1691                                 case 0x00000400:
1692                                         proto_tree_add_item(flags_tree, values->bit11hfname, tvb, values->voffset, values->vlength, TRUE);
1693                                         break;
1694                                 case 0x00000800:
1695                                         proto_tree_add_item(flags_tree, values->bit12hfname, tvb, values->voffset, values->vlength, TRUE);
1696                                         break;
1697                                 case 0x00001000:
1698                                         proto_tree_add_item(flags_tree, values->bit13hfname, tvb, values->voffset, values->vlength, TRUE);
1699                                         break;
1700                                 case 0x00002000:
1701                                         proto_tree_add_item(flags_tree, values->bit14hfname, tvb, values->voffset, values->vlength, TRUE);
1702                                         break;
1703                                 case 0x00004000:
1704                                         proto_tree_add_item(flags_tree, values->bit15hfname, tvb, values->voffset, values->vlength, TRUE);
1705                                         break;
1706                                 case 0x00008000:
1707                                         proto_tree_add_item(flags_tree, values->bit16hfname, tvb, values->voffset, values->vlength, TRUE);
1708                                         break;
1709                                 default:
1710                                         break;
1711                         }
1712                 }
1713                 bvalue = bvalue*2;
1714         }
1715 }
1716
1717
1718 static void
1719 print_nds_values(proto_tree *vtree, tvbuff_t *tvb, guint32 syntax_type, nds_val *vvalues)
1720 {
1721         guint32         value1 = 0;
1722         guint32         value2 = 0;
1723         guint32         value3 = 0;
1724         guint32         value4 = 0;
1725         guint32         value5 = 0;
1726         guint32         value6 = 0;
1727         guint32         voffset = 0;
1728         guint32         icounter;
1729         guint32         number_of_values = 0;
1730         guint32         number_of_items = 0;
1731         guint32         r;
1732         proto_item      *vitem;
1733         proto_tree      *nvtree;
1734         proto_item      *aditem;
1735         proto_tree      *adtree;
1736         char            *valuestr = NULL;
1737         guint16         rtype = 0;
1738         guint16         rstate = 0;
1739         guint16         rnum = 0;
1740         guint16         revent = 0;
1741         gint            length_remaining;
1742
1743         voffset = vvalues->voffset;
1744         if(tvb_get_guint8(tvb, voffset) == 0x00)
1745         {
1746                 voffset = voffset+2;
1747         }                
1748         
1749         number_of_values = tvb_get_letohl(tvb, voffset);
1750         
1751         vitem = proto_tree_add_uint_format(vtree, hf_nds_uint32value, tvb, voffset,
1752                 4, number_of_values, "Number of Values: %u", number_of_values);
1753         
1754         nvtree = proto_item_add_subtree(vitem, ett_nds);
1755         
1756         voffset = voffset + 4; 
1757         
1758         for (icounter = 1 ; icounter <= number_of_values; icounter++ )
1759         {                      
1760                 switch(syntax_type)
1761                 {       
1762                        case 0x00000006:        /* Case Insensitive List */
1763                        case 0x0000000d:        /* Binary String List */
1764                        case 0x00000012:        /* Postal Address */
1765                                voffset += align_4(tvb, voffset);
1766                                voffset = voffset+4;         
1767                                number_of_items = tvb_get_letohl(tvb, voffset);
1768                                voffset = voffset+4;
1769                                for (r=1; r<=number_of_items; r++)
1770                                {
1771                                        value1 = tvb_get_letohl(tvb, voffset);
1772                                        voffset = voffset + 4;
1773                                        get_string(tvb, voffset, value1, vvalues->vstring);
1774                                        proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1775                                            value1, vvalues->vstring);
1776                                        voffset = voffset + value1;    
1777                                        voffset += align_4(tvb, voffset);
1778                                }            
1779                                break;
1780                        case 0x00000007:        /* Boolean */
1781                                value1 = tvb_get_letohl(tvb, voffset); /* length of field */
1782                                if (value1==0)
1783                                {
1784                                        vvalues->vstring = "False";
1785                                }
1786                                else
1787                                {
1788                                        vvalues->vstring = "True";
1789                                }
1790                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1791                                            value1, vvalues->vstring);
1792                                voffset=voffset+8;
1793                                break;
1794                        case 0x00000009:        /* Binary String */
1795                        case 0x00000015:        /* Stream */
1796                                value1 = tvb_get_letohl(tvb, voffset); /* length of field */
1797                                length_remaining = tvb_length_remaining(tvb, voffset);
1798                                if(length_remaining == -1 || value1 > (guint32) length_remaining)
1799                                {
1800                                         break;
1801                                }
1802                                voffset += 4;
1803                                proto_tree_add_bytes(nvtree, hf_value_bytes, tvb, voffset, value1, tvb_get_ptr(tvb, voffset, value1));
1804                                voffset += value1;
1805                                voffset += (value1%2);
1806                                break;
1807                        case 0x00000008:        /* Signed Integer */
1808                        case 0x00000016:        /* Counter */
1809                        case 0x00000018:        /* Time */
1810                        case 0x0000001b:        /* Interval */
1811                                value1 = tvb_get_letohl(tvb, voffset); /* length of field */
1812                                voffset = voffset+4;
1813                                value2 = tvb_get_letohl(tvb, voffset); /* Value */
1814                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
1815                                         value1, value2, "Value %d", value2);
1816                                voffset = voffset+4;
1817                                break;
1818                        case 0x0000000b:        /* Fax Number */
1819                                value1 = tvb_get_letohl(tvb, voffset); /* length of field */
1820                                voffset = voffset+4;
1821                                get_string(tvb, voffset, value1, vvalues->vstring);
1822                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1823                                         value1, vvalues->vstring);
1824                                voffset = voffset + value1;
1825                                voffset += align_4(tvb, voffset);
1826                                value2 = tvb_get_letohl(tvb, voffset); /* Bit Count */
1827                                voffset=voffset+4;
1828                                value3 = tvb_get_letohl(tvb, voffset); /* Bit length */
1829                                voffset = voffset+4;
1830                                get_string(tvb, voffset, value3, vvalues->vstring);
1831                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1832                                         value3, vvalues->vstring);
1833                                voffset = voffset+value3;         
1834                                voffset += align_4(tvb, voffset);
1835                                break;
1836                        case 0x0000000c:        /* Network Address */
1837                                value1 = tvb_get_letohl(tvb, voffset); /* length of field */
1838                                voffset = voffset + 4;
1839                                value2 = tvb_get_letohl(tvb, voffset); /* type of Protocol */
1840                                valuestr = match_strval(value2, nds_protocol_type);
1841                                if (valuestr == NULL)
1842                                { 
1843                                                valuestr="(Undefined Protocol)";
1844                                }
1845                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
1846                                    value1, value2, valuestr, value2);
1847                                voffset = voffset+4;
1848                                value3 = tvb_get_letohl(tvb, voffset); /* length of address */
1849                                voffset = voffset+4;
1850                                switch (value2)
1851                                { 
1852                                         case 0x00000000:
1853                                                 proto_tree_add_item(nvtree, hf_nds_net, tvb, voffset, 4, FALSE);
1854                                                 proto_tree_add_item(nvtree, hf_nds_node, tvb, voffset+4, 6, FALSE);
1855                                                 proto_tree_add_item(nvtree, hf_nds_socket, tvb, voffset+10, 2, FALSE);
1856                                                 break;
1857                                         case 0x00000008:
1858                                                 proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, FALSE);
1859                                                 value4 = tvb_get_letohl(tvb, voffset+2);
1860                                                 proto_tree_add_ipv4(nvtree, hf_add_ref_udp, tvb, voffset+2, 4, value4);
1861                                                 break;
1862                                         case 0x00000009:
1863                                                 proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, FALSE);
1864                                                 value4 = tvb_get_letohl(tvb, voffset+2);
1865                                                 proto_tree_add_ipv4(nvtree, hf_add_ref_tcp, tvb, voffset+2, 4, value4);
1866                                                 break;
1867                                         case 0x00000001:
1868                                                 proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, FALSE);
1869                                                 value4 = tvb_get_letohl(tvb, voffset+2);
1870                                                 proto_tree_add_ipv4(nvtree, hf_add_ref_ip, tvb, voffset+2, 4, value4);
1871                                                 break;
1872                                         case 0x0000000d:
1873                                                 get_string(tvb, voffset, value3, vvalues->vstring);
1874                                                 proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1875                                                         value3, vvalues->vstring);
1876                                                 break;
1877                                         default:
1878                                                 break;
1879                                }
1880                                voffset = voffset + value3;
1881                                voffset += align_4(tvb, voffset);
1882                                break;
1883                        case 0x0000000f:        /* File System Path */
1884                                value1 = tvb_get_letohl(tvb, voffset); /* length of field */
1885                                voffset = voffset + 4;
1886                                value2 = tvb_get_letohl(tvb, voffset); /* Name Space */
1887                                valuestr = match_strval(value2, name_space_type);
1888                                if (valuestr == NULL)
1889                                {
1890                                         valuestr = "Unknown Name Space";
1891                                }
1892                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1893                                         4, valuestr);
1894                                voffset = voffset+4;
1895                                value3 = tvb_get_letohl(tvb, voffset); /* Length of Volume name */
1896                                voffset = voffset+4;
1897                                get_string(tvb, voffset, value3, vvalues->vstring);
1898                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1899                                         value3, vvalues->vstring);
1900                                voffset = voffset+value3;
1901                                voffset += align_4(tvb, voffset);
1902                                value4 = tvb_get_letohl(tvb, voffset); /* Length of Path name */
1903                                voffset = voffset+4;
1904                                get_string(tvb, voffset, value4, vvalues->vstring);
1905                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1906                                         value4, vvalues->vstring);
1907                                voffset = voffset+value4;
1908                                voffset += align_4(tvb, voffset);
1909                                break;
1910                        case 0x00000010:        /* Replica Pointer */
1911                                value1 = tvb_get_letohl(tvb, voffset); /* length of field */
1912                                voffset = voffset + 4;
1913                                value2 = tvb_get_letohl(tvb, voffset); /* Length of Server name */
1914                                voffset = voffset+4;
1915                                get_string(tvb, voffset, value2, vvalues->vstring);
1916                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
1917                                         value2, vvalues->vstring);
1918                                voffset = voffset+value2;
1919                                voffset += align_4(tvb, voffset);
1920                                rtype = tvb_get_letohs(tvb, voffset); /* replica type */
1921                                valuestr = match_strval(rtype, nds_replica_type);
1922                                if (valuestr == NULL)
1923                                { 
1924                                         valuestr="(Unknown Replica Type)";
1925                                }
1926                                proto_tree_add_string(nvtree, hf_replica_type, tvb, voffset,
1927                                         2, valuestr);
1928                                voffset = voffset+2; 
1929                                rstate = tvb_get_letohs(tvb, voffset); /* replica state */
1930                                valuestr = match_strval(rstate, nds_replica_state);
1931                                if (valuestr == NULL)
1932                                { 
1933                                         valuestr="(Unknown Replica State)";
1934                                }
1935                                proto_tree_add_string(nvtree, hf_replica_state, tvb, voffset,
1936                                         2, valuestr);
1937                                voffset = voffset+2;
1938                                value3 = tvb_get_letohl(tvb, voffset); /* Replica number */
1939                                proto_tree_add_uint_format(nvtree, hf_replica_number, tvb, voffset, 
1940                                         4, value3, "Replica Number %d", value3);
1941                                voffset = voffset+4;
1942                                if(vvalues->nds_version == 0xfe)
1943                                {
1944                                         voffset += 4;
1945                                }
1946                                number_of_items = tvb_get_letohl(tvb, voffset);  /* Number of Addresses */
1947                                aditem = proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
1948                                         4, number_of_items, "Number of Addresses: %u", number_of_items);
1949         
1950                                adtree = proto_item_add_subtree(aditem, ett_nds);
1951                                voffset = voffset+4;
1952                                for (r=1; r <= number_of_items; r++)
1953                                {
1954                                         voffset += align_4(tvb, voffset);
1955                                         value4 = tvb_get_letohl(tvb, voffset); /* type of Protocol */
1956                                         valuestr = match_strval(value4, nds_protocol_type);
1957                                         if (valuestr == NULL)
1958                                         { 
1959                                                valuestr="(Undefined Protocol)";
1960                                         }
1961                                         proto_tree_add_uint_format(adtree, hf_nds_uint32value, tvb, voffset,
1962                                                 4, value4, valuestr, value4);
1963                                         voffset = voffset+4;
1964                                         value5 = tvb_get_letohl(tvb, voffset); /* length of address */
1965                                         voffset = voffset+4;
1966                                         switch (value4)
1967                                         { 
1968                                                 case 0x00000000:
1969                                                         proto_tree_add_item(adtree, hf_nds_net, tvb, voffset, 4, FALSE);
1970                                                         proto_tree_add_item(adtree, hf_nds_node, tvb, voffset+4, 6, FALSE);
1971                                                         proto_tree_add_item(adtree, hf_nds_socket, tvb, voffset+10, 2, FALSE);
1972                                                         break;
1973                                                 case 0x00000001:
1974                                                         proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, FALSE);
1975                                                         value6 = tvb_get_letohl(tvb, voffset+2);
1976                                                         proto_tree_add_ipv4(adtree, hf_add_ref_ip, tvb, voffset+2, 4, value6);
1977                                                         break;
1978                                                 case 0x00000008:
1979                                                         proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, FALSE);
1980                                                         value6 = tvb_get_letohl(tvb, voffset+2);
1981                                                         proto_tree_add_ipv4(adtree, hf_add_ref_udp, tvb, voffset+2, 4, value6);
1982                                                         break;
1983                                                 case 0x00000009:
1984                                                         proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, FALSE);
1985                                                         value6 = tvb_get_letohl(tvb, voffset+2);
1986                                                         proto_tree_add_ipv4(adtree, hf_add_ref_tcp, tvb, voffset+2, 4, value6);
1987                                                         break;
1988                                                 case 0x0000000d:
1989                                                         get_string(tvb, voffset, value5, vvalues->vstring);
1990                                                         proto_tree_add_string(adtree, hf_value_string, tvb, voffset, 
1991                                                                 value5, vvalues->vstring);
1992                                                         break;
1993                                                 default:
1994                                                         break;
1995                                         }
1996                                         voffset = voffset + value5;
1997                                }            
1998                                voffset += align_4(tvb, voffset);
1999                                break;
2000                        case 0x00000011:        /* Object ACL */
2001                                value1 = tvb_get_letohl(tvb, voffset); /* Length of Field */
2002                                voffset = voffset + 4;
2003                                value2 = tvb_get_letohl(tvb, voffset);
2004                                voffset = voffset + 4;
2005                                get_string(tvb, voffset, value2, vvalues->vstring); /* Unicode String */
2006                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
2007                                    value2, vvalues->vstring);
2008                                voffset = voffset + value2;    
2009                                voffset += align_4(tvb, voffset);
2010                                value3 = tvb_get_letohl(tvb, voffset);
2011                                voffset = voffset + 4;
2012                                get_string(tvb, voffset, value3, vvalues->vstring); /* Unicode Subject Name */
2013                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
2014                                    value3, vvalues->vstring);
2015                                voffset = voffset + value3;    
2016                                voffset += align_4(tvb, voffset);
2017                                value4 = tvb_get_letohl(tvb, voffset);         /* Privileges */
2018                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2019                                         4, value4, "Privileges %8x", value4);
2020                                voffset = voffset+4;
2021                                voffset += align_4(tvb, voffset);
2022                                break;
2023                        case 0x00000013:        /* Time Stamp */
2024                                value1 = tvb_get_letohl(tvb, voffset);         /* Seconds */
2025                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2026                                         4, value1, "Lenght of Record: %d", value1);
2027                                voffset = voffset+4;
2028                                value2 = tvb_get_letohl(tvb, voffset);
2029                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2030                                         4, value2, "Seconds: %d", value2);
2031                                voffset = voffset + 4;
2032                                rnum = tvb_get_letohs(tvb, voffset); /* replica number */
2033                                proto_tree_add_uint_format(nvtree, hf_nds_rnum, tvb, voffset,
2034                                         2, rnum, "Replica Number: %d", rnum);
2035                                voffset = voffset+2;
2036                                revent = tvb_get_letohs(tvb, voffset); /* Event */
2037                                proto_tree_add_uint_format(nvtree, hf_nds_revent, tvb, voffset,
2038                                         2, revent, "Event: %d", revent);
2039                                voffset = voffset+2;
2040                                voffset += align_4(tvb, voffset);
2041                                break;
2042                        case 0x00000017:        /* Back Link */
2043                                value1 = tvb_get_letohl(tvb, voffset);         /* Length */
2044                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2045                                         4, value1, "Length of Record %08x", value1);
2046                                voffset = voffset+4;
2047                                value2 = tvb_get_letohl(tvb, voffset);         /* Remote ID */
2048                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2049                                         4, value2, "Remote ID %08x", value2);
2050                                voffset = voffset+4;
2051                                value3 = tvb_get_letohl(tvb, voffset);         /* Length of string */
2052                                voffset = voffset+4;
2053                                get_string(tvb, voffset, value3, vvalues->vstring);
2054                                proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset, 
2055                                         value3, vvalues->vstring,
2056                                         "Server Distinguished Name - %s", vvalues->vstring);
2057                                voffset = voffset+value3;
2058                                voffset += align_4(tvb, voffset);
2059                                break;
2060                        case 0x00000019:        /* Typed Name */
2061                                value1 = tvb_get_letohl(tvb, voffset);         /* Length */
2062                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2063                                         4, value1, "Length of Record %08x", value1);
2064                                voffset = voffset+4;
2065                                value2 = tvb_get_letohl(tvb, voffset);         /* Level */
2066                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2067                                         4, value2, "Level %d", value2);
2068                                voffset = voffset+4;
2069                                value3 = tvb_get_letohl(tvb, voffset);         /* Interval */
2070                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2071                                         4, value3, "Interval %d", value3);
2072                                voffset = voffset+4;
2073                                value4 = tvb_get_letohl(tvb, voffset);         /* Distinguished Name */
2074                                voffset = voffset+4;
2075                                get_string(tvb, voffset, value4, vvalues->vstring);
2076                                proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset, 
2077                                         value4, vvalues->vstring,
2078                                         "Distinguished Name - %s", vvalues->vstring);
2079                                voffset = voffset+value4;
2080                                voffset += align_4(tvb, voffset);
2081                                break;
2082                        case 0x0000001a:        /* Hold */
2083                                value1 = tvb_get_letohl(tvb, voffset);         /* Length */
2084                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2085                                         4, value1, "Length of Record %08x", value1);
2086                                voffset = voffset+4;
2087                                value2 = tvb_get_letohl(tvb, voffset);         /* Amount */
2088                                proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset,
2089                                         4, value2, "Amount %d", value2);
2090                                voffset = voffset+4;
2091                                value3 = tvb_get_letohl(tvb, voffset);         /* Subject */
2092                                voffset = voffset+4;
2093                                get_string(tvb, voffset, value3, vvalues->vstring);
2094                                proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset, 
2095                                         value3, vvalues->vstring,
2096                                         "Subject - %s", vvalues->vstring);
2097                                voffset = voffset+value3;
2098                                voffset += align_4(tvb, voffset);
2099                                break;
2100                        case 0x00000001:        /* Distinguished Name */
2101                        case 0x00000002:        /* Case Sensitive Unicode String */
2102                        case 0x00000003:        /* Non Case Sensitive Unicode String */
2103                        case 0x00000004:        /* Printable String */
2104                        case 0x00000005:        /* Numeric String */
2105                        case 0x0000000a:        /* Telephone Number */
2106                        case 0x0000000e:        /* Email Address */
2107                        case 0x00000014:        /* Class Name */
2108                        default:
2109                                value1 = tvb_get_letohl(tvb, voffset);
2110                                voffset = voffset + 4;
2111                                get_string(tvb, voffset, value1, vvalues->vstring);
2112                                proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, 
2113                                    value1, vvalues->vstring);
2114                                voffset = voffset + value1;    
2115                                voffset += align_4(tvb, voffset);
2116                                break;
2117                 }
2118                 voffset += align_4(tvb, voffset);
2119         }
2120         vvalues->voffset=voffset;                           
2121 return;
2122 }      
2123
2124 static guint32
2125 print_es_type(proto_tree *estree, tvbuff_t *tvb, nds_val *values, guint32 vtype, guint32 ioffset)
2126
2127         guint32         value1;
2128         guint32         value2;
2129         guint32         value3;
2130         guint32         value4;
2131         guint32         value5;
2132         guint32         number_of_referrals;
2133         guint32         r;
2134         guint32         i;
2135         guint16         replica_num;
2136         guint16         event_num;
2137         nw_uni_t        mval_buf;
2138         proto_tree      *nestree;
2139         proto_item      *nesitem;
2140         proto_tree      *atree;
2141         proto_item      *aitem;
2142         char *          vstring="";
2143               
2144         strcpy(mval_buf.buffer, "");
2145
2146         switch (vtype)
2147         {
2148                 case 0: /* No Specifier Type */
2149                         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2150                         proto_tree_add_item(estree, hf_es_value, tvb, ioffset, 
2151                                 4, value1);
2152                         ioffset = ioffset + 4;
2153                         break;
2154                 case 1: /* Unicode String */
2155                         value1 = tvb_get_letohl(tvb, ioffset);   /* Delimeter Set */
2156                         ioffset = ioffset + 4;        
2157                         get_string(tvb, ioffset, value1, mval_buf.buffer);
2158                         values->vstring = mval_buf.buffer;
2159                         proto_tree_add_string_format(estree, hf_mv_string, tvb, ioffset, 
2160                                 value1, values->vstring, "Delimeter ->%s", values->vstring);
2161                         ioffset=ioffset + value1;
2162                         ioffset += align_4(tvb, ioffset);
2163                         value2 = tvb_get_letohl(tvb, ioffset);
2164                         ioffset = ioffset + 4;        
2165                         get_string(tvb, ioffset, value2, mval_buf.buffer);
2166                         values->vstring = mval_buf.buffer;
2167                         proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, 
2168                                 value2, values->vstring);
2169                         values->voffset=ioffset + value2;
2170                         ioffset = values->voffset;
2171                         ioffset += align_4(tvb, ioffset);
2172                         break;
2173                 case 2: /* Based */
2174                         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2175                         vstring = match_strval(value1, es_type);
2176                         if (vstring == NULL)
2177                         {
2178                                 vstring = "No ES Type Found";
2179                         }        
2180                         nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset, 
2181                                 4, vstring, "Base Context Type - %s", vstring);
2182                         nestree = proto_item_add_subtree(nesitem, ett_nds);
2183                         ioffset = ioffset + 4;
2184                         switch (value1)
2185                         {
2186                                 case 0: /* No Specifier Type */
2187                                         value2 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2188                                         proto_tree_add_item(nestree, hf_es_value, tvb, ioffset, 
2189                                                 4, value2);
2190                                         ioffset = ioffset + 4;
2191                                         break;
2192                                 case 1: /* Unicode String */
2193                                         value2 = tvb_get_letohl(tvb, ioffset);   /* Delimeter Set */
2194                                         ioffset = ioffset + 4;        
2195                                         get_string(tvb, ioffset, value2, mval_buf.buffer);
2196                                         values->vstring = mval_buf.buffer;
2197                                         proto_tree_add_string_format(nestree, hf_mv_string, tvb, ioffset, 
2198                                                 value2, values->vstring, "Delimeter ->%s", values->vstring);
2199                                         ioffset=ioffset + value2;
2200                                         ioffset += align_4(tvb, ioffset);
2201                                         value3 = tvb_get_letohl(tvb, ioffset);
2202                                         ioffset = ioffset + 4;        
2203                                         get_string(tvb, ioffset, value3, mval_buf.buffer);
2204                                         values->vstring = mval_buf.buffer;
2205                                         proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset, 
2206                                                 value3, values->vstring);
2207                                         values->voffset=ioffset + value3;
2208                                         ioffset = values->voffset;
2209                                         ioffset += align_4(tvb, ioffset);
2210                                         break;
2211                                 case 2: /* Based */
2212                                         break;
2213                                 case 3: /* Hinted */
2214                                         break;
2215                                 case 4: /* Tuned */
2216                                         value2 = tvb_get_letohl(tvb, ioffset);   /* Count */
2217                                         proto_tree_add_item(nestree, hf_es_rdn_count, tvb, ioffset, 
2218                                                 4, value2);
2219                                         ioffset = ioffset + 4;
2220                                         for (r = 1 ; r <= value2; r++ )
2221                                         {
2222                                                 value3 = tvb_get_letohl(tvb, ioffset);   /* Seconds */
2223                                                 proto_tree_add_item(nestree, hf_es_seconds, tvb, ioffset, 
2224                                                         4, value3);
2225                                                 ioffset = ioffset + 4;
2226                                                 replica_num = tvb_get_letohs(tvb, ioffset);   /* Replica */
2227                                                 proto_tree_add_item(nestree, hf_nds_replica_num, tvb, ioffset, 
2228                                                         2, replica_num);
2229                                                 ioffset = ioffset + 2;
2230                                                 event_num = tvb_get_letohs(tvb, ioffset);   /* Event */
2231                                                 proto_tree_add_item(nestree, hf_nds_event_num, tvb, ioffset, 
2232                                                         2, event_num);
2233                                                 ioffset = ioffset + 2;
2234                                         }        
2235                                         value4 = tvb_get_letohl(tvb, ioffset);   /* Delimeter Set */
2236                                         ioffset = ioffset + 4;        
2237                                         get_string(tvb, ioffset, value4, mval_buf.buffer);
2238                                         values->vstring = mval_buf.buffer;
2239                                         proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset, 
2240                                                 value4, values->vstring);
2241                                         ioffset=ioffset + value4;
2242                                         ioffset += align_4(tvb, ioffset);
2243                                         value5 = tvb_get_letohl(tvb, ioffset);   /* RDN */
2244                                         ioffset = ioffset + 4;        
2245                                         get_string(tvb, ioffset, value5, mval_buf.buffer);
2246                                         values->vstring = mval_buf.buffer;
2247                                         proto_tree_add_string(nestree, hf_rdn_string, tvb, ioffset, 
2248                                                 value5, values->vstring);
2249                                         ioffset=ioffset + value5;
2250                                         ioffset += align_4(tvb, ioffset);
2251                                         break;
2252                                 case 5: /* GUID */
2253                                 case 6: /* ID32 */
2254                                 case 7: /* Count */
2255                                 default:
2256                                         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2257                                         proto_tree_add_item(estree, hf_es_value, tvb, ioffset, 
2258                                                 4, value1);
2259                                         ioffset = ioffset + 4;
2260                                         break;
2261                          }
2262                         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2263                         vstring = match_strval(value1, es_type);
2264                         if (vstring == NULL)
2265                         {
2266                                 vstring = "No ES Type Found";
2267                         }        
2268                         nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset, 
2269                                 4, vstring, "Object Name Type - %s", vstring);
2270                         nestree = proto_item_add_subtree(nesitem, ett_nds);
2271                         ioffset = ioffset + 4;
2272                         switch (value1)
2273                         {
2274                                 case 0: /* No Specifier Type */
2275                                         value2 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2276                                         proto_tree_add_item(estree, hf_es_value, tvb, ioffset, 
2277                                                 4, value2);
2278                                         ioffset = ioffset + 4;
2279                                         break;
2280                                 case 1: /* Unicode String */
2281                                         value2 = tvb_get_letohl(tvb, ioffset);   /* Delimeter Set */
2282                                         ioffset = ioffset + 4;        
2283                                         get_string(tvb, ioffset, value2, mval_buf.buffer);
2284                                         values->vstring = mval_buf.buffer;
2285                                         proto_tree_add_string_format(estree, hf_mv_string, tvb, ioffset, 
2286                                                 value2, values->vstring, "Delimeter ->%s", values->vstring);
2287                                         ioffset=ioffset + value2;
2288                                         ioffset += align_4(tvb, ioffset);
2289                                         value3 = tvb_get_letohl(tvb, ioffset);
2290                                         ioffset = ioffset + 4;        
2291                                         get_string(tvb, ioffset, value3, mval_buf.buffer);
2292                                         values->vstring = mval_buf.buffer;
2293                                         proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, 
2294                                                 value3, values->vstring);
2295                                         values->voffset=ioffset + value3;
2296                                         ioffset = values->voffset;
2297                                         ioffset += align_4(tvb, ioffset);
2298                                         break;
2299                                 case 2: /* Based */
2300                                         break;
2301                                 case 3: /* Hinted */
2302                                         break;
2303                                 case 4: /* Tuned */
2304                                         value2 = tvb_get_letohl(tvb, ioffset);   /* Count */
2305                                         proto_tree_add_item(estree, hf_es_rdn_count, tvb, ioffset, 
2306                                                 4, value2);
2307                                         ioffset = ioffset + 4;
2308                                         for (r = 1 ; r <= value2; r++ )
2309                                         {
2310                                                 value3 = tvb_get_letohl(tvb, ioffset);   /* Seconds */
2311                                                 proto_tree_add_item(estree, hf_es_seconds, tvb, ioffset, 
2312                                                         4, value3);
2313                                                 ioffset = ioffset + 4;
2314                                                 replica_num = tvb_get_letohs(tvb, ioffset);   /* Replica */
2315                                                 proto_tree_add_item(estree, hf_nds_replica_num, tvb, ioffset, 
2316                                                         2, replica_num);
2317                                                 ioffset = ioffset + 2;
2318                                                 event_num = tvb_get_letohs(tvb, ioffset);   /* Event */
2319                                                 proto_tree_add_item(estree, hf_nds_event_num, tvb, ioffset, 
2320                                                         2, event_num);
2321                                                 ioffset = ioffset + 2;
2322                                         }        
2323                                         value4 = tvb_get_letohl(tvb, ioffset);   /* Delimeter Set */
2324                                         ioffset = ioffset + 4;        
2325                                         get_string(tvb, ioffset, value4, mval_buf.buffer);
2326                                         values->vstring = mval_buf.buffer;
2327                                         proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, 
2328                                                 value4, values->vstring);
2329                                         ioffset=ioffset + value4;
2330                                         ioffset += align_4(tvb, ioffset);
2331                                         value5 = tvb_get_letohl(tvb, ioffset);   /* RDN */
2332                                         ioffset = ioffset + 4;        
2333                                         get_string(tvb, ioffset, value5, mval_buf.buffer);
2334                                         values->vstring = mval_buf.buffer;
2335                                         proto_tree_add_string(estree, hf_rdn_string, tvb, ioffset, 
2336                                                 value5, values->vstring);
2337                                         ioffset=ioffset + value5;
2338                                         ioffset += align_4(tvb, ioffset);
2339                                         break;
2340                                 case 5: /* GUID */
2341                                 case 6: /* ID32 */
2342                                 case 7: /* Count */
2343                                 default:
2344                                         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2345                                         proto_tree_add_item(estree, hf_es_value, tvb, ioffset, 
2346                                                 4, value1);
2347                                         ioffset = ioffset + 4;
2348                                         break;
2349                          }
2350                         break;
2351                 case 3: /* Hinted */
2352                         number_of_referrals = tvb_get_letohl(tvb, ioffset);
2353                         
2354                         for (r = 1 ; r <= number_of_referrals; r++ )
2355                         {
2356                                 aitem = proto_tree_add_uint_format(estree, hf_referral_record, tvb, 6, 0,
2357                                 r, "NDS Referral Record #%u", r);
2358                                 atree = proto_item_add_subtree(aitem, ett_nds);
2359                                 
2360                                 value1 = tvb_get_letohl(tvb, ioffset);
2361                                 
2362                                 proto_tree_add_uint_format(atree, hf_referral_addcount, tvb, ioffset, 4,
2363                                         value1, "Number of Addresses in Referral - %d", value1);
2364                                      
2365                                 ioffset = ioffset + 4;
2366                                 for (i = 1 ; i <= value1; i++ ) 
2367                                 {
2368                                         value2 = tvb_get_letohl(tvb, ioffset);
2369                                         values->vstring = match_strval(value2, nds_protocol_type);
2370                                         if (values->vstring == NULL)
2371                                         { 
2372                                                values->vstring="(Undefined Protocol)";
2373                                         }
2374                                         proto_tree_add_uint_format(atree, hf_nds_uint32value, tvb, ioffset,
2375                                         4, value2, vstring, value2);
2376                                         ioffset = ioffset+4;
2377                                         value3 = tvb_get_letohl(tvb, ioffset);
2378                                         ioffset = ioffset+4;
2379                                         switch (value2)
2380                                         { 
2381                                                 case 0x00000000:
2382                                                         proto_tree_add_item(atree, hf_nds_net, tvb, ioffset, 4, FALSE);
2383                                                         proto_tree_add_item(atree, hf_nds_node, tvb, ioffset+4, 6, FALSE);
2384                                                         proto_tree_add_item(atree, hf_nds_socket, tvb, ioffset+10, 2, FALSE);
2385                                                         break;
2386                                                 case 0x00000001:
2387                                                         proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE);
2388                                                         value4 = tvb_get_letohl(tvb, ioffset+2);
2389                                                         proto_tree_add_ipv4(atree, hf_add_ref_ip, tvb, ioffset+2, 4, value4);
2390                                                         break;
2391                                                 case 0x00000008:
2392                                                         proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE);
2393                                                         value4 = tvb_get_letohl(tvb, ioffset+2);
2394                                                         proto_tree_add_ipv4(atree, hf_add_ref_udp, tvb, ioffset+2, 4, value4);
2395                                                         break;
2396                                                 case 0x00000009:
2397                                                         proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE);
2398                                                         value4 = tvb_get_letohl(tvb, ioffset+2);
2399                                                         proto_tree_add_ipv4(atree, hf_add_ref_tcp, tvb, ioffset+2, 4, value4);
2400                                                         break;
2401                                                 case 0x0000000d:
2402                                                         get_string(tvb, ioffset, value3, values->vstring);
2403                                                         proto_tree_add_string(atree, hf_value_string, tvb, ioffset, 
2404                                                                 value3, values->vstring);
2405                                                         break;
2406                                                 default:
2407                                                         break;
2408                                         }
2409                                         ioffset = ioffset + value3;    
2410                                         ioffset += align_4(tvb, ioffset);
2411                                 }
2412                 
2413                         }
2414                         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2415                         vstring = match_strval(value1, es_type);
2416                         if (vstring == NULL)
2417                         {
2418                                 vstring = "No ES Type Found";
2419                         }        
2420                         nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset, 
2421                                 4, vstring, "Object Name Type - %s", vstring);
2422                         nestree = proto_item_add_subtree(nesitem, ett_nds);
2423                         ioffset = ioffset + 4;
2424                         switch (value1)
2425                         {
2426                                 case 0: /* No Specifier Type */
2427                                         value2 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2428                                         proto_tree_add_item(estree, hf_es_value, tvb, ioffset, 
2429                                                 4, value2);
2430                                         ioffset = ioffset + 4;
2431                                         break;
2432                                 case 1: /* Unicode String */
2433                                         value2 = tvb_get_letohl(tvb, ioffset);   /* Delimeter Set */
2434                                         ioffset = ioffset + 4;        
2435                                         get_string(tvb, ioffset, value2, mval_buf.buffer);
2436                                         values->vstring = mval_buf.buffer;
2437                                         proto_tree_add_string_format(estree, hf_mv_string, tvb, ioffset, 
2438                                                 value2, values->vstring, "Delimeter ->%s", values->vstring);
2439                                         ioffset=ioffset + value2;
2440                                         ioffset += align_4(tvb, ioffset);
2441                                         value3 = tvb_get_letohl(tvb, ioffset);
2442                                         ioffset = ioffset + 4;        
2443                                         get_string(tvb, ioffset, value3, mval_buf.buffer);
2444                                         values->vstring = mval_buf.buffer;
2445                                         proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, 
2446                                                 value3, values->vstring);
2447                                         values->voffset=ioffset + value3;
2448                                         ioffset = values->voffset;
2449                                         ioffset += align_4(tvb, ioffset);
2450                                         break;
2451                                 case 2: /* Based */
2452                                         break;
2453                                 case 3: /* Hinted */
2454                                         break;
2455                                 case 4: /* Tuned */
2456                                         value2 = tvb_get_letohl(tvb, ioffset);   /* Count */
2457                                         proto_tree_add_item(estree, hf_es_rdn_count, tvb, ioffset, 
2458                                                 4, value2);
2459                                         ioffset = ioffset + 4;
2460                                         for (r = 1 ; r <= value2; r++ )
2461                                         {
2462                                                 value3 = tvb_get_letohl(tvb, ioffset);   /* Seconds */
2463                                                 proto_tree_add_item(estree, hf_es_seconds, tvb, ioffset, 
2464                                                         4, value3);
2465                                                 ioffset = ioffset + 4;
2466                                                 replica_num = tvb_get_letohs(tvb, ioffset);   /* Replica */
2467                                                 proto_tree_add_item(estree, hf_nds_replica_num, tvb, ioffset, 
2468                                                         2, replica_num);
2469                                                 ioffset = ioffset + 2;
2470                                                 event_num = tvb_get_letohs(tvb, ioffset);   /* Event */
2471                                                 proto_tree_add_item(estree, hf_nds_event_num, tvb, ioffset, 
2472                                                         2, event_num);
2473                                                 ioffset = ioffset + 2;
2474                                         }        
2475                                         value4 = tvb_get_letohl(tvb, ioffset);   /* Delimeter Set */
2476                                         ioffset = ioffset + 4;        
2477                                         get_string(tvb, ioffset, value4, mval_buf.buffer);
2478                                         values->vstring = mval_buf.buffer;
2479                                         proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, 
2480                                                 value4, values->vstring);
2481                                         ioffset=ioffset + value4;
2482                                         ioffset += align_4(tvb, ioffset);
2483                                         value5 = tvb_get_letohl(tvb, ioffset);   /* RDN */
2484                                         ioffset = ioffset + 4;        
2485                                         get_string(tvb, ioffset, value5, mval_buf.buffer);
2486                                         values->vstring = mval_buf.buffer;
2487                                         proto_tree_add_string(estree, hf_rdn_string, tvb, ioffset, 
2488                                                 value5, values->vstring);
2489                                         ioffset=ioffset + value5;
2490                                         ioffset += align_4(tvb, ioffset);
2491                                         break;
2492                                 case 5: /* GUID */
2493                                 case 6: /* ID32 */
2494                                 case 7: /* Count */
2495                                 default:
2496                                         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2497                                         proto_tree_add_item(estree, hf_es_value, tvb, ioffset, 
2498                                                 4, value1);
2499                                         ioffset = ioffset + 4;
2500                                         break;
2501                          }
2502                         break;
2503                 case 4: /* Tuned */
2504                         value1 = tvb_get_letohl(tvb, ioffset);   /* Count */
2505                         proto_tree_add_item(estree, hf_es_rdn_count, tvb, ioffset, 
2506                                 4, value1);
2507                         ioffset = ioffset + 4;
2508                         for (r = 1 ; r <= value1; r++ )
2509                         {
2510                                 value2 = tvb_get_letohl(tvb, ioffset);   /* Seconds */
2511                                 proto_tree_add_item(estree, hf_es_seconds, tvb, ioffset, 
2512                                         4, value2);
2513                                 ioffset = ioffset + 4;
2514                                 replica_num = tvb_get_letohs(tvb, ioffset);   /* Replica */
2515                                 proto_tree_add_item(estree, hf_nds_replica_num, tvb, ioffset, 
2516                                         2, replica_num);
2517                                 ioffset = ioffset + 2;
2518                                 event_num = tvb_get_letohs(tvb, ioffset);   /* Event */
2519                                 proto_tree_add_item(estree, hf_nds_event_num, tvb, ioffset, 
2520                                         2, event_num);
2521                                 ioffset = ioffset + 2;
2522                         }        
2523                         value3 = tvb_get_letohl(tvb, ioffset);   /* Delimeter Set */
2524                         ioffset = ioffset + 4;        
2525                         get_string(tvb, ioffset, value3, mval_buf.buffer);
2526                         values->vstring = mval_buf.buffer;
2527                         proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, 
2528                                 value3, values->vstring);
2529                         ioffset=ioffset + value3;
2530                         ioffset += align_4(tvb, ioffset);
2531                         value4 = tvb_get_letohl(tvb, ioffset);   /* RDN */
2532                         ioffset = ioffset + 4;        
2533                         get_string(tvb, ioffset, value4, mval_buf.buffer);
2534                         values->vstring = mval_buf.buffer;
2535                         proto_tree_add_string(estree, hf_rdn_string, tvb, ioffset, 
2536                                 value4, values->vstring);
2537                         ioffset=ioffset + value4;
2538                         ioffset += align_4(tvb, ioffset);
2539                         break;
2540                 case 5: /* GUID */
2541                 case 6: /* ID32 */
2542                 case 7: /* Count */
2543                 default:
2544                         value1 = tvb_get_letohl(tvb, ioffset);   /* ES Type */
2545                         proto_tree_add_item(estree, hf_es_value, tvb, ioffset, 
2546                                 4, value1);
2547                         ioffset = ioffset + 4;
2548                         break;
2549          }
2550         return ioffset;
2551 }   
2552
2553 static void
2554 process_multivalues(proto_tree *ncp_tree, tvbuff_t *tvb, nds_val *values)
2555 {
2556         guint32         i;
2557         guint32         r;
2558         guint32         ioffset = 0;
2559         guint32         value1 = 0;
2560         guint32         value2 = 0;
2561         guint8          value3 = 0;
2562         guint32         value4 = 0;
2563         gint            value5 = 0;
2564         guint32         value6 = 0;
2565         guint32         value7 = 0;
2566         char *          valuestr = "";
2567         proto_tree      *ntree;
2568         proto_tree      *atree;
2569         proto_item      *nitem;
2570         proto_item      *aitem;
2571         guint32         number_of_referrals = 0;
2572         nw_uni_t        mval_buf;
2573         proto_tree      *estree;
2574         proto_item      *esitem;
2575         guint16         replica_num = 0;
2576         guint16         event_num = 0;
2577         guint32         bvalue=0;
2578         nds_val         temp_values;
2579         proto_tree      *sub1tree;
2580         proto_item      *sub1item;
2581         proto_tree      *sub2tree;
2582         proto_item      *sub2item;
2583         gint            length_remaining;
2584                
2585         strcpy(mval_buf.buffer, "");
2586         
2587         if(values->mvtype != MVTYPE_LIST_PARTITIONS)
2588         {
2589                 nitem = proto_tree_add_uint_format(ncp_tree, values->hfname, tvb, values->voffset+ioffset,
2590                         values->vlength, values->vvalue, values->vdesc, values->vvalue);
2591         }
2592         else
2593         {
2594                 nitem = proto_tree_add_string_format(ncp_tree, values->hfname, tvb, values->voffset+ioffset,
2595                         values->vlength, values->vdesc, "%s", values->vdesc);
2596         }                
2597         ioffset = (values->voffset+4);
2598         
2599         ntree = proto_item_add_subtree(nitem, ett_nds);
2600
2601         switch (values->mvtype)
2602         {
2603                 case MVTYPE_ATTR_REQUEST:       /* Attribute Request */
2604                         for (i = 1 ; i <= values->vvalue; i++ )
2605                         {
2606                                 ioffset += align_4(tvb, ioffset);
2607                                 value1 = tvb_get_letohl(tvb, ioffset);
2608                                 ioffset = ioffset + 4;
2609                                 get_string(tvb, ioffset, value1, mval_buf.buffer);
2610                                 values->vstring = mval_buf.buffer;                                
2611                                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, 
2612                                         value1, values->vstring);
2613                                 ioffset = ioffset + value1;        
2614                         }
2615                         break;
2616
2617                 case MVTYPE_ATTR_REPLY:         /* Attribute Reply */
2618                         switch(values->vflags)
2619                         {
2620                                 case 0:
2621                                         for (i = 1 ; i <= values->vvalue; i++ )
2622                                         {
2623                                                 ioffset += align_4(tvb, ioffset);
2624                                                 value1 = tvb_get_letohl(tvb, ioffset);
2625                                                 ioffset = ioffset + 4;
2626                                                 get_string(tvb, ioffset, value1, mval_buf.buffer);
2627                                                 values->vstring = mval_buf.buffer;                                
2628                                                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, 
2629                                                         value1, values->vstring);
2630                                                 ioffset = ioffset + value1;        
2631                                         }
2632                                         break;
2633                                 case 1:
2634                                         for (i = 1 ; i <= values->vvalue; i++ )
2635                                         {
2636                                                 value1 = tvb_get_letohl(tvb, ioffset);
2637                                                 values->vstring = match_strval(value1, nds_syntax);
2638                                                 if (values->vstring == NULL)
2639                                                 {
2640                                                         values->vstring = "No Syntax Found";
2641                                                 }        
2642                                                 proto_tree_add_string(ntree, hf_nds_syntax, tvb, ioffset, 
2643                                                 4, values->vstring);
2644                                                 ioffset = ioffset + 4;
2645                                                 value2 = tvb_get_letohl(tvb, ioffset);
2646                                                 ioffset = ioffset + 4;        
2647                                                 get_string(tvb, ioffset, value2, mval_buf.buffer);
2648                                                 values->vstring = mval_buf.buffer;
2649                                                 proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, 
2650                                                         value2, values->vstring);        
2651                                                 ioffset += value2;
2652                                                 ioffset += align_4(tvb, ioffset);
2653                                                 values->voffset = ioffset; 
2654         
2655                                                 print_nds_values(ntree, tvb, value1, values);        
2656                                                 ioffset = values->voffset;
2657                                         }
2658                                         break;                
2659                                 case 2:
2660                                         for (i = 1 ; i <= values->vvalue; i++ )
2661                                         {
2662                                                 value1 = tvb_get_letohl(tvb, ioffset);
2663                                                 values->vstring = match_strval(value1, nds_syntax);
2664                                                 if (values->vstring == NULL)
2665                                                 {
2666                                                         values->vstring = "No Syntax Found";
2667                                                 }        
2668                                                 proto_tree_add_string(ntree, hf_nds_syntax, tvb, ioffset, 
2669