diff options
author | Gilbert Ramirez <gram@alumni.rice.edu> | 2004-07-18 18:06:47 +0000 |
---|---|---|
committer | Gilbert Ramirez <gram@alumni.rice.edu> | 2004-07-18 18:06:47 +0000 |
commit | 669db206cb1f270046ad400fff7655e20c63e723 (patch) | |
tree | 4eff24a2e16c8963e497e1fc575f35e6af59bd26 /epan/dissectors/packet-ncp2222.inc | |
parent | ae46c27a38700af669ef907491081f09df6f6b2c (diff) |
Move dissectors to epan/dissectors directory.
Also move ncp222.py, x11-fields, process-x11-fields.pl,
make-reg-dotc, and make-reg-dotc.py.
Adjust #include lines in files that include packet-*.h
files.
svn path=/trunk/; revision=11410
Diffstat (limited to 'epan/dissectors/packet-ncp2222.inc')
-rw-r--r-- | epan/dissectors/packet-ncp2222.inc | 8650 |
1 files changed, 8650 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ncp2222.inc b/epan/dissectors/packet-ncp2222.inc new file mode 100644 index 0000000000..52331bedba --- /dev/null +++ b/epan/dissectors/packet-ncp2222.inc @@ -0,0 +1,8650 @@ +/* packet-ncp2222.inc + * + * Routines for NetWare Core Protocol. This C code gets #include'd + * into packet-ncp2222.c, which is generated from ncp2222.py. It's + * #include'd instead of being in a separate compilation unit so + * that all the data tables in packet-ncp2222.c can remain static. + * + * Gilbert Ramirez <gram@alumni.rice.edu> + * Modified to decode NDS packets by Greg Morris <gmorris@novell.com> + * + * Portions Copyright (c) Gilbert Ramirez 2000-2002 + * Portions Copyright (c) Novell, Inc. 2000-2003 + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 2000 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define NCP_PACKET_INIT_COUNT 200 +#define PROTO_LENGTH_UNTIL_END -1 + +gboolean nds_defragment = TRUE; + +typedef struct { + guint32 nds_frag_verb; + guint32 nds_frag_version; + guint32 nds_frag_flags; + guint32 nds_length; + guint32 nds_frag; + gboolean nds_fragmented; +} frag_info; + +frag_info frags[100]; + +const fragment_items nds_frag_items = { + &ett_nds_segment, + &ett_nds_segments, + &hf_nds_segments, + &hf_nds_segment, + &hf_nds_segment_overlap, + &hf_nds_segment_overlap_conflict, + &hf_nds_segment_multiple_tails, + &hf_nds_segment_too_long_segment, + &hf_nds_segment_error, + NULL, + "segments" +}; + +static const value_string nds_tags[] = { + { 0x00000000, "No Such Entry" }, + { 0x00000001, "Local Entry" }, + { 0x00000002, "Remote Entry" }, + { 0x00000003, "Alias Entry" }, + { 0x00000004, "Referral Information" }, + { 0x00000006, "Entry and Referrals" }, + { 0, NULL } +}; + +static const value_string nds_info_type[] = { + { 0x00000000, "Attribute Names Only / " }, + { 0x00000001, "Attribute Name & Value / " }, + { 0x00000002, "Effective Privileges / " }, + { 0x00000003, "Value Information / " }, + { 0x00000004, "Abbreviated Value / " }, + { 0, NULL } +}; + +static const value_string nds_kind_of_changes[] = { + { 0x00000000, "Add Attribute" }, + { 0x00000001, "Remove Attribute" }, + { 0x00000002, "Add Value" }, + { 0x00000003, "Remove Value" }, + { 0x00000004, "Add Additional Value" }, + { 0x00000005, "Overwrite Value" }, + { 0x00000006, "Clear Attribute" }, + { 0x00000007, "Clear Value" }, + { 0, NULL } +}; + +static const value_string es_type[] = { + { 0x00000000, "No type is specified" }, + { 0x00000001, "Unicode string" }, + { 0x00000002, "Partial name" }, + { 0x00000003, "Referrals" }, + { 0x00000004, "Tuned name" }, + { 0x00000005, "GUID attribute" }, + { 0x00000006, "Local entry ID" }, + { 0x00000007, "Number of defined entry specifiers" }, + { 0, NULL } +}; + +static const value_string nds_protocol_type[] = { + { 0x00000000, "(IPX Protocol)" }, + { 0x00000001, "(IP Protocol)" }, + { 0x00000002, "(SDLC Protocol)" }, + { 0x00000003, "(TokenRing on Ethernet Protocol)" }, + { 0x00000004, "(OSI Protocol)" }, + { 0x00000005, "(AppleTalk Protocol)" }, + { 0x00000006, "(NetBEUI Protocol)" }, + { 0x00000007, "(Socket Address Protocol)" }, + { 0x00000008, "(UDP Protocol)" }, + { 0x00000009, "(TCP Protocol)" }, + { 0x0000000a, "(UDP v6 Protocol)" }, + { 0x0000000b, "(TCP v6 Protocol)" }, + { 0x0000000c, "(Internal Protocol)" }, + { 0x0000000d, "(URL Protocol)" }, + { 0, NULL } +}; + + +static const value_string nds_syntax[] = { + { 0x00000000, "Unknown Syntax" }, + { 0x00000001, "Distinguished Name" }, + { 0x00000002, "Case Sensitive Unicode String" }, + { 0x00000003, "Non Case Sensitive Unicode String" }, + { 0x00000004, "Printable String" }, + { 0x00000005, "Numeric String" }, + { 0x00000006, "Case Insensitive List" }, + { 0x00000007, "Boolean" }, + { 0x00000008, "Signed Integer" }, + { 0x00000009, "Binary String" }, + { 0x0000000a, "Telephone Number" }, + { 0x0000000b, "Fax Number" }, + { 0x0000000c, "Network Address" }, + { 0x0000000d, "Binary String List" }, + { 0x0000000e, "Email Address" }, + { 0x0000000f, "File System Path" }, + { 0x00000010, "Replica Pointer" }, + { 0x00000011, "Object ACL" }, + { 0x00000012, "Postal Address" }, + { 0x00000013, "Time Stamp" }, + { 0x00000014, "Class Name" }, + { 0x00000015, "Stream" }, + { 0x00000016, "Counter" }, + { 0x00000017, "Back Link" }, + { 0x00000018, "Time" }, + { 0x00000019, "Typed Name" }, + { 0x0000001a, "Hold" }, + { 0x0000001b, "Interval" }, + { 0, NULL } +}; + +static const value_string name_space_type[] = { + { 0x00000000, "DOS Name Space" }, + { 0x00000001, "MAC Name Space" }, + { 0x00000002, "NFS Name Space" }, + { 0x00000003, "FTAM Name Space" }, + { 0x00000004, "OS/2, Long Name Space" }, + { 0, NULL } +}; + + +static const value_string nds_replica_state[] = { + { 0x0000, "On" }, + { 0x0001, "New" }, + { 0x0002, "Dying" }, + { 0x0003, "Locked" }, + { 0x0004, "Create Master State 0" }, + { 0x0005, "Create Master State 1" }, + { 0x0006, "Transition On" }, + { 0x0007, "Dead Replica" }, + { 0x0008, "Begin Add" }, + { 0x000b, "Master Start" }, + { 0x000c, "Master Done" }, + { 0x0017, "Federated" }, + { 0x0030, "Split State 0" }, + { 0x0031, "Split State 1" }, + { 0x0040, "Join State 0" }, + { 0x0041, "Join State 1" }, + { 0x0042, "Join State 2" }, + { 0x0050, "Move Subtree State 0" }, + { 0x0051, "Move Subtree State 1" }, + { 0, NULL } +}; + +static const value_string nds_replica_type[] = { + { 0x0000, "Master" }, + { 0x0001, "Secondary" }, + { 0x0002, "Read Only" }, + { 0x0003, "Sub Ref" }, + { 0, NULL } +}; + +static const value_string class_def_type[] = { + { 0x0000, "Return Class Name" }, + { 0x0001, "Return Class Name, Flag, and Definition" }, + { 0x0002, "Return Class Name, Flag, Definition, and Super Class" }, + { 0x0003, "Return Class Name, Flag, and ASN.1 identifier" }, + { 0x0004, "Return Class Name, Flag, Definition, Super Class, and ACL" }, + { 0x0005, "Return Class Name, Flag, Creation Timestamp, Modification Timestamp, Definition, and ACL" }, + { 0, NULL } +}; + +static const value_string nds_search_scope[] = { + { 0x0000, "Examine the base object only" }, + { 0x0001, "Search the immediate subordinates of the base object" }, + { 0x0002, "Search the base object and all its subordinates" }, + { 0x0003, "Search the base objects and all objects in its partition (Implemented in NDS 8)" }, + { 0, NULL } +}; + +static const value_string nds_reply_errors[] = { + { 0xffffffff, "(-1) Insufficient Space" }, + { 0xffffff89, "(-119) Buffer too Small" }, + { 0xffffff88, "(-120) RR Volume Flag Not Set" }, + { 0xffffff87, "(-121) No Items Found" }, + { 0xffffff86, "(-122) Connection Already Temporary" }, + { 0xffffff85, "(-123) Connection Already Logged In" }, + { 0xffffff84, "(-124) Connection Not Authenticated" }, + { 0xffffff83, "(-125) Connection Not Logged In" }, + { 0xffffff82, "(-126) NCP Boundary Check Failed" }, + { 0xffffff81, "(-127) Lock Waiting" }, + { 0xffffff80, "(-128) Lock Fail" }, + { 0xffffff7f, "(-129) Out of Handles" }, + { 0xffffff7e, "(-130) No Open Privilege" }, + { 0xffffff7d, "(-131) Hard IO Error" }, + { 0xffffff7c, "(-132) No Create Privilege" }, + { 0xffffff7b, "(-133) No Create Delete Privilege" }, + { 0xffffff7a, "(-134) Create Duplicate When Read Only" }, + { 0xffffff79, "(-135) Create File with Invalid Name" }, + { 0xffffff78, "(-136) Invalid File Handle" }, + { 0xffffff77, "(-137) No Search Privilege" }, + { 0xffffff76, "(-138) No Delete Privilege" }, + { 0xffffff75, "(-139) No Rename Privilege" }, + { 0xffffff74, "(-140) No Set Privilege" }, + { 0xffffff73, "(-141) Some File in Use" }, + { 0xffffff72, "(-142) All File in Use" }, + { 0xffffff71, "(-143) Some Read Only" }, + { 0xffffff70, "(-144) All Read Only" }, + { 0xffffff6f, "(-145) Some names Exist" }, + { 0xffffff6e, "(-146) All Names Exist" }, + { 0xffffff6d, "(-147) No Read Privilege" }, + { 0xffffff6c, "(-148) No Write Privilege" }, + { 0xffffff6b, "(-149) File Detached" }, + { 0xffffff6a, "(-150) No Alloc Space/Target Not a Subdirectory/Insuffficient Memory" }, + { 0xffffff69, "(-151) No Spool Space" }, + { 0xffffff68, "(-152) Invalid Volume" }, + { 0xffffff67, "(-153) Directory Full" }, + { 0xffffff66, "(-154) Rename Across Volume" }, + { 0xffffff65, "(-155) Bad Directory Handle" }, + { 0xffffff64, "(-156) Invalid Path/No Such Extension" }, + { 0xffffff63, "(-157) No Directory Handles" }, + { 0xffffff62, "(-158) Bad File Name" }, + { 0xffffff61, "(-159) Directory Active" }, + { 0xffffff60, "(-160) Directory Not Empty" }, + { 0xffffff5f, "(-161) Directory IO Error" }, + { 0xffffff5e, "(-162) IO Locked" }, + { 0xffffff5d, "(-163) Transaction Restarted" }, + { 0xffffff5c, "(-164) Rename Directory Invalid" }, + { 0xffffff5b, "(-165) Invalid Open/Create Mode" }, + { 0xffffff5a, "(-166) Already in Use" }, + { 0xffffff59, "(-167) Invalid Resource Tag" }, + { 0xffffff58, "(-168) Access Denied" }, + { 0xffffff44, "(-188) Login Signing Required" }, + { 0xffffff43, "(-189) Login Encryption Required" }, + { 0xffffff42, "(-190) Invalid Data Stream" }, + { 0xffffff41, "(-191) Invalid Name Space" }, + { 0xffffff40, "(-192) No Accounting Privileges" }, + { 0xffffff3f, "(-193) No Account Balance" }, + { 0xffffff3e, "(-194) Credit Limit Exceeded" }, + { 0xffffff3d, "(-195) Too Many Holds" }, + { 0xffffff3c, "(-196) Accounting Disabled" }, + { 0xffffff3b, "(-197) Intruder Login Lockout" }, + { 0xffffff3a, "(-198) No Console Rights" }, + { 0xffffff30, "(-208) Queue IO Failure" }, + { 0xffffff2f, "(-209) No Queue" }, + { 0xffffff2e, "(-210) No Queue Server" }, + { 0xffffff2d, "(-211) No Queue Rights" }, + { 0xffffff2c, "(-212) Queue Full" }, + { 0xffffff2b, "(-213) No Queue Job" }, + { 0xffffff2a, "(-214) No Queue Job Rights/Unencrypted Not Allowed" }, + { 0xffffff29, "(-215) Queue In Service/Duplicate Password" }, + { 0xffffff28, "(-216) Queue Not Active/Password Too Short" }, + { 0xffffff27, "(-217) Queue Station Not Server/Maximum Logins Exceeded" }, + { 0xffffff26, "(-218) Queue Halted/Bad Login Time" }, + { 0xffffff25, "(-219) Queue Maximum Servers/Node Address Violation" }, + { 0xffffff24, "(-220) Login Account Expired" }, + { 0xffffff22, "(-222) Bad Password" }, + { 0xffffff21, "(-223) Password Expired" }, + { 0xffffff20, "(-224) No Login Connection Available" }, + { 0xffffff18, "(-232) Write to Group Property" }, + { 0xffffff17, "(-233) Member Already Exists" }, + { 0xffffff16, "(-234) No Such Member" }, + { 0xffffff15, "(-235) Property Not Group" }, + { 0xffffff14, "(-236) No Such Value Set" }, + { 0xffffff13, "(-237) Property Already Exists" }, + { 0xffffff12, "(-238) Object Already Exists" }, + { 0xffffff11, "(-239) Illegal Name" }, + { 0xffffff10, "(-240) Illegal Wildcard" }, + { 0xffffff0f, "(-241) Bindery Security" }, + { 0xffffff0e, "(-242) No Object Read Rights" }, + { 0xffffff0d, "(-243) No Object Rename Rights" }, + { 0xffffff0c, "(-244) No Object Delete Rights" }, + { 0xffffff0b, "(-245) No Object Create Rights" }, + { 0xffffff0a, "(-246) No Property Delete Rights" }, + { 0xffffff09, "(-247) No Property Create Rigths" }, + { 0xffffff08, "(-248) No Property Write Rights" }, + { 0xffffff07, "(-249) No Propery Read Rights" }, + { 0xffffff06, "(-250) Temp Remap" }, + { 0xffffff05, "(-251) Unknown Request/No Such Property" }, + { 0xffffff04, "(-252) Message Queue Full/Target Already Has Message/No Such Object" }, + { 0xffffff03, "(-253) Bad Station Number" }, + { 0xffffff02, "(-254) Bindery Locked/Directory Locked/Spool Delete/Trustee not Found/Timeout" }, + { 0xffffff01, "(-255) Hard Failure" }, + { 0xfffffed3, "(-301) Not Enough Memory" }, + { 0xfffffed2, "(-302) Bad Key" }, + { 0xfffffed1, "(-303) Bad Context" }, + { 0xfffffed0, "(-304) Buffer Full" }, + { 0xfffffecf, "(-305) List Empty" }, + { 0xfffffece, "(-306) Bad Syntax" }, + { 0xfffffecd, "(-307) Buffer Empty" }, + { 0xfffffecc, "(-308) Bad Verb" }, + { 0xfffffecb, "(-309) Expected Identifier" }, + { 0xfffffeca, "(-310) Expected Equals" }, + { 0xfffffec9, "(-311) Attribute Type Expected" }, + { 0xfffffec8, "(-312) Attribute Type Not Expected" }, + { 0xfffffec7, "(-313) Filter Tree Empty" }, + { 0xfffffec6, "(-314) Invalid Object Name" }, + { 0xfffffec5, "(-315) Expected RDN Delimiter" }, + { 0xfffffec4, "(-316) Too Many Tokens" }, + { 0xfffffec3, "(-317) Inconsistent MultiAVA" }, + { 0xfffffec2, "(-318) Country Name Too Long" }, + { 0xfffffec1, "(-319) Internal Error" }, + { 0xfffffec0, "(-320) Can't Add Root" }, + { 0xfffffebf, "(-321) Unable to Attach" }, + { 0xfffffebe, "(-322) Invalid Iteration Handle" }, + { 0xfffffebd, "(-323) Buffer Zero Length" }, + { 0xfffffebc, "(-324) Invalid Replica Type" }, + { 0xfffffebb, "(-325) Invalid Attribute Syntax" }, + { 0xfffffeba, "(-326) Invalid Filter Syntax" }, + { 0xfffffeb8, "(-328) Unicode Error during Context Creation" }, + { 0xfffffeb7, "(-329) Invalid Union Tag" }, + { 0xfffffeb6, "(-330) Invalid Server Response" }, + { 0xfffffeb5, "(-331) Null Pointer" }, + { 0xfffffeb4, "(-332) No Server Found" }, + { 0xfffffeb3, "(-333) No Connection" }, + { 0xfffffeb2, "(-334) RDN Too Long" }, + { 0xfffffeb1, "(-335) Duplicate Type" }, + { 0xfffffeb0, "(-336) Data Store Failure" }, + { 0xfffffeaf, "(-337) Not Logged In" }, + { 0xfffffeae, "(-338) Invalid Password Characters" }, + { 0xfffffead, "(-339) Failed Server Authentication" }, + { 0xfffffeac, "(-340) Transport Failed" }, + { 0xfffffeab, "(-341) No Such Syntax" }, + { 0xfffffeaa, "(-342) Invalid DS Name" }, + { 0xfffffea9, "(-343) Attribute Name Too Long" }, + { 0xfffffea8, "(-344) Invalid TDS" }, + { 0xfffffea7, "(-345) Invalid DS Version" }, + { 0xfffffea6, "(-346) Unicode Translation" }, + { 0xfffffea5, "(-347) Schema Name Too Long" }, + { 0xfffffea4, "(-348) Unicode File Not Found" }, + { 0xfffffea3, "(-349) Unicode Already Loaded" }, + { 0xfffffea2, "(-350) Not Context Owner" }, + { 0xfffffea1, "(-351) Attempt to Authenticate" }, + { 0xfffffea0, "(-352) No Writable Replicas" }, + { 0xfffffe9f, "(-353) DN Too Long" }, + { 0xfffffe9e, "(-354) Rename Not Allowed" }, + { 0xfffffe9d, "(-355) Not NDS for NT" }, + { 0xfffffe9c, "(-356) NDS for NT - No Domain" }, + { 0xfffffe9b, "(-357) NDS for NT - Sync Disabled" }, + { 0xfffffe9a, "(-358) Iterator Invalid Handle" }, + { 0xfffffe99, "(-359) Iterator Invalid Position" }, + { 0xfffffe98, "(-360) Iterator Invalid Search Data" }, + { 0xfffffe97, "(-361) Iterator Invalid Scope" }, + { 0xfffffda7, "(-601) No Such Entry" }, + { 0xfffffda6, "(-602) No Such Value" }, + { 0xfffffda5, "(-603) No Such Attribute" }, + { 0xfffffda4, "(-604) No Such Class" }, + { 0xfffffda3, "(-605) No Such Partition" }, + { 0xfffffda2, "(-606) Entry Already Exists" }, + { 0xfffffda1, "(-607) Not Effective Class" }, + { 0xfffffda0, "(-608) Illegal Attribute" }, + { 0xfffffd9f, "(-609) Missing Mandatory" }, + { 0xfffffd9e, "(-610) Illegal DS Name" }, + { 0xfffffd9d, "(-611) Illegal Containment" }, + { 0xfffffd9c, "(-612) Can't Have Multiple Values" }, + { 0xfffffd9b, "(-613) Syntax Violation" }, + { 0xfffffd9a, "(-614) Duplicate Value" }, + { 0xfffffd99, "(-615) Attribute Already Exists" }, + { 0xfffffd98, "(-616) Maximum Entries Exist" }, + { 0xfffffd97, "(-617) Database Format" }, + { 0xfffffd96, "(-618) Inconsistent Database" }, + { 0xfffffd95, "(-619) Invalid Comparison" }, + { 0xfffffd94, "(-620) Comparison Failed" }, + { 0xfffffd93, "(-621) Transaction Tracking Disabled" }, + { 0xfffffd92, "(-622) Invalid Transport" }, + { 0xfffffd91, "(-623) Syntax Invalid in Name" }, + { 0xfffffd90, "(-624) Replica Already Exists" }, + { 0xfffffd8f, "(-625) Transport Failure" }, + { 0xfffffd8e, "(-626) All Referrals Failed" }, + { 0xfffffd8d, "(-627) Can't Remove Naming Value" }, + { 0xfffffd8c, "(-628) Object Class Violation" }, + { 0xfffffd8b, "(-629) Entry is Not Leaf" }, + { 0xfffffd8a, "(-630) Different Tree" }, + { 0xfffffd89, "(-631) Illegal Replica Type" }, + { 0xfffffd88, "(-632) System Failure" }, + { 0xfffffd87, "(-633) Invalid Entry for Root" }, + { 0xfffffd86, "(-634) No Referrals" }, + { 0xfffffd85, "(-635) Remote Failure" }, + { 0xfffffd84, "(-636) Unreachable Server" }, + { 0xfffffd83, "(-637) Previous Move in Progress" }, + { 0xfffffd82, "(-638) No Character Mapping" }, + { 0xfffffd81, "(-639) Incomplete Authentication" }, + { 0xfffffd80, "(-640) Invalid Certificate" }, + { 0xfffffd7f, "(-641) Invalid Request" }, + { 0xfffffd7e, "(-642) Invalid Iteration" }, + { 0xfffffd7d, "(-643) Schema is Non-removable" }, + { 0xfffffd7c, "(-644) Schema is in Use" }, + { 0xfffffd7b, "(-645) Class Already Exists" }, + { 0xfffffd7a, "(-646) Bad Naming Attributes" }, + { 0xfffffd79, "(-647) Not Root Partition" }, + { 0xfffffd78, "(-648) Insufficient Stack" }, + { 0xfffffd77, "(-649) Insufficient Buffer" }, + { 0xfffffd76, "(-650) Ambiguous Containment" }, + { 0xfffffd75, "(-651) Ambiguous Naming" }, + { 0xfffffd74, "(-652) Duplicate Mandatory" }, + { 0xfffffd73, "(-653) Duplicate Optional" }, + { 0xfffffd72, "(-654) Partition Busy" }, + { 0xfffffd71, "(-655) Multiple Replicas" }, + { 0xfffffd70, "(-656) Crucial Replica" }, + { 0xfffffd6f, "(-657) Schema Sync in Progress" }, + { 0xfffffd6e, "(-658) Skulk in Progress" }, + { 0xfffffd6d, "(-659) Time Not Synchronized" }, + { 0xfffffd6c, "(-660) Record in Use" }, + { 0xfffffd6b, "(-661) DS Volume Not Mounted" }, + { 0xfffffd6a, "(-662) DS Volume IO Failure" }, + { 0xfffffd69, "(-663) DS Locked" }, + { 0xfffffd68, "(-664) Old Epoch" }, + { 0xfffffd67, "(-665) New Epoch" }, + { 0xfffffd66, "(-666) Incompatible DS Version" }, + { 0xfffffd65, "(-667) Partition Root" }, + { 0xfffffd64, "(-668) Entry Not Container" }, + { 0xfffffd63, "(-669) Failed Authentication" }, + { 0xfffffd62, "(-670) Invalid Context" }, + { 0xfffffd61, "(-671) No Such Parent" }, + { 0xfffffd60, "(-672) No Access" }, + { 0xfffffd5f, "(-673) Replica Not On" }, + { 0xfffffd5e, "(-674) Invalid Name Service" }, + { 0xfffffd5d, "(-675) Invalid Task" }, + { 0xfffffd5c, "(-676) Invalide Connection Handle" }, + { 0xfffffd5b, "(-677) Invalid Identity" }, + { 0xfffffd5a, "(-678) Duplicate ACL" }, + { 0xfffffd59, "(-679) Partition Already Exists" }, + { 0xfffffd58, "(-680) Transport Modified" }, + { 0xfffffd57, "(-681) Alias of an Alias" }, + { 0xfffffd56, "(-682) Auditing Failed" }, + { 0xfffffd55, "(-683) Invalid API Version" }, + { 0xfffffd54, "(-684) Secure NCP Violation" }, + { 0xfffffd53, "(-685) Move in Progress" }, + { 0xfffffd52, "(-686) Not a Leaf Partition" }, + { 0xfffffd51, "(-687) Cannot Abort" }, + { 0xfffffd50, "(-688) Cache Overflow" }, + { 0xfffffd4f, "(-689) Invalid Subordinate Count" }, + { 0xfffffd4e, "(-690) Invalid RDN" }, + { 0xfffffd4d, "(-691) Modification Time Not Current" }, + { 0xfffffd4c, "(-692) Incorrect Base Class" }, + { 0xfffffd4b, "(-693) Missing Reference" }, + { 0xfffffd4a, "(-694) Lost Entry" }, + { 0xfffffd49, "(-695) Agent Already Registered" }, + { 0xfffffd48, "(-696) DS Loader Busy" }, + { 0xfffffd47, "(-697) DS Cannot Reload" }, + { 0xfffffd46, "(-698) Replica in Skulk" }, + { 0xfffffd45, "(-699) Fatal" }, + { 0xfffffd44, "(-700) Obsolete API" }, + { 0xfffffd43, "(-701) Synchronization Disabled" }, + { 0xfffffd42, "(-702) Invalid Parameter" }, + { 0xfffffd41, "(-703) Duplicate Template" }, + { 0xfffffd40, "(-704) No Master Replica" }, + { 0xfffffd3f, "(-705) Duplicate Containment" }, + { 0xfffffd3e, "(-706) Not a Sibling" }, + { 0xfffffd3d, "(-707) Invalid Signature" }, + { 0xfffffd3c, "(-708) Invalid Response" }, + { 0xfffffd3b, "(-709) Insufficient Sockets" }, + { 0xfffffd3a, "(-710) Database Read Fail" }, + { 0xfffffd39, "(-711) Invalid Code Page" }, + { 0xfffffd38, "(-712) Invalid Escape Character" }, + { 0xfffffd37, "(-713) Invalide Delimiters" }, + { 0xfffffd36, "(-714) Not Implemented" }, + { 0xfffffd35, "(-715) Checksum Failure" }, + { 0xfffffd34, "(-716) Checksumming Not Supported" }, + { 0xfffffd33, "(-717) CRC Failure" }, + { 0xfffffd32, "(-718) Invalid Entry Handle" }, + { 0xfffffd31, "(-719) Invalid Value Handle" }, + { 0xfffffd30, "(-720) Connection Denied" }, + { 0xfffffd2f, "(-721) No Such Federation Link" }, + { 0xfffffd2e, "(-722) Operetational Schema Mismatch" }, + { 0xfffffd2d, "(-723) Stream Not Found" }, + { 0xfffffd2c, "(-724) DClient Unavailable" }, + { 0xfffffd2b, "(-725) MASV No Access" }, + { 0xfffffd2a, "(-726) MASV Invalid Request" }, + { 0xfffffd29, "(-727) MASV Failure" }, + { 0xfffffd28, "(-728) MASV Already Exists" }, + { 0xfffffd27, "(-729) MASV Not Found" }, + { 0xfffffd26, "(-730) MASV Bad Range" }, + { 0xfffffd25, "(-731) Value Data" }, + { 0xfffffd24, "(-732) Database Locked" }, + { 0xfffffd21, "(-735) Nothing to Abort" }, + { 0xfffffd20, "(-736) End of Stream" }, + { 0xfffffd1f, "(-737) No Such Template" }, + { 0xfffffd1e, "(-738) SAS Locked" }, + { 0xfffffd1d, "(-739) Invalid SAS Version" }, + { 0xfffffd1c, "(-740) SAS Already Registered" }, + { 0xfffffd1b, "(-741) Name Type Not Supported" }, + { 0xfffffd1a, "(-742) Wrong DS Version" }, + { 0xfffffd19, "(-743) Invalid Control Function" }, + { 0xfffffd18, "(-744) Invalid Control State" }, + { 0xfffffd17, "(-745) Cache in Use" }, + { 0xfffffd16, "(-746) Zero Creation Time" }, + { 0xfffffd15, "(-747) Would Block" }, + { 0xfffffd14, "(-748) Connection Timeout" }, + { 0xfffffd13, "(-749) Too Many Referrals" }, + { 0xfffffd12, "(-750) Operation Cancelled" }, + { 0xfffffd11, "(-751) Unknown Target" }, + { 0xfffffd10, "(-752) GUID Failure" }, + { 0xfffffd0f, "(-753) Incompatible OS" }, + { 0xfffffd0e, "(-754) Callback Cancel" }, + { 0xfffffd0d, "(-755) Invalid Synchronization Data" }, + { 0xfffffd0c, "(-756) Stream Exists" }, + { 0xfffffd0b, "(-757) Auxiliary Has Containment" }, + { 0xfffffd0a, "(-758) Auxiliary Not Container" }, + { 0xfffffd09, "(-759) Auxiliary Not Effective" }, + { 0xfffffd08, "(-760) Auxiliary On Alias" }, + { 0xfffffd07, "(-761) Have Seen State" }, + { 0xfffffd06, "(-762) Verb Locked" }, + { 0xfffffd05, "(-763) Verb Exceeds Table Length" }, + { 0xfffffd04, "(-764) BOF Hit" }, + { 0xfffffd03, "(-765) EOF Hit" }, + { 0xfffffd02, "(-766) Incompatible Replica Version" }, + { 0xfffffd01, "(-767) Query Timeout" }, + { 0xfffffd00, "(-768) Query Maximum Count" }, + { 0xfffffcff, "(-769) Duplicate Naming" }, + { 0xfffffcfe, "(-770) No Transaction Active" }, + { 0xfffffcfd, "(-771) Transaction Active" }, + { 0xfffffcfc, "(-772) Illegal Transaction Operation" }, + { 0xfffffcfb, "(-773) Iterator Syntax" }, + { 0xfffffcfa, "(-774) Repairing DIB" }, + { 0xfffffcf9, "(-775) Invalid OID Format" }, + { 0xfffffcf8, "(-776) Attempted to perform an NDS operation, and the DS agent on this server is closing" }, + { 0xfffffcf7, "(-777) Attempted to modify an object's attribute that is not stored on the sparse replica" }, + { 0xfffffcf6, "(-778) VpVector and VpvUser which must be correlated, are out of sync" }, + { 0xfffffcf5, "(-779) Error Cannot Go Remote" }, + { 0xfffffcf4, "(-780) Request not Supported" }, + { 0xfffffcf3, "(-781) Entry Not Local" }, + { 0xfffffcf2, "(-782) Root Unreachable" }, + { 0xfffffcf1, "(-783) VRDIM Not Initialized" }, + { 0xfffffcf0, "(-784) Wait Timeout" }, + { 0xfffffcef, "(-785) DIB Error" }, + { 0xfffffcee, "(-786) DIB IO Failure" }, + { 0xfffffced, "(-787) Illegal Schema Attribute" }, + { 0xfffffcec, "(-788) Error Schema Partition" }, + { 0xfffffceb, "(-789) Invalid Template" }, + { 0xfffffcea, "(-790) Error Opening File" }, + { 0xfffffce9, "(-791) Error Direct Opening File" }, + { 0xfffffce8, "(-792) Error Creating File" }, + { 0xfffffce7, "(-793) Error Direct Creating File" }, + { 0xfffffce6, "(-794) Error Reading File" }, + { 0xfffffce5, "(-795) Error Direct Reading File" }, + { 0xfffffce4, "(-796) Error Writing File" }, + { 0xfffffce3, "(-797) Error Direct Writing File" }, + { 0xfffffce2, "(-798) Error Positioning in File" }, + { 0xfffffce1, "(-799) Error Getting File Size" }, + { 0xffffe88f, "(-6001) Error Truncating File" }, + { 0xffffe88e, "(-6002) Error Parsing File Name" }, + { 0xffffe88d, "(-6003) Error Closing File" }, + { 0xffffe88c, "(-6004) Error Getting File Info" }, + { 0xffffe88b, "(-6005) Error Expanding File" }, + { 0xffffe88a, "(-6006) Error Getting Free Blocks" }, + { 0xffffe889, "(-6007) Error Checking File Existence" }, + { 0xffffe888, "(-6008) Error Deleting File" }, + { 0xffffe887, "(-6009) Error Renaming File" }, + { 0xffffe886, "(-6010) Error Initializing IO System" }, + { 0xffffe885, "(-6011) Error Flushing File" }, + { 0xffffe884, "(-6012) Error Setting Up for Read" }, + { 0xffffe883, "(-6013) Error Setting up for Write" }, + { 0xffffe882, "(-6014) Error Old View" }, + { 0xffffe881, "(-6015) Server in Skulk" }, + { 0xffffe880, "(-6016) Error Returning Partial Results" }, + { 0xffffe87f, "(-6017) No Such Schema" }, + { 0xffffe87e, "(-6018) Serial Number Mismatch" }, + { 0xffffe87d, "(-6019) Bad Referal Database Serial Number" }, + { 0xffffe87c, "(-6020) Bad Referal Serial Number" }, + { 0xffffe87b, "(-6021) Invalid File Sequence" }, + { 0xffffe87a, "(-6022) Error Referal Trans Gap" }, + { 0xffffe879, "(-6023) Bad Referal File Number" }, + { 0xffffe878, "(-6024) Referal File Not Found" }, + { 0xffffe877, "(-6025) Error Backup Active" }, + { 0xffffe876, "(-6026) Referal Device Full" }, + { 0xffffe875, "(-6027) Unsupported Version" }, + { 0xffffe874, "(-6028) Error Must Wait Checkpoint" }, + { 0xffffe873, "(-6029) Attribute Maintenance in Progress" }, + { 0xffffe872, "(-6030) Error Abort Transaction" }, + { 0xffff0000, "Ok" }, + { 0x0000, "Ok" }, + { 0, NULL } +}; + + +static void +process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec, + int *req_cond_results, gboolean really_decode, + const ncp_record *ncp_rec); + +/* NCP packets come in request/reply pairs. The request packets tell the type + * of NCP request and give a sequence ID. The response, unfortunately, only + * identifies itself via the sequence ID; you have to know what type of NCP + * request the request packet contained in order to successfully parse the NCP + * response. A global method for doing this does not exist in ethereal yet + * (NFS also requires it), so for now the NCP section will keep its own hash + * table keeping track of NCP packet types. + * + * We construct a conversation specified by the client and server + * addresses and the connection number; the key representing the unique + * NCP request then is composed of the pointer to the conversation + * structure, cast to a "guint" (which may throw away the upper 32 + * bits of the pointer on a P64 platform, but the low-order 32 bits + * are more likely to differ between conversations than the upper 32 bits), + * and the sequence number. + * + * The value stored in the hash table is the ncp_req_hash_value pointer. This + * struct tells us the NCP type and gives the ncp2222_record pointer, if + * ncp_type == 0x2222. + */ +typedef struct { + conversation_t *conversation; + guint8 nw_sequence; +} ncp_req_hash_key; + + +typedef struct { + guint32 nw_eid; +} ncp_req_eid_hash_key; + +typedef struct { + char object_name[256]; + char *object_class; +} ncp_req_eid_hash_value; + +static GHashTable *ncp_req_hash = NULL; +static GHashTable *ncp_req_eid_hash = NULL; +static GMemChunk *ncp_req_eid_hash_keys = NULL; +static GMemChunk *ncp_req_eid_hash_values = NULL; +static GMemChunk *ncp_req_hash_keys = NULL; +static GMemChunk *ncp_req_hash_values = NULL; + +/* Hash Functions */ +gint +ncp_equal(gconstpointer v, gconstpointer v2) +{ + const ncp_req_hash_key *val1 = (const ncp_req_hash_key*)v; + const ncp_req_hash_key *val2 = (const ncp_req_hash_key*)v2; + + if (val1->conversation == val2->conversation && + val1->nw_sequence == val2->nw_sequence ) { + return 1; + } + return 0; +} + +gint +ncp_eid_equal(gconstpointer v, gconstpointer v2) +{ + const ncp_req_eid_hash_key *val1 = (const ncp_req_eid_hash_key*)v; + const ncp_req_eid_hash_key *val2 = (const ncp_req_eid_hash_key*)v2; + + if (val1->nw_eid == val2->nw_eid ) { + return 1; + } + return 0; +} + +guint +ncp_hash(gconstpointer v) +{ + const ncp_req_hash_key *ncp_key = (const ncp_req_hash_key*)v; + return GPOINTER_TO_UINT(ncp_key->conversation) + ncp_key->nw_sequence; +} + +guint +ncp_eid_hash(gconstpointer v) +{ + const ncp_req_eid_hash_key *ncp_eid_key = (const ncp_req_eid_hash_key*)v; + return GPOINTER_TO_UINT(ncp_eid_key->nw_eid); +} + +/* Frees memory used by the ncp_req_hash_value's */ +static void +ncp_req_hash_cleanup(gpointer key _U_, gpointer value, gpointer user_data _U_) +{ + ncp_req_hash_value *request_value = (ncp_req_hash_value*) value; + + if (request_value->req_cond_results) { + g_free(request_value->req_cond_results); + } +} + +/* Frees memory used by the ncp_req_hash_value's */ +static void +ncp_req_eid_hash_cleanup(gpointer key _U_, gpointer value, gpointer user_data _U_) +{ + ncp_req_eid_hash_value *request_eid_value = (ncp_req_eid_hash_value*) value; + + if (request_eid_value->object_class) { + g_free(request_eid_value->object_name); + } +} + +/* Initializes the hash table and the mem_chunk area each time a new + * file is loaded or re-loaded in ethereal */ +static void +ncp_init_protocol(void) +{ + /* fragment */ + fragment_table_init(&nds_fragment_table); + reassembled_table_init(&nds_reassembled_table); + + if (ncp_req_hash) { + g_hash_table_foreach(ncp_req_hash, ncp_req_hash_cleanup, NULL); + g_hash_table_destroy(ncp_req_hash); + } + if (ncp_req_eid_hash) { + g_hash_table_foreach(ncp_req_eid_hash, ncp_req_eid_hash_cleanup, NULL); + g_hash_table_destroy(ncp_req_eid_hash); + } + if (ncp_req_hash_keys) + g_mem_chunk_destroy(ncp_req_hash_keys); + if (ncp_req_hash_values) + g_mem_chunk_destroy(ncp_req_hash_values); + if (ncp_req_eid_hash_keys) + g_mem_chunk_destroy(ncp_req_eid_hash_keys); + if (ncp_req_eid_hash_values) + g_mem_chunk_destroy(ncp_req_eid_hash_values); + + ncp_req_hash = g_hash_table_new(ncp_hash, ncp_equal); + ncp_req_eid_hash = g_hash_table_new(ncp_eid_hash, ncp_eid_equal); + ncp_req_hash_keys = g_mem_chunk_new("ncp_req_hash_keys", + sizeof(ncp_req_hash_key), + NCP_PACKET_INIT_COUNT * sizeof(ncp_req_hash_key), + G_ALLOC_ONLY); + ncp_req_hash_values = g_mem_chunk_new("ncp_req_hash_values", + sizeof(ncp_req_hash_value), + NCP_PACKET_INIT_COUNT * sizeof(ncp_req_hash_value), + G_ALLOC_ONLY); + ncp_req_eid_hash_keys = g_mem_chunk_new("ncp_req_eid_hash_keys", + sizeof(ncp_req_eid_hash_key), + NCP_PACKET_INIT_COUNT * sizeof(ncp_req_eid_hash_key), + G_ALLOC_ONLY); + ncp_req_eid_hash_values = g_mem_chunk_new("ncp_req_eid_hash_values", + sizeof(ncp_req_eid_hash_value), + NCP_PACKET_INIT_COUNT * sizeof(ncp_req_eid_hash_value), + G_ALLOC_ONLY); +} + +/* After the sequential run, we don't need the ncp_request hash and keys + * anymore; the lookups have already been done and the vital info + * saved in the reply-packets' private_data in the frame_data struct. */ +static void +ncp_postseq_cleanup(void) +{ + if (ncp_req_hash) { + /* Destroy the hash, but don't clean up request_condition data. */ + /*g_hash_table_destroy(ncp_req_hash); + ncp_req_hash = NULL;*/ + } + if (ncp_req_hash_keys) { + /*g_mem_chunk_destroy(ncp_req_hash_keys); + ncp_req_hash_keys = NULL;*/ + } + /* Don't free the ncp_req_hash_values or EID_hash_table, as they're + * needed during random-access processing of the proto_tree.*/ +} + +ncp_req_hash_value* +ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence, + const ncp_record *ncp_rec) +{ + ncp_req_hash_key *request_key; + ncp_req_hash_value *request_value; + + /* Now remember the request, so we can find it if we later + a reply to it. */ + request_key = g_mem_chunk_alloc(ncp_req_hash_keys); + request_key->conversation = conversation; + request_key->nw_sequence = nw_sequence; + + request_value = g_mem_chunk_alloc(ncp_req_hash_values); + request_value->ncp_rec = ncp_rec; + request_value->req_cond_results = NULL; + request_value->req_nds_flags = 0; + request_value->nds_request_verb = 0; + request_value->nds_version = 0; + strcpy(request_value->object_name, " "); + request_value->nds_frag = TRUE; + + g_hash_table_insert(ncp_req_hash, request_key, request_value); + + return request_value; +} + +ncp_req_eid_hash_value* +ncp_eid_hash_insert(guint32 nw_eid) +{ + ncp_req_eid_hash_key *request_eid_key; + ncp_req_eid_hash_value *request_eid_value; + + /* Now remember the request, so we can find it if we later + a reply to it. */ + request_eid_key = g_mem_chunk_alloc(ncp_req_eid_hash_keys); + request_eid_key->nw_eid = nw_eid; + + request_eid_value = g_mem_chunk_alloc(ncp_req_eid_hash_values); + strcpy(request_eid_value->object_name, " "); + request_eid_value->object_class = NULL; + + g_hash_table_insert(ncp_req_eid_hash, request_eid_key, request_eid_value); + + return request_eid_value; +} + +/* Returns the ncp_rec*, or NULL if not found. */ +ncp_req_hash_value* +ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence) +{ + ncp_req_hash_key request_key; + + request_key.conversation = conversation; + request_key.nw_sequence = nw_sequence; + + return g_hash_table_lookup(ncp_req_hash, &request_key); +} + +/* Returns the value_rec* for needed EID, or NULL if not found. */ +ncp_req_eid_hash_value* +ncp_eid_hash_lookup(conversation_t *conversation _U_, guint32 nw_eid) +{ + ncp_req_eid_hash_key request_eid_key; + + request_eid_key.nw_eid = nw_eid; + + return g_hash_table_lookup(ncp_req_eid_hash, &request_eid_key); +} + +/* Does NCP func require a subfunction code? */ +static gboolean +ncp_requires_subfunc(guint8 func) +{ + const guint8 *ncp_func_requirement = ncp_func_requires_subfunc; + + while (*ncp_func_requirement != 0) { + if (*ncp_func_requirement == func) { + return TRUE; + } + ncp_func_requirement++; + } + return FALSE; +} + +/* Does the NCP func have a length parameter? */ +static gboolean +ncp_has_length_parameter(guint8 func) +{ + const guint8 *ncp_func_requirement = ncp_func_has_no_length_parameter; + + while (*ncp_func_requirement != 0) { + if (*ncp_func_requirement == func) { + return FALSE; + } + ncp_func_requirement++; + } + return TRUE; +} + + +/* Return a ncp_record* based on func and possibly subfunc */ +static const ncp_record * +ncp_record_find(guint8 func, guint8 subfunc) +{ + const ncp_record *ncp_rec = ncp_packets; + + while(ncp_rec->func != 0 || ncp_rec->subfunc != 0 || + ncp_rec->name != NULL ) { + if (ncp_rec->func == func) { + if (ncp_rec->has_subfunc) { + if (ncp_rec->subfunc == subfunc) { + return ncp_rec; + } + } + else { + return ncp_rec; + } + } + ncp_rec++; + } + return NULL; +} + + +/* Given a proto_item*, assume it contains an integer value + * and return a guint from it. */ +guint +get_item_value(proto_item *item) +{ + return fvalue_get_integer(&PITEM_FINFO(item)->value); +} + + +char * +get_item_string(proto_item *item) +{ + return fvalue_get(&PITEM_FINFO(item)->value); +} + +char * +get_item_name(proto_item *item) +{ + return PITEM_FINFO(item)->hfinfo->name; +} + + +typedef proto_item* (*padd_func_t)(ptvcursor_t*, const ptvc_record*); + +/* + * XXX - are these just DOS-format dates and times? + * + * Should we put code to understand various date and time formats (UNIX, + * DOS, SMB weird mutant UNIX, NT, Mac, etc. into libethereal, and have + * the "display" member of an HF_ABSOLUTE_TIME field specify whether + * it's DOS date/DOS time, DOS time/DOS date, NT time, UNIX time_t, + * UNIX "struct timeval", NFSv3/NFSv4 seconds/nanoseconds, Mac, etc.? + * + * What about hijacking the "bitmask" field to specify the precision of + * the time stamp, or putting a combination of precision and format + * into the "display" member? + * + * What about relative times? Should they have units (seconds, milliseconds, + * microseconds, nanoseconds, etc.), precision, and format in there? + */ +typedef struct { + guint year; + guint month; + guint day; +} nw_date_t; + +typedef struct { + guint hour; + guint minute; + guint second; +} nw_time_t; + +typedef struct { + char buffer[1024]; +} nw_uni_t; + +#define VTYPE_NONE 0 /* no value */ +#define VTYPE_UINT8 1 +#define VTYPE_UINT16 2 +#define VTYPE_UINT32 3 +#define VTYPE_STRING 4 +#define VTYPE_BITFIELD 5 +#define VTYPE_MULTIVALUE_UINT32 6 +#define VTYPE_BYTES 7 +#define VTYPE_BOOLEAN 8 + +#define MVTYPE_ATTR_REQUEST 1 +#define MVTYPE_ATTR_REPLY 2 +#define MVTYPE_ATTR_REQUEST2 3 /* XXX - how does this differ from 1? */ +#define MVTYPE_READ_CLASS_REQ 4 +#define MVTYPE_READ_REPLICAS 5 +#define MVTYPE_MODIFY_ATTR_REQUEST 6 +#define MVTYPE_ADDR_REFERRAL_REQUEST 7 +#define MVTYPE_ADDR_REFERRAL_REPLY 8 +#define MVTYPE_LOC_ADDR_REFERRAL_REPLY 9 +#define MVTYPE_PROC_ENTRY_SPECIFIERS 10 +#define MVTYPE_PRINT_TIMESTAMP 11 +#define MVTYPE_LIST_PARTITIONS 12 +#define MVTYPE_CLASS_NAMES 13 +#define MVTYPE_MODIFY_CLASS 14 +#define MVTYPE_ADD_ATTR_REQUEST 15 + +typedef struct { + guint8 vtype; + guint32 vvalue; + char* vstring; + char* vdesc; + guint32 vlength; + guint32 voffset; + guint32 hfname; + char* bit1; + guint32 bit1hfname; + char* bit2; + guint32 bit2hfname; + char* bit3; + guint32 bit3hfname; + char* bit4; + guint32 bit4hfname; + char* bit5; + guint32 bit5hfname; + char* bit6; + guint32 bit6hfname; + char* bit7; + guint32 bit7hfname; + char* bit8; + guint32 bit8hfname; + char* bit9; + guint32 bit9hfname; + char* bit10; + guint32 bit10hfname; + char* bit11; + guint32 bit11hfname; + char* bit12; + guint32 bit12hfname; + char* bit13; + guint32 bit13hfname; + char* bit14; + guint32 bit14hfname; + char* bit15; + guint32 bit15hfname; + char* bit16; + guint32 bit16hfname; + guint8 mvtype; + guint32 vflags; + guint32 nds_version; +} nds_val; + + +/* Given an integer, fill in a nw_date_t struct. */ +static void +uint_to_nwdate(guint data, nw_date_t *nwdate) +{ + nwdate->day = data & 0x001f; + nwdate->month = (data & 0x01e0) >> 5; + nwdate->year = ((data & 0xfe00) >> 9) + 1980; +} + +/* Given an integer, fill in a nw_time_t struct. */ +static void +uint_to_nwtime(guint data, nw_time_t *nwtime) +{ + /* 2-second resolution */ + nwtime->second = (data & 0x001f) * 2; + nwtime->minute = ((data & 0x07e0) >> 5); + nwtime->hour = ((data & 0xf800) >> 11); +} + +char * +unicode_to_string(char * data, guint32 length) +{ + guint32 i; + guint16 character; + int offset = 0; + char * buffer = ""; + + if (data[1] == 0x00){ + + for (i = 0; i < length; i++) { + character = data[offset]; + buffer[i] = character & 0xff; + offset += 2; + } + } + else + { + buffer = data; + } + return buffer; +} + +static proto_item* +padd_normal(ptvcursor_t *ptvc, const ptvc_record *rec) +{ + return + ptvcursor_add(ptvc, *rec->hf_ptr, + rec->length, rec->endianness); +} + + +static proto_item* +padd_date(ptvcursor_t *ptvc, const ptvc_record *rec) +{ + proto_item *item; + nw_date_t nw_date; + gint offset; + + offset = ptvcursor_current_offset(ptvc); + + item = ptvcursor_add(ptvc, *rec->hf_ptr, + rec->length, rec->endianness); + + uint_to_nwdate(get_item_value(item), &nw_date); + + proto_item_set_text(item, get_item_name(item)); + proto_item_append_text(item, ": %04u/%02u/%02u", + nw_date.year, nw_date.month, nw_date.day); + return item; +} + +static proto_item* +padd_time(ptvcursor_t *ptvc, const ptvc_record *rec) +{ + proto_item *item; + nw_time_t nw_time; + gint offset; + + offset = ptvcursor_current_offset(ptvc); + + item = ptvcursor_add(ptvc, *rec->hf_ptr, + rec->length, rec->endianness); + + uint_to_nwtime(get_item_value(item), &nw_time); + + proto_item_set_text(item, get_item_name(item)); + proto_item_append_text(item, ": %02u:%02u:%02u", + nw_time.hour, nw_time.minute, nw_time.second); + return item; +} + + +/* Convert a string from little-endian unicode to ascii. At the moment we + fake it by taking every odd byte. )-: The caller must free the + result returned. */ +static proto_item* +padd_uni(ptvcursor_t *ptvc, const ptvc_record *rec) +{ + proto_item *item; + nw_uni_t nw_uni; + guint offset; + + strcpy(nw_uni.buffer, ""); + offset = ptvcursor_current_offset(ptvc); + + item = ptvcursor_add(ptvc, *rec->hf_ptr, + rec->length, rec->endianness); + + proto_item_set_text(item, get_item_name(item)); + proto_item_append_text(item, " %s", + nw_uni.buffer); + + return item; +} + +/* Add a value for a ptvc_record, and process the sub-ptvc_record + * that it points to. */ +static void +process_bitfield_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec, + gboolean really_decode) +{ + proto_item *item; + proto_tree *sub_tree; + const ptvc_record *sub_rec; + int current_offset; + gint ett; + ptvcursor_t *sub_ptvc; + + if (really_decode) { + /* Save the current offset */ + current_offset = ptvcursor_current_offset(ptvc); + + /* Add the item */ + item = ptvcursor_add(ptvc, *rec->hf_ptr, rec->length, + rec->endianness); + + ett = *rec->sub_ptvc_rec->ett; + + /* Make a new protocol sub-tree */ + sub_tree = proto_item_add_subtree(item, ett); + + /* Make a new ptvcursor */ + sub_ptvc = ptvcursor_new(sub_tree, ptvcursor_tvbuff(ptvc), + current_offset); + + /* Use it */ + sub_rec = rec->sub_ptvc_rec->ptvc_rec; + while(sub_rec->hf_ptr != NULL) { + g_assert(!sub_rec->sub_ptvc_rec); + ptvcursor_add_no_advance(sub_ptvc, *sub_rec->hf_ptr, + sub_rec->length, sub_rec->endianness); + sub_rec++; + } + + /* Free it. */ + ptvcursor_free(sub_ptvc); + } + else { + ptvcursor_advance(ptvc, rec->length); + } +} + +/* Process a sub-ptvc_record that points to a "struct" ptvc_record. */ +static void +process_struct_sub_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec, + int *req_cond_results, gboolean really_decode, + const ncp_record *ncp_rec) +{ + const ptvc_record *sub_rec; + gint ett; + proto_tree *old_tree=NULL, *new_tree; + proto_item *item=NULL; + gint offset=0; + + /* Create a sub-proto_tree? */ + if (rec->sub_ptvc_rec->descr) { + ett = *rec->sub_ptvc_rec->ett; + old_tree = ptvcursor_tree(ptvc); + offset = ptvcursor_current_offset(ptvc); + item = proto_tree_add_text(old_tree, ptvcursor_tvbuff(ptvc), + offset, PROTO_LENGTH_UNTIL_END, + rec->sub_ptvc_rec->descr); + new_tree = proto_item_add_subtree(item, ett); + ptvcursor_set_tree(ptvc, new_tree); + } + + /* Get the ptvc_record for the struct and call our caller + * to process it. */ + sub_rec = rec->sub_ptvc_rec->ptvc_rec; + process_ptvc_record(ptvc, sub_rec, req_cond_results, really_decode, ncp_rec); + + /* Re-set the tree */ + if (rec->sub_ptvc_rec->descr) { + proto_item_set_len(item, ptvcursor_current_offset(ptvc) - offset); + ptvcursor_set_tree(ptvc, old_tree); + } +} + +/* Run through the table of ptvc_record's and add info to the tree. This + * is the work-horse of process_ptvc_record(). */ +static void +_process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec, + int *req_cond_results, gboolean really_decode, + const ncp_record *ncp_rec) +{ + proto_item *item; + guint i, repeat_count; + padd_func_t func = NULL; + + if (rec->sub_ptvc_rec) { + /* Repeat this? */ + if (rec->repeat_index == NO_REPEAT) { + if (rec->hf_ptr == PTVC_STRUCT) { + process_struct_sub_ptvc_record(ptvc, rec, + req_cond_results, really_decode, + ncp_rec); + } + else { + process_bitfield_sub_ptvc_record(ptvc, rec, + really_decode); + } + } + else { + repeat_count = repeat_vars[rec->repeat_index]; + for (i = 0; i < repeat_count; i++ ) { + if (rec->hf_ptr == PTVC_STRUCT) { + process_struct_sub_ptvc_record(ptvc, rec, + req_cond_results, really_decode, + ncp_rec); + } + else { + process_bitfield_sub_ptvc_record(ptvc, rec, + really_decode); + } + } + } + } + else { + /* If we can't repeat this field, we might use it + * to set a 'var'. */ + if (rec->repeat_index == NO_REPEAT) { + if (really_decode) { + /* Handle any special formatting. */ + switch(rec->special_fmt) { + case NCP_FMT_NONE: + func = padd_normal; + break; + case NCP_FMT_NW_DATE: + func = padd_date; + break; + case NCP_FMT_NW_TIME: + func = padd_time; + break; + case NCP_FMT_UNICODE: + func = padd_uni; + break; + default: + g_assert_not_reached(); + } + item = func(ptvc, rec); + + /* Set the value as a 'var' ? */ + if (rec->var_index != NO_VAR) { + repeat_vars[rec->var_index] = get_item_value(item); + } + } + else { + /* If we don't decode the field, we + * better not use the value to set a var. + * Actually, we could, as long as we don't + * *use* that var; for now keep this assert in + * place. */ + g_assert(rec->var_index == NO_VAR); + ptvcursor_advance(ptvc, rec->length); + } + } + else { + /* We do repeat this field. */ + repeat_count = repeat_vars[rec->repeat_index]; + if (really_decode) { + /* Handle any special formatting. */ + switch(rec->special_fmt) { + case NCP_FMT_NONE: + func = padd_normal; + break; + case NCP_FMT_NW_DATE: + func = padd_date; + break; + case NCP_FMT_NW_TIME: + func = padd_time; + break; + case NCP_FMT_UNICODE: + func = padd_uni; + break; + default: + g_assert_not_reached(); + } + for (i = 0; i < repeat_count; i++ ) { + func(ptvc, rec); + } + } + else { + for (i = 0; i < repeat_count; i++ ) { + ptvcursor_advance(ptvc, rec->length); + } + } + } + } +} + +/* Run through the table of ptvc_record's and add info to the tree. + * Honor a request condition result. */ +static void +process_ptvc_record(ptvcursor_t *ptvc, const ptvc_record *rec, + int *req_cond_results, gboolean really_decode, + const ncp_record *ncp_rec) +{ + gboolean decode; + + while(rec->hf_ptr != NULL) { + decode = really_decode; + /* If we're supposed to decode, check the request condition + * results to see if we should override this and *not* decode. */ + if (decode && req_cond_results) { + if (rec->req_cond_index != NO_REQ_COND) { + if (req_cond_results[rec->req_cond_index] == FALSE) { + decode = FALSE; + } + } + } + if (decode || ncp_rec->req_cond_size_type == REQ_COND_SIZE_CONSTANT) { + _process_ptvc_record(ptvc, rec, req_cond_results, decode, ncp_rec); + } + rec++; + } +} + + + +/* Clear the repeat_vars array. */ +static void +clear_repeat_vars(void) +{ + guint i; + + for (i = 0 ; i < NUM_REPEAT_VARS; i++ ) { + repeat_vars[i] = 0; + } +} + + +/* Given an error_equivalency table and a completion code, return + * the string representing the error. */ +static const char* +ncp_error_string(const error_equivalency *errors, guint8 completion_code) +{ + while (errors->ncp_error_index != -1) { + if (errors->error_in_packet == completion_code) { + return ncp_errors[errors->ncp_error_index]; + } + errors++; + } + + return "Unknown Error Code"; +} + +static const ncp_record ncp1111_request = + { 0x01, 0x00, NO_SUBFUNC, "Create Connection Service", NCP_GROUP_CONNECTION, + NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL }; + +static const ncp_record ncp5555_request = + { 0x01, 0x00, NO_SUBFUNC, "Destroy Connection Service", NCP_GROUP_CONNECTION, + NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL }; + +static const ncp_record ncpbbbb_request = + { 0x01, 0x00, NO_SUBFUNC, "Server Broadcast Message", NCP_GROUP_CONNECTION, + NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL }; + +static const ncp_record ncplip_echo = + { 0x01, 0x00, NO_SUBFUNC, "LIP Echo Packet", NCP_GROUP_CONNECTION, + NULL, NULL, ncp_0x2_errors, NULL, NO_REQ_COND_SIZE, NULL }; + +/* Wrapper around proto_tree_free() */ +void free_proto_tree(void *tree) +{ + if (tree) { + proto_tree_free((proto_tree*) tree); + } +} + +static guint32 +align_4(tvbuff_t *tvb, guint32 aoffset) +{ + if(tvb_length_remaining(tvb, aoffset) > 4 ) + { + return (aoffset%4); + } + return 0; +} + +static void +get_string(tvbuff_t* tvb, guint offset, guint str_length, char *dest_buf) +{ + guint32 i; + guint16 c_char; + guint32 length_remaining = 0; + + length_remaining = tvb_length_remaining(tvb, offset); + if(str_length > length_remaining || str_length > 1024) + { + strcpy(dest_buf, "String too long to process"); + return; + } + dest_buf[0] = '\0'; + if(str_length == 0) + { + return; + } + for ( i = 0; i < str_length; i++ ) + { + c_char = tvb_get_guint8(tvb, offset ); + if (c_char<0x20 || c_char>0x7e) + { + if (c_char != 0x00) + { + c_char = '.'; + dest_buf[i] = c_char & 0xff; + } + else + { + i--; + str_length--; + } + } + else + { + dest_buf[i] = c_char & 0xff; + } + offset++; + length_remaining--; + + if(length_remaining==1) + { + dest_buf[i+1] = '\0'; + return; + } + } + dest_buf[i] = '\0'; + return; +} + +static void +uni_to_string(char * data, guint32 str_length, char *dest_buf) +{ + guint32 i; + guint16 c_char; + guint32 length_remaining = 0; + + length_remaining = str_length; + dest_buf[0] = '\0'; + if(str_length == 0) + { + return; + } + for ( i = 0; i < str_length; i++ ) + { + c_char = data[i]; + if (c_char<0x20 || c_char>0x7e) + { + if (c_char != 0x00) + { + c_char = '.'; + dest_buf[i] = c_char & 0xff; + } + else + { + i--; + str_length--; + } + } + else + { + dest_buf[i] = c_char & 0xff; + } + length_remaining--; + + if(length_remaining==0) + { + dest_buf[i+1] = '\0'; + return; + } + } + dest_buf[i] = '\0'; + return; +} + +/************************************* +* Return based on % format in request +* %d = integer in decimal format = 0 +* %x = integer in hex format = 1 +* %s = string = 2 +**************************************/ +int +get_info_type(const gchar* check_string) +{ + guint length; + guint i; + char char_val; + + length = strlen(check_string); + + for (i = 0 ; i < length-1 ; i++ ) { + char_val = check_string[i+1]; + if (check_string[i] == 0x25 && check_string[i+1] == 0x64) { /* %d Digits*/ + return 0; + } + if ( check_string[i] == 0x78 && check_string[i+1] == 0x25 && check_string[i+2] == 0x73) { /* x%s Bytes*/ + return 1; + } + } + return 2; /* Normal String */ +} + +static void +process_bitfield(proto_tree *ncp_tree, tvbuff_t *tvb, nds_val *values) +{ + gchar flags_str[512]; + gchar *sep; + proto_item *tinew; + proto_tree *flags_tree; + guint32 i; + guint32 bvalue = 0; + + bvalue = 0x00000001; + flags_str[0]='\0'; + sep=""; + for (i = 0 ; i < (values->vlength*8); i++ ) { + if (values->vvalue & bvalue) + { + strcat(flags_str, sep); + switch(bvalue){ + case 0x00000001: + strcat(flags_str, values->bit1); + break; + case 0x00000002: + strcat(flags_str, values->bit2); + break; + case 0x00000004: + strcat(flags_str, values->bit3); + break; + case 0x00000008: + strcat(flags_str, values->bit4); + break; + case 0x00000010: + strcat(flags_str, values->bit5); + break; + case 0x00000020: + strcat(flags_str, values->bit6); + break; + case 0x00000040: + strcat(flags_str, values->bit7); + break; + case 0x00000080: + strcat(flags_str, values->bit8); + break; + case 0x00000100: + strcat(flags_str, values->bit9); + break; + case 0x00000200: + strcat(flags_str, values->bit10); + break; + case 0x00000400: + strcat(flags_str, values->bit11); + break; + case 0x00000800: + strcat(flags_str, values->bit12); + break; + case 0x00001000: + strcat(flags_str, values->bit13); + break; + case 0x00002000: + strcat(flags_str, values->bit14); + break; + case 0x00004000: + strcat(flags_str, values->bit15); + break; + case 0x00008000: + strcat(flags_str, values->bit16); + break; + default: + break; + } + sep = ", "; + } + bvalue = bvalue*2; + } + if(values->vlength==4) + { + tinew = proto_tree_add_uint_format(ncp_tree, values->hfname, + tvb, values->voffset, values->vlength, values->vvalue, "%s 0x%08x", + values->vdesc, values->vvalue); + } + else + { + tinew = proto_tree_add_uint_format(ncp_tree, values->hfname, + tvb, values->voffset, values->vlength, values->vvalue, "%s 0x%04x", + values->vdesc, values->vvalue); + } + if (flags_str[0] != '\0') + proto_item_append_text(tinew, " - (%s)", flags_str); + + flags_tree = proto_item_add_subtree(tinew, ett_nds); + + bvalue = 0x00000001; + + for (i = 0 ; i < (values->vlength*8); i++ ) { + if (values->vvalue & bvalue) + { + switch(bvalue) + { + case 0x00000001: + proto_tree_add_item(flags_tree, values->bit1hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000002: + proto_tree_add_item(flags_tree, values->bit2hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000004: + proto_tree_add_item(flags_tree, values->bit3hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000008: + proto_tree_add_item(flags_tree, values->bit4hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000010: + proto_tree_add_item(flags_tree, values->bit5hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000020: + proto_tree_add_item(flags_tree, values->bit6hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000040: + proto_tree_add_item(flags_tree, values->bit7hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000080: + proto_tree_add_item(flags_tree, values->bit8hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000100: + proto_tree_add_item(flags_tree, values->bit9hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000200: + proto_tree_add_item(flags_tree, values->bit10hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000400: + proto_tree_add_item(flags_tree, values->bit11hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00000800: + proto_tree_add_item(flags_tree, values->bit12hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00001000: + proto_tree_add_item(flags_tree, values->bit13hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00002000: + proto_tree_add_item(flags_tree, values->bit14hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00004000: + proto_tree_add_item(flags_tree, values->bit15hfname, tvb, values->voffset, values->vlength, TRUE); + break; + case 0x00008000: + proto_tree_add_item(flags_tree, values->bit16hfname, tvb, values->voffset, values->vlength, TRUE); + break; + default: + break; + } + } + bvalue = bvalue*2; + } +} + + +static void +print_nds_values(proto_tree *vtree, tvbuff_t *tvb, guint32 syntax_type, nds_val *vvalues) +{ + guint32 value1 = 0; + guint32 value2 = 0; + guint32 value3 = 0; + guint32 value4 = 0; + guint32 value5 = 0; + guint32 value6 = 0; + guint32 voffset = 0; + guint32 icounter; + guint32 number_of_values = 0; + guint32 number_of_items = 0; + guint32 r; + proto_item *vitem; + proto_tree *nvtree; + proto_item *aditem; + proto_tree *adtree; + char *valuestr = NULL; + guint16 rtype = 0; + guint16 rstate = 0; + guint16 rnum = 0; + guint16 revent = 0; + gint length_remaining; + + voffset = vvalues->voffset; + if(tvb_get_guint8(tvb, voffset) == 0x00) + { + voffset = voffset+2; + } + + number_of_values = tvb_get_letohl(tvb, voffset); + + vitem = proto_tree_add_uint_format(vtree, hf_nds_uint32value, tvb, voffset, + 4, number_of_values, "Number of Values: %u", number_of_values); + + nvtree = proto_item_add_subtree(vitem, ett_nds); + + voffset = voffset + 4; + + for (icounter = 1 ; icounter <= number_of_values; icounter++ ) + { + switch(syntax_type) + { + case 0x00000006: /* Case Insensitive List */ + case 0x0000000d: /* Binary String List */ + case 0x00000012: /* Postal Address */ + voffset += align_4(tvb, voffset); + voffset = voffset+4; + number_of_items = tvb_get_letohl(tvb, voffset); + voffset = voffset+4; + for (r=1; r<=number_of_items; r++) + { + value1 = tvb_get_letohl(tvb, voffset); + voffset = voffset + 4; + get_string(tvb, voffset, value1, vvalues->vstring); + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value1, vvalues->vstring); + voffset = voffset + value1; + voffset += align_4(tvb, voffset); + } + break; + case 0x00000007: /* Boolean */ + value1 = tvb_get_letohl(tvb, voffset); /* length of field */ + if (value1==0) + { + vvalues->vstring = "False"; + } + else + { + vvalues->vstring = "True"; + } + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value1, vvalues->vstring); + voffset=voffset+8; + break; + case 0x00000009: /* Binary String */ + case 0x00000015: /* Stream */ + value1 = tvb_get_letohl(tvb, voffset); /* length of field */ + length_remaining = tvb_length_remaining(tvb, voffset); + if(length_remaining == -1 || value1 > (guint32) length_remaining) + { + break; + } + voffset += 4; + proto_tree_add_bytes(nvtree, hf_value_bytes, tvb, voffset, value1, tvb_get_ptr(tvb, voffset, value1)); + voffset += value1; + voffset += (value1%2); + break; + case 0x00000008: /* Signed Integer */ + case 0x00000016: /* Counter */ + case 0x00000018: /* Time */ + case 0x0000001b: /* Interval */ + value1 = tvb_get_letohl(tvb, voffset); /* length of field */ + voffset = voffset+4; + value2 = tvb_get_letohl(tvb, voffset); /* Value */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + value1, value2, "Value %d", value2); + voffset = voffset+4; + break; + case 0x0000000b: /* Fax Number */ + value1 = tvb_get_letohl(tvb, voffset); /* length of field */ + voffset = voffset+4; + get_string(tvb, voffset, value1, vvalues->vstring); + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value1, vvalues->vstring); + voffset = voffset + value1; + voffset += align_4(tvb, voffset); + value2 = tvb_get_letohl(tvb, voffset); /* Bit Count */ + voffset=voffset+4; + value3 = tvb_get_letohl(tvb, voffset); /* Bit length */ + voffset = voffset+4; + get_string(tvb, voffset, value3, vvalues->vstring); + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value3, vvalues->vstring); + voffset = voffset+value3; + voffset += align_4(tvb, voffset); + break; + case 0x0000000c: /* Network Address */ + value1 = tvb_get_letohl(tvb, voffset); /* length of field */ + voffset = voffset + 4; + value2 = tvb_get_letohl(tvb, voffset); /* type of Protocol */ + valuestr = match_strval(value2, nds_protocol_type); + if (valuestr == NULL) + { + valuestr="(Undefined Protocol)"; + } + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + value1, value2, valuestr, value2); + voffset = voffset+4; + value3 = tvb_get_letohl(tvb, voffset); /* length of address */ + voffset = voffset+4; + switch (value2) + { + case 0x00000000: + proto_tree_add_item(nvtree, hf_nds_net, tvb, voffset, 4, FALSE); + proto_tree_add_item(nvtree, hf_nds_node, tvb, voffset+4, 6, FALSE); + proto_tree_add_item(nvtree, hf_nds_socket, tvb, voffset+10, 2, FALSE); + break; + case 0x00000008: + proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, voffset+2); + proto_tree_add_ipv4(nvtree, hf_add_ref_udp, tvb, voffset+2, 4, value4); + break; + case 0x00000009: + proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, voffset+2); + proto_tree_add_ipv4(nvtree, hf_add_ref_tcp, tvb, voffset+2, 4, value4); + break; + case 0x00000001: + proto_tree_add_item(nvtree, hf_nds_port, tvb, voffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, voffset+2); + proto_tree_add_ipv4(nvtree, hf_add_ref_ip, tvb, voffset+2, 4, value4); + break; + case 0x0000000d: + get_string(tvb, voffset, value3, vvalues->vstring); + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value3, vvalues->vstring); + break; + default: + break; + } + voffset = voffset + value3; + voffset += align_4(tvb, voffset); + break; + case 0x0000000f: /* File System Path */ + value1 = tvb_get_letohl(tvb, voffset); /* length of field */ + voffset = voffset + 4; + value2 = tvb_get_letohl(tvb, voffset); /* Name Space */ + valuestr = match_strval(value2, name_space_type); + if (valuestr == NULL) + { + valuestr = "Unknown Name Space"; + } + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + 4, valuestr); + voffset = voffset+4; + value3 = tvb_get_letohl(tvb, voffset); /* Length of Volume name */ + voffset = voffset+4; + get_string(tvb, voffset, value3, vvalues->vstring); + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value3, vvalues->vstring); + voffset = voffset+value3; + voffset += align_4(tvb, voffset); + value4 = tvb_get_letohl(tvb, voffset); /* Length of Path name */ + voffset = voffset+4; + get_string(tvb, voffset, value4, vvalues->vstring); + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value4, vvalues->vstring); + voffset = voffset+value4; + voffset += align_4(tvb, voffset); + break; + case 0x00000010: /* Replica Pointer */ + value1 = tvb_get_letohl(tvb, voffset); /* length of field */ + voffset = voffset + 4; + value2 = tvb_get_letohl(tvb, voffset); /* Length of Server name */ + voffset = voffset+4; + get_string(tvb, voffset, value2, vvalues->vstring); + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value2, vvalues->vstring); + voffset = voffset+value2; + voffset += align_4(tvb, voffset); + rtype = tvb_get_letohs(tvb, voffset); /* replica type */ + valuestr = match_strval(rtype, nds_replica_type); + if (valuestr == NULL) + { + valuestr="(Unknown Replica Type)"; + } + proto_tree_add_string(nvtree, hf_replica_type, tvb, voffset, + 2, valuestr); + voffset = voffset+2; + rstate = tvb_get_letohs(tvb, voffset); /* replica state */ + valuestr = match_strval(rstate, nds_replica_state); + if (valuestr == NULL) + { + valuestr="(Unknown Replica State)"; + } + proto_tree_add_string(nvtree, hf_replica_state, tvb, voffset, + 2, valuestr); + voffset = voffset+2; + value3 = tvb_get_letohl(tvb, voffset); /* Replica number */ + proto_tree_add_uint_format(nvtree, hf_replica_number, tvb, voffset, + 4, value3, "Replica Number %d", value3); + voffset = voffset+4; + if(vvalues->nds_version == 0xfe) + { + voffset += 4; + } + number_of_items = tvb_get_letohl(tvb, voffset); /* Number of Addresses */ + aditem = proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, number_of_items, "Number of Addresses: %u", number_of_items); + + adtree = proto_item_add_subtree(aditem, ett_nds); + voffset = voffset+4; + for (r=1; r <= number_of_items; r++) + { + voffset += align_4(tvb, voffset); + value4 = tvb_get_letohl(tvb, voffset); /* type of Protocol */ + valuestr = match_strval(value4, nds_protocol_type); + if (valuestr == NULL) + { + valuestr="(Undefined Protocol)"; + } + proto_tree_add_uint_format(adtree, hf_nds_uint32value, tvb, voffset, + 4, value4, valuestr, value4); + voffset = voffset+4; + value5 = tvb_get_letohl(tvb, voffset); /* length of address */ + voffset = voffset+4; + switch (value4) + { + case 0x00000000: + proto_tree_add_item(adtree, hf_nds_net, tvb, voffset, 4, FALSE); + proto_tree_add_item(adtree, hf_nds_node, tvb, voffset+4, 6, FALSE); + proto_tree_add_item(adtree, hf_nds_socket, tvb, voffset+10, 2, FALSE); + break; + case 0x00000001: + proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, FALSE); + value6 = tvb_get_letohl(tvb, voffset+2); + proto_tree_add_ipv4(adtree, hf_add_ref_ip, tvb, voffset+2, 4, value6); + break; + case 0x00000008: + proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, FALSE); + value6 = tvb_get_letohl(tvb, voffset+2); + proto_tree_add_ipv4(adtree, hf_add_ref_udp, tvb, voffset+2, 4, value6); + break; + case 0x00000009: + proto_tree_add_item(adtree, hf_nds_port, tvb, voffset, 2, FALSE); + value6 = tvb_get_letohl(tvb, voffset+2); + proto_tree_add_ipv4(adtree, hf_add_ref_tcp, tvb, voffset+2, 4, value6); + break; + case 0x0000000d: + get_string(tvb, voffset, value5, vvalues->vstring); + proto_tree_add_string(adtree, hf_value_string, tvb, voffset, + value5, vvalues->vstring); + break; + default: + break; + } + voffset = voffset + value5; + } + voffset += align_4(tvb, voffset); + break; + case 0x00000011: /* Object ACL */ + value1 = tvb_get_letohl(tvb, voffset); /* Length of Field */ + voffset = voffset + 4; + value2 = tvb_get_letohl(tvb, voffset); + voffset = voffset + 4; + get_string(tvb, voffset, value2, vvalues->vstring); /* Unicode String */ + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value2, vvalues->vstring); + voffset = voffset + value2; + voffset += align_4(tvb, voffset); + value3 = tvb_get_letohl(tvb, voffset); + voffset = voffset + 4; + get_string(tvb, voffset, value3, vvalues->vstring); /* Unicode Subject Name */ + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value3, vvalues->vstring); + voffset = voffset + value3; + voffset += align_4(tvb, voffset); + value4 = tvb_get_letohl(tvb, voffset); /* Privileges */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value4, "Privileges %8x", value4); + voffset = voffset+4; + voffset += align_4(tvb, voffset); + break; + case 0x00000013: /* Time Stamp */ + value1 = tvb_get_letohl(tvb, voffset); /* Seconds */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value1, "Lenght of Record: %d", value1); + voffset = voffset+4; + value2 = tvb_get_letohl(tvb, voffset); + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value2, "Seconds: %d", value2); + voffset = voffset + 4; + rnum = tvb_get_letohs(tvb, voffset); /* replica number */ + proto_tree_add_uint_format(nvtree, hf_nds_rnum, tvb, voffset, + 2, rnum, "Replica Number: %d", rnum); + voffset = voffset+2; + revent = tvb_get_letohs(tvb, voffset); /* Event */ + proto_tree_add_uint_format(nvtree, hf_nds_revent, tvb, voffset, + 2, revent, "Event: %d", revent); + voffset = voffset+2; + voffset += align_4(tvb, voffset); + break; + case 0x00000017: /* Back Link */ + value1 = tvb_get_letohl(tvb, voffset); /* Length */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value1, "Length of Record %08x", value1); + voffset = voffset+4; + value2 = tvb_get_letohl(tvb, voffset); /* Remote ID */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value2, "Remote ID %08x", value2); + voffset = voffset+4; + value3 = tvb_get_letohl(tvb, voffset); /* Length of string */ + voffset = voffset+4; + get_string(tvb, voffset, value3, vvalues->vstring); + proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset, + value3, vvalues->vstring, + "Server Distinguished Name - %s", vvalues->vstring); + voffset = voffset+value3; + voffset += align_4(tvb, voffset); + break; + case 0x00000019: /* Typed Name */ + value1 = tvb_get_letohl(tvb, voffset); /* Length */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value1, "Length of Record %08x", value1); + voffset = voffset+4; + value2 = tvb_get_letohl(tvb, voffset); /* Level */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value2, "Level %d", value2); + voffset = voffset+4; + value3 = tvb_get_letohl(tvb, voffset); /* Interval */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value3, "Interval %d", value3); + voffset = voffset+4; + value4 = tvb_get_letohl(tvb, voffset); /* Distinguished Name */ + voffset = voffset+4; + get_string(tvb, voffset, value4, vvalues->vstring); + proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset, + value4, vvalues->vstring, + "Distinguished Name - %s", vvalues->vstring); + voffset = voffset+value4; + voffset += align_4(tvb, voffset); + break; + case 0x0000001a: /* Hold */ + value1 = tvb_get_letohl(tvb, voffset); /* Length */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value1, "Length of Record %08x", value1); + voffset = voffset+4; + value2 = tvb_get_letohl(tvb, voffset); /* Amount */ + proto_tree_add_uint_format(nvtree, hf_nds_uint32value, tvb, voffset, + 4, value2, "Amount %d", value2); + voffset = voffset+4; + value3 = tvb_get_letohl(tvb, voffset); /* Subject */ + voffset = voffset+4; + get_string(tvb, voffset, value3, vvalues->vstring); + proto_tree_add_string_format(nvtree, hf_value_string, tvb, voffset, + value3, vvalues->vstring, + "Subject - %s", vvalues->vstring); + voffset = voffset+value3; + voffset += align_4(tvb, voffset); + break; + case 0x00000001: /* Distinguished Name */ + case 0x00000002: /* Case Sensitive Unicode String */ + case 0x00000003: /* Non Case Sensitive Unicode String */ + case 0x00000004: /* Printable String */ + case 0x00000005: /* Numeric String */ + case 0x0000000a: /* Telephone Number */ + case 0x0000000e: /* Email Address */ + case 0x00000014: /* Class Name */ + default: + value1 = tvb_get_letohl(tvb, voffset); + voffset = voffset + 4; + get_string(tvb, voffset, value1, vvalues->vstring); + proto_tree_add_string(nvtree, hf_value_string, tvb, voffset, + value1, vvalues->vstring); + voffset = voffset + value1; + voffset += align_4(tvb, voffset); + break; + } + voffset += align_4(tvb, voffset); + } + vvalues->voffset=voffset; +return; +} + +static guint32 +print_es_type(proto_tree *estree, tvbuff_t *tvb, nds_val *values, guint32 vtype, guint32 ioffset) +{ + guint32 value1; + guint32 value2; + guint32 value3; + guint32 value4; + guint32 value5; + guint32 number_of_referrals; + guint32 r; + guint32 i; + guint16 replica_num; + guint16 event_num; + nw_uni_t mval_buf; + proto_tree *nestree; + proto_item *nesitem; + proto_tree *atree; + proto_item *aitem; + char * vstring=""; + + strcpy(mval_buf.buffer, ""); + + switch (vtype) + { + case 0: /* No Specifier Type */ + value1 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + proto_tree_add_item(estree, hf_es_value, tvb, ioffset, + 4, value1); + ioffset = ioffset + 4; + break; + case 1: /* Unicode String */ + value1 = tvb_get_letohl(tvb, ioffset); /* Delimeter Set */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string_format(estree, hf_mv_string, tvb, ioffset, + value1, values->vstring, "Delimeter ->%s", values->vstring); + ioffset=ioffset + value1; + ioffset += align_4(tvb, ioffset); + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, + value2, values->vstring); + values->voffset=ioffset + value2; + ioffset = values->voffset; + ioffset += align_4(tvb, ioffset); + break; + case 2: /* Based */ + value1 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + vstring = match_strval(value1, es_type); + if (vstring == NULL) + { + vstring = "No ES Type Found"; + } + nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset, + 4, vstring, "Base Context Type - %s", vstring); + nestree = proto_item_add_subtree(nesitem, ett_nds); + ioffset = ioffset + 4; + switch (value1) + { + case 0: /* No Specifier Type */ + value2 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + proto_tree_add_item(nestree, hf_es_value, tvb, ioffset, + 4, value2); + ioffset = ioffset + 4; + break; + case 1: /* Unicode String */ + value2 = tvb_get_letohl(tvb, ioffset); /* Delimeter Set */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string_format(nestree, hf_mv_string, tvb, ioffset, + value2, values->vstring, "Delimeter ->%s", values->vstring); + ioffset=ioffset + value2; + ioffset += align_4(tvb, ioffset); + value3 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value3, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset, + value3, values->vstring); + values->voffset=ioffset + value3; + ioffset = values->voffset; + ioffset += align_4(tvb, ioffset); + break; + case 2: /* Based */ + break; + case 3: /* Hinted */ + break; + case 4: /* Tuned */ + value2 = tvb_get_letohl(tvb, ioffset); /* Count */ + proto_tree_add_item(nestree, hf_es_rdn_count, tvb, ioffset, + 4, value2); + ioffset = ioffset + 4; + for (r = 1 ; r <= value2; r++ ) + { + value3 = tvb_get_letohl(tvb, ioffset); /* Seconds */ + proto_tree_add_item(nestree, hf_es_seconds, tvb, ioffset, + 4, value3); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(nestree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(nestree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + } + value4 = tvb_get_letohl(tvb, ioffset); /* Delimeter Set */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value4, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(nestree, hf_mv_string, tvb, ioffset, + value4, values->vstring); + ioffset=ioffset + value4; + ioffset += align_4(tvb, ioffset); + value5 = tvb_get_letohl(tvb, ioffset); /* RDN */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value5, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(nestree, hf_rdn_string, tvb, ioffset, + value5, values->vstring); + ioffset=ioffset + value5; + ioffset += align_4(tvb, ioffset); + break; + case 5: /* GUID */ + case 6: /* ID32 */ + case 7: /* Count */ + default: + value1 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + proto_tree_add_item(estree, hf_es_value, tvb, ioffset, + 4, value1); + ioffset = ioffset + 4; + break; + } + value1 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + vstring = match_strval(value1, es_type); + if (vstring == NULL) + { + vstring = "No ES Type Found"; + } + nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset, + 4, vstring, "Object Name Type - %s", vstring); + nestree = proto_item_add_subtree(nesitem, ett_nds); + ioffset = ioffset + 4; + switch (value1) + { + case 0: /* No Specifier Type */ + value2 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + proto_tree_add_item(estree, hf_es_value, tvb, ioffset, + 4, value2); + ioffset = ioffset + 4; + break; + case 1: /* Unicode String */ + value2 = tvb_get_letohl(tvb, ioffset); /* Delimeter Set */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string_format(estree, hf_mv_string, tvb, ioffset, + value2, values->vstring, "Delimeter ->%s", values->vstring); + ioffset=ioffset + value2; + ioffset += align_4(tvb, ioffset); + value3 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value3, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, + value3, values->vstring); + values->voffset=ioffset + value3; + ioffset = values->voffset; + ioffset += align_4(tvb, ioffset); + break; + case 2: /* Based */ + break; + case 3: /* Hinted */ + break; + case 4: /* Tuned */ + value2 = tvb_get_letohl(tvb, ioffset); /* Count */ + proto_tree_add_item(estree, hf_es_rdn_count, tvb, ioffset, + 4, value2); + ioffset = ioffset + 4; + for (r = 1 ; r <= value2; r++ ) + { + value3 = tvb_get_letohl(tvb, ioffset); /* Seconds */ + proto_tree_add_item(estree, hf_es_seconds, tvb, ioffset, + 4, value3); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(estree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(estree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + } + value4 = tvb_get_letohl(tvb, ioffset); /* Delimeter Set */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value4, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, + value4, values->vstring); + ioffset=ioffset + value4; + ioffset += align_4(tvb, ioffset); + value5 = tvb_get_letohl(tvb, ioffset); /* RDN */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value5, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_rdn_string, tvb, ioffset, + value5, values->vstring); + ioffset=ioffset + value5; + ioffset += align_4(tvb, ioffset); + break; + case 5: /* GUID */ + case 6: /* ID32 */ + case 7: /* Count */ + default: + value1 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + proto_tree_add_item(estree, hf_es_value, tvb, ioffset, + 4, value1); + ioffset = ioffset + 4; + break; + } + break; + case 3: /* Hinted */ + number_of_referrals = tvb_get_letohl(tvb, ioffset); + + for (r = 1 ; r <= number_of_referrals; r++ ) + { + aitem = proto_tree_add_uint_format(estree, hf_referral_record, tvb, 6, 0, + r, "NDS Referral Record #%u", r); + atree = proto_item_add_subtree(aitem, ett_nds); + + value1 = tvb_get_letohl(tvb, ioffset); + + proto_tree_add_uint_format(atree, hf_referral_addcount, tvb, ioffset, 4, + value1, "Number of Addresses in Referral - %d", value1); + + ioffset = ioffset + 4; + for (i = 1 ; i <= value1; i++ ) + { + value2 = tvb_get_letohl(tvb, ioffset); + values->vstring = match_strval(value2, nds_protocol_type); + if (values->vstring == NULL) + { + values->vstring="(Undefined Protocol)"; + } + proto_tree_add_uint_format(atree, hf_nds_uint32value, tvb, ioffset, + 4, value2, vstring, value2); + ioffset = ioffset+4; + value3 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset+4; + switch (value2) + { + case 0x00000000: + proto_tree_add_item(atree, hf_nds_net, tvb, ioffset, 4, FALSE); + proto_tree_add_item(atree, hf_nds_node, tvb, ioffset+4, 6, FALSE); + proto_tree_add_item(atree, hf_nds_socket, tvb, ioffset+10, 2, FALSE); + break; + case 0x00000001: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, ioffset+2); + proto_tree_add_ipv4(atree, hf_add_ref_ip, tvb, ioffset+2, 4, value4); + break; + case 0x00000008: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, ioffset+2); + proto_tree_add_ipv4(atree, hf_add_ref_udp, tvb, ioffset+2, 4, value4); + break; + case 0x00000009: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, ioffset+2); + proto_tree_add_ipv4(atree, hf_add_ref_tcp, tvb, ioffset+2, 4, value4); + break; + case 0x0000000d: + get_string(tvb, ioffset, value3, values->vstring); + proto_tree_add_string(atree, hf_value_string, tvb, ioffset, + value3, values->vstring); + break; + default: + break; + } + ioffset = ioffset + value3; + ioffset += align_4(tvb, ioffset); + } + + } + value1 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + vstring = match_strval(value1, es_type); + if (vstring == NULL) + { + vstring = "No ES Type Found"; + } + nesitem = proto_tree_add_string_format(estree, hf_es_type, tvb, ioffset, + 4, vstring, "Object Name Type - %s", vstring); + nestree = proto_item_add_subtree(nesitem, ett_nds); + ioffset = ioffset + 4; + switch (value1) + { + case 0: /* No Specifier Type */ + value2 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + proto_tree_add_item(estree, hf_es_value, tvb, ioffset, + 4, value2); + ioffset = ioffset + 4; + break; + case 1: /* Unicode String */ + value2 = tvb_get_letohl(tvb, ioffset); /* Delimeter Set */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string_format(estree, hf_mv_string, tvb, ioffset, + value2, values->vstring, "Delimeter ->%s", values->vstring); + ioffset=ioffset + value2; + ioffset += align_4(tvb, ioffset); + value3 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value3, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, + value3, values->vstring); + values->voffset=ioffset + value3; + ioffset = values->voffset; + ioffset += align_4(tvb, ioffset); + break; + case 2: /* Based */ + break; + case 3: /* Hinted */ + break; + case 4: /* Tuned */ + value2 = tvb_get_letohl(tvb, ioffset); /* Count */ + proto_tree_add_item(estree, hf_es_rdn_count, tvb, ioffset, + 4, value2); + ioffset = ioffset + 4; + for (r = 1 ; r <= value2; r++ ) + { + value3 = tvb_get_letohl(tvb, ioffset); /* Seconds */ + proto_tree_add_item(estree, hf_es_seconds, tvb, ioffset, + 4, value3); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(estree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(estree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + } + value4 = tvb_get_letohl(tvb, ioffset); /* Delimeter Set */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value4, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, + value4, values->vstring); + ioffset=ioffset + value4; + ioffset += align_4(tvb, ioffset); + value5 = tvb_get_letohl(tvb, ioffset); /* RDN */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value5, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_rdn_string, tvb, ioffset, + value5, values->vstring); + ioffset=ioffset + value5; + ioffset += align_4(tvb, ioffset); + break; + case 5: /* GUID */ + case 6: /* ID32 */ + case 7: /* Count */ + default: + value1 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + proto_tree_add_item(estree, hf_es_value, tvb, ioffset, + 4, value1); + ioffset = ioffset + 4; + break; + } + break; + case 4: /* Tuned */ + value1 = tvb_get_letohl(tvb, ioffset); /* Count */ + proto_tree_add_item(estree, hf_es_rdn_count, tvb, ioffset, + 4, value1); + ioffset = ioffset + 4; + for (r = 1 ; r <= value1; r++ ) + { + value2 = tvb_get_letohl(tvb, ioffset); /* Seconds */ + proto_tree_add_item(estree, hf_es_seconds, tvb, ioffset, + 4, value2); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(estree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(estree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + } + value3 = tvb_get_letohl(tvb, ioffset); /* Delimeter Set */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value3, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_mv_string, tvb, ioffset, + value3, values->vstring); + ioffset=ioffset + value3; + ioffset += align_4(tvb, ioffset); + value4 = tvb_get_letohl(tvb, ioffset); /* RDN */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value4, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(estree, hf_rdn_string, tvb, ioffset, + value4, values->vstring); + ioffset=ioffset + value4; + ioffset += align_4(tvb, ioffset); + break; + case 5: /* GUID */ + case 6: /* ID32 */ + case 7: /* Count */ + default: + value1 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + proto_tree_add_item(estree, hf_es_value, tvb, ioffset, + 4, value1); + ioffset = ioffset + 4; + break; + } + return ioffset; +} + +static void +process_multivalues(proto_tree *ncp_tree, tvbuff_t *tvb, nds_val *values) +{ + guint32 i; + guint32 r; + guint32 ioffset = 0; + guint32 value1 = 0; + guint32 value2 = 0; + guint8 value3 = 0; + guint32 value4 = 0; + gint value5 = 0; + guint32 value6 = 0; + guint32 value7 = 0; + char * valuestr = ""; + proto_tree *ntree; + proto_tree *atree; + proto_item *nitem; + proto_item *aitem; + guint32 number_of_referrals = 0; + nw_uni_t mval_buf; + proto_tree *estree; + proto_item *esitem; + guint16 replica_num = 0; + guint16 event_num = 0; + guint32 bvalue=0; + nds_val temp_values; + proto_tree *sub1tree; + proto_item *sub1item; + proto_tree *sub2tree; + proto_item *sub2item; + gint length_remaining; + + strcpy(mval_buf.buffer, ""); + + if(values->mvtype != MVTYPE_LIST_PARTITIONS) + { + nitem = proto_tree_add_uint_format(ncp_tree, values->hfname, tvb, values->voffset+ioffset, + values->vlength, values->vvalue, values->vdesc, values->vvalue); + } + else + { + nitem = proto_tree_add_string_format(ncp_tree, values->hfname, tvb, values->voffset+ioffset, + values->vlength, values->vdesc, "%s", values->vdesc); + } + ioffset = (values->voffset+4); + + ntree = proto_item_add_subtree(nitem, ett_nds); + + switch (values->mvtype) + { + case MVTYPE_ATTR_REQUEST: /* Attribute Request */ + for (i = 1 ; i <= values->vvalue; i++ ) + { + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value1, values->vstring); + ioffset = ioffset + value1; + } + break; + + case MVTYPE_ATTR_REPLY: /* Attribute Reply */ + switch(values->vflags) + { + case 0: + for (i = 1 ; i <= values->vvalue; i++ ) + { + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value1, values->vstring); + ioffset = ioffset + value1; + } + break; + case 1: + for (i = 1 ; i <= values->vvalue; i++ ) + { + value1 = tvb_get_letohl(tvb, ioffset); + values->vstring = match_strval(value1, nds_syntax); + if (values->vstring == NULL) + { + values->vstring = "No Syntax Found"; + } + proto_tree_add_string(ntree, hf_nds_syntax, tvb, ioffset, + 4, values->vstring); + ioffset = ioffset + 4; + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value2, values->vstring); + ioffset += value2; + ioffset += align_4(tvb, ioffset); + values->voffset = ioffset; + + print_nds_values(ntree, tvb, value1, values); + ioffset = values->voffset; + } + break; + case 2: + for (i = 1 ; i <= values->vvalue; i++ ) + { + value1 = tvb_get_letohl(tvb, ioffset); + values->vstring = match_strval(value1, nds_syntax); + if (values->vstring == NULL) + { + values->vstring = "No Syntax Found"; + } + proto_tree_add_string(ntree, hf_nds_syntax, tvb, ioffset, + 4, values->vstring); + ioffset = ioffset + 4; + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value2, values->vstring); + values->voffset=ioffset + value2; + ioffset += value2; + ioffset += align_4(tvb, ioffset); + value3 = tvb_get_letohl(tvb, ioffset); + + proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, 4, + value1, "Number of Values - %d", value1); + + ioffset = ioffset + 4; + for (r = 1 ; r <= value3; r++ ) + { + ioffset += 4; /* Length = 4 */ + value4 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint(ntree, hf_nds_privileges, tvb, ioffset, + values->vlength, value4); + ioffset = ioffset+4; + } + } + break; + case 3: + for (i = 1 ; i <= values->vvalue; i++ ) + { + value1 = tvb_get_letohl(tvb, ioffset); + values->vstring = match_strval(value1, nds_syntax); + if (values->vstring == NULL) + { + values->vstring = "No Syntax Found"; + } + proto_tree_add_string(ntree, hf_nds_syntax, tvb, ioffset, + 4, values->vstring); + ioffset = ioffset + 4; + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value2, values->vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + value3 = tvb_get_letohl(tvb, ioffset); + + aitem = proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, 4, + value3, "Number of Values - %d", value3); + + atree = proto_item_add_subtree(aitem, ett_nds); + + ioffset = ioffset + 4; + for (r = 1 ; r <= value3; r++ ) + { + ioffset += align_4(tvb, ioffset); + temp_values.vvalue = tvb_get_letohl(tvb, ioffset); + temp_values.vlength = 2; + temp_values.hfname = hf_nds_vflags; + temp_values.voffset = ioffset; + temp_values.vdesc = "Value Flags"; + temp_values.bit1 = "Naming"; + temp_values.bit1hfname = hf_bit1vflags; + temp_values.bit2 = "Base Class"; + temp_values.bit2hfname = hf_bit2vflags; + temp_values.bit3 = "Present"; + temp_values.bit3hfname = hf_bit3vflags; + temp_values.bit4 = "Value Damaged"; + temp_values.bit4hfname = hf_bit4vflags; + temp_values.bit5 = "Not Defined"; + temp_values.bit5hfname = hf_bit5vflags; + temp_values.bit6 = "Not Defined"; + temp_values.bit6hfname = hf_bit6vflags; + temp_values.bit7 = "Not Defined"; + temp_values.bit7hfname = hf_bit7vflags; + temp_values.bit8 = "Not Defined"; + temp_values.bit8hfname = hf_bit8vflags; + temp_values.bit9 = "Not Defined"; + temp_values.bit9hfname = hf_bit9vflags; + temp_values.bit10 = "Not Defined"; + temp_values.bit10hfname = hf_bit10vflags; + temp_values.bit11 = "Not Defined"; + temp_values.bit11hfname = hf_bit11vflags; + temp_values.bit12 = "Not Defined"; + temp_values.bit12hfname = hf_bit12vflags; + temp_values.bit13 = "Not Defined"; + temp_values.bit13hfname = hf_bit13vflags; + temp_values.bit14 = "Not Defined"; + temp_values.bit14hfname = hf_bit14vflags; + temp_values.bit15 = "Not Defined"; + temp_values.bit15hfname = hf_bit15vflags; + temp_values.bit16 = "Not Defined"; + temp_values.bit16hfname = hf_bit16vflags; + process_bitfield(atree, tvb, &temp_values); + ioffset = ioffset + 4; + value4 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(atree, hf_es_seconds, tvb, ioffset, + 4, value4, "Seconds %d", value4); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(atree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(atree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + value5 = tvb_get_letohl(tvb, ioffset); /* length of field */ + if(value5 > tvb_length_remaining(tvb, ioffset)) + { + break; + } + ioffset += 4; + proto_tree_add_bytes(atree, hf_value_bytes, tvb, ioffset, value5, tvb_get_ptr(tvb, ioffset, value5)); + ioffset += value5; + ioffset += (value5%2); + } + } + break; + case 4: + for (i = 1 ; i <= values->vvalue; i++ ) + { + value1 = tvb_get_letohl(tvb, ioffset); + values->vstring = match_strval(value1, nds_syntax); + if (values->vstring == NULL) + { + values->vstring = "No Syntax Found"; + } + proto_tree_add_string(ntree, hf_nds_syntax, tvb, ioffset, + 4, values->vstring); + ioffset = ioffset + 4; + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value2, values->vstring); + ioffset = ioffset + value2; + value3 = tvb_get_letohl(tvb, ioffset); + + proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, 4, + value3, "Number of Values - %d", value3); + + ioffset = ioffset + 4; + for (r = 1 ; r <= value3; r++ ) + { + ioffset += align_4(tvb, ioffset); + temp_values.vvalue = tvb_get_letohl(tvb, ioffset); + temp_values.vlength = 2; + temp_values.hfname = hf_nds_vflags; + temp_values.voffset = ioffset; + temp_values.vdesc = "Value Flags"; + temp_values.bit1 = "Naming"; + temp_values.bit1hfname = hf_bit1vflags; + temp_values.bit2 = "Base Class"; + temp_values.bit2hfname = hf_bit2vflags; + temp_values.bit3 = "Present"; + temp_values.bit3hfname = hf_bit3vflags; + temp_values.bit4 = "Value Damaged"; + temp_values.bit4hfname = hf_bit4vflags; + temp_values.bit5 = "Not Defined"; + temp_values.bit5hfname = hf_bit5vflags; + temp_values.bit6 = "Not Defined"; + temp_values.bit6hfname = hf_bit6vflags; + temp_values.bit7 = "Not Defined"; + temp_values.bit7hfname = hf_bit7vflags; + temp_values.bit8 = "Not Defined"; + temp_values.bit8hfname = hf_bit8vflags; + temp_values.bit9 = "Not Defined"; + temp_values.bit9hfname = hf_bit9vflags; + temp_values.bit10 = "Not Defined"; + temp_values.bit10hfname = hf_bit10vflags; + temp_values.bit11 = "Not Defined"; + temp_values.bit11hfname = hf_bit11vflags; + temp_values.bit12 = "Not Defined"; + temp_values.bit12hfname = hf_bit12vflags; + temp_values.bit13 = "Not Defined"; + temp_values.bit13hfname = hf_bit13vflags; + temp_values.bit14 = "Not Defined"; + temp_values.bit14hfname = hf_bit14vflags; + temp_values.bit15 = "Not Defined"; + temp_values.bit15hfname = hf_bit15vflags; + temp_values.bit16 = "Not Defined"; + temp_values.bit16hfname = hf_bit16vflags; + process_bitfield(ntree, tvb, &temp_values); + ioffset = ioffset + 4; + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_es_seconds, tvb, ioffset, + 4, value1, "Seconds %d", value1); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint(ntree, hf_nds_value_len, tvb, ioffset, + 4, value1); + ioffset = ioffset + 4; + } + } + break; + default: + break; + } + break; + + case MVTYPE_ATTR_REQUEST2: /* Attribute Request */ + for (i = 1 ; i <= values->vvalue; i++ ) + { + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, + 4, value1, "Value %d", value1); + ioffset = ioffset + value1; + } + break; + + case MVTYPE_ADD_ATTR_REQUEST: /* Add Attribute Request */ + for (i = 1 ; i <= values->vvalue; i++ ) + { + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value1, values->vstring); + ioffset = ioffset + value1; + ioffset += align_4(tvb, ioffset); + values->voffset = ioffset; + print_nds_values(ntree, tvb, 9, values); + ioffset = values->voffset; + } + break; + + case MVTYPE_READ_CLASS_REQ: /* Read Class Request */ + for (i = 1 ; i <= values->vvalue; i++ ) + { + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_base, tvb, ioffset, + value1, values->vstring); + values->mvtype = 1; + ioffset = ioffset + value1; + } + break; + + case MVTYPE_READ_REPLICAS: /* Read Replicas */ + for (i = 1 ; i <= values->vvalue; i++ ) + { + + bvalue = 0x00000001; + + for (r = 0 ; r < 9; r++ ) + { + + if (values->vflags & bvalue) + { + switch(bvalue) + { + case 0x00000001: /*p3values.bit1 = "Output Flags"*/ + temp_values.vvalue = tvb_get_letohl(tvb, ioffset); + temp_values.vlength = 2; + temp_values.hfname = hf_nds_rflags; + temp_values.voffset = ioffset; + temp_values.vdesc = "Output Flags"; + temp_values.bit1 = values->bit1; + temp_values.bit1hfname = hf_bit1outflags; + temp_values.bit2 = values->bit2; + temp_values.bit2hfname = hf_bit2outflags; + temp_values.bit3 = values->bit3; + temp_values.bit3hfname = hf_bit3outflags; + temp_values.bit4 = values->bit4; + temp_values.bit4hfname = hf_bit4outflags; + temp_values.bit5 = values->bit5; + temp_values.bit5hfname = hf_bit5outflags; + temp_values.bit6 = values->bit6; + temp_values.bit6hfname = hf_bit6outflags; + temp_values.bit7 = values->bit7; + temp_values.bit7hfname = hf_bit7outflags; + temp_values.bit8 = values->bit8; + temp_values.bit8hfname = hf_bit8outflags; + temp_values.bit9 = values->bit9; + temp_values.bit9hfname = hf_bit9outflags; + temp_values.bit10 = "Not Defined"; + temp_values.bit10hfname = hf_bit10outflags; + temp_values.bit11 = "Not Defined"; + temp_values.bit11hfname = hf_bit11outflags; + temp_values.bit12 = "Not Defined"; + temp_values.bit12hfname = hf_bit12outflags; + temp_values.bit13 = "Not Defined"; + temp_values.bit13hfname = hf_bit13outflags; + temp_values.bit14 = "Not Defined"; + temp_values.bit14hfname = hf_bit14outflags; + temp_values.bit15 = "Not Defined"; + temp_values.bit15hfname = hf_bit15outflags; + temp_values.bit16 = "Not Defined"; + temp_values.bit16hfname = hf_bit16outflags; + process_bitfield(ntree, tvb, &temp_values); + ioffset = ioffset + 4; + break; + case 0x00000002: /*p3values.bit2 = "Entry ID"*/ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_eid, tvb, ioffset, + 4, value1, "Entry ID %08x", value1); + ioffset = ioffset + 4; + break; + case 0x00000004: /*p3values.bit3 = "Replica State"*/ + value1 = tvb_get_letohl(tvb, ioffset); + temp_values.vstring = match_strval(value1, nds_replica_state); + if (temp_values.vstring == NULL) + { + temp_values.vstring = "No Replica State Found"; + } + proto_tree_add_string(ntree, hf_replica_state, tvb, ioffset, + 4, temp_values.vstring); + ioffset = ioffset + 4; + break; + case 0x0000008: /*p3values.bit4 = "Modification Timestamp"*/ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_es_seconds, tvb, ioffset, + 4, value1, "Seconds %d", value1); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + break; + case 0x00000010: /*p3values.bit5 = "Purge Time"*/ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_purge, tvb, ioffset, + 4, value1, "Purge Time %d", value1); + ioffset = ioffset + 4; + break; + case 0x00000020: /*p3values.bit6 = "Local Partition ID"*/ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_local_partition, tvb, ioffset, + 4, value1, "Local Partition ID %08x", value1); + ioffset = ioffset + 4; + break; + case 0x00000040: /*p3values.bit7 = "Distinguished Name"*/ + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_name, tvb, ioffset, + value1, temp_values.vstring); + ioffset = ioffset + value1; + break; + case 0x00000080: /*p3values.bit8 = "Replica Type & State"*/ + value1 = tvb_get_letohl(tvb, ioffset); + value2 = value1 & 0x00ff; + temp_values.vstring = match_strval(value2, nds_replica_type); + if (temp_values.vstring == NULL) + { + temp_values.vstring = "No Replica Type Found"; + } + proto_tree_add_string(ntree, hf_replica_type, tvb, ioffset, + 4, temp_values.vstring); + value3 = value1 & 0xff00; + temp_values.vstring = match_strval(value3, nds_replica_state); + if (temp_values.vstring == NULL) + { + temp_values.vstring = "No Replica State Found"; + } + proto_tree_add_string(ntree, hf_replica_state, tvb, ioffset, + 4, temp_values.vstring); + ioffset = ioffset + 4; + break; + case 0x00000100: /*p3values.bit9 = "Partition Busy"*/ + value1 = tvb_get_letohs(tvb, ioffset); + proto_tree_add_boolean(ntree, hf_partition_busy, tvb, ioffset, 4, value1); + ioffset += 4; + break; + default: + break; + + } + } + bvalue = bvalue*2; + ioffset += align_4(tvb, ioffset); + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + } + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + } + break; + + case MVTYPE_MODIFY_ATTR_REQUEST: /* Modify Attribute Request */ + for (i = 0 ; i < values->vvalue; i++ ) + { + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + valuestr = match_strval(value1, nds_kind_of_changes); + if (valuestr == NULL) + { + valuestr="(Kind Change Not Found)"; + } + proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, + values->vlength, value1, valuestr, value1); + ioffset = ioffset+4; + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); /* Name of Attribute */ + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + if(value1 != 1 && value1 != 6) + { + values->voffset = ioffset; + print_nds_values(ntree, tvb, 9, values); + ioffset = values->voffset; + } + } + break; + + case MVTYPE_ADDR_REFERRAL_REQUEST: /* Address Referral Request */ + for (i = 0 ; i < values->vvalue; i++ ) + { + + value1 = tvb_get_letohl(tvb, ioffset); + valuestr = match_strval(value1, nds_protocol_type); + if (valuestr == NULL) + { + valuestr="(Undefined Protocol)"; + } + proto_tree_add_uint_format(ntree, hf_nds_uint32value, tvb, ioffset, + values->vlength, value1, valuestr, value1); + ioffset = ioffset+4; + } + break; + + case MVTYPE_ADDR_REFERRAL_REPLY: /* Address Referral Reply */ + number_of_referrals = values->vvalue; + + for (r = 1 ; r <= number_of_referrals; r++ ) + { + aitem = proto_tree_add_uint_format(ntree, hf_referral_record, tvb, 6, 0, + r, "NDS Referral Record #%u", r); + atree = proto_item_add_subtree(aitem, ett_nds); + + value1 = tvb_get_letohl(tvb, ioffset); + + proto_tree_add_uint_format(atree, hf_referral_addcount, tvb, ioffset, 4, + value1, "Number of Addresses in Referral - %d", value1); + + ioffset = ioffset + 4; + for (i = 1 ; i <= value1; i++ ) + { + value2 = tvb_get_letohl(tvb, ioffset); + valuestr = match_strval(value2, nds_protocol_type); + if (valuestr == NULL) + { + valuestr="(Undefined Protocol)"; + } + proto_tree_add_uint_format(atree, hf_nds_uint32value, tvb, ioffset, + values->vlength, value2, valuestr, value2); + ioffset = ioffset+4; + value3 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset+4; + switch (value2) + { + case 0x00000000: + proto_tree_add_item(atree, hf_nds_net, tvb, ioffset, 4, FALSE); + proto_tree_add_item(atree, hf_nds_node, tvb, ioffset+4, 6, FALSE); + proto_tree_add_item(atree, hf_nds_socket, tvb, ioffset+10, 2, FALSE); + break; + case 0x00000001: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, ioffset+2); + proto_tree_add_ipv4(atree, hf_add_ref_ip, tvb, ioffset+2, 4, value4); + break; + case 0x00000008: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, ioffset+2); + proto_tree_add_ipv4(atree, hf_add_ref_udp, tvb, ioffset+2, 4, value4); + break; + case 0x00000009: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + value4 = tvb_get_letohl(tvb, ioffset+2); + proto_tree_add_ipv4(atree, hf_add_ref_tcp, tvb, ioffset+2, 4, value4); + break; + case 0x0000000d: + get_string(tvb, ioffset, value3, values->vstring); + proto_tree_add_string(atree, hf_value_string, tvb, ioffset, + value3, values->vstring); + break; + default: + break; + } + ioffset = ioffset + value3; + ioffset += align_4(tvb, ioffset); + } + + } + break; + + case MVTYPE_LOC_ADDR_REFERRAL_REPLY: /* Local Address Referral Reply */ + number_of_referrals = values->vvalue; + + for (r = 1 ; r <= number_of_referrals; r++ ) + { + aitem = proto_tree_add_uint_format(ntree, hf_referral_record, tvb, 6, 0, + r, "NDS Referral Record #%u", r); + atree = proto_item_add_subtree(aitem, ett_nds); + + value2 = tvb_get_letohl(tvb, ioffset); + valuestr = match_strval(value2, nds_protocol_type); + if (valuestr == NULL) + { + valuestr="(Undefined Protocol)"; + } + proto_tree_add_uint_format(atree, hf_nds_uint32value, tvb, ioffset, + values->vlength, value2, valuestr, value2); + ioffset = ioffset+4; + value3 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset+4; + + switch (value2) + { + case 0x00000000: + proto_tree_add_item(atree, hf_nds_net, tvb, ioffset, 4, FALSE); + proto_tree_add_item(atree, hf_nds_node, tvb, ioffset+4, 6, FALSE); + proto_tree_add_item(atree, hf_nds_socket, tvb, ioffset+10, 2, FALSE); + break; + case 0x00000001: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + ioffset=ioffset+2; + value4 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_ipv4(atree, hf_add_ref_ip, tvb, ioffset, 4, value4); + break; + case 0x00000008: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + ioffset=ioffset+2; + value4 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_ipv4(atree, hf_add_ref_udp, tvb, ioffset, 4, value4); + break; + case 0x00000009: + proto_tree_add_item(atree, hf_nds_port, tvb, ioffset, 2, FALSE); + ioffset=ioffset+2; + value4 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_ipv4(atree, hf_add_ref_tcp, tvb, ioffset, 4, value4); + break; + case 0x0000000d: + get_string(tvb, ioffset, value3, values->vstring); + proto_tree_add_string(atree, hf_value_string, tvb, ioffset, + value3, values->vstring); + break; + default: + break; + } + ioffset = ioffset + value3; + ioffset += align_4(tvb, ioffset); + } + break; + + case MVTYPE_PROC_ENTRY_SPECIFIERS: /* Process Entry Specifiers */ + value2 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + values->vstring = match_strval(value2, es_type); + if (values->vstring == NULL) + { + values->vstring = "No ES Type Found"; + } + esitem = proto_tree_add_string_format(ntree, hf_es_type, tvb, ioffset, + 4, values->vstring, "Output Entry Specifier - %s", values->vstring); + estree = proto_item_add_subtree(esitem, ett_nds); + ioffset = ioffset + 4; + ioffset = print_es_type(estree, tvb, values, value2, ioffset); + value3 = tvb_get_letohl(tvb, ioffset); /* ES Type */ + values->vstring = match_strval(value3, es_type); + if (values->vstring == NULL) + { + values->vstring = "No ES Type Found"; + } + esitem = proto_tree_add_string_format(ntree, hf_es_type, tvb, ioffset, + 4, values->vstring, "Input Entry Specifier - %s", values->vstring); + estree = proto_item_add_subtree(esitem, ett_nds); + ioffset = ioffset + 4; + ioffset = print_es_type(estree, tvb, values, value3, ioffset); + value4 = tvb_get_letohl(tvb, ioffset); + aitem = proto_tree_add_uint_format(ntree, hf_referral_record, tvb, ioffset, 4, + value4, "Referral Protocols - %d", value4); + atree = proto_item_add_subtree(aitem, ett_nds); + ioffset += 4; + for (i = 0 ; i < value4; i++ ) + { + value5 = tvb_get_letohl(tvb, ioffset); + valuestr = match_strval(value5, nds_protocol_type); + if (valuestr == NULL) + { + valuestr="(Undefined Protocol)"; + } + proto_tree_add_string_format(atree, hf_value_string, tvb, ioffset, + 4, valuestr, "Protocol -> %s", valuestr); + ioffset = ioffset+4; + } + value6 = tvb_get_letohl(tvb, ioffset); + aitem = proto_tree_add_uint_format(ntree, hf_referral_record, tvb, ioffset, 4, + value6, "Tree Walking Protocols - %d", value6); + atree = proto_item_add_subtree(aitem, ett_nds); + ioffset += 4; + for (i = 0 ; i < value6; i++ ) + { + value7 = tvb_get_letohl(tvb, ioffset); + valuestr = match_strval(value7, nds_protocol_type); + if (valuestr == NULL) + { + valuestr="(Undefined Protocol)"; + } + proto_tree_add_string_format(atree, hf_value_string, tvb, ioffset, + 4, valuestr, "Protocol -> %s", valuestr); + ioffset = ioffset+4; + } + break; + + case MVTYPE_PRINT_TIMESTAMP: /* Print Timestamp */ + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(ncp_tree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(ncp_tree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + /* fall through */ + + case MVTYPE_LIST_PARTITIONS: /* List Partitions */ + number_of_referrals = values->vvalue; + for (i = 0; i < number_of_referrals; i++) + { + bvalue = 0x00000001; + + for (r = 0 ; r < 32; r++ ) + { + if (values->vflags & bvalue) + { + switch(bvalue) + { + case 0x00000001: /* Information Flags */ + temp_values.vvalue = tvb_get_letohs(tvb, ioffset); + temp_values.vtype = VTYPE_BITFIELD; + temp_values.vstring = mval_buf.buffer; + temp_values.vdesc = "Information Flags (low) Byte:"; + temp_values.vlength = 2; + temp_values.hfname= hf_nds_rflags; + temp_values.voffset = ioffset; + temp_values.bit1 = "Output Flags"; + temp_values.bit1hfname = hf_bit1infoflagsl; + temp_values.bit2 = "Entry ID"; + temp_values.bit2hfname = hf_bit2infoflagsl; + temp_values.bit3 = "Entry Flags"; + temp_values.bit3hfname = hf_bit3infoflagsl; + temp_values.bit4 = "Subordinate Count"; + temp_values.bit4hfname = hf_bit4infoflagsl; + temp_values.bit5 = "Modification Time"; + temp_values.bit5hfname = hf_bit5infoflagsl; + temp_values.bit6 = "Modification Timestamp"; + temp_values.bit6hfname = hf_bit6infoflagsl; + temp_values.bit7 = "Creation Timestamp"; + temp_values.bit7hfname = hf_bit7infoflagsl; + temp_values.bit8 = "Partition Root ID"; + temp_values.bit8hfname = hf_bit8infoflagsl; + temp_values.bit9 = "Parent ID"; + temp_values.bit9hfname = hf_bit9infoflagsl; + temp_values.bit10 = "Revision Count"; + temp_values.bit10hfname = hf_bit10infoflagsl; + temp_values.bit11 = "Replica Type"; + temp_values.bit11hfname = hf_bit11infoflagsl; + temp_values.bit12 = "Base Class"; + temp_values.bit12hfname = hf_bit12infoflagsl; + temp_values.bit13 = "Relative Distinguished Name"; + temp_values.bit13hfname = hf_bit13infoflagsl; + temp_values.bit14 = "Distinguished Name"; + temp_values.bit14hfname = hf_bit14infoflagsl; + temp_values.bit15 = "Root Distinguished Name"; + temp_values.bit15hfname = hf_bit15infoflagsl; + temp_values.bit16 = "Parent Distinguished Name"; + temp_values.bit16hfname = hf_bit16infoflagsl; + process_bitfield(ntree, tvb, &temp_values); + ioffset = ioffset+2; + temp_values.vvalue = tvb_get_letohs(tvb, ioffset); + temp_values.vtype = VTYPE_BITFIELD; + temp_values.vstring = mval_buf.buffer; + temp_values.vdesc = "Information Flags (high) Byte:"; + temp_values.vlength = 2; + temp_values.hfname= hf_nds_rflags; + temp_values.voffset = ioffset; + temp_values.bit1 = "Purge Time"; + temp_values.bit1hfname = hf_bit1infoflagsh; + temp_values.bit2 = "Dereference Base Class"; + temp_values.bit2hfname = hf_bit2infoflagsh; + temp_values.bit3 = "Not Defined"; + temp_values.bit3hfname = hf_bit3infoflagsh; + temp_values.bit4 = "Not Defined"; + temp_values.bit4hfname = hf_bit4infoflagsh; + temp_values.bit5 = "Not Defined"; + temp_values.bit5hfname = hf_bit5infoflagsh; + temp_values.bit6 = "Not Defined"; + temp_values.bit6hfname = hf_bit6infoflagsh; + temp_values.bit7 = "Not Defined"; + temp_values.bit7hfname = hf_bit7infoflagsh; + temp_values.bit8 = "Not Defined"; + temp_values.bit8hfname = hf_bit8infoflagsh; + temp_values.bit9 = "Not Defined"; + temp_values.bit9hfname = hf_bit9infoflagsh; + temp_values.bit10 = "Not Defined"; + temp_values.bit10hfname = hf_bit10infoflagsh; + temp_values.bit11 = "Not Defined"; + temp_values.bit11hfname = hf_bit11infoflagsh; + temp_values.bit12 = "Not Defined"; + temp_values.bit12hfname = hf_bit12infoflagsh; + temp_values.bit13 = "Not Defined"; + temp_values.bit13hfname = hf_bit13infoflagsh; + temp_values.bit14 = "Not Defined"; + temp_values.bit14hfname = hf_bit14infoflagsh; + temp_values.bit15 = "Not Defined"; + temp_values.bit15hfname = hf_bit15infoflagsh; + temp_values.bit16 = "Not Defined"; + temp_values.bit16hfname = hf_bit16infoflagsh; + process_bitfield(ntree, tvb, &temp_values); + ioffset = ioffset+2; + break; + case 0x00000002: /* Entry ID */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_eid, tvb, ioffset, + 4, value1, "Entry ID %08x", value1); + ioffset = ioffset + 4; + break; + case 0x00000004: /* Entry Flags */ + temp_values.vvalue = tvb_get_letohl(tvb, ioffset); + temp_values.vtype = VTYPE_BITFIELD; + temp_values.vstring = mval_buf.buffer; + temp_values.vdesc = "Entry Flags:"; + temp_values.vlength = 2; + temp_values.hfname= hf_nds_eflags; + temp_values.voffset = ioffset; + temp_values.bit1 = "Alias Entry"; + temp_values.bit1hfname = hf_bit1eflags; + temp_values.bit2 = "Partition Root"; + temp_values.bit2hfname = hf_bit2eflags; + temp_values.bit3 = "Container Entry"; + temp_values.bit3hfname = hf_bit3eflags; + temp_values.bit4 = "Container Alias"; + temp_values.bit4hfname = hf_bit4eflags; + temp_values.bit5 = "Matches List Filter"; + temp_values.bit5hfname = hf_bit5eflags; + temp_values.bit6 = "Reference Entry"; + temp_values.bit6hfname = hf_bit6eflags; + temp_values.bit7 = "40x Reference Entry"; + temp_values.bit7hfname = hf_bit7eflags; + temp_values.bit8 = "Back Linked"; + temp_values.bit8hfname = hf_bit8eflags; + temp_values.bit9 = "New Entry"; + temp_values.bit9hfname = hf_bit9eflags; + temp_values.bit10 = "Temporary Reference"; + temp_values.bit10hfname = hf_bit10eflags; + temp_values.bit11 = "Audited"; + temp_values.bit11hfname = hf_bit11eflags; + temp_values.bit12 = "Entry Not Present"; + temp_values.bit12hfname = hf_bit12eflags; + temp_values.bit13 = "Entry Verify CTS"; + temp_values.bit13hfname = hf_bit13eflags; + temp_values.bit14 = "Entry Damaged"; + temp_values.bit14hfname = hf_bit14eflags; + temp_values.bit15 = "Not Defined"; + temp_values.bit15hfname = hf_bit15eflags; + temp_values.bit16 = "Not Defined"; + temp_values.bit16hfname = hf_bit16eflags; + process_bitfield(ntree, tvb, &temp_values); + ioffset = ioffset+4; + break; + case 0x0000008: /* Subordinate Count */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_sub_count, tvb, ioffset, + 4, value1, "Subordinate Count %d", value1); + ioffset = ioffset + 4; + break; + case 0x0000010: /* Modification Time */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_es_seconds, tvb, ioffset, + 4, value1, "Modification Time in Seconds %d", value1); + ioffset = ioffset + 4; + break; + case 0x0000020: /* Modification Timestamp */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_es_seconds, tvb, ioffset, + 4, value1, "Modification Timestamp Seconds %d", value1); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + break; + case 0x0000040: /* Creation Timestamp */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_es_seconds, tvb, ioffset, + 4, value1, "Creation Timestamp Seconds %d", value1); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(ntree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(ntree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + break; + case 0x00000080: /* Partition Root ID */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_partition_root_id, tvb, ioffset, + 4, value1, "Partition Root ID %08x", value1); + ioffset = ioffset + 4; + break; + case 0x00000100: /* Parent ID */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_parent, tvb, ioffset, + 4, value1, "Parent ID %08x", value1); + ioffset = ioffset + 4; + break; + case 0x00000200: /* Revision Count */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_revision, tvb, ioffset, + 4, value1, "Revision Count %d", value1); + ioffset = ioffset + 4; + break; + case 0x00000400: /* Replica Type & State */ + value1 = tvb_get_letohl(tvb, ioffset); + value2 = value1 & 0x00ff; + temp_values.vstring = match_strval(value2, nds_replica_type); + if (temp_values.vstring == NULL) + { + temp_values.vstring = "No Replica Type Found"; + } + proto_tree_add_string(ntree, hf_replica_type, tvb, ioffset, + 4, temp_values.vstring); + value3 = value1 & 0xff00; + temp_values.vstring = match_strval(value3, nds_replica_state); + if (temp_values.vstring == NULL) + { + temp_values.vstring = "No Replica State Found"; + } + proto_tree_add_string(ntree, hf_replica_state, tvb, ioffset, + 4, temp_values.vstring); + ioffset = ioffset + 4; + break; + case 0x00000800: /* Base Class */ + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_base, tvb, ioffset, + value1, temp_values.vstring); + ioffset = ioffset + value1; + break; + case 0x00001000: /* Relative Distinguished Name */ + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_relative_dn, tvb, ioffset, + value1, temp_values.vstring); + ioffset = ioffset + value1; + break; + case 0x00002000: /* Distinguished Name */ + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_name, tvb, ioffset, + value1, temp_values.vstring); + ioffset = ioffset + value1; + break; + case 0x00004000: /* Root Distinguished Name */ + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_name, tvb, ioffset, + value1, temp_values.vstring); + ioffset = ioffset + value1; + break; + case 0x00008000: /* Parent Distinguished Name */ + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_name, tvb, ioffset, + value1, temp_values.vstring); + ioffset = ioffset + value1; + break; + case 0x00010000: /* Purge Time */ + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_purge, tvb, ioffset, + 4, value1, "Purge Time %d", value1); + ioffset = ioffset + 4; + break; + case 0x00020000: /* Dereference Base Class */ + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_deref_base, tvb, ioffset, + value1, temp_values.vstring); + ioffset = ioffset + value1; + break; + default: + break; + + } + ioffset += align_4(tvb, ioffset); + } + bvalue = bvalue*2; + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + } + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + } + break; + + case MVTYPE_CLASS_NAMES: /* Class Names */ + number_of_referrals = values->vvalue; + for (i = 0; i < number_of_referrals; i++) + { + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + sub1item = proto_tree_add_string(ntree, hf_nds_base_class, tvb, ioffset, + value1, temp_values.vstring); + sub1tree = proto_item_add_subtree(sub1item, ett_nds); + ioffset = ioffset + value1; + ioffset += align_4(tvb, ioffset); + if(values->vflags != 0) + { + temp_values.vvalue = tvb_get_letohl(tvb, ioffset); + temp_values.vtype = VTYPE_BITFIELD; + temp_values.vstring = mval_buf.buffer; + temp_values.vdesc = "Class Flags:"; + temp_values.vlength = 2; + temp_values.hfname= hf_nds_cflags; + temp_values.voffset = ioffset; + temp_values.bit1 = "Ambiguous Containment"; + temp_values.bit1hfname = hf_bit1cflags; + temp_values.bit2 = "Ambiguous Naming"; + temp_values.bit2hfname = hf_bit2cflags; + temp_values.bit3 = "Class Definition Cannot be Removed"; + temp_values.bit3hfname = hf_bit3cflags; + temp_values.bit4 = "Effective Class"; + temp_values.bit4hfname = hf_bit4cflags; + temp_values.bit5 = "Container Class"; + temp_values.bit5hfname = hf_bit5cflags; + temp_values.bit6 = "Not Defined"; + temp_values.bit6hfname = hf_bit6cflags; + temp_values.bit7 = "Not Defined"; + temp_values.bit7hfname = hf_bit7cflags; + temp_values.bit8 = "Not Defined"; + temp_values.bit8hfname = hf_bit8cflags; + temp_values.bit9 = "Not Defined"; + temp_values.bit9hfname = hf_bit9cflags; + temp_values.bit10 = "Not Defined"; + temp_values.bit10hfname = hf_bit10cflags; + temp_values.bit11 = "Not Defined"; + temp_values.bit11hfname = hf_bit11cflags; + temp_values.bit12 = "Not Defined"; + temp_values.bit12hfname = hf_bit12cflags; + temp_values.bit13 = "Not Defined"; + temp_values.bit13hfname = hf_bit13cflags; + temp_values.bit14 = "Not Defined"; + temp_values.bit14hfname = hf_bit14cflags; + temp_values.bit15 = "Not Defined"; + temp_values.bit15hfname = hf_bit15cflags; + temp_values.bit16 = "Not Defined"; + temp_values.bit16hfname = hf_bit16cflags; + process_bitfield(sub1tree, tvb, &temp_values); + ioffset = ioffset+4; + if(values->vflags != 5) + { + value1 = tvb_get_letohl(tvb, ioffset); /* length of field */ + length_remaining = tvb_length_remaining(tvb, ioffset); + if(length_remaining == -1 || value1 > (guint32) length_remaining) + { + break; + } + ioffset += 4; + proto_tree_add_bytes(sub1tree, hf_nds_asn1, tvb, ioffset, value1, tvb_get_ptr(tvb, ioffset, value1)); + ioffset += value1; + ioffset += (value1%2); + } + if(values->vflags == 1 || values->vflags == 2 || values->vflags == 4) + { + value1 = tvb_get_letohl(tvb, ioffset); /* Super Classes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Super Classes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_nds_super, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Containment Classes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Containment Classes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_nds_base_class, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Naming Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Naming Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Mandatory Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Mandatory Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Optional Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Optional Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + ioffset += align_4(tvb, ioffset); + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + } + } + /*if(values->vflags == 2 || values->vflags == 4)*/ /* Class Definitions of Super Classes */ + if(values->vflags == 4) /* Class Definitions of Super Classes */ + { + value1 = tvb_get_letohl(tvb, ioffset); /* Containment Classes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Containment Classes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_nds_base_class, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Naming Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Naming Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Mandatory Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Mandatory Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Optional Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Optional Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Default ACL */ + proto_tree_add_uint_format(sub1tree, hf_nds_eid, tvb, ioffset, + 4, value1, "Default ACL %08x", value1); + ioffset = ioffset + 4; + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + } + if(values->vflags == 5) /* Base Class Definitions */ + { + value1 = tvb_get_letohl(tvb, ioffset); /* Creation Timestamp */ + proto_tree_add_uint_format(sub1tree, hf_es_seconds, tvb, ioffset, + 4, value1, "Creation Timestamp Seconds %d", value1); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(sub1tree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(sub1tree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + value1 = tvb_get_letohl(tvb, ioffset); /* Modification Timestamp */ + proto_tree_add_uint_format(sub1tree, hf_es_seconds, tvb, ioffset, + 4, value1, "Modification Timestamp Seconds %d", value1); + ioffset = ioffset + 4; + replica_num = tvb_get_letohs(tvb, ioffset); /* Replica */ + proto_tree_add_item(sub1tree, hf_nds_replica_num, tvb, ioffset, + 2, replica_num); + ioffset = ioffset + 2; + event_num = tvb_get_letohs(tvb, ioffset); /* Event */ + proto_tree_add_item(sub1tree, hf_nds_event_num, tvb, ioffset, + 2, event_num); + ioffset = ioffset + 2; + /* Class Definition */ + value1 = tvb_get_letohl(tvb, ioffset); /* Super Classes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Super Classes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_nds_super, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Containment Classes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Containment Classes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_nds_base_class, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Naming Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Naming Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Mandatory Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Mandatory Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Optional Attributes */ + sub2item = proto_tree_add_uint_format(sub1tree, hf_nds_purge, tvb, ioffset, + 4, value1, "Optional Attributes %d", value1); + sub2tree = proto_item_add_subtree(sub2item, ett_nds); + ioffset = ioffset + 4; + for (r = 0; r < value1; r++) + { + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + temp_values.vstring = mval_buf.buffer; + proto_tree_add_string(sub2tree, hf_mv_string, tvb, ioffset, + value2, temp_values.vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + } + value1 = tvb_get_letohl(tvb, ioffset); /* Default ACL */ + proto_tree_add_uint_format(sub1tree, hf_nds_eid, tvb, ioffset, + 4, value1, "Default ACL %08x", value1); + ioffset = ioffset + 4; + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + } + } + } + break; + + case MVTYPE_MODIFY_CLASS: /* Modify Class */ + for (i = 1 ; i <= values->vvalue; i++ ) /* Attribute Names to add*/ + { + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value1, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value1, values->vstring); + ioffset = ioffset + value1; + } + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_att_del, tvb, ioffset, + 4, value1, "Attribute Names to Delete %d", value1); + ioffset = ioffset + 4; + for (i = 1 ; i <= value1; i++ ) /* Attribute Names to delete*/ + { + ioffset += align_4(tvb, ioffset); + value2 = tvb_get_letohl(tvb, ioffset); + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_mv_string, tvb, ioffset, + value2, values->vstring); + ioffset = ioffset + value2; + } + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_acl_add, tvb, ioffset, + 4, value1, "ACL Templates to Add %d", value1); + ioffset = ioffset + 4; + for (i = 1 ; i <= value1; i++ ) /* ACL templates to add*/ + { + ioffset += align_4(tvb, ioffset); + value2 = tvb_get_letohl(tvb, ioffset); /* Attribute Name */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_attribute_dn, tvb, ioffset, + value2, values->vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + value2 = tvb_get_letohl(tvb, ioffset); /* DN of Trustee */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_trustee_dn, tvb, ioffset, + value2, values->vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_privileges, tvb, ioffset, + 4, value1, "Priviledges 0x%08x", value1); + ioffset = ioffset + 4; + } + if(tvb_length_remaining(tvb, ioffset) < 4 ) + { + break; + } + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); + proto_tree_add_uint_format(ntree, hf_nds_acl_del, tvb, ioffset, + 4, value1, "ACL Templates to Delete %d", value1); + ioffset = ioffset + 4; + for (i = 1 ; i <= value1; i++ ) /* ACL templates to delete*/ + { + ioffset += align_4(tvb, ioffset); + value2 = tvb_get_letohl(tvb, ioffset); /* Attribute Name */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_attribute_dn, tvb, ioffset, + value2, values->vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + value2 = tvb_get_letohl(tvb, ioffset); /* DN of Trustee */ + ioffset = ioffset + 4; + get_string(tvb, ioffset, value2, mval_buf.buffer); + values->vstring = mval_buf.buffer; + proto_tree_add_string(ntree, hf_nds_trustee_dn, tvb, ioffset, + value2, values->vstring); + ioffset = ioffset + value2; + ioffset += align_4(tvb, ioffset); + value1 = tvb_get_letohl(tvb, ioffset); /* Priviledges */ + proto_tree_add_uint_format(ntree, hf_nds_privileges, tvb, ioffset, + 4, value1, "Priviledges 0x%08x", value1); + ioffset = ioffset + 4; + } + break; + default: + break; + } +} + +/* + * Defrag logic + * + * NDS fragment not being set to 0xffffffff indicates we are inside or at the + * beginning of a fragment. But when the end of the fragment + * is encounterd the flag is set to 0xffffffff. So we must mark what the + * frame number is of the end fragment so that we will be + * able to redissect if the user clicks on the packet + * or resorts/filters the trace. + * + * Once we are certain that we are in a fragment sequence + * then we can just process each fragment in this conversation + * until we reach the fragment == 0xffffffff packet. + * + * We will be able to easily determine if a conversation is a fragment + * with the exception of the last packet in the fragment. So remember + * the last fragment packet number. + * + * Also the NDS dissection requires the values of NDS Verb, Version, and Flags. + * Without this values being remembered from the first request packet then + * we will be unable to dissect the reply packet. For this reason we remember + * these values on the first fragment and then populate the values in the final + * fragment. We only do this on the first dissection. + * + * XXX - this has several problems: + * + * 1) it uses global variables ("frags"); + * + * 2) the sequence numbers don't start at a fixed value, they're + * per-connection sequence numbers; + * + * 3) the fragment size and handle aren't put into the protocol + * tree for fragments other than the last fragment. + * + * 2) needs to be fixed by having a way of doing defragmentation using + * connection sequence numbers; that's needed for fragmentation in + * connection-oriented protocols, e.g. COTP, as well. + * That might let us fix 1) as well. + * + * 3) should be fixed by putting that into the protocol tree ourselves + * if this isn't the first fragment. +*/ +void +nds_defrag(tvbuff_t *tvb, packet_info *pinfo, guint16 nw_connection, guint8 sequence, guint16 type, proto_tree *tree) +{ + int i, frag_count=0; + guint len=0; + guint32 tid = 1; + tvbuff_t *frag_tvb = NULL; + fragment_data *fd_head; + ncp_req_hash_value *request_value = NULL; + conversation_t *conversation; + guint32 nds_frag; + + for (i = 0; i < 9; i++) { + if (!frags[i].nds_fragmented) + { + frags[i].nds_frag = 0xfffffff0; + } + } + /* Check to see if defragmentation is enabeled in the dissector */ + if (!nds_defragment) { + dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree); + return; + } + /* Has this already been dissected? */ + if (!pinfo->fd->flags.visited) { + /* Find the conversation whence the request would have come. */ + conversation = find_conversation(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + if (conversation != NULL) { + /* find the record telling us the request made that caused + this reply */ + request_value = ncp_hash_lookup(conversation, sequence); + if (!request_value) { + dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree); + return; + } + p_add_proto_data(pinfo->fd, proto_ncp, (void*) request_value); + } + /* else... we haven't seen an NCP Request for that conversation and sequence. */ + else + { + dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree); + return; + } + } + else { + request_value = p_get_proto_data(pinfo->fd, proto_ncp); + if (!request_value) { + dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree); + return; + } + } + /* Validate that this is an NDS packet */ + /* If this isn't an NDS packet then just return */ + if (!request_value->ncp_rec || + request_value->ncp_rec->func!=104 || request_value->ncp_rec->subfunc!=2) { + dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree); + return; + } + /* Get the fragment flag */ + nds_frag = tvb_get_letohl(tvb, 12); + + /* Now we need to find if this is a new fragment or already one defined. */ + /* We currently limit the maximum number of simultaneous fragments to 100. */ + for (i=0; i<100; i++) + { + if (frags[i].nds_frag == nds_frag || frags[i].nds_frag == 0xfffffff0) + { + if (frags[i].nds_frag == 0xfffffff0) + { + frags[i].nds_length = 0; + frags[i].nds_frag = nds_frag; + frags[i].nds_fragmented = TRUE; + } + break; + } + } + frag_count = i; + + /* is this the end of an existing fragment or just another reply */ + if (nds_frag == 0xffffffff && request_value->nds_frag_num == 0xffffffff) + { + dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree); + return; + } + + /* Now we process the fragments */ + if (request_value->nds_frag || (request_value->nds_end_frag == pinfo->fd->num)) + { + /* Check to see of this is a fragment. If so then mark as a fragment. */ + if (frags[frag_count].nds_frag==0xffffffff) { + request_value->nds_frag = FALSE; + /* nds_length of 0 means start of fragment */ + frags[frag_count].nds_length = 0; + } + else + { + if (frags[frag_count].nds_length == 0) + { + frags[frag_count].nds_length = tvb_get_letohl(tvb, 0); + } + } + /* + * Fragment + * + */ + tid = (pinfo->srcport+pinfo->destport); + len = tvb_reported_length(tvb); + if (len > 0 && tvb_bytes_exist(tvb, 0, len)) + { + if (frags[frag_count].nds_length > len) + { + /* This is the first fragment so remember the verb, version, and flags. */ + frags[frag_count].nds_frag_verb = request_value->nds_request_verb; + frags[frag_count].nds_frag_version = request_value->nds_version; + frags[frag_count].nds_frag_flags = request_value->req_nds_flags; + fd_head = fragment_add_seq_next(tvb, 0, pinfo, tid, nds_fragment_table, nds_reassembled_table, len, request_value->nds_frag); + frags[frag_count].nds_length = 1; + } + else + { + /* Subsequent fragments should be offset by 16 since we do not need */ + /* the additional fragment handle and size fields in our composite data */ + fd_head = fragment_add_seq_next(tvb, 16, pinfo, tid, nds_fragment_table, nds_reassembled_table, len-16, request_value->nds_frag); + } + if (fd_head != NULL) + { + /* Is this the last fragment? nds_frag will indicate */ + if (fd_head->next != NULL && !request_value->nds_frag) + { + frag_tvb = tvb_new_real_data(fd_head->data, + fd_head->len, fd_head->len); + tvb_set_child_real_data_tvbuff(tvb, + frag_tvb); + add_new_data_source(pinfo, + frag_tvb, + "Reassembled NDS"); + /* Show all fragments. */ + if (tree) + { + show_fragment_seq_tree(fd_head, + &nds_frag_items, + tree, pinfo, + frag_tvb); + tid++; + } + + if (!pinfo->fd->flags.visited) + { + /* Now we need to find the original fragment number. */ + /* Get the fragment flag */ + nds_frag = tvb_get_letohl(frag_tvb, 12); + for (i=0; i<100; i++) + { + if (frags[i].nds_frag == nds_frag) + { + break; + } + } + if (frags[i].nds_frag == 0xffffffff) + { + /* Error can't find fragment */ + /*g_assert(0);*/ + } + frag_count = i; + /* Remember this fragment information so we can dissect. + * Only do this on the first dissection. After the first + * dissection we will just read the memory values. + */ + request_value->nds_end_frag = pinfo->fd->num; + request_value->nds_request_verb = frags[frag_count].nds_frag_verb; + request_value->nds_version = frags[frag_count].nds_frag_version; + request_value->req_nds_flags = frags[frag_count].nds_frag_flags; + } + + } + else + { + /* This is either a beggining or middle fragment on second dissection */ + frag_tvb = tvb_new_subset(tvb, 0, -1, -1); + if (check_col(pinfo->cinfo, COL_INFO)) + { + if (request_value->nds_frag) + { + col_add_fstr(pinfo->cinfo, COL_INFO, "[NDS Fragment %08x]", frags[frag_count].nds_frag); + } + } + } + } + else + { + /* Fragment from first pass of dissection */ + if (check_col(pinfo->cinfo, COL_INFO)) + { + if (request_value->nds_frag) + { + col_add_fstr(pinfo->cinfo, COL_INFO, "[NDS Fragment %08x]", frags[frag_count].nds_frag); + } + } + frag_tvb = NULL; + } + } + else + { + /* + * There are no bytes so Dissect this + */ + frag_tvb = tvb_new_subset(tvb, 0, -1, -1); + } + if (frag_tvb == NULL) + { + /* This is a fragment packet */ + frag_tvb = tvb_new_subset (tvb, 0, -1, -1); + nds_data_handle = find_dissector("data"); + call_dissector(nds_data_handle, frag_tvb, pinfo, tree); + } + else + { + /* This is the end fragment so dissect */ + if (!request_value->nds_frag) { + frags[frag_count].nds_length = 0; + dissect_ncp_reply(frag_tvb, pinfo, nw_connection, sequence, type, tree); + } + } + } + else + { + /* This is not any fragment packet */ + frags[frag_count].nds_length = 0; + request_value->nds_frag = FALSE; + dissect_ncp_reply(tvb, pinfo, nw_connection, sequence, type, tree); + } +} + +void +dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo, + guint16 nw_connection, guint8 sequence, + guint16 type, proto_tree *ncp_tree) +{ + guint8 func, subfunc = 0; + gboolean requires_subfunc = FALSE; + gboolean has_length = FALSE; + ncp_req_hash_value *request_value = NULL; + const ncp_record *ncp_rec = NULL; + conversation_t *conversation; + ptvcursor_t *ptvc = NULL; + proto_tree *temp_tree = NULL; + gboolean run_req_cond = FALSE; + gboolean run_info_str = FALSE; + guint32 length_remaining; + guint32 testvar; + + func = tvb_get_guint8(tvb, 6); + + /* Determine which ncp_record to use. */ + switch (type) { + case NCP_ALLOCATE_SLOT: + length_remaining = tvb_length_remaining(tvb, 4); + if (length_remaining > 4) + { + testvar = tvb_get_ntohl(tvb, 4); + if( testvar == 0x4c495020) + { + ncp_rec = &ncplip_echo; + } + else + { + ncp_rec = &ncp1111_request; + } + } + else + { + ncp_rec = &ncp1111_request; + } + break; + case NCP_SERVICE_REQUEST: + requires_subfunc = ncp_requires_subfunc(func); + has_length = ncp_has_length_parameter(func); + if (requires_subfunc) { + if (has_length) { + subfunc = tvb_get_guint8(tvb, 9); + } + else { + subfunc = tvb_get_guint8(tvb, 7); + } + } + ncp_rec = ncp_record_find(func, subfunc); + break; + case NCP_DEALLOCATE_SLOT: + ncp_rec = &ncp5555_request; + break; + case NCP_BROADCAST_SLOT: + ncp_rec = &ncpbbbb_request; + break; + case NCP_LIP_ECHO: + ncp_rec = &ncplip_echo; + break; + default: + ncp_rec = NULL; + break; + } + + /* Fill in the INFO column. */ + if (check_col(pinfo->cinfo, COL_INFO)) { + if (ncp_rec) { + col_add_fstr(pinfo->cinfo, COL_INFO, "C %s", ncp_rec->name); + if (ncp_rec->req_info_str) { + /* We want to add more stuff to the Info + column. */ + run_info_str = TRUE; + } + } + else { + if (requires_subfunc) { + col_add_fstr(pinfo->cinfo, COL_INFO, + "C Unknown Function %u %u (0x%02X/0x%02x)", + func, subfunc, func, subfunc); + } + else { + col_add_fstr(pinfo->cinfo, COL_INFO, + "C Unknown Function %u (0x%02x)", + func, func); + } + } + } + + if (!pinfo->fd->flags.visited) { + /* This is the first time we've looked at this packet. + Keep track of the address and connection whence the request + came, and the address and connection to which the request + is being sent, so that we can match up calls with replies. + (We don't include the sequence number, as we may want + to have all packets over the same connection treated + as being part of a single conversation so that we can + let the user select that conversation to be displayed.) */ + conversation = find_conversation(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + + if (conversation == NULL) { + /* It's not part of any conversation - create a new one. */ + conversation = conversation_new(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + } + request_value = ncp_hash_insert(conversation, sequence, ncp_rec); + request_value->req_frame_num = pinfo->fd->num; + request_value->req_frame_time.secs=pinfo->fd->abs_secs; + request_value->req_frame_time.nsecs=pinfo->fd->abs_usecs*1000; + + /* If this is the first time we're examining the packet, + * check to see if this NCP type uses a "request condition". + * If so, we have to build a proto_tree because request conditions + * use display filters to work, and without a proto_tree, + * display filters can't possibly work. */ + if (ncp_rec) { + if (ncp_rec->req_cond_indexes) { + run_req_cond = TRUE; + } + } + } + + /* If we have to handle a request condition, or have to + add to the Info column, we need to construct a protocol + tree. If we already have a proto_tree, then wonderful. + If we don't, we need to build one. */ + if ((run_info_str || run_req_cond) && !ncp_tree) { + proto_item *ti; + + temp_tree = proto_tree_create_root(); + proto_tree_set_visible(temp_tree, FALSE); + ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE); + ncp_tree = proto_item_add_subtree(ti, ett_ncp); + } + + if (ncp_tree) { + /* If the dissection throws an exception, be sure to free + * the temporary proto_tree that was created. Because of the + * way the CLEANUP_PUSH macro works, we can't put it in an 'if' + * block; it has to be in the same scope as the terminating + * CLEANUP_POP or CLEANUP_POP_AND_ALLOC. So, we always + * call CLEANUP_POP and friends, but the value of temp_tree is + * NULL if no cleanup is needed, and non-null if cleanup is needed. */ + CLEANUP_PUSH(free_proto_tree, temp_tree); + + /* Before the dissection, if we're saving data for a request + * condition, we have to prime the proto tree using the + * dfilter information */ + if (run_req_cond) { + const int *needed; + dfilter_t *dfilter; + + needed = ncp_rec->req_cond_indexes; + + while (*needed != -1) { + dfilter = req_conds[*needed].dfilter; + /* Prime the proto_tree with "interesting fields". */ + dfilter_prime_proto_tree(dfilter, ncp_tree); + needed++; + } + } + + /* Before the dissection, if we need a field for the info_str, + * prime the tree. */ + if (run_info_str) { + proto_tree_prime_hfid(ncp_tree, *ncp_rec->req_info_str->hf_ptr); + } + + switch (type) { + case NCP_BROADCAST_SLOT: + ; /* nothing */ + break; + + case NCP_SERVICE_REQUEST: + proto_tree_add_uint_format(ncp_tree, hf_ncp_func, tvb, 6, 1, + func, "Function: %u (0x%02X), %s", + func, func, ncp_rec ? ncp_rec->name : "Unknown"); + break; + + default: + ; /* nothing */ + break; + } + + if (requires_subfunc) { + if (has_length) { + proto_tree_add_item(ncp_tree, hf_ncp_length, tvb, 7, + 2, FALSE); + proto_tree_add_uint_format(ncp_tree, hf_ncp_subfunc, tvb, 9, 1, + subfunc, "SubFunction: %u (0x%02x)", + subfunc, subfunc); + ptvc = ptvcursor_new(ncp_tree, tvb, 10); + } + else { + proto_tree_add_uint_format(ncp_tree, hf_ncp_subfunc, tvb, 7, 1, + subfunc, "SubFunction: %u (0x%02x)", + subfunc, subfunc); + ptvc = ptvcursor_new(ncp_tree, tvb, 8); + } + } + else { + ptvc = ptvcursor_new(ncp_tree, tvb, 7); + } + + /* The group is not part of the packet, but it's useful + * information to display anyway. */ + if (ncp_rec) { + proto_tree_add_text(ncp_tree, tvb, 0, 0, "Group: %s", + ncp_groups[ncp_rec->group]); + } + + if (ncp_rec && ncp_rec->request_ptvc) { + clear_repeat_vars(); + process_ptvc_record(ptvc, ncp_rec->request_ptvc, NULL, TRUE, ncp_rec); + } + ptvcursor_free(ptvc); + /* NMAS packets are dessected in packet-ncp-nmas.c */ + if (func == 0x5e && ncp_tree) { + dissect_nmas_request(tvb, pinfo, ncp_tree, request_value); + } + + /* Now that the dissection is done, do we need to run + * some display filters on the resulting tree in order + * to save results for "request conditions" ? */ + if (run_req_cond) { + const int *needed; + gboolean *results; + dfilter_t *dfilter; + + results = g_new0(gboolean, NUM_REQ_CONDS); + needed = ncp_rec->req_cond_indexes; + + while (*needed != -1) { + /* ncp_tree is not a root proto_tree, but + * dfilters will still work on it. */ + dfilter = req_conds[*needed].dfilter; + results[*needed] = dfilter_apply(dfilter, ncp_tree); + needed++; + } + + /* Save the results so the reply packet dissection + * get to them. */ + request_value->req_cond_results = results; + } + /* Construct the info string if necessary */ + if (run_info_str) { + GPtrArray *parray; + char* byte_string; + char non_uni_string[1024]; + int i, len; + field_info *finfo; + int info_type; + + if (!request_value) + { + conversation = find_conversation(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + if (conversation != NULL) { + /* find the record telling us the request made that caused + this reply */ + request_value = ncp_hash_lookup(conversation, sequence); + } + if (!conversation || !request_value) + { + return; + } + } + + parray = proto_get_finfo_ptr_array(ncp_tree, + *ncp_rec->req_info_str->hf_ptr); + len = g_ptr_array_len(parray); + + if (len > 0) { + + col_set_str(pinfo->cinfo, COL_INFO, "C "); + + finfo = g_ptr_array_index(parray, 0); + + info_type = get_info_type((const gchar*) ncp_rec->req_info_str->first_string); + + if (info_type != 0) { /* Is this a string or not? */ + + if (info_type == 1) { /* Is this bytes? */ + byte_string = bytes_to_str(fvalue_get(&finfo->value), fvalue_length(&finfo->value)); + col_append_fstr(pinfo->cinfo, COL_INFO, + (const gchar*) ncp_rec->req_info_str->first_string, + byte_string); + } + else + { + if (info_type == 2) { /* Is this a String? */ + uni_to_string(fvalue_get(&finfo->value), fvalue_length(&finfo->value), non_uni_string); + col_append_fstr(pinfo->cinfo, COL_INFO, + (const gchar*) ncp_rec->req_info_str->first_string, + non_uni_string); + } + else + { + col_append_fstr(pinfo->cinfo, COL_INFO, + (const gchar*) ncp_rec->req_info_str->first_string, + fvalue_get(&finfo->value)); + } + } + } + else + { + col_append_fstr(pinfo->cinfo, COL_INFO, + (const gchar*) ncp_rec->req_info_str->first_string, + fvalue_get_integer(&finfo->value)); + } + } + if (len > 1) { + for (i = 1; i < len; i++) { + non_uni_string[0]='\0'; + finfo = g_ptr_array_index(parray, i); + info_type = get_info_type((const gchar*) ncp_rec->req_info_str->repeat_string); + + if (info_type != 0) { /* Is this a string or not? */ + if (info_type == 1) + { /* Is this bytes? */ + byte_string = bytes_to_str(fvalue_get(&finfo->value), fvalue_length(&finfo->value)); + col_append_fstr(pinfo->cinfo, COL_INFO, + (const gchar*) ncp_rec->req_info_str->repeat_string, + byte_string); + } + else + { + if (info_type == 2) { /* Is this a String? */ + uni_to_string(fvalue_get(&finfo->value), fvalue_length(&finfo->value), non_uni_string); + col_append_fstr(pinfo->cinfo, COL_INFO, + (const gchar*) ncp_rec->req_info_str->repeat_string, + non_uni_string); + } + else + { + col_append_fstr(pinfo->cinfo, COL_INFO, + (const gchar*) ncp_rec->req_info_str->repeat_string, + fvalue_get(&finfo->value)); + } + } + } + else + { + col_append_fstr(pinfo->cinfo, COL_INFO, + (const gchar*) ncp_rec->req_info_str->repeat_string, + fvalue_get_integer(&finfo->value)); + } + } + } + } + + /* Free the temporary proto_tree */ + CLEANUP_CALL_AND_POP; + } +} + + +void +dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo, + guint16 nw_connection, guint8 sequence, guint16 type, + proto_tree *ncp_tree) +{ + conversation_t *conversation = NULL; + ncp_req_hash_value *request_value = NULL; + ncp_req_eid_hash_value *request_eid_value = NULL; + const ncp_record *ncp_rec = NULL; + int *req_cond_results; + guint8 completion_code=0; + guint length; + ptvcursor_t *ptvc = NULL; + const char *error_string; + guint32 nds_string_len = 0; + guint8 ping_version = 0; + guint32 nds_flags = 0; + guint32 nds_offset = 0; + nw_uni_t reply_buffer; + char * verb_string=""; + guint32 nds_error_code = 0; + guint32 nds_reply_buffer = 0; + char * nds_error_string = NULL; + guint32 nds_frag=0; + nds_val pvalues[9]; + char string_buffer[9][1024]; + gboolean resolve_eid=FALSE; + guint32 global_eid=0; + gboolean add_eid = FALSE; + char global_object_name[256]; + int i; + guint32 bvalue=0; + + strcpy(reply_buffer.buffer, ""); + strcpy(global_object_name, ""); + + if (!pinfo->fd->flags.visited) { + /* Find the conversation whence the request would have come. */ + conversation = find_conversation(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + if (conversation != NULL) { + /* find the record telling us the request made that caused + this reply */ + request_value = ncp_hash_lookup(conversation, sequence); + if (request_value) { + ncp_rec = request_value->ncp_rec; + } + p_add_proto_data(pinfo->fd, proto_ncp, (void*) request_value); + } + /* else... we haven't seen an NCP Request for that conversation and sequence. */ + } + else { + request_value = p_get_proto_data(pinfo->fd, proto_ncp); + if (request_value) { + ncp_rec = request_value->ncp_rec; + } + } + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) { + if (ncp_rec && ncp_rec->func==0x68 && + (ncp_rec->subfunc==0x02 || ncp_rec->subfunc==0x01)) { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDS"); + } + } + + /* A completion code of 0 always means OK. Non-zero means failure, + * but each non-zero value has a different meaning. And the same value + * can have different meanings, depending on the ncp.func (and ncp.subfunc) + * value. */ + completion_code = tvb_get_guint8(tvb, 6); + if (completion_code == 0) { + + if(type == NCP_POSITIVE_ACK) + { + error_string = "Server Busy, Request Being Processed"; + } + else + { + error_string = "OK"; + } + } else { + if (ncp_rec && ncp_rec->errors) { + error_string = ncp_error_string(ncp_rec->errors, completion_code); + } + else { + error_string = "Original Request Packet not Found"; + } + } + if (type == NCP_SERVICE_REPLY && ncp_rec && ncp_rec->func==0x68 && + ncp_rec->subfunc==0x02) + { + nds_offset = 8; + nds_reply_buffer = tvb_get_letohl(tvb, nds_offset); + nds_offset += 4; + nds_frag = tvb_get_letohl(tvb, nds_offset); + if (nds_reply_buffer > 7) + { + nds_offset += 4; + nds_error_code = tvb_get_letohl(tvb, nds_offset); + nds_error_string = match_strval(nds_error_code, nds_reply_errors); + if (nds_error_string == NULL) + { + nds_error_string = "NDS Error - No Definition Found"; + } + if (nds_error_string == NULL || nds_error_code == 0x00000000) + { + nds_error_string = "Ok"; + } + } + } + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", + type == NCP_SERVICE_REPLY ? "R" : "ACK", + nds_error_string ? nds_error_string : error_string); + } + + if (ncp_tree) { + if (request_value) { + nstime_t ns; + + proto_tree_add_uint(ncp_tree, hf_ncp_req_frame_num, tvb, 0, 0, + request_value->req_frame_num); + ns.secs=pinfo->fd->abs_secs-request_value->req_frame_time.secs; + ns.nsecs=pinfo->fd->abs_usecs*1000-request_value->req_frame_time.nsecs; + if(ns.nsecs<0){ + ns.nsecs+=1000000000; + ns.secs--; + } + proto_tree_add_time(ncp_tree, hf_ncp_req_frame_time, tvb, 0, 0, &ns); + + } + + /* Put the func (and maybe subfunc) from the request packet + * in the proto tree, but hidden. That way filters on ncp.func + * or ncp.subfunc will find both the requests and the replies. + */ + if (ncp_rec) { + proto_tree_add_uint_format(ncp_tree, hf_ncp_func, tvb, 6, 0, + ncp_rec->func, "Function: %u (0x%02X), %s", + ncp_rec->func, ncp_rec->func, ncp_rec->name); + if (ncp_requires_subfunc(ncp_rec->func)) { + proto_tree_add_uint_format(ncp_tree, hf_ncp_subfunc, tvb, 6, 0, + ncp_rec->subfunc, "SubFunction: %u (0x%02x)", + ncp_rec->subfunc, ncp_rec->subfunc); + } + } + + proto_tree_add_uint_format(ncp_tree, hf_ncp_completion_code, tvb, 6, 1, + completion_code, "Completion Code: %d (0x%02x), %s", + completion_code, completion_code, error_string); + + proto_tree_add_item(ncp_tree, hf_ncp_connection_status, tvb, 7, 1, FALSE); + + /* + * Unless this is a reply, that's all there is to parse. + */ + if (type != NCP_SERVICE_REPLY) + return; + + /* Decode NDS Reply packets */ + if (ncp_rec) { + /* Dissect NMAS Reply packets */ + if (ncp_rec->func == 0x5e && request_value) + { + dissect_nmas_reply(tvb, pinfo, ncp_tree, ncp_rec->func, ncp_rec->subfunc, request_value); + } + if ((ncp_rec->func == 0x68 && ncp_rec->subfunc == 0x01) && completion_code == 0) { + ping_version = tvb_get_guint8(tvb, 8); + proto_tree_add_item(ncp_tree, hf_ping_version, tvb, 8, 1, TRUE); + if (ping_version == 9) { + nds_string_len = tvb_get_ntohl(tvb, 9); + nds_offset = nds_string_len+16; + proto_tree_add_item(ncp_tree, hf_nds_tree_name, tvb, 16, nds_string_len, FALSE); + proto_tree_add_item(ncp_tree, hf_nds_reply_depth, tvb, nds_offset, 4, FALSE); + proto_tree_add_item(ncp_tree, hf_nds_reply_rev, tvb, (nds_offset+4), 4, FALSE); + proto_tree_add_item(ncp_tree, hf_nds_reply_flags, tvb, (nds_offset+8), 4, TRUE); + } + else { + nds_offset = 12; + nds_flags = request_value->req_nds_flags; + bvalue = 0x00000001; + + for (i = 0 ; i < 32; i++ ) { + if (nds_flags & bvalue) + { + switch(bvalue) + { + case 0x00000001: /* Supported Fields */ + pvalues[0].vvalue = tvb_get_letohs(tvb, nds_offset); + pvalues[0].vtype = VTYPE_BITFIELD; + pvalues[0].vstring = ""; + pvalues[0].vdesc = "Ping (low) Supported Fields:"; + pvalues[0].vlength = 2; + pvalues[0].hfname= hf_nds_rflags; + pvalues[0].voffset = nds_offset; + pvalues[0].bit1 = "Supported Fields"; + pvalues[0].bit1hfname = hf_bit1pingflags1; + pvalues[0].bit2 = "Depth"; + pvalues[0].bit2hfname = hf_bit2pingflags1; + pvalues[0].bit3 = "Revision"; + pvalues[0].bit3hfname = hf_bit3pingflags1; + pvalues[0].bit4 = "Flags"; + pvalues[0].bit4hfname = hf_bit4pingflags1; + pvalues[0].bit5 = "Verification Flags"; + pvalues[0].bit5hfname = hf_bit5pingflags1; + pvalues[0].bit6 = "Letter Version"; + pvalues[0].bit6hfname = hf_bit6pingflags1; + pvalues[0].bit7 = "OS Version"; + pvalues[0].bit7hfname = hf_bit7pingflags1; + pvalues[0].bit8 = "License Flags"; + pvalues[0].bit8hfname = hf_bit8pingflags1; + pvalues[0].bit9 = "DS Time"; + pvalues[0].bit9hfname = hf_bit9pingflags1; + pvalues[0].bit10 = "Not Defined"; + pvalues[0].bit10hfname = hf_bit10pingflags1; + pvalues[0].bit11 = "Not Defined"; + pvalues[0].bit11hfname = hf_bit11pingflags1; + pvalues[0].bit12 = "Not Defined"; + pvalues[0].bit12hfname = hf_bit12pingflags1; + pvalues[0].bit13 = "Not Defined"; + pvalues[0].bit13hfname = hf_bit13pingflags1; + pvalues[0].bit14 = "Not Defined"; + pvalues[0].bit14hfname = hf_bit14pingflags1; + pvalues[0].bit15 = "Not Defined"; + pvalues[0].bit15hfname = hf_bit15pingflags1; + pvalues[0].bit16 = "Not Defined"; + pvalues[0].bit16hfname = hf_bit16pingflags1; + + process_bitfield(ncp_tree, tvb, &pvalues[0]); + nds_offset += 2; + + pvalues[0].vvalue = tvb_get_letohs(tvb, nds_offset); + pvalues[0].vtype = VTYPE_BITFIELD; + pvalues[0].vstring = ""; + pvalues[0].vdesc = "Ping (high) Supported Fields:"; + pvalues[0].vlength = 2; + pvalues[0].hfname= hf_nds_rflags; + pvalues[0].voffset = nds_offset; + pvalues[0].bit1 = "Sap Name"; + pvalues[0].bit1hfname = hf_bit1pingflags2; + pvalues[0].bit2 = "Tree Name"; + pvalues[0].bit2hfname = hf_bit2pingflags2; + pvalues[0].bit3 = "OS Name"; + pvalues[0].bit3hfname = hf_bit3pingflags2; + pvalues[0].bit4 = "Hardware Name"; + pvalues[0].bit4hfname = hf_bit4pingflags2; + pvalues[0].bit5 = "Vendor Name"; + pvalues[0].bit5hfname = hf_bit5pingflags2; + pvalues[0].bit6 = "Not Defined"; + pvalues[0].bit6hfname = hf_bit6pingflags2; + pvalues[0].bit7 = "Not Defined"; + pvalues[0].bit7hfname = hf_bit7pingflags2; + pvalues[0].bit8 = "Not Defined"; + pvalues[0].bit8hfname = hf_bit8pingflags2; + pvalues[0].bit9 = "Not Defined"; + pvalues[0].bit9hfname = hf_bit9pingflags2; + pvalues[0].bit10 = "Not Defined"; + pvalues[0].bit10hfname = hf_bit10pingflags2; + pvalues[0].bit11 = "Not Defined"; + pvalues[0].bit11hfname = hf_bit11pingflags2; + pvalues[0].bit12 = "Not Defined"; + pvalues[0].bit12hfname = hf_bit12pingflags2; + pvalues[0].bit13 = "Not Defined"; + pvalues[0].bit13hfname = hf_bit13pingflags2; + pvalues[0].bit14 = "Not Defined"; + pvalues[0].bit14hfname = hf_bit14pingflags2; + pvalues[0].bit15 = "Not Defined"; + pvalues[0].bit15hfname = hf_bit15pingflags2; + pvalues[0].bit16 = "Not Defined"; + pvalues[0].bit16hfname = hf_bit16pingflags2; + + process_bitfield(ncp_tree, tvb, &pvalues[0]); + nds_offset += 2; + break; + case 0x00000002: + proto_tree_add_item(ncp_tree, hf_nds_reply_depth, tvb, nds_offset, 4, TRUE); + nds_offset += 4; + break; + case 0x00000004: + proto_tree_add_item(ncp_tree, hf_nds_reply_rev, tvb, nds_offset, 4, TRUE); + nds_offset += 4; + break; + case 0x00000008: + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_BITFIELD; + pvalues[0].vstring = ""; + pvalues[0].vdesc = "Ping Flags:"; + pvalues[0].vlength = 4; + pvalues[0].hfname= hf_nds_rflags; + pvalues[0].voffset = nds_offset; + pvalues[0].bit1 = "Root Most Master Replica"; + pvalues[0].bit1hfname = hf_bit1pingpflags1; + pvalues[0].bit2 = "Time Synchronized"; + pvalues[0].bit2hfname = hf_bit2pingpflags1; + pvalues[0].bit3 = "Not Defined"; + pvalues[0].bit3hfname = hf_bit3pingpflags1; + pvalues[0].bit4 = "Not Defined"; + pvalues[0].bit4hfname = hf_bit4pingpflags1; + pvalues[0].bit5 = "Not Defined"; + pvalues[0].bit5hfname = hf_bit5pingpflags1; + pvalues[0].bit6 = "Not Defined"; + pvalues[0].bit6hfname = hf_bit6pingpflags1; + pvalues[0].bit7 = "Not Defined"; + pvalues[0].bit7hfname = hf_bit7pingpflags1; + pvalues[0].bit8 = "Not Defined"; + pvalues[0].bit8hfname = hf_bit8pingpflags1; + pvalues[0].bit9 = "Not Defined"; + pvalues[0].bit9hfname = hf_bit9pingpflags1; + pvalues[0].bit10 = "Not Defined"; + pvalues[0].bit10hfname = hf_bit10pingpflags1; + pvalues[0].bit11 = "Not Defined"; + pvalues[0].bit11hfname = hf_bit11pingpflags1; + pvalues[0].bit12 = "Not Defined"; + pvalues[0].bit12hfname = hf_bit12pingpflags1; + pvalues[0].bit13 = "Not Defined"; + pvalues[0].bit13hfname = hf_bit13pingpflags1; + pvalues[0].bit14 = "Not Defined"; + pvalues[0].bit14hfname = hf_bit14pingpflags1; + pvalues[0].bit15 = "Not Defined"; + pvalues[0].bit15hfname = hf_bit15pingpflags1; + pvalues[0].bit16 = "Not Defined"; + pvalues[0].bit16hfname = hf_bit16pingpflags1; + + process_bitfield(ncp_tree, tvb, &pvalues[0]); + nds_offset += 4; + break; + case 0x00000010: + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_BITFIELD; + pvalues[0].vstring = ""; + pvalues[0].vdesc = "Verification Flags:"; + pvalues[0].vlength = 4; + pvalues[0].hfname= hf_nds_rflags; + pvalues[0].voffset = nds_offset; + pvalues[0].bit1 = "Checksum"; + pvalues[0].bit1hfname = hf_bit1pingvflags1; + pvalues[0].bit2 = "CRC32"; + pvalues[0].bit2hfname = hf_bit2pingvflags1; + pvalues[0].bit3 = "Not Defined"; + pvalues[0].bit3hfname = hf_bit3pingvflags1; + pvalues[0].bit4 = "Not Defined"; + pvalues[0].bit4hfname = hf_bit4pingvflags1; + pvalues[0].bit5 = "Not Defined"; + pvalues[0].bit5hfname = hf_bit5pingvflags1; + pvalues[0].bit6 = "Not Defined"; + pvalues[0].bit6hfname = hf_bit6pingvflags1; + pvalues[0].bit7 = "Not Defined"; + pvalues[0].bit7hfname = hf_bit7pingvflags1; + pvalues[0].bit8 = "Not Defined"; + pvalues[0].bit8hfname = hf_bit8pingvflags1; + pvalues[0].bit9 = "Not Defined"; + pvalues[0].bit9hfname = hf_bit9pingvflags1; + pvalues[0].bit10 = "Not Defined"; + pvalues[0].bit10hfname = hf_bit10pingvflags1; + pvalues[0].bit11 = "Not Defined"; + pvalues[0].bit11hfname = hf_bit11pingvflags1; + pvalues[0].bit12 = "Not Defined"; + pvalues[0].bit12hfname = hf_bit12pingvflags1; + pvalues[0].bit13 = "Not Defined"; + pvalues[0].bit13hfname = hf_bit13pingvflags1; + pvalues[0].bit14 = "Not Defined"; + pvalues[0].bit14hfname = hf_bit14pingvflags1; + pvalues[0].bit15 = "Not Defined"; + pvalues[0].bit15hfname = hf_bit15pingvflags1; + pvalues[0].bit16 = "Not Defined"; + pvalues[0].bit16hfname = hf_bit16pingvflags1; + + process_bitfield(ncp_tree, tvb, &pvalues[0]); + nds_offset += 4; + break; + case 0x00000020: + proto_tree_add_item(ncp_tree, hf_nds_letter_ver, tvb, nds_offset, 4, TRUE); + nds_offset += 4; + break; + case 0x00000040: + proto_tree_add_item(ncp_tree, hf_nds_os_ver, tvb, nds_offset, 4, TRUE); + nds_offset += 4; + break; + case 0x00000080: + proto_tree_add_item(ncp_tree, hf_nds_lic_flags, tvb, nds_offset, 4, TRUE); + nds_offset += 4; + break; + case 0x00000100: + proto_tree_add_item(ncp_tree, hf_nds_ds_time, tvb, nds_offset, 4, TRUE); + nds_offset += 4; + break; + case 0x00010000: + nds_string_len = tvb_get_letohl(tvb, nds_offset); + nds_offset += 4; + get_string(tvb, nds_offset, nds_string_len, reply_buffer.buffer); + proto_tree_add_text(ncp_tree, tvb, nds_offset, nds_string_len, "SAP Name: %s", reply_buffer.buffer); + nds_offset += nds_string_len; + nds_offset += align_4(tvb, nds_offset); + nds_offset += 2; + break; + case 0x00020000: + nds_string_len = tvb_get_letohl(tvb, nds_offset); + nds_offset += 4; + get_string(tvb, nds_offset, nds_string_len, reply_buffer.buffer); + proto_tree_add_text(ncp_tree, tvb, nds_offset, nds_string_len, "NDS Tree Name: %s", reply_buffer.buffer); + nds_offset += nds_string_len; + nds_offset += align_4(tvb, nds_offset); + break; + case 0x00040000: + nds_string_len = tvb_get_letohl(tvb, nds_offset); + nds_offset += 4; + get_string(tvb, nds_offset, nds_string_len, reply_buffer.buffer); + proto_tree_add_text(ncp_tree, tvb, nds_offset, nds_string_len, "OS Name: %s", reply_buffer.buffer); + nds_offset += nds_string_len; + nds_offset += align_4(tvb, nds_offset); + break; + case 0x00080000: + nds_string_len = tvb_get_letohl(tvb, nds_offset); + nds_offset += 4; + get_string(tvb, nds_offset, nds_string_len, reply_buffer.buffer); + proto_tree_add_text(ncp_tree, tvb, nds_offset, nds_string_len, "Hardware Name: %s", reply_buffer.buffer); + nds_offset += nds_string_len; + nds_offset += align_4(tvb, nds_offset); + break; + case 0x00100000: + nds_string_len = tvb_get_letohl(tvb, nds_offset); + nds_offset += 4; + get_string(tvb, nds_offset, nds_string_len, reply_buffer.buffer); + proto_tree_add_text(ncp_tree, tvb, nds_offset, nds_string_len, "Vendor Name: %s", reply_buffer.buffer); + nds_offset += nds_string_len; + nds_offset += align_4(tvb, nds_offset); + break; + case 0x00000200: + /* Not Defined */ + case 0x00000400: + /* Not Defined */ + case 0x00000800: + /* Not Defined */ + case 0x00001000: + /* Not Defined */ + case 0x00002000: + /* Not Defined */ + case 0x00004000: + /* Not Defined */ + case 0x00008000: + /* Not Defined */ + case 0x00200000: + /* Not Defined */ + case 0x00400000: + /* Not Defined */ + case 0x00800000: + /* Not Defined */ + case 0x01000000: + /* Not Defined */ + case 0x02000000: + /* Not Defined */ + case 0x04000000: + /* Not Defined */ + case 0x08000000: + /* Not Defined */ + case 0x10000000: + /* Not Defined */ + case 0x20000000: + /* Not Defined */ + case 0x40000000: + /* Not Defined */ + case 0x80000000: + /* Not Defined */ + default: + break; + } + } + bvalue = bvalue*2; + } + } + } + if (ncp_rec->func == 0x68 && ncp_rec->subfunc == 0x02) + { + nds_offset = 8; + + nds_reply_buffer = tvb_get_letohl(tvb, nds_offset); + proto_tree_add_uint(ncp_tree, hf_ncp_fragment_size, tvb, nds_offset, + 4, nds_reply_buffer); + nds_offset += 4; + nds_frag = tvb_get_letohl(tvb, nds_offset); + proto_tree_add_uint(ncp_tree, hf_ncp_fragment_handle, tvb, nds_offset, + 4, nds_frag); + nds_offset += 4; + if (nds_reply_buffer > 7) + { + /* + * XXX - is this present in + * replies to continuation + * messages? It doesn't appear to + * be. + */ + proto_tree_add_uint_format(ncp_tree, hf_nds_reply_error, tvb, nds_offset, + 4, nds_error_code, "NDS Completion Code: 0x%08x, %s", + nds_error_code, nds_error_string); + } + if (request_value && nds_error_code == 0x00000000) + { + nds_offset = 20; + for (i = 0; i < 9; i++) { + pvalues[i].vtype = 0; + pvalues[i].vvalue = 0; + pvalues[i].vlength = 0; + pvalues[i].voffset = 0; + pvalues[i].hfname = 0; + pvalues[i].vdesc = ""; + string_buffer[i][0] = '\0'; + pvalues[i].vstring = string_buffer[i]; + pvalues[i].mvtype = 0; + } + verb_string = val_to_str(request_value->nds_request_verb, + ncp_nds_verb_vals, + "Continuation Fragment"); + switch (request_value->nds_request_verb) + { + case 0x01: + if(request_value->nds_version == 0) + { + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vstring = match_strval(pvalues[0].vvalue, nds_tags); + if(pvalues[0].vstring == NULL) + { + pvalues[0].vstring = "No Tags Set"; + } + pvalues[0].vtype = VTYPE_STRING; + pvalues[0].vdesc = "Tag: %s"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_tag_string; + nds_offset = nds_offset+pvalues[0].vlength; + switch(pvalues[0].vvalue) + { + case 0: /* No Such Entry */ + break; + case 1: /* Local Entry */ + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + add_eid = TRUE; + strcpy(global_object_name, request_value->object_name); + global_eid = pvalues[1].vvalue; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_eid; + nds_offset = nds_offset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[2].vdesc = "Referral Records: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_referrals; + pvalues[2].mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY; + break; + case 2: /* Remote Entry */ + nds_offset += 4; /* GUINT32 reserved field */ + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + add_eid = TRUE; + global_eid = pvalues[1].vvalue; + strcpy(global_object_name, request_value->object_name); + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_eid; + nds_offset = nds_offset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[2].vdesc = "Referral Records: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_referrals; + pvalues[2].mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY; + break; + case 3: /* Alias Entry */ + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Alias Name: %s"; + pvalues[1].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[1].vvalue = 0; + pvalues[1].vlength = 256; + pvalues[1].vlength = tvb_get_letohl(tvb, nds_offset); + if (pvalues[1].vlength == 0x00) + { + pvalues[1].vtype = VTYPE_NONE; + break; + } + pvalues[1].voffset = nds_offset+4; + nds_offset += 4; + get_string(tvb, pvalues[1].voffset, pvalues[1].vlength, pvalues[1].vstring); + nds_offset += pvalues[1].vlength; + nds_offset += align_4(tvb, nds_offset); + pvalues[1].hfname= hf_nds_name; + break; + case 4: /* Referral Information */ + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Distance Object is From Root: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_eid; + nds_offset = nds_offset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[2].vdesc = "Referral Records: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_depth; + pvalues[2].mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY; + break; + case 6: /* Entry and Referrals */ + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Result Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_result_flags; + nds_offset = nds_offset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Entry ID: 0x%08x"; + add_eid = TRUE; + global_eid = pvalues[2].vvalue; + strcpy(global_object_name, request_value->object_name); + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_eid; + nds_offset = nds_offset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[3].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[3].vdesc = "Referral Records: %u"; + pvalues[3].vlength = 4; + pvalues[3].voffset = nds_offset; + pvalues[3].mvtype = MVTYPE_ADDR_REFERRAL_REPLY; + pvalues[3].hfname = hf_nds_referrals; + break; + default: + break; + } + } + else + { + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "CRC: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_crc; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vstring = match_strval(pvalues[1].vvalue, nds_tags); + if(pvalues[1].vstring == NULL) + { + pvalues[1].vstring = "No Tags Set"; + } + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Tag: %s"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + nds_offset = nds_offset+pvalues[1].vlength; + pvalues[1].hfname = hf_nds_tag_string; + switch(pvalues[1].vvalue) + { + case 0: /* No Such Entry */ + break; + case 1: /* Local Entry */ + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Entry ID: 0x%08x"; + add_eid = TRUE; + global_eid = pvalues[2].vvalue; + strcpy(global_object_name, request_value->object_name); + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_eid; + nds_offset = nds_offset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[3].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[3].vdesc = "Referral Records: %u"; + pvalues[3].vlength = 4; + pvalues[3].voffset = nds_offset; + pvalues[3].hfname = hf_nds_referrals; + pvalues[3].mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY; + break; + case 2: /* Remote Entry */ + nds_offset += 4; /* GUINT32 reserved field */ + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + add_eid = TRUE; + global_eid = pvalues[2].vvalue; + strcpy(global_object_name, request_value->object_name); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Entry ID: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_eid; + nds_offset = nds_offset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[3].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[3].vdesc = "Referral Records: %u"; + pvalues[3].vlength = 4; + pvalues[3].voffset = nds_offset; + pvalues[3].hfname = hf_nds_referrals; + pvalues[3].mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY; + break; + case 3: /* Alias Entry */ + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Alias Name: %s"; + pvalues[2].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[2].vvalue = 0; + pvalues[2].vlength = 256; + pvalues[2].vlength = tvb_get_letohl(tvb, nds_offset); + if (pvalues[2].vlength == 0x00) + { + pvalues[2].vtype = VTYPE_NONE; + break; + } + pvalues[2].voffset = nds_offset+4; + nds_offset += 4; + get_string(tvb, pvalues[2].voffset, pvalues[2].vlength, pvalues[2].vstring); + nds_offset += pvalues[2].vlength; + nds_offset += align_4(tvb, nds_offset); + pvalues[2].hfname= hf_nds_name; + break; + case 4: /* Referral Information */ + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Distance Object is From Root: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_eid; + nds_offset = nds_offset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[3].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[3].vdesc = "Referral Records: %u"; + pvalues[3].vlength = 4; + pvalues[3].voffset = nds_offset; + pvalues[3].hfname = hf_nds_depth; + pvalues[3].mvtype = MVTYPE_ADDR_REFERRAL_REPLY; + break; + case 6: /* Entry and Referrals */ + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Result Flags: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_result_flags; + nds_offset = nds_offset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[3].vtype = VTYPE_UINT32; + pvalues[3].vdesc = "Entry ID: 0x%08x"; + add_eid = TRUE; + strcpy(global_object_name, request_value->object_name); + global_eid = pvalues[3].vvalue; + pvalues[3].vlength = 4; + pvalues[3].voffset = nds_offset; + pvalues[3].hfname = hf_nds_eid; + nds_offset = nds_offset+pvalues[3].vlength; + pvalues[4].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[4].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[4].vdesc = "Referral Records: %u"; + pvalues[4].vlength = 4; + pvalues[4].voffset = nds_offset; + pvalues[4].mvtype = MVTYPE_ADDR_REFERRAL_REPLY; + pvalues[4].hfname = hf_nds_referrals; + break; + default: + break; + } + + } + break; + case 0x02: + if(request_value->nds_version != 0x000000fe) + { + pvalues[0].vvalue = 1; + pvalues[0].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[0].vdesc = "Entry Information"; + pvalues[0].vlength = 0; + pvalues[0].voffset = nds_offset-4; + pvalues[0].hfname = hf_nds_name; + pvalues[0].mvtype = MVTYPE_LIST_PARTITIONS; + pvalues[0].vflags = request_value->req_nds_flags; + } + else + { + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "CRC: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_crc; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vvalue = 1; + pvalues[1].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[1].vdesc = "Entry Information"; + pvalues[1].vlength = 0; + pvalues[1].voffset = nds_offset-4; + pvalues[1].hfname = hf_nds_name; + pvalues[1].mvtype = MVTYPE_LIST_PARTITIONS; + pvalues[1].vflags = request_value->req_nds_flags; + } + break; + case 0x03: + if(request_value->nds_version != 0x000000fe) + { + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Iteration Handle: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_iteration; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vstring = match_strval(pvalues[1].vvalue, nds_info_type); + if(pvalues[1].vstring == NULL) + { + pvalues[1].vstring = "No Info Type Set"; + } + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Info Type: %s"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_info_type; + nds_offset = nds_offset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[2].vdesc = "Number of Attributes: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_attr; + pvalues[2].mvtype = MVTYPE_ATTR_REPLY; + pvalues[2].vflags = request_value->req_nds_flags; + pvalues[2].nds_version = request_value->nds_version; + } + else + { + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "CRC: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_crc; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Iteration Handle: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_iteration; + nds_offset = nds_offset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vstring = match_strval(pvalues[2].vvalue, nds_info_type); + if(pvalues[2].vstring == NULL) + { + pvalues[2].vstring = "No Info Type Set"; + } + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Info Type: %s"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_info_type; + nds_offset = nds_offset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[3].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[3].vdesc = "Number of Attributes: %u"; + pvalues[3].vlength = 4; + pvalues[3].voffset = nds_offset; + pvalues[3].hfname = hf_nds_attr; + pvalues[3].mvtype = MVTYPE_ATTR_REPLY; + pvalues[3].vflags = request_value->req_nds_flags; + pvalues[3].nds_version = request_value->nds_version; + } + break; + case 0x04: + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + if (pvalues[0].vvalue == 0x00000000) + { + pvalues[0].vstring = "Did Not Match"; + } + else + { + pvalues[0].vstring = "Matched"; + } + pvalues[0].vtype = VTYPE_STRING; + pvalues[0].vdesc = "Compare Values Returned - %s"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].mvtype = 0; + pvalues[0].hfname= hf_nds_compare_results; + nds_offset += pvalues[0].vlength; + break; + case 0x05: + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Iteration Handle: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_iteration; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[1].vdesc = "Entry Information"; + pvalues[1].vlength = 0; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_name; + pvalues[1].mvtype = MVTYPE_LIST_PARTITIONS; + pvalues[1].vflags = request_value->req_nds_flags; + break; + case 0x06: + break; + case 0x07: + break; + case 0x08: + break; + case 0x09: + break; + case 0x0a: + break; + case 0x0b: + break; + case 0x0c: + break; + case 0x0d: + break; + case 0x0e: + break; + case 0x0f: + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Iteration Handle: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_iteration; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vstring = match_strval(pvalues[1].vvalue, class_def_type); + if(pvalues[1].vstring == NULL) + { + pvalues[1].vstring = "No Class Definition Type Set"; + } + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Class Definition Type: %s"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].mvtype = 0; + pvalues[1].hfname= hf_nds_class_def_type; + nds_offset = nds_offset + pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset);; + pvalues[2].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[2].vdesc = "Class Definitions %u"; + pvalues[2].vlength = 0; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_classes; + pvalues[2].mvtype = MVTYPE_CLASS_NAMES; + pvalues[2].vflags = request_value->req_nds_flags; + break; + case 0x10: + break; + case 0x11: + break; + case 0x12: + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Iteration Handle: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_iteration; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[1].vdesc = "Classes: %u"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].mvtype = MVTYPE_READ_CLASS_REQ; + pvalues[1].hfname= hf_nds_classes; + break; + case 0x13: + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Privileges: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_privileges; + nds_offset = nds_offset+pvalues[0].vlength; + break; + case 0x14: + break; + case 0x15: + break; + case 0x16: + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Iteration Handle: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_iteration; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Server Distinguished Name: %s"; + pvalues[1].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[1].vvalue = 0; + pvalues[1].vlength = 256; + pvalues[1].vlength = tvb_get_letohl(tvb, nds_offset); + if (pvalues[1].vlength == 0x00) + { + pvalues[1].vtype = VTYPE_NONE; + break; + } + pvalues[1].voffset = nds_offset+4; + nds_offset += 4; + get_string(tvb, pvalues[1].voffset, pvalues[1].vlength, pvalues[1].vstring); + nds_offset += pvalues[1].vlength; + nds_offset += align_4(tvb, nds_offset); + pvalues[1].hfname= hf_nds_name; + nds_offset += align_4(tvb, nds_offset); + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[2].vdesc = "Replicas: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_replicas; + pvalues[2].mvtype = MVTYPE_READ_REPLICAS; + pvalues[2].bit1 = "Output Flags"; + pvalues[2].bit2 = "Entry ID"; + pvalues[2].bit3 = "Replica State"; + pvalues[2].bit4 = "Modification Timestamp"; + pvalues[2].bit5 = "Purge Time"; + pvalues[2].bit6 = "Local Partition ID"; + pvalues[2].bit7 = "Distinguished Name"; + pvalues[2].bit8 = "Replica Type"; + pvalues[2].bit9 = "Partition Busy"; + pvalues[2].vflags = request_value->req_nds_flags; + break; + case 0x17: + break; + case 0x18: + break; + case 0x19: + break; + case 0x1a: + break; + case 0x1b: + pvalues[0].vvalue = tvb_get_ntohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "File Handle: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_file_handle; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "File Size: %u"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_file_size; + nds_offset = nds_offset+pvalues[1].vlength; + break; + case 0x1c: + break; + case 0x1d: + break; + case 0x1e: + break; + case 0x1f: + break; + case 0x20: + break; + case 0x21: + break; + case 0x22: + break; + case 0x23: + break; + case 0x24: + break; + case 0x25: + break; + case 0x26: + break; + case 0x27: + break; + case 0x28: + break; + case 0x29: + break; + case 0x2a: + break; + case 0x2b: + break; + case 0x2c: + break; + case 0x2d: + break; + case 0x2e: + break; + case 0x2f: + break; + case 0x30: + break; + case 0x31: + break; + case 0x32: + break; + case 0x33: + break; + case 0x34: + break; + case 0x35: + if(request_value->nds_version != 0x000000fe) + { + pvalues[0].vtype = VTYPE_STRING; + pvalues[0].vdesc = "Distinguished Name: %s"; + pvalues[0].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[0].vvalue = 0; + pvalues[0].vlength = 256; + pvalues[0].vlength = tvb_get_letohl(tvb, nds_offset); + if (pvalues[0].vlength == 0x00) + { + pvalues[0].vtype = VTYPE_NONE; + break; + } + pvalues[0].voffset = nds_offset+4; + nds_offset += 4; + get_string(tvb, pvalues[0].voffset, pvalues[0].vlength, pvalues[0].vstring); + nds_offset += pvalues[0].vlength; + nds_offset += align_4(tvb, nds_offset); + pvalues[0].hfname= hf_nds_name; + pvalues[1].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[1].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[1].vdesc = "Referral Records: %u"; + pvalues[1].vlength = 4; + pvalues[1].voffset = nds_offset; + pvalues[1].hfname = hf_nds_referrals; + pvalues[1].mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY; + } + else + { + pvalues[0].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Iteration Handle: 0x%08x"; + pvalues[0].vlength = 4; + pvalues[0].voffset = nds_offset; + pvalues[0].hfname = hf_nds_iteration; + nds_offset = nds_offset+pvalues[0].vlength; + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Distinguished Name: %s"; + pvalues[1].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[1].vvalue = 0; + pvalues[1].vlength = 256; + pvalues[1].vlength = tvb_get_letohl(tvb, nds_offset); + if (pvalues[1].vlength == 0x00) + { + pvalues[1].vtype = VTYPE_NONE; + break; + } + pvalues[1].voffset = nds_offset+4; + nds_offset += 4; + get_string(tvb, pvalues[1].voffset, pvalues[1].vlength, pvalues[1].vstring); + nds_offset += pvalues[1].vlength; + nds_offset += align_4(tvb, nds_offset); + pvalues[1].hfname= hf_nds_name; + pvalues[2].vvalue = tvb_get_letohl(tvb, nds_offset); + pvalues[2].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[2].vdesc = "Referral Records: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = nds_offset; + pvalues[2].hfname = hf_nds_referrals; + pvalues[2].mvtype = MVTYPE_LOC_ADDR_REFERRAL_REPLY; + } + break; + case 0x36: + break; + case 0x37: + break; + case 0x38: + break; + case 0x39: + break; + case 0x3a: + break; + case 0x3b: + break; + case 0x3c: + break; + case 0x3d: + break; + case 0x3e: + break; + case 0x3f: + break; + case 0x40: + break; + case 0x41: + break; + case 0x42: + break; + case 0x43: + break; + case 0x44: + break; + case 0x45: + break; + case 0x46: + break; + case 0x47: + break; + case 0x48: + break; + case 0x49: + break; + case 0x4a: + break; + case 0x4b: + break; + case 0x4c: + break; + case 0x4d: + break; + default: + break; + } + if(request_value->nds_request_verb != 0) + { + proto_tree_add_uint_format(ncp_tree, hf_ncp_nds_verb, tvb, 6, 0, + request_value->nds_request_verb, "NDS Verb: %d, %s", + request_value->nds_request_verb, verb_string); + } + /* NDS Entry ID's (EID) is identified in the reply packet of an NDS + * resolve name. We need to store this EID and it's associated + * name into our hash so that we can resolve the name for + * other NDS requests. */ + if (!pinfo->fd->flags.visited) { + if(add_eid) + { + request_eid_value = ncp_eid_hash_lookup(conversation, global_eid); + if (!request_eid_value) { + request_eid_value = ncp_eid_hash_insert(global_eid); + strcpy(request_eid_value->object_name, global_object_name); + } + } + } + /* For NDS requests with just an EID, resolve name from hash table. */ + if(resolve_eid) + { + request_eid_value = ncp_eid_hash_lookup(conversation, global_eid); + if (request_eid_value) { + strcpy(global_object_name, request_eid_value->object_name); + proto_tree_add_string_format(ncp_tree, hf_nds_name, tvb, 6, 0, + global_object_name, "NDS Name for EID - %s", + global_object_name); + } + } + for (i = 0; i < 9; i++) { + switch (pvalues[i].vtype) { + + case VTYPE_NONE: /* no value */ + break; + + case VTYPE_UINT8: + proto_tree_add_uint_format(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vtype, "NDS Parameter not defined %u", + pvalues[i].vtype); + break; + + case VTYPE_UINT16: + proto_tree_add_uint_format(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vtype, "NDS Parameter not defined %u", + pvalues[i].vtype); + break; + + case VTYPE_UINT32: + proto_tree_add_uint_format(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vvalue, pvalues[i].vdesc, + pvalues[i].vvalue); + break; + + case VTYPE_STRING: + proto_tree_add_string_format(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vstring, pvalues[i].vdesc, + pvalues[i].vstring); + break; + + case VTYPE_BITFIELD: + process_bitfield(ncp_tree, tvb, &pvalues[i]); + break; + + case VTYPE_MULTIVALUE_UINT32: + process_multivalues(ncp_tree, tvb, &pvalues[i]); + break; + + default: + proto_tree_add_uint_format(ncp_tree, hf_nds_p1type, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vtype, "NDS Parameter not defined %u", + pvalues[i].vtype); + break; + } + } + } + } + } + + length = tvb_length(tvb); + if (!ncp_rec && length > 8) { + proto_tree_add_text(ncp_tree, tvb, 8, length - 8, + "No request record found. Parsing is impossible."); + } + else if (ncp_rec && ncp_rec->reply_ptvc) { + /* If a non-zero completion code was found, it is + * legal to not have any fields, even if the packet + * type is defined as having fields. */ + if (completion_code != 0 && tvb_length(tvb) == 8) { + return; + } + /*printf("func=0x%x subfunc=0x%x\n", ncp_rec->func, ncp_rec->subfunc);*/ + + /* Any request condition results? */ + if (request_value) { + req_cond_results = request_value->req_cond_results; + } + else { + req_cond_results = NULL; + } + + clear_repeat_vars(); + ptvc = ptvcursor_new(ncp_tree, tvb, 8); + process_ptvc_record(ptvc, ncp_rec->reply_ptvc, req_cond_results, + TRUE, ncp_rec); + ptvcursor_free(ptvc); + } + } +} + +void +dissect_nds_request(tvbuff_t *tvb, packet_info *pinfo, + guint16 nw_connection, guint8 sequence, + guint16 type, proto_tree *ncp_tree) +{ + guint8 func, subfunc = 0; + ncp_req_hash_value *request_value = NULL; + ncp_req_eid_hash_value *request_eid_value = NULL; + const ncp_record *ncp_rec = NULL; + conversation_t *conversation; + ptvcursor_t *ptvc = NULL; + proto_tree *temp_tree = NULL; + gboolean run_req_cond = FALSE; + gboolean run_info_str = FALSE; + guint8 nds_verb = 0; + char * verb_string = ""; + guint32 nds_frag = 0; + gboolean added_arrow; + nds_val pvalues[9]; + char string_buffer[9][1024]; + guint8 nds_version = 0; + guint32 foffset = 0; + nw_uni_t req_buffer; + char global_object_name[256]; + guint32 global_eid=0; + gboolean resolve_eid=FALSE; + guint32 global_flags=0; + int i; + + for (i = 0; i < 9; i++) { + pvalues[i].vtype = 0; + pvalues[i].vvalue = 0; + pvalues[i].vlength = 0; + pvalues[i].voffset = 0; + pvalues[i].hfname = 0; + pvalues[i].vdesc = ""; + string_buffer[i][0] = '\0'; + pvalues[i].vstring = string_buffer[i]; + pvalues[i].mvtype = 0; + } + + strcpy(req_buffer.buffer, ""); + strcpy(global_object_name, ""); + + func = tvb_get_guint8(tvb, 6); + subfunc = tvb_get_guint8(tvb, 7); + + ncp_rec = ncp_record_find(func, subfunc); + + /* Check to see if this is a fragment packet */ + nds_frag = tvb_get_letohl(tvb, 8); + + /* Get NDS Verb */ + if (nds_frag == 0xffffffff) { + nds_verb = tvb_get_guint8(tvb, 24); + if (nds_verb == 0xfe) + { + nds_version = nds_verb; + nds_verb = tvb_get_guint8(tvb, 32); + foffset = 36; + } + else + { + nds_version = 0; + foffset = 28; + } + if (type == NCP_SERVICE_REQUEST) { + proto_tree_add_item(ncp_tree, hf_nds_buffer_size, tvb, foffset, + 4, TRUE); + } + foffset = foffset+4; + verb_string = val_to_str(nds_verb, ncp_nds_verb_vals, + "Continuation Fragment"); + switch(nds_verb) { + + case 0x01: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[0].vvalue; + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].hfname = hf_nds_ver; + pvalues[0].voffset = foffset; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_BITFIELD; + pvalues[1].vdesc = "Flags:"; + pvalues[1].vlength = 2; + pvalues[1].hfname= hf_nds_nflags; + pvalues[1].voffset = foffset; + pvalues[1].bit1 = "Entry ID"; + pvalues[1].bit1hfname = hf_bit1nflags; + pvalues[1].bit2 = "Readable"; + pvalues[1].bit2hfname = hf_bit2nflags; + pvalues[1].bit3 = "Writeable"; + pvalues[1].bit3hfname = hf_bit3nflags; + pvalues[1].bit4 = "Master"; + pvalues[1].bit4hfname = hf_bit4nflags; + pvalues[1].bit5 = "Create ID"; + pvalues[1].bit5hfname = hf_bit5nflags; + pvalues[1].bit6 = "Walk Tree"; + pvalues[1].bit6hfname = hf_bit6nflags; + pvalues[1].bit7 = "Dereference Alias"; + pvalues[1].bit7hfname = hf_bit7nflags; + pvalues[1].bit8 = "Not Defined"; + pvalues[1].bit8hfname = hf_bit8nflags; + pvalues[1].bit9 = "Not Defined"; + pvalues[1].bit9hfname = hf_bit9nflags; + pvalues[1].bit10 = "Not Defined"; + pvalues[1].bit10hfname = hf_bit10nflags; + pvalues[1].bit11= "Not Defined"; + pvalues[1].bit11hfname = hf_bit11nflags; + pvalues[1].bit12 = "Not Defined"; + pvalues[1].bit12hfname = hf_bit12nflags; + pvalues[1].bit13 = "Not Defined"; + pvalues[1].bit13hfname = hf_bit13nflags; + pvalues[1].bit14 = "Prefer Referrals"; + pvalues[1].bit14hfname = hf_bit14nflags; + pvalues[1].bit15 = "Prefer Only Referrals"; + pvalues[1].bit15hfname = hf_bit15nflags; + pvalues[1].bit16 = "Not Defined"; + pvalues[1].bit16hfname = hf_bit16nflags; + foffset = foffset+4; + if (pvalues[0].vvalue == 0 || pvalues[0].vvalue == 1) + { + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Scope: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].hfname= hf_nds_scope; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "Name: %s"; + pvalues[3].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[3].vvalue = 0; + pvalues[3].vlength = 256; + pvalues[3].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[3].vlength == 0x00) + { + pvalues[3].vtype = VTYPE_NONE; + break; + } + pvalues[3].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[3].voffset, pvalues[3].vlength, req_buffer.buffer); + pvalues[3].vstring = req_buffer.buffer; + strcpy(global_object_name, req_buffer.buffer); + pvalues[3].hfname= hf_nds_name; + foffset = foffset+pvalues[3].vlength; + foffset += align_4(tvb, foffset); + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[4].vdesc = "Communications Transports: %u"; + pvalues[4].vlength = 4; + pvalues[4].hfname= hf_nds_comm_trans; + pvalues[4].voffset = foffset; + pvalues[4].mvtype = MVTYPE_ADDR_REFERRAL_REQUEST; + foffset = foffset + (pvalues[4].vvalue * 4) + 4; + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[5].vdesc = "Tree Walker Transport Type: %u"; + pvalues[5].vlength = 4; + pvalues[5].mvtype = MVTYPE_ADDR_REFERRAL_REQUEST; + pvalues[5].hfname= hf_nds_tree_trans; + pvalues[5].voffset = foffset; + } + else + { + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Minimum DS Version: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].hfname= hf_min_nds_ver; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[3].vdesc = "Number of Versions to Include: %u"; + pvalues[3].vlength = 4; + pvalues[3].mvtype = MVTYPE_ATTR_REQUEST2; + pvalues[3].voffset = foffset; + pvalues[3].hfname= hf_nds_ver_include; + foffset += (pvalues[3].vvalue * 4) + 4; + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[4].vdesc = "Number of Versions to Exclude: %u"; + pvalues[4].vlength = 4; + pvalues[4].mvtype = MVTYPE_ATTR_REQUEST2; + pvalues[4].hfname= hf_nds_ver_exclude; + pvalues[4].voffset = foffset; + foffset += 4; + pvalues[5].vtype = VTYPE_UINT32; + pvalues[5].vdesc = "DN Output Type: %u"; + pvalues[5].vlength = 4; + pvalues[5].voffset = foffset; + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].hfname= hf_nds_dn_output_type; + foffset = foffset+pvalues[5].vlength; + pvalues[6].vtype = VTYPE_UINT32; + pvalues[6].vdesc = "Nested Output Type: %u"; + pvalues[6].vlength = 4; + pvalues[6].voffset = foffset; + pvalues[6].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[6].hfname= hf_nds_nested_output_type; + foffset = foffset+pvalues[6].vlength; + pvalues[7].vtype = VTYPE_STRING; + pvalues[7].vdesc = "Output Delimiter: %s"; + pvalues[7].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[7].vvalue = 0; + pvalues[7].vlength = 256; + pvalues[7].vlength = tvb_get_letohl(tvb, foffset); + pvalues[7].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[7].voffset, pvalues[7].vlength, req_buffer.buffer); + pvalues[7].vstring = req_buffer.buffer; + pvalues[7].hfname= hf_nds_output_delimiter; + foffset = foffset+pvalues[7].vlength; + foffset += align_4(tvb, foffset); + pvalues[8].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[8].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[8].vdesc = "Size of Entry Specifier: %u"; + pvalues[8].vlength = 4; + pvalues[8].mvtype = MVTYPE_PROC_ENTRY_SPECIFIERS; + pvalues[8].hfname= hf_nds_output_entry_specifier; + pvalues[8].voffset = foffset; + } + break; + case 0x02: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + switch(pvalues[0].vvalue) + { + case 0: + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + pvalues[1].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[1].vvalue; + pvalues[1].voffset = foffset; + pvalues[1].hfname = hf_nds_eid; + foffset = foffset+pvalues[1].vlength; + break; + case 1: + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_BITFIELD; + pvalues[1].vdesc = "Request Flags:"; + pvalues[1].vlength = 2; + pvalues[1].hfname= hf_nds_rflags; + pvalues[1].voffset = foffset; + pvalues[1].bit1 = "Typeless"; + pvalues[1].bit1hfname = hf_bit1rflags; + pvalues[1].bit2 = "Slashed"; + pvalues[1].bit2hfname = hf_bit2rflags; + pvalues[1].bit3 = "Dotted"; + pvalues[1].bit3hfname = hf_bit3rflags; + pvalues[1].bit4 = "Tuned"; + pvalues[1].bit4hfname = hf_bit4rflags; + pvalues[1].bit5 = "Not Defined"; + pvalues[1].bit5hfname = hf_bit5rflags; + pvalues[1].bit6 = "Not Defined"; + pvalues[1].bit6hfname = hf_bit6rflags; + pvalues[1].bit7 = "Not Defined"; + pvalues[1].bit7hfname = hf_bit7rflags; + pvalues[1].bit8 = "Not Defined"; + pvalues[1].bit8hfname = hf_bit8rflags; + pvalues[1].bit9 = "Not Defined"; + pvalues[1].bit9hfname = hf_bit9rflags; + pvalues[1].bit10 = "Not Defined"; + pvalues[1].bit10hfname = hf_bit10rflags; + pvalues[1].bit11 = "Not Defined"; + pvalues[1].bit11hfname = hf_bit11rflags; + pvalues[1].bit12 = "Not Defined"; + pvalues[1].bit12hfname = hf_bit12rflags; + pvalues[1].bit13 = "Not Defined"; + pvalues[1].bit13hfname = hf_bit13rflags; + pvalues[1].bit14 = "Not Defined"; + pvalues[1].bit14hfname = hf_bit14rflags; + pvalues[1].bit15 = "Not Defined"; + pvalues[1].bit15hfname = hf_bit15rflags; + pvalues[1].bit16 = "Not Defined"; + pvalues[1].bit16hfname = hf_bit16rflags; + if((pvalues[1].vvalue&&0xf000) == 0xc000) + { + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Name Type: %s"; + pvalues[2].vstring = "Partial"; + pvalues[2].mvtype = 0; + pvalues[2].vvalue = 0; + pvalues[2].vlength = 0; + pvalues[2].voffset = 0; + pvalues[2].hfname= hf_nds_name_type; + } + else + { + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Name Type: %s"; + pvalues[2].vstring = "Full"; + pvalues[2].vvalue = 0; + pvalues[2].mvtype = 0; + pvalues[2].vlength = 0; + pvalues[2].voffset = 0; + pvalues[2].hfname= hf_nds_name_type; + } + foffset = foffset+4; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vtype = VTYPE_UINT32; + pvalues[3].vdesc = "Entry ID: 0x%08x"; + pvalues[3].vlength = 4; + pvalues[3].voffset = foffset; + resolve_eid = TRUE; + global_eid = pvalues[3].vvalue; + pvalues[3].hfname = hf_nds_eid; + foffset = foffset+pvalues[3].vlength; + break; + case 2: + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_BITFIELD; + pvalues[1].vdesc = "Request Flags:"; + pvalues[1].vlength = 2; + pvalues[1].hfname= hf_nds_rflags; + pvalues[1].voffset = foffset; + pvalues[1].bit1 = "Typeless"; + pvalues[1].bit1hfname = hf_bit1rflags; + pvalues[1].bit2 = "Slashed"; + pvalues[1].bit2hfname = hf_bit2rflags; + pvalues[1].bit3 = "Dotted"; + pvalues[1].bit3hfname = hf_bit3rflags; + pvalues[1].bit4 = "Tuned"; + pvalues[1].bit4hfname = hf_bit4rflags; + pvalues[1].bit5 = "Not Defined"; + pvalues[1].bit5hfname = hf_bit5rflags; + pvalues[1].bit6 = "Not Defined"; + pvalues[1].bit6hfname = hf_bit6rflags; + pvalues[1].bit7 = "Not Defined"; + pvalues[1].bit7hfname = hf_bit7rflags; + pvalues[1].bit8 = "Not Defined"; + pvalues[1].bit8hfname = hf_bit8rflags; + pvalues[1].bit9 = "Not Defined"; + pvalues[1].bit9hfname = hf_bit9rflags; + pvalues[1].bit10 = "Not Defined"; + pvalues[1].bit10hfname = hf_bit10rflags; + pvalues[1].bit11 = "Not Defined"; + pvalues[1].bit11hfname = hf_bit11rflags; + pvalues[1].bit12 = "Not Defined"; + pvalues[1].bit12hfname = hf_bit12rflags; + pvalues[1].bit13 = "Not Defined"; + pvalues[1].bit13hfname = hf_bit13rflags; + pvalues[1].bit14 = "Not Defined"; + pvalues[1].bit14hfname = hf_bit14rflags; + pvalues[1].bit15 = "Not Defined"; + pvalues[1].bit15hfname = hf_bit15rflags; + pvalues[1].bit16 = "Not Defined"; + pvalues[1].bit16hfname = hf_bit16rflags; + if((pvalues[1].vvalue&&0xf000) == 0xc000) + { + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Name Type: %s"; + pvalues[2].vstring = "Return Partion Name"; + pvalues[2].vvalue = 0; + pvalues[2].vlength = 4; + pvalues[2].voffset = pvalues[1].voffset; + pvalues[2].mvtype = 0; + pvalues[2].hfname= hf_nds_name_type; + } + else + { + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Name Type: %s"; + pvalues[2].vstring = "Return Full Name"; + pvalues[2].vvalue = 0; + pvalues[2].vlength = 4; + pvalues[2].mvtype = 0; + pvalues[2].voffset = pvalues[1].voffset; + pvalues[2].hfname= hf_nds_name_type; + } + foffset = foffset+4; + pvalues[3].vvalue = tvb_get_letohs(tvb, foffset); + global_flags = tvb_get_letohl(tvb, foffset); + pvalues[3].vtype = VTYPE_BITFIELD; + pvalues[3].vdesc = "Information Flags (low) Byte:"; + pvalues[3].vlength = 2; + pvalues[3].hfname= hf_nds_rflags; + pvalues[3].voffset = foffset; + pvalues[3].bit1 = "Output Flags"; + pvalues[3].bit1hfname = hf_bit1infoflagsl; + pvalues[3].bit2 = "Entry ID"; + pvalues[3].bit2hfname = hf_bit2infoflagsl; + pvalues[3].bit3 = "Entry Flags"; + pvalues[3].bit3hfname = hf_bit3infoflagsl; + pvalues[3].bit4 = "Subordinate Count"; + pvalues[3].bit4hfname = hf_bit4infoflagsl; + pvalues[3].bit5 = "Modification Time"; + pvalues[3].bit5hfname = hf_bit5infoflagsl; + pvalues[3].bit6 = "Modification Timestamp"; + pvalues[3].bit6hfname = hf_bit6infoflagsl; + pvalues[3].bit7 = "Creation Timestamp"; + pvalues[3].bit7hfname = hf_bit7infoflagsl; + pvalues[3].bit8 = "Partition Root ID"; + pvalues[3].bit8hfname = hf_bit8infoflagsl; + pvalues[3].bit9 = "Parent ID"; + pvalues[3].bit9hfname = hf_bit9infoflagsl; + pvalues[3].bit10 = "Revision Count"; + pvalues[3].bit10hfname = hf_bit10infoflagsl; + pvalues[3].bit11 = "Replica Type"; + pvalues[3].bit11hfname = hf_bit11infoflagsl; + pvalues[3].bit12 = "Base Class"; + pvalues[3].bit12hfname = hf_bit12infoflagsl; + pvalues[3].bit13 = "Relative Distinguished Name"; + pvalues[3].bit13hfname = hf_bit13infoflagsl; + pvalues[3].bit14 = "Distinguished Name"; + pvalues[3].bit14hfname = hf_bit14infoflagsl; + pvalues[3].bit15 = "Root Distinguished Name"; + pvalues[3].bit15hfname = hf_bit15infoflagsl; + pvalues[3].bit16 = "Parent Distinguished Name"; + pvalues[3].bit16hfname = hf_bit16infoflagsl; + foffset = foffset+2; + pvalues[4].vvalue = tvb_get_letohs(tvb, foffset); + pvalues[4].vtype = VTYPE_BITFIELD; + pvalues[4].vdesc = "Information Flags (high) Byte:"; + pvalues[4].vlength = 2; + pvalues[4].hfname= hf_nds_rflags; + pvalues[4].voffset = foffset; + pvalues[4].bit1 = "Purge Time"; + pvalues[4].bit1hfname = hf_bit1infoflagsh; + pvalues[4].bit2 = "Dereference Base Class"; + pvalues[4].bit2hfname = hf_bit2infoflagsh; + pvalues[4].bit3 = "Not Defined"; + pvalues[4].bit3hfname = hf_bit3infoflagsh; + pvalues[4].bit4 = "Not Defined"; + pvalues[4].bit4hfname = hf_bit4infoflagsh; + pvalues[4].bit5 = "Not Defined"; + pvalues[4].bit5hfname = hf_bit5infoflagsh; + pvalues[4].bit6 = "Not Defined"; + pvalues[4].bit6hfname = hf_bit6infoflagsh; + pvalues[4].bit7 = "Not Defined"; + pvalues[4].bit7hfname = hf_bit7infoflagsh; + pvalues[4].bit8 = "Not Defined"; + pvalues[4].bit8hfname = hf_bit8infoflagsh; + pvalues[4].bit9 = "Not Defined"; + pvalues[4].bit9hfname = hf_bit9infoflagsh; + pvalues[4].bit10 = "Not Defined"; + pvalues[4].bit10hfname = hf_bit10infoflagsh; + pvalues[4].bit11 = "Not Defined"; + pvalues[4].bit11hfname = hf_bit11infoflagsh; + pvalues[4].bit12 = "Not Defined"; + pvalues[4].bit12hfname = hf_bit12infoflagsh; + pvalues[4].bit13 = "Not Defined"; + pvalues[4].bit13hfname = hf_bit13infoflagsh; + pvalues[4].bit14 = "Not Defined"; + pvalues[4].bit14hfname = hf_bit14infoflagsh; + pvalues[4].bit15 = "Not Defined"; + pvalues[4].bit15hfname = hf_bit15infoflagsh; + pvalues[4].bit16 = "Not Defined"; + pvalues[4].bit16hfname = hf_bit16infoflagsh; + foffset = foffset+2; + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].vtype = VTYPE_UINT32; + pvalues[5].vdesc = "Entry ID: 0x%08x"; + pvalues[5].vlength = 4; + pvalues[5].voffset = foffset; + resolve_eid = TRUE; + global_eid = pvalues[5].vvalue; + pvalues[5].hfname = hf_nds_eid; + foffset = foffset+pvalues[5].vlength; + break; + default: + break; + } + + break; + case 0x03: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + if(pvalues[0].vvalue == 0) + { + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Iteration Handle: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_iteration; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Entry ID: 0x%08x"; + pvalues[2].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[2].vvalue; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_eid; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vstring = match_strval(pvalues[3].vvalue, nds_info_type); + global_flags = pvalues[3].vvalue; + if(pvalues[3].vstring == NULL) + { + pvalues[3].vstring = "No Info Type Set"; + } + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "Info Type: %s"; + pvalues[3].vlength = 4; + pvalues[3].voffset = foffset; + pvalues[3].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[3].hfname= hf_nds_info_type; + foffset = foffset + pvalues[3].vlength; + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vtype = VTYPE_UINT32; + pvalues[4].vdesc = "All Attributes: %u"; + pvalues[4].vlength = 4; + pvalues[4].voffset = foffset; + pvalues[4].hfname= hf_nds_all_attr; + foffset = foffset+pvalues[4].vlength; + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[5].vdesc = "Attributes: %u"; + pvalues[5].vlength = 4; + pvalues[5].voffset = foffset; + pvalues[5].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[5].hfname= hf_nds_attr; + } + else + { + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Request Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_req_flags; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Iteration Handle: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_iteration; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vtype = VTYPE_UINT32; + pvalues[3].vdesc = "Entry ID: 0x%08x"; + pvalues[3].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[3].vvalue; + pvalues[3].voffset = foffset; + pvalues[3].hfname= hf_nds_eid; + foffset = foffset+pvalues[3].vlength; + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vstring = match_strval(pvalues[4].vvalue, nds_info_type); + global_flags = pvalues[4].vvalue; + if(pvalues[4].vstring == NULL) + { + pvalues[4].vstring = "No Info Type Set"; + } + pvalues[4].vtype = VTYPE_STRING; + pvalues[4].vdesc = "Info Type: %s"; + pvalues[4].vlength = 4; + pvalues[4].voffset = foffset; + pvalues[4].hfname= hf_nds_info_type; + pvalues[4].mvtype = MVTYPE_ATTR_REQUEST; + foffset = foffset+pvalues[4].vlength; + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].vtype = VTYPE_UINT32; + pvalues[5].vdesc = "All Attributes: %u"; + pvalues[5].vlength = 4; + pvalues[5].voffset = foffset; + pvalues[5].hfname= hf_nds_all_attr; + foffset = foffset+pvalues[5].vlength; + pvalues[6].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[6].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[6].vdesc = "Attributes: %u"; + pvalues[6].vlength = 4; + pvalues[6].voffset = foffset; + pvalues[6].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[6].hfname= hf_nds_attr; + } + break; + case 0x04: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + pvalues[1].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[1].vvalue; + pvalues[1].voffset = foffset; + pvalues[1].hfname = hf_nds_eid; + foffset = foffset+pvalues[1].vlength; + foffset += 4; /* Attribute Count = 1 */ + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Attribute Name Being Compared: %s"; + pvalues[2].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[2].vvalue = 0; + pvalues[2].vlength = 256; + pvalues[2].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[2].vlength == 0x00) + { + pvalues[2].vtype = VTYPE_NONE; + break; + } + pvalues[2].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[2].voffset, pvalues[2].vlength, req_buffer.buffer); + pvalues[2].vstring = req_buffer.buffer; + strcpy(global_object_name, req_buffer.buffer); + pvalues[2].hfname= hf_nds_name; + foffset = foffset+pvalues[2].vlength; + foffset += align_4(tvb, foffset); + foffset += 4; /* Attribute Value Count = 1 */ + /*************** + * Need Trace file to test. Will have to create a + * new mvtype to call print_nds_values. + ***************/ + break; + case 0x05: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_BITFIELD; + pvalues[1].vdesc = "Request Flags:"; + pvalues[1].vlength = 2; + pvalues[1].hfname= hf_nds_rflags; + pvalues[1].voffset = foffset; + pvalues[1].bit1 = "List Typeless"; + pvalues[1].bit1hfname = hf_bit1lflags; + pvalues[1].bit2 = "List Containers"; + pvalues[1].bit2hfname = hf_bit2lflags; + pvalues[1].bit3 = "List Slashed"; + pvalues[1].bit3hfname = hf_bit3lflags; + pvalues[1].bit4 = "List Dotted"; + pvalues[1].bit4hfname = hf_bit4lflags; + pvalues[1].bit5 = "Dereference Alias"; + pvalues[1].bit5hfname = hf_bit5lflags; + pvalues[1].bit6 = "List All Containers"; + pvalues[1].bit6hfname = hf_bit6lflags; + pvalues[1].bit7 = "List Obsolete"; + pvalues[1].bit7hfname = hf_bit7lflags; + pvalues[1].bit8 = "List Tuned Output"; + pvalues[1].bit8hfname = hf_bit8lflags; + pvalues[1].bit9 = "List External Reference"; + pvalues[1].bit9hfname = hf_bit9lflags; + pvalues[1].bit10 = "Not Defined"; + pvalues[1].bit10hfname = hf_bit10lflags; + pvalues[1].bit11 = "Not Defined"; + pvalues[1].bit11hfname = hf_bit11lflags; + pvalues[1].bit12 = "Not Defined"; + pvalues[1].bit12hfname = hf_bit12lflags; + pvalues[1].bit13 = "Not Defined"; + pvalues[1].bit13hfname = hf_bit13lflags; + pvalues[1].bit14 = "Not Defined"; + pvalues[1].bit14hfname = hf_bit14lflags; + pvalues[1].bit15 = "Not Defined"; + pvalues[1].bit15hfname = hf_bit15lflags; + pvalues[1].bit16 = "Not Defined"; + pvalues[1].bit16hfname = hf_bit16lflags; + foffset = foffset+pvalues[1].vlength; + foffset += 2; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Iteration Handle: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_iteration; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vtype = VTYPE_UINT32; + pvalues[3].vdesc = "Parent ID: 0x%08x"; + pvalues[3].vlength = 4; + pvalues[3].voffset = foffset; + pvalues[3].hfname= hf_nds_parent; + foffset = foffset+pvalues[3].vlength; + pvalues[4].vvalue = tvb_get_letohs(tvb, foffset); + global_flags = tvb_get_letohl(tvb, foffset); + pvalues[4].vtype = VTYPE_BITFIELD; + pvalues[4].vdesc = "Information Flags (low) Byte:"; + pvalues[4].vlength = 2; + pvalues[4].hfname= hf_nds_rflags; + pvalues[4].voffset = foffset; + pvalues[4].bit1 = "Output Flags"; + pvalues[4].bit1hfname = hf_bit1infoflagsl; + pvalues[4].bit2 = "Entry ID"; + pvalues[4].bit2hfname = hf_bit2infoflagsl; + pvalues[4].bit3 = "Entry Flags"; + pvalues[4].bit3hfname = hf_bit3infoflagsl; + pvalues[4].bit4 = "Subordinate Count"; + pvalues[4].bit4hfname = hf_bit4infoflagsl; + pvalues[4].bit5 = "Modification Time"; + pvalues[4].bit5hfname = hf_bit5infoflagsl; + pvalues[4].bit6 = "Modification Timestamp"; + pvalues[4].bit6hfname = hf_bit6infoflagsl; + pvalues[4].bit7 = "Creation Timestamp"; + pvalues[4].bit7hfname = hf_bit7infoflagsl; + pvalues[4].bit8 = "Partition Root ID"; + pvalues[4].bit8hfname = hf_bit8infoflagsl; + pvalues[4].bit9 = "Parent ID"; + pvalues[4].bit9hfname = hf_bit9infoflagsl; + pvalues[4].bit10 = "Revision Count"; + pvalues[4].bit10hfname = hf_bit10infoflagsl; + pvalues[4].bit11 = "Replica Type"; + pvalues[4].bit11hfname = hf_bit11infoflagsl; + pvalues[4].bit12 = "Base Class"; + pvalues[4].bit12hfname = hf_bit12infoflagsl; + pvalues[4].bit13 = "Relative Distinguished Name"; + pvalues[4].bit13hfname = hf_bit13infoflagsl; + pvalues[4].bit14 = "Distinguished Name"; + pvalues[4].bit14hfname = hf_bit14infoflagsl; + pvalues[4].bit15 = "Root Distinguished Name"; + pvalues[4].bit15hfname = hf_bit15infoflagsl; + pvalues[4].bit16 = "Parent Distinguished Name"; + pvalues[4].bit16hfname = hf_bit16infoflagsl; + foffset = foffset+2; + pvalues[5].vvalue = tvb_get_letohs(tvb, foffset); + pvalues[5].vtype = VTYPE_BITFIELD; + pvalues[5].vdesc = "Information Flags (high) Byte:"; + pvalues[5].vlength = 2; + pvalues[5].hfname= hf_nds_rflags; + pvalues[5].voffset = foffset; + pvalues[5].bit1 = "Purge Time"; + pvalues[5].bit1hfname = hf_bit1infoflagsh; + pvalues[5].bit2 = "Dereference Base Class"; + pvalues[5].bit2hfname = hf_bit2infoflagsh; + pvalues[5].bit3 = "Not Defined"; + pvalues[5].bit3hfname = hf_bit3infoflagsh; + pvalues[5].bit4 = "Not Defined"; + pvalues[5].bit4hfname = hf_bit4infoflagsh; + pvalues[5].bit5 = "Not Defined"; + pvalues[5].bit5hfname = hf_bit5infoflagsh; + pvalues[5].bit6 = "Not Defined"; + pvalues[5].bit6hfname = hf_bit6infoflagsh; + pvalues[5].bit7 = "Not Defined"; + pvalues[5].bit7hfname = hf_bit7infoflagsh; + pvalues[5].bit8 = "Not Defined"; + pvalues[5].bit8hfname = hf_bit8infoflagsh; + pvalues[5].bit9 = "Not Defined"; + pvalues[5].bit9hfname = hf_bit9infoflagsh; + pvalues[5].bit10 = "Not Defined"; + pvalues[5].bit10hfname = hf_bit10infoflagsh; + pvalues[5].bit11 = "Not Defined"; + pvalues[5].bit11hfname = hf_bit11infoflagsh; + pvalues[5].bit12 = "Not Defined"; + pvalues[5].bit12hfname = hf_bit12infoflagsh; + pvalues[5].bit13 = "Not Defined"; + pvalues[5].bit13hfname = hf_bit13infoflagsh; + pvalues[5].bit14 = "Not Defined"; + pvalues[5].bit14hfname = hf_bit14infoflagsh; + pvalues[5].bit15 = "Not Defined"; + pvalues[5].bit15hfname = hf_bit15infoflagsh; + pvalues[5].bit16 = "Not Defined"; + pvalues[5].bit16hfname = hf_bit16infoflagsh; + foffset = foffset+2; + pvalues[6].vtype = VTYPE_STRING; + pvalues[6].vdesc = "Name Filter: %s"; + pvalues[6].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[6].vvalue = 0; + pvalues[6].vlength = 256; + pvalues[6].vlength = tvb_get_letohl(tvb, foffset); + pvalues[6].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[6].voffset, pvalues[6].vlength, pvalues[6].vstring); + pvalues[6].hfname= hf_nds_name_filter; + foffset = foffset+pvalues[6].vlength; + if(pvalues[0].vvalue == 0) + { + break; + } + foffset += align_4(tvb, foffset); + pvalues[7].vtype = VTYPE_STRING; + pvalues[7].vdesc = "Class Filter: %s"; + pvalues[7].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[7].vvalue = 0; + pvalues[7].vlength = 256; + pvalues[7].vlength = tvb_get_letohl(tvb, foffset); + pvalues[7].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[7].voffset, pvalues[7].vlength, pvalues[7].vstring); + pvalues[7].hfname= hf_nds_class_filter; + foffset = foffset+pvalues[7].vlength; + if(pvalues[0].vvalue == 1) + { + break; + } + foffset += align_4(tvb, foffset); + pvalues[8].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[8].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[8].vdesc = "Seconds: %u"; + pvalues[8].vlength = 4; + pvalues[8].mvtype = MVTYPE_PRINT_TIMESTAMP; + pvalues[8].hfname= hf_nds_time_filter; + pvalues[8].voffset = foffset; + break; + case 0x06: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vstring = ""; + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vstring = ""; + pvalues[1].vdesc = "Request Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].hfname= hf_nds_rflags; + pvalues[1].voffset = foffset; + foffset = foffset+4; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Iteration Handle: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_iteration; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vstring = ""; + pvalues[3].vtype = VTYPE_UINT32; + pvalues[3].vdesc = "Base Entry ID: 0x%08x"; + pvalues[3].vlength = 4; + resolve_eid = FALSE; + global_eid = pvalues[3].vvalue; + pvalues[3].voffset = foffset; + pvalues[3].hfname= hf_nds_eid; + foffset = foffset+pvalues[3].vlength; + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vstring = match_strval(pvalues[4].vvalue, nds_search_scope); + if(pvalues[4].vstring == NULL) + { + pvalues[4].vstring = "No Search Scope Defined"; + } + pvalues[4].vtype = VTYPE_STRING; + pvalues[4].vdesc = "Replica Type: %s"; + pvalues[4].vlength = 4; + pvalues[4].voffset = foffset; + pvalues[4].mvtype = 0; + pvalues[4].hfname= hf_nds_search_scope; + foffset = foffset + pvalues[4].vlength; + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].vtype = VTYPE_UINT32; + pvalues[5].vdesc = "Number of Objects to Search: 0x%08x"; + pvalues[5].vlength = 4; + pvalues[5].voffset = foffset; + pvalues[5].hfname= hf_nds_num_objects; + foffset = foffset+pvalues[5].vlength; + pvalues[6].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[6].vtype = VTYPE_BITFIELD; + pvalues[6].vdesc = "Information Types:"; + pvalues[6].vlength = 2; + pvalues[6].hfname= hf_nds_nflags; + pvalues[6].voffset = foffset; + pvalues[6].bit1 = "Names"; + pvalues[6].bit1hfname = hf_bit1siflags; + pvalues[6].bit2 = "Names and Values"; + pvalues[6].bit2hfname = hf_bit2siflags; + pvalues[6].bit3 = "Effective Privileges"; + pvalues[6].bit3hfname = hf_bit3siflags; + pvalues[6].bit4 = "Value Info"; + pvalues[6].bit4hfname = hf_bit4siflags; + pvalues[6].bit5 = "Abbreviated Value"; + pvalues[6].bit5hfname = hf_bit5siflags; + pvalues[6].bit6 = "Not Defined"; + pvalues[6].bit6hfname = hf_bit6siflags; + pvalues[6].bit7 = "Not Defined"; + pvalues[6].bit7hfname = hf_bit7siflags; + pvalues[6].bit8 = "Not Defined"; + pvalues[6].bit8hfname = hf_bit8siflags; + pvalues[6].bit9 = "Expanded Class"; + pvalues[6].bit9hfname = hf_bit9siflags; + pvalues[6].bit10 = "Not Defined"; + pvalues[6].bit10hfname = hf_bit10siflags; + pvalues[6].bit11= "Not Defined"; + pvalues[6].bit11hfname = hf_bit11siflags; + pvalues[6].bit12 = "Not Defined"; + pvalues[6].bit12hfname = hf_bit12siflags; + pvalues[6].bit13 = "Not Defined"; + pvalues[6].bit13hfname = hf_bit13siflags; + pvalues[6].bit14 = "Not Defined"; + pvalues[6].bit14hfname = hf_bit14siflags; + pvalues[6].bit15 = "Not Defined"; + pvalues[6].bit15hfname = hf_bit15siflags; + pvalues[6].bit16 = "Not Defined"; + pvalues[6].bit16hfname = hf_bit16siflags; + foffset = foffset+4; + if(pvalues[0].vvalue != 2) + { + pvalues[7].vvalue = tvb_get_letohs(tvb, foffset); + global_flags = tvb_get_letohl(tvb, foffset); + pvalues[7].vtype = VTYPE_BITFIELD; + pvalues[7].vdesc = "Information Flags (low) Byte:"; + pvalues[7].vlength = 2; + pvalues[7].hfname= hf_nds_rflags; + pvalues[7].voffset = foffset; + pvalues[7].bit1 = "Output Flags"; + pvalues[7].bit1hfname = hf_bit1infoflagsl; + pvalues[7].bit2 = "Entry ID"; + pvalues[7].bit2hfname = hf_bit2infoflagsl; + pvalues[7].bit3 = "Entry Flags"; + pvalues[7].bit3hfname = hf_bit3infoflagsl; + pvalues[7].bit4 = "Subordinate Count"; + pvalues[7].bit4hfname = hf_bit4infoflagsl; + pvalues[7].bit5 = "Modification Time"; + pvalues[7].bit5hfname = hf_bit5infoflagsl; + pvalues[7].bit6 = "Modification Timestamp"; + pvalues[7].bit6hfname = hf_bit6infoflagsl; + pvalues[7].bit7 = "Creation Timestamp"; + pvalues[7].bit7hfname = hf_bit7infoflagsl; + pvalues[7].bit8 = "Partition Root ID"; + pvalues[7].bit8hfname = hf_bit8infoflagsl; + pvalues[7].bit9 = "Parent ID"; + pvalues[7].bit9hfname = hf_bit9infoflagsl; + pvalues[7].bit10 = "Revision Count"; + pvalues[7].bit10hfname = hf_bit10infoflagsl; + pvalues[7].bit11 = "Replica Type"; + pvalues[7].bit11hfname = hf_bit11infoflagsl; + pvalues[7].bit12 = "Base Class"; + pvalues[7].bit12hfname = hf_bit12infoflagsl; + pvalues[7].bit13 = "Relative Distinguished Name"; + pvalues[7].bit13hfname = hf_bit13infoflagsl; + pvalues[7].bit14 = "Distinguished Name"; + pvalues[7].bit14hfname = hf_bit14infoflagsl; + pvalues[7].bit15 = "Root Distinguished Name"; + pvalues[7].bit15hfname = hf_bit15infoflagsl; + pvalues[7].bit16 = "Parent Distinguished Name"; + pvalues[7].bit16hfname = hf_bit16infoflagsl; + foffset = foffset+2; + pvalues[8].vvalue = tvb_get_letohs(tvb, foffset); + pvalues[8].vtype = VTYPE_BITFIELD; + pvalues[8].vdesc = "Information Flags (high) Byte:"; + pvalues[8].vlength = 2; + pvalues[8].hfname= hf_nds_rflags; + pvalues[8].voffset = foffset; + pvalues[8].bit1 = "Purge Time"; + pvalues[8].bit1hfname = hf_bit1infoflagsh; + pvalues[8].bit2 = "Dereference Base Class"; + pvalues[8].bit2hfname = hf_bit2infoflagsh; + pvalues[8].bit3 = "Not Defined"; + pvalues[8].bit3hfname = hf_bit3infoflagsh; + pvalues[8].bit4 = "Not Defined"; + pvalues[8].bit4hfname = hf_bit4infoflagsh; + pvalues[8].bit5 = "Not Defined"; + pvalues[8].bit5hfname = hf_bit5infoflagsh; + pvalues[8].bit6 = "Not Defined"; + pvalues[8].bit6hfname = hf_bit6infoflagsh; + pvalues[8].bit7 = "Not Defined"; + pvalues[8].bit7hfname = hf_bit7infoflagsh; + pvalues[8].bit8 = "Not Defined"; + pvalues[8].bit8hfname = hf_bit8infoflagsh; + pvalues[8].bit9 = "Not Defined"; + pvalues[8].bit9hfname = hf_bit9infoflagsh; + pvalues[8].bit10 = "Not Defined"; + pvalues[8].bit10hfname = hf_bit10infoflagsh; + pvalues[8].bit11 = "Not Defined"; + pvalues[8].bit11hfname = hf_bit11infoflagsh; + pvalues[8].bit12 = "Not Defined"; + pvalues[8].bit12hfname = hf_bit12infoflagsh; + pvalues[8].bit13 = "Not Defined"; + pvalues[8].bit13hfname = hf_bit13infoflagsh; + pvalues[8].bit14 = "Not Defined"; + pvalues[8].bit14hfname = hf_bit14infoflagsh; + pvalues[8].bit15 = "Not Defined"; + pvalues[8].bit15hfname = hf_bit15infoflagsh; + pvalues[8].bit16 = "Not Defined"; + pvalues[8].bit16hfname = hf_bit16infoflagsh; + foffset = foffset+2; + } + break; + case 0x07: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vstring = ""; + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vstring = ""; + pvalues[1].vdesc = "Request Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].hfname= hf_nds_rflags; + pvalues[1].voffset = foffset; + foffset = foffset+4; + if(pvalues[0].vvalue == 0) + { + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vstring = ""; + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Parent Entry ID: 0x%08x"; + pvalues[2].vlength = 4; + resolve_eid = FALSE; + global_eid = pvalues[2].vvalue; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_eid; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "Relative Distinguished Name: %s"; + pvalues[3].vstring = ""; + pvalues[3].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[3].vvalue = 0; + pvalues[3].vlength = 256; + pvalues[3].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[3].vlength == 0x00) + { + pvalues[3].vtype = VTYPE_NONE; + break; + } + pvalues[3].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[3].voffset, pvalues[3].vlength, req_buffer.buffer); + pvalues[3].vstring = req_buffer.buffer; + strcpy(global_object_name, req_buffer.buffer); + pvalues[3].hfname= hf_nds_relative_dn; + foffset = foffset+pvalues[3].vlength; + foffset += align_4(tvb, foffset); + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[4].vstring = ""; + pvalues[4].vdesc = "Attributes: %u"; + pvalues[4].vlength = 4; + pvalues[4].voffset = foffset; + pvalues[4].mvtype = MVTYPE_ADD_ATTR_REQUEST; + pvalues[4].hfname= hf_nds_attr; + } + else + { + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vstring = ""; + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Iteration Handle: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_iteration; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vstring = ""; + pvalues[3].vtype = VTYPE_UINT32; + pvalues[3].vdesc = "Parent Entry ID: 0x%08x"; + pvalues[3].vlength = 4; + resolve_eid = FALSE; + global_eid = pvalues[3].vvalue; + pvalues[3].voffset = foffset; + pvalues[3].hfname= hf_nds_eid; + foffset = foffset+pvalues[3].vlength; + pvalues[4].vtype = VTYPE_STRING; + pvalues[4].vdesc = "Relative Distinguished Name: %s"; + pvalues[4].vstring = ""; + pvalues[4].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[4].vvalue = 0; + pvalues[4].vlength = 256; + pvalues[4].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[4].vlength == 0x00) + { + pvalues[4].vtype = VTYPE_NONE; + break; + } + pvalues[4].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[4].voffset, pvalues[4].vlength, req_buffer.buffer); + pvalues[4].vstring = req_buffer.buffer; + strcpy(global_object_name, req_buffer.buffer); + pvalues[4].hfname= hf_nds_relative_dn; + foffset = foffset+pvalues[4].vlength; + foffset += align_4(tvb, foffset); + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[5].vstring = ""; + pvalues[5].vdesc = "Attributes: %u"; + pvalues[5].vlength = 4; + pvalues[5].voffset = foffset; + pvalues[5].mvtype = MVTYPE_ADD_ATTR_REQUEST; + pvalues[5].hfname= hf_nds_attr; + } + break; + case 0x08: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + pvalues[1].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[1].vvalue; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_eid; + foffset = foffset+pvalues[1].vlength; + break; + case 0x09: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + if(pvalues[0].vvalue == 0) + { + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vstring = ""; + pvalues[1].vdesc = "Iteration Handle: 0x%08x"; /* always 0 */ + pvalues[1].vlength = 4; + pvalues[1].hfname= hf_nds_iteration; + pvalues[1].voffset = foffset; + foffset = foffset+4; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vstring = ""; + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Entry ID: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + resolve_eid = TRUE; + global_eid = pvalues[2].vvalue; + pvalues[2].hfname = hf_nds_eid; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[3].vstring = ""; + pvalues[3].vdesc = "Number of Attributes to Change %u"; + pvalues[3].vlength = 4; + pvalues[3].mvtype = MVTYPE_MODIFY_ATTR_REQUEST; + pvalues[3].hfname= hf_nds_number_of_changes; + pvalues[3].voffset = foffset; + } + else + { + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vstring = ""; + pvalues[1].vdesc = "Request Flags: 0x%08x"; /* always 0 */ + pvalues[1].vlength = 4; + pvalues[1].hfname= hf_nds_rflags; + pvalues[1].voffset = foffset; + foffset = foffset+4; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vstring = ""; + pvalues[2].vdesc = "Iteration Handle: 0x%08x"; /* always 0 */ + pvalues[2].vlength = 4; + pvalues[2].hfname= hf_nds_iteration; + pvalues[2].voffset = foffset; + foffset = foffset+4; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vstring = ""; + pvalues[3].vtype = VTYPE_UINT32; + pvalues[3].vdesc = "Entry ID: 0x%08x"; + pvalues[3].vlength = 4; + pvalues[3].voffset = foffset; + resolve_eid = TRUE; + global_eid = pvalues[3].vvalue; + pvalues[3].hfname = hf_nds_eid; + foffset = foffset+pvalues[3].vlength; + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[4].vstring = ""; + pvalues[4].vdesc = "Number of Attributes to Change %u"; + pvalues[4].vlength = 4; + pvalues[4].mvtype = MVTYPE_MODIFY_ATTR_REQUEST; + pvalues[4].hfname= hf_nds_number_of_changes; + pvalues[4].voffset = foffset; + } + break; + case 0x0a: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + pvalues[1].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[1].vvalue; + pvalues[1].voffset = foffset; + pvalues[1].hfname = hf_nds_eid; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_BOOLEAN; + pvalues[2].vdesc = "Keep Original RDN: %s"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].mvtype = 0; + pvalues[2].hfname= hf_nds_keep; + foffset = foffset+4; + foffset += align_4(tvb, foffset); + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "New RDN: %s"; + pvalues[3].mvtype = 0; + pvalues[3].vvalue = 0; + pvalues[3].vlength = 256; + pvalues[3].vlength = tvb_get_letohl(tvb, foffset); + pvalues[3].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[3].voffset, pvalues[3].vlength, pvalues[3].vstring); + pvalues[3].hfname= hf_nds_new_rdn; + foffset = foffset+pvalues[3].vlength; + break; + case 0x0b: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohs(tvb, foffset); + global_flags = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_BITFIELD; + pvalues[1].vdesc = "Attribute Constraints:"; + pvalues[1].vlength = 2; + pvalues[1].hfname= hf_nds_acflags; + pvalues[1].voffset = foffset; + pvalues[1].bit1 = "Single Valued"; + pvalues[1].bit1hfname = hf_bit1acflags; + pvalues[1].bit2 = "Sized"; + pvalues[1].bit2hfname = hf_bit2acflags; + pvalues[1].bit3 = "Non-Removable"; + pvalues[1].bit3hfname = hf_bit3acflags; + pvalues[1].bit4 = "Read Only"; + pvalues[1].bit4hfname = hf_bit4acflags; + pvalues[1].bit5 = "Hidden"; + pvalues[1].bit5hfname = hf_bit5acflags; + pvalues[1].bit6 = "String"; + pvalues[1].bit6hfname = hf_bit6acflags; + pvalues[1].bit7 = "Synchronize Immediate"; + pvalues[1].bit7hfname = hf_bit7acflags; + pvalues[1].bit8 = "Public Read"; + pvalues[1].bit8hfname = hf_bit8acflags; + pvalues[1].bit9 = "Server Read"; + pvalues[1].bit9hfname = hf_bit9acflags; + pvalues[1].bit10 = "Write Managed"; + pvalues[1].bit10hfname = hf_bit10acflags; + pvalues[1].bit11 = "Per Replica"; + pvalues[1].bit11hfname = hf_bit11acflags; + pvalues[1].bit12 = "Never Schedule Synchronization"; + pvalues[1].bit12hfname = hf_bit12acflags; + pvalues[1].bit13 = "Operational"; + pvalues[1].bit13hfname = hf_bit13acflags; + pvalues[1].bit14 = "Not Defined"; + pvalues[1].bit14hfname = hf_bit14acflags; + pvalues[1].bit15 = "Not Defined"; + pvalues[1].bit15hfname = hf_bit15acflags; + pvalues[1].bit16 = "Not Defined"; + pvalues[1].bit16hfname = hf_bit16acflags; + foffset = foffset+4; + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Attribute Name: %s"; + pvalues[2].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[2].vvalue = 0; + pvalues[2].vlength = 256; + pvalues[2].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[2].vlength == 0x00) + { + pvalues[2].vtype = VTYPE_NONE; + break; + } + pvalues[2].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[2].voffset, pvalues[2].vlength, req_buffer.buffer); + pvalues[2].vstring = req_buffer.buffer; + strcpy(global_object_name, req_buffer.buffer); + pvalues[2].hfname= hf_nds_name; + foffset = foffset+pvalues[2].vlength; + foffset += align_4(tvb, foffset); + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vstring = match_strval(pvalues[3].vvalue, nds_syntax); + if(pvalues[3].vstring == NULL) + { + pvalues[3].vstring = "No Syntax Found"; + } + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "Syntax: %s"; + pvalues[3].vlength = 4; + pvalues[3].voffset = foffset; + pvalues[3].hfname= hf_nds_syntax; + pvalues[3].mvtype = 0; + foffset = foffset+pvalues[3].vlength; + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vtype = VTYPE_UINT32; + pvalues[4].vdesc = "Lower Limit Value %u"; + pvalues[4].vlength = 4; + pvalues[4].voffset = foffset; + pvalues[4].hfname = hf_nds_lower; + foffset += 4; + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].vtype = VTYPE_UINT32; + pvalues[5].vdesc = "Upper Limit Value %u"; + pvalues[5].vlength = 4; + pvalues[5].voffset = foffset; + pvalues[5].hfname = hf_nds_upper; + foffset += 4; + pvalues[6].vvalue = tvb_get_letohl(tvb, foffset); /* Length of bytes field */ + foffset += 4; + pvalues[6].vtype = VTYPE_BYTES; + pvalues[6].vdesc = "ASN.1 ID"; + pvalues[6].vlength = pvalues[6].vvalue; + pvalues[6].voffset = foffset; + pvalues[6].hfname = hf_nds_asn1; + break; + case 0x0c: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x0d: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Attribute Name: %s"; + pvalues[1].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[1].vvalue = 0; + pvalues[1].vlength = 256; + pvalues[1].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[1].vlength == 0x00) + { + pvalues[1].vtype = VTYPE_NONE; + break; + } + pvalues[1].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[1].voffset, pvalues[1].vlength, req_buffer.buffer); + pvalues[1].vstring = req_buffer.buffer; + strcpy(global_object_name, req_buffer.buffer); + pvalues[1].hfname= hf_nds_attribute_dn; + break; + case 0x0e: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x0f: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Iteration Handle: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_iteration; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + global_flags = pvalues[2].vvalue; + pvalues[2].vstring = match_strval(pvalues[2].vvalue, class_def_type); + if(pvalues[2].vstring == NULL) + { + pvalues[2].vstring = "No Class Definition Type Set"; + } + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Class Definition Type: %s"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].mvtype = 0; + pvalues[2].hfname= hf_nds_class_def_type; + foffset = foffset + pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + if (pvalues[3].vvalue == 0x00000000) + { + pvalues[3].vstring = "Do Not Return All Classes"; + pvalues[3].mvtype = 0; + } + else + { + pvalues[3].vstring = "Return All Classes"; + pvalues[3].mvtype = MVTYPE_ATTR_REQUEST; + } + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "%s"; + pvalues[3].vlength = 4; + pvalues[3].voffset = foffset; + pvalues[3].hfname= hf_nds_return_all_classes; + foffset = foffset + pvalues[3].vlength; + foffset += align_4(tvb, foffset); + pvalues[4].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[4].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[4].vdesc = "Classes: %d"; + pvalues[4].vlength = 4; + pvalues[4].voffset = foffset; + pvalues[4].mvtype = MVTYPE_READ_CLASS_REQ; + pvalues[4].hfname= hf_nds_classes; + break; + case 0x10: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Class Name: %s"; + pvalues[1].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[1].vvalue = 0; + pvalues[1].vlength = 256; + pvalues[1].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[1].vlength == 0x00) + { + pvalues[1].vtype = VTYPE_NONE; + break; + } + pvalues[1].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[1].voffset, pvalues[1].vlength, req_buffer.buffer); + pvalues[1].vstring = req_buffer.buffer; + strcpy(global_object_name, req_buffer.buffer); + pvalues[1].hfname= hf_nds_base_class; + foffset = foffset+pvalues[1].vlength; + foffset += align_4(tvb, foffset); + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_MULTIVALUE_UINT32; + pvalues[2].vdesc = "Number of Attributes to Add: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].mvtype = MVTYPE_MODIFY_CLASS; + pvalues[2].hfname= hf_nds_att_add; + break; + case 0x11: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vtype = VTYPE_STRING; + pvalues[1].vdesc = "Class Name: %s"; + pvalues[1].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[1].vvalue = 0; + pvalues[1].vlength = 256; + pvalues[1].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[1].vlength == 0x00) + { + pvalues[1].vtype = VTYPE_NONE; + break; + } + pvalues[1].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[1].voffset, pvalues[1].vlength, req_buffer.buffer); + pvalues[1].vstring = req_buffer.buffer; + strcpy(global_object_name, req_buffer.buffer); + pvalues[1].hfname= hf_nds_base; + break; + case 0x12: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Iteration Handle: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_iteration; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Entry ID: 0x%08x"; + pvalues[2].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[2].vvalue; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_eid; + foffset = foffset+pvalues[2].vlength; + break; + case 0x13: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + pvalues[1].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[1].vvalue; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_eid; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vtype = VTYPE_STRING; + pvalues[2].vdesc = "Trustee Name: %s"; + pvalues[2].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[2].vvalue = 0; + pvalues[2].vlength = 256; + pvalues[2].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[2].vlength == 0x00) + { + pvalues[2].vtype = VTYPE_NONE; + break; + } + pvalues[2].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[2].voffset, pvalues[2].vlength, req_buffer.buffer); + pvalues[2].vstring = req_buffer.buffer; + pvalues[2].hfname= hf_nds_name; + foffset = foffset+pvalues[2].vlength; + foffset += align_4(tvb, foffset); + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "Attribute to be Checked: %s"; + pvalues[3].mvtype = 0; + pvalues[3].vvalue = 0; + pvalues[3].vlength = 256; + pvalues[3].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[3].vlength == 0x00) + { + pvalues[3].vtype = VTYPE_NONE; + break; + } + pvalues[3].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[3].voffset, pvalues[3].vlength, pvalues[3].vstring); + pvalues[3].hfname= hf_nds_name; + foffset = foffset+pvalues[3].vlength; + foffset += align_4(tvb, foffset); + if(pvalues[0].vvalue != 0) + { + pvalues[4].vtype = VTYPE_STRING; + pvalues[4].vdesc = "Security Equivalence: %s"; + pvalues[4].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[4].vvalue = 0; + pvalues[4].vlength = 256; + pvalues[4].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[4].vlength == 0x00) + { + pvalues[4].vtype = VTYPE_NONE; + break; + } + pvalues[4].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[4].voffset, pvalues[4].vlength, pvalues[4].vstring); + pvalues[4].hfname= hf_nds_name; + foffset = foffset+pvalues[4].vlength; + foffset += align_4(tvb, foffset); + } + break; + case 0x14: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x15: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x16: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_BITFIELD; + pvalues[1].vdesc = "Request Flags:"; + pvalues[1].vlength = 2; + pvalues[1].hfname= hf_nds_rflags; + pvalues[1].voffset = foffset; + pvalues[1].bit1 = "Typeless"; + pvalues[1].bit1hfname = hf_nds_bit1; + pvalues[1].bit2 = "All Containers"; + pvalues[1].bit2hfname = hf_nds_bit2; + pvalues[1].bit3 = "Slashed"; + pvalues[1].bit3hfname = hf_nds_bit3; + pvalues[1].bit4 = "Dotted"; + pvalues[1].bit4hfname = hf_nds_bit4; + pvalues[1].bit5 = "Tuned"; + pvalues[1].bit5hfname = hf_nds_bit5; + pvalues[1].bit6 = "Not Defined"; + pvalues[1].bit6hfname = hf_nds_bit6; + pvalues[1].bit7 = "Not Defined"; + pvalues[1].bit7hfname = hf_nds_bit7; + pvalues[1].bit8 = "Not Defined"; + pvalues[1].bit8hfname = hf_nds_bit8; + pvalues[1].bit9 = "Not Defined"; + pvalues[1].bit9hfname = hf_nds_bit9; + pvalues[1].bit10 = "Not Defined"; + pvalues[1].bit10hfname = hf_nds_bit10; + pvalues[1].bit11 = "Not Defined"; + pvalues[1].bit11hfname = hf_nds_bit11; + pvalues[1].bit12 = "Not Defined"; + pvalues[1].bit12hfname = hf_nds_bit12; + pvalues[1].bit13 = "Not Defined"; + pvalues[1].bit13hfname = hf_nds_bit13; + pvalues[1].bit14 = "Not Defined"; + pvalues[1].bit14hfname = hf_nds_bit14; + pvalues[1].bit15 = "Not Defined"; + pvalues[1].bit15hfname = hf_nds_bit15; + pvalues[1].bit16 = "Not Defined"; + pvalues[1].bit16hfname = hf_nds_bit16; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Iteration Handle: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_iteration; + foffset = foffset+pvalues[2].vlength; + if(pvalues[0].vvalue == 0) + { + global_flags = 0x000000c0; + break; + } + pvalues[3].vvalue = tvb_get_letohs(tvb, foffset); + pvalues[3].vtype = VTYPE_BITFIELD; + pvalues[3].vdesc = "Information Flags (low) Byte:"; + pvalues[3].vlength = 2; + pvalues[3].hfname= hf_nds_rflags; + pvalues[3].voffset = foffset; + pvalues[3].bit1 = "Output Flags"; + pvalues[3].bit1hfname = hf_bit1l1flagsl; + pvalues[3].bit2 = "Entry ID"; + pvalues[3].bit2hfname = hf_bit2l1flagsl; + pvalues[3].bit3 = "Replica State"; + pvalues[3].bit3hfname = hf_bit3l1flagsl; + pvalues[3].bit4 = "Modification Timestamp"; + pvalues[3].bit4hfname = hf_bit4l1flagsl; + pvalues[3].bit5 = "Purge Time"; + pvalues[3].bit5hfname = hf_bit5l1flagsl; + pvalues[3].bit6 = "Local Partition ID"; + pvalues[3].bit6hfname = hf_bit6l1flagsl; + pvalues[3].bit7 = "Distinguished Name"; + pvalues[3].bit7hfname = hf_bit7l1flagsl; + pvalues[3].bit8 = "Replica Type"; + pvalues[3].bit8hfname = hf_bit8l1flagsl; + pvalues[3].bit9 = "Partition Busy"; + pvalues[3].bit9hfname = hf_bit9l1flagsl; + pvalues[3].bit10 = "Not Defined"; + pvalues[3].bit10hfname = hf_bit10l1flagsl; + pvalues[3].bit11 = "Not Defined"; + pvalues[3].bit11hfname = hf_bit11l1flagsl; + pvalues[3].bit12 = "Not Defined"; + pvalues[3].bit12hfname = hf_bit12l1flagsl; + pvalues[3].bit13 = "Not Defined"; + pvalues[3].bit13hfname = hf_bit13l1flagsl; + pvalues[3].bit14 = "Not Defined"; + pvalues[3].bit14hfname = hf_bit14l1flagsl; + pvalues[3].bit15 = "Not Defined"; + pvalues[3].bit15hfname = hf_bit15l1flagsl; + pvalues[3].bit16 = "Not Defined"; + pvalues[3].bit16hfname = hf_bit16l1flagsl; + global_flags = pvalues[3].vvalue; + foffset = foffset+2; + pvalues[4].vvalue = tvb_get_letohs(tvb, foffset); + pvalues[4].vtype = VTYPE_BITFIELD; + pvalues[4].vdesc = "Information Flags (high) Byte:"; + pvalues[4].vlength = 2; + pvalues[4].hfname= hf_nds_rflags; + pvalues[4].voffset = foffset; + pvalues[4].bit1 = "Not Defined"; + pvalues[4].bit1hfname = hf_bit1l1flagsl; + pvalues[4].bit2 = "Not Defined"; + pvalues[4].bit2hfname = hf_bit2l1flagsl; + pvalues[4].bit3 = "Not Defined"; + pvalues[4].bit3hfname = hf_bit3l1flagsl; + pvalues[4].bit4 = "Not Defined"; + pvalues[4].bit4hfname = hf_bit4l1flagsl; + pvalues[4].bit5 = "Not Defined"; + pvalues[4].bit5hfname = hf_bit5l1flagsl; + pvalues[4].bit6 = "Not Defined"; + pvalues[4].bit6hfname = hf_bit6l1flagsl; + pvalues[4].bit7 = "Not Defined"; + pvalues[4].bit7hfname = hf_bit7l1flagsl; + pvalues[4].bit8 = "Not Defined"; + pvalues[4].bit8hfname = hf_bit8l1flagsl; + pvalues[4].bit9 = "Not Defined"; + pvalues[4].bit9hfname = hf_bit9l1flagsl; + pvalues[4].bit10 = "Not Defined"; + pvalues[4].bit10hfname = hf_bit10l1flagsl; + pvalues[4].bit11 = "Not Defined"; + pvalues[4].bit11hfname = hf_bit11l1flagsl; + pvalues[4].bit12 = "Not Defined"; + pvalues[4].bit12hfname = hf_bit12l1flagsl; + pvalues[4].bit13 = "Not Defined"; + pvalues[4].bit13hfname = hf_bit13l1flagsl; + pvalues[4].bit14 = "Not Defined"; + pvalues[4].bit14hfname = hf_bit14l1flagsl; + pvalues[4].bit15 = "Not Defined"; + pvalues[4].bit15hfname = hf_bit15l1flagsl; + pvalues[4].bit16 = "Not Defined"; + pvalues[4].bit16hfname = hf_bit16l1flagsl; + foffset = foffset+2; + if(pvalues[0].vvalue == 1) + { + break; + } + pvalues[5].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[5].vtype = VTYPE_UINT32; + pvalues[5].vdesc = "Partition Root ID: 0x%08x"; + pvalues[5].vlength = 4; + pvalues[5].voffset = foffset; + pvalues[5].hfname= hf_nds_partition_root_id; + foffset = foffset+pvalues[5].vlength; + break; + case 0x17: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[0].vvalue; + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].hfname = hf_nds_ver; + pvalues[0].voffset = foffset; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[1].vvalue; + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].hfname = hf_nds_req_flags; + pvalues[1].voffset = foffset; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "New Partition Root ID: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_new_part_id; + foffset = foffset+pvalues[2].vlength; + break; + case 0x18: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[0].vvalue; + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].hfname = hf_nds_ver; + pvalues[0].voffset = foffset; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[1].vvalue; + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].hfname = hf_nds_req_flags; + pvalues[1].voffset = foffset; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Child Partition Root ID: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_child_part_id; + foffset = foffset+pvalues[2].vlength; + break; + case 0x19: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[0].vvalue; + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].hfname = hf_nds_ver; + pvalues[0].voffset = foffset; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[1].vvalue; + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].hfname = hf_nds_req_flags; + pvalues[1].voffset = foffset; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Master Partition Root ID: 0x%08x"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_master_part_id; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vstring = match_strval(pvalues[3].vvalue, nds_replica_type); + if(pvalues[3].vstring == NULL) + { + pvalues[3].vstring = "No Replica Type Found"; + } + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "Replica Type: %s"; + pvalues[3].vlength = 4; + pvalues[3].voffset = foffset; + pvalues[3].mvtype = 0; + pvalues[3].hfname= hf_replica_type; + foffset = foffset + pvalues[3].vlength; + pvalues[4].vtype = VTYPE_STRING; + pvalues[4].vdesc = "Target Server Name: %s"; + pvalues[4].mvtype = 0; + pvalues[4].vvalue = 0; + pvalues[4].vlength = 256; + pvalues[4].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[4].vlength == 0x00) + { + pvalues[4].vtype = VTYPE_NONE; + break; + } + pvalues[4].voffset = foffset+4; + foffset = foffset + 4; + get_string(tvb, pvalues[4].voffset, pvalues[4].vlength, pvalues[4].vstring); + pvalues[4].hfname= hf_nds_target_name; + break; + case 0x1a: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x1b: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[0].vvalue; + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].hfname = hf_nds_ver; + pvalues[0].voffset = foffset; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[1].vvalue; + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Streams Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].hfname = hf_nds_stream_flags; + pvalues[1].voffset = foffset; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Entry ID: 0x%08x"; + pvalues[2].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[2].vvalue; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_eid; + foffset = foffset+pvalues[2].vlength; + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "Stream Name: %s"; + pvalues[3].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[3].vvalue = 0; + pvalues[3].vlength = 256; + pvalues[3].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[3].vlength == 0x00) + { + pvalues[3].vtype = VTYPE_NONE; + break; + } + pvalues[3].voffset = foffset+4; + foffset += 4; + get_string(tvb, pvalues[3].voffset, pvalues[3].vlength, pvalues[3].vstring); + foffset += pvalues[3].vlength; + foffset += align_4(tvb, foffset); + pvalues[3].hfname= hf_nds_stream_name; + break; + case 0x1c: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x1d: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x1e: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x1f: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x20: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x21: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x22: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x23: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x24: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x25: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x26: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[0].vvalue; + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].hfname = hf_nds_ver; + pvalues[0].voffset = foffset; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + nds_version = pvalues[1].vvalue; + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Flags: 0x%08x"; + pvalues[1].vlength = 4; + pvalues[1].hfname = hf_nds_req_flags; + pvalues[1].voffset = foffset; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Time Delay in Seconds: %u"; + pvalues[2].vlength = 4; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_time_delay; + foffset = foffset+pvalues[2].vlength; + if(pvalues[0].vvalue == 0) + { + pvalues[3].vtype = VTYPE_STRING; + pvalues[3].vdesc = "Root Most Object Name: %s"; + pvalues[3].mvtype = MVTYPE_ATTR_REQUEST; + pvalues[3].vvalue = 0; + pvalues[3].vlength = 256; + pvalues[3].vlength = tvb_get_letohl(tvb, foffset); + if (pvalues[3].vlength == 0x00) + { + pvalues[3].vtype = VTYPE_NONE; + break; + } + pvalues[3].voffset = foffset+4; + foffset += 4; + get_string(tvb, pvalues[3].voffset, pvalues[3].vlength, pvalues[3].vstring); + foffset += pvalues[3].vlength; + foffset += align_4(tvb, foffset); + pvalues[3].hfname= hf_nds_root_name; + } + else + { + pvalues[3].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[3].vtype = VTYPE_UINT32; + pvalues[3].vdesc = "Entry ID: 0x%08x"; + pvalues[3].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[3].vvalue; + pvalues[3].voffset = foffset; + pvalues[3].hfname= hf_nds_eid; + foffset = foffset+pvalues[3].vlength; + resolve_eid = TRUE; + global_eid = pvalues[3].vvalue; + } + break; + case 0x27: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x28: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x29: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x2a: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x2b: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x2c: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x2d: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x2e: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x2f: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x30: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x31: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x32: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x33: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x34: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x35: + pvalues[0].vvalue = 0; + break; + case 0x36: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x37: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x38: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x39: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + pvalues[1].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[1].vvalue; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_eid; + foffset = foffset+pvalues[1].vlength; + break; + case 0x3a: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Reply Buffer Size: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_buffer_size; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Version: %u"; + pvalues[1].vlength = 4; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_ver; + foffset = foffset+pvalues[1].vlength; + pvalues[2].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[2].vtype = VTYPE_UINT32; + pvalues[2].vdesc = "Entry ID: 0x%08x"; + pvalues[2].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[2].vvalue; + pvalues[2].voffset = foffset; + pvalues[2].hfname= hf_nds_eid; + foffset = foffset+pvalues[2].vlength; + break; + case 0x3b: + pvalues[0].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[0].vtype = VTYPE_UINT32; + pvalues[0].vdesc = "Version: %u"; + pvalues[0].vlength = 4; + pvalues[0].voffset = foffset; + pvalues[0].hfname= hf_nds_ver; + foffset = foffset+pvalues[0].vlength; + pvalues[1].vvalue = tvb_get_letohl(tvb, foffset); + pvalues[1].vtype = VTYPE_UINT32; + pvalues[1].vdesc = "Entry ID: 0x%08x"; + pvalues[1].vlength = 4; + resolve_eid = TRUE; + global_eid = pvalues[1].vvalue; + pvalues[1].voffset = foffset; + pvalues[1].hfname= hf_nds_eid; + foffset = foffset+pvalues[1].vlength; + break; + case 0x3c: + break; + case 0x3d: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x3e: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x3f: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x40: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x41: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x42: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x43: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x44: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x45: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x46: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x47: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x48: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x49: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x4a: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x4b: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x4c: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + case 0x4d: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + break; + default: + pvalues[0].vtype = VTYPE_NONE; /* Not Defined */ + } + } + /* Fill in the INFO column. */ + if (check_col(pinfo->cinfo, COL_INFO)) { + if (ncp_rec) { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDS"); + if (nds_frag != 0xffffffff) { + col_add_fstr(pinfo->cinfo, COL_INFO, "C Continue NDS Fragment %08x", nds_frag); + } + else { + col_add_fstr(pinfo->cinfo, COL_INFO, "C NDS %s", verb_string); + } + run_info_str = TRUE; + } + else { + col_add_fstr(pinfo->cinfo, COL_INFO, + "C Unknown Function %d (0x%02x)", + func, func); + } + + } + + /* Keep track of the address and connection whence the request + came, and the address and connection to which the request + is being sent, so that we can match up calls with replies. + (We don't include the sequence number, as we may want + to have all packets over the same connection treated + as being part of a single conversation so that we can + let the user select that conversation to be displayed.) */ + + conversation = find_conversation(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + if (conversation == NULL) { + /* It's not part of any conversation - create a new one. */ + conversation = conversation_new(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + } + + if (!pinfo->fd->flags.visited) { + request_value = ncp_hash_insert(conversation, sequence, ncp_rec); + request_value->req_frame_num = pinfo->fd->num; + request_value->req_frame_time.secs=pinfo->fd->abs_secs; + request_value->req_frame_time.nsecs=pinfo->fd->abs_usecs*1000; + + /* If this is the first time we're examining the packet, + * check to see if this NCP type uses a "request condition". + * If so, we have to build a proto_tree because request conditions + * use display filters to work, and without a proto_tree, + * display filters can't possibly work. If we already have + * a proto_tree, then wonderful. If we don't, we need to build + * one. */ + if (ncp_rec && !ncp_tree) { + run_req_cond = TRUE; + } + /* Keep track of the Fragment number in the request for defrag logic */ + request_value->nds_frag_num = nds_frag; + } + + /* If we have to handle a request condition, or have to + add to the Info column, we need to construct a protocol + tree. If we already have a proto_tree, then wonderful. + If we don't, we need to build one. */ + if ((run_info_str || run_req_cond) && !ncp_tree) { + proto_item *ti; + + temp_tree = proto_tree_create_root(); + proto_tree_set_visible(temp_tree, FALSE); + ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE); + ncp_tree = proto_item_add_subtree(ti, ett_ncp); + } + + if (ncp_tree) { + /* If the dissection throws an exception, be sure to free + * the temporary proto_tree that was created. Because of the + * way the CLEANUP_PUSH macro works, we can't put it in an 'if' + * block; it has to be in the same scope as the terminating + * CLEANUP_POP or CLEANUP_POP_AND_ALLOC. So, we always + * call CLEANUP_POP and friends, but the value of temp_tree is + * NULL if no cleanup is needed, and non-null if cleanup is needed. + */ + + CLEANUP_PUSH(free_proto_tree, temp_tree); + + request_value = ncp_hash_lookup(conversation, sequence); + + switch (type) { + case NCP_BROADCAST_SLOT: + ; /* nothing */ + break; + + case NCP_SERVICE_REQUEST: + + ptvc = ptvcursor_new(ncp_tree, tvb, 7); + if (ncp_rec && ncp_rec->request_ptvc) + { + clear_repeat_vars(); + process_ptvc_record(ptvc, ncp_rec->request_ptvc, NULL, TRUE, ncp_rec); + } + proto_tree_add_uint_format(ncp_tree, hf_ncp_func, tvb, 6, 1, + func, "Function: %d (0x%02X), %s", + func, func, ncp_rec ? ncp_rec->name : "Unknown"); + + proto_tree_add_uint_format(ncp_tree, hf_ncp_subfunc, tvb, 7, 1, + subfunc, "SubFunction: %d (0x%02x)", + subfunc, subfunc); + + proto_tree_add_uint(ncp_tree, hf_ncp_fragment_handle, tvb, 8, 4, + nds_frag); + + if (nds_frag == 0xffffffff) { + + proto_tree_add_item(ncp_tree, hf_ncp_fragment_size, tvb, 12, 4, TRUE); + + proto_tree_add_item(ncp_tree, hf_ncp_message_size, tvb, 16, 4, TRUE); + + proto_tree_add_item(ncp_tree, hf_ncp_nds_flag, tvb, 20, 4, FALSE); + + proto_tree_add_uint_format(ncp_tree, hf_ncp_nds_verb, tvb, 24, 4, + nds_verb, "NDS Verb: %d, (0x%02x), %s", + nds_verb, nds_verb, verb_string); + added_arrow = FALSE; + for (i = 0; i < 9; i++) { + switch (pvalues[i].vtype) { + + case VTYPE_NONE: /* no value */ + break; + + case VTYPE_UINT8: + proto_tree_add_uint_format(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vtype, "NDS Parameter not defined %d", + pvalues[i].vtype); + break; + + case VTYPE_UINT16: + proto_tree_add_uint_format(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vtype, "NDS Parameter not defined %d", + pvalues[i].vtype); + break; + + case VTYPE_UINT32: + proto_tree_add_uint_format(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vvalue, pvalues[i].vdesc, + pvalues[i].vvalue); + break; + + case VTYPE_STRING: + proto_tree_add_string_format(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vstring, pvalues[i].vdesc, pvalues[i].vstring); + if (pvalues[i].mvtype == MVTYPE_ATTR_REQUEST) { + /* + * The "vstring" value is set to the input ES type + * for MVTYPE_PROC_ENTRY_SPECIFIERS, + * to add string to columninfo + */ + if (check_col(pinfo->cinfo, COL_INFO)) { + if (!added_arrow) { + col_append_str(pinfo->cinfo, COL_INFO, " -> "); + added_arrow = TRUE; + } + col_append_str(pinfo->cinfo, COL_INFO, pvalues[i].vstring); + } + } + break; + + case VTYPE_BITFIELD: + process_bitfield(ncp_tree, tvb, &pvalues[i]); + break; + + case VTYPE_MULTIVALUE_UINT32: + process_multivalues(ncp_tree, tvb, &pvalues[i]); + if (pvalues[i].mvtype == MVTYPE_PROC_ENTRY_SPECIFIERS) { + /* + * The "vstring" value is set to the input ES type + * by "process_multivalues()". + */ + strcpy(global_object_name, pvalues[i].vstring); + } + if (pvalues[i].mvtype == MVTYPE_ATTR_REQUEST || pvalues[i].mvtype == MVTYPE_PROC_ENTRY_SPECIFIERS) { + /* + * The "vstring" value is set to the input ES type + * for MVTYPE_PROC_ENTRY_SPECIFIERS, + * and the last string for MVTYPE_ATTR_REQUEST, + * by "process_multivalues()". + */ + if (check_col(pinfo->cinfo, COL_INFO)) { + if (!added_arrow) { + col_append_str(pinfo->cinfo, COL_INFO, " -> "); + added_arrow = TRUE; + } + col_append_str(pinfo->cinfo, COL_INFO, pvalues[i].vstring); + } + } + break; + + case VTYPE_BYTES: + proto_tree_add_bytes(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, + pvalues[i].vlength, tvb_get_ptr(tvb, pvalues[i].voffset, pvalues[i].vvalue)); + break; + + case VTYPE_BOOLEAN: + proto_tree_add_item(ncp_tree, pvalues[i].hfname, tvb, pvalues[i].voffset, pvalues[i].vlength, TRUE); + break; + + default: + proto_tree_add_uint_format(ncp_tree, hf_nds_p1type, tvb, pvalues[i].voffset, + pvalues[i].vlength, pvalues[i].vtype, "NDS Parameter not defined %u", + pvalues[i].vtype); + break; + } + /* For NDS requests with just an EID, resolve name from hash table. */ + } + request_eid_value = ncp_eid_hash_lookup(conversation, global_eid); + if(resolve_eid) { + if (request_eid_value) { + strcpy(global_object_name, request_eid_value->object_name); + if (check_col(pinfo->cinfo, COL_INFO)) + { + col_append_str(pinfo->cinfo, COL_INFO, ", Object Name - "); + col_append_str(pinfo->cinfo, COL_INFO, global_object_name); + } + } + } + if (request_value) + { + request_value->nds_request_verb = nds_verb; + request_value->nds_version = nds_version; + strcpy(request_value->object_name, global_object_name); + request_value->req_nds_flags = global_flags; + } + } + break; + + default: + ; /* nothing */ + break; + } + ptvcursor_free(ptvc); + + /* Free the temporary proto_tree */ + CLEANUP_CALL_AND_POP; + } +} + +/* + * XXX - this duplicates stuff in "dissect_ncp_request()"; could + * "dissect_ncp_request()" not just call "dissect_ping_req()" if + * the operation is an NCP ping, and "dissect_ping_req()" just dissect + * ping portion? + */ +void +dissect_ping_req(tvbuff_t *tvb, packet_info *pinfo, + guint16 nw_connection, guint8 sequence, + guint16 type, proto_tree *ncp_tree) +{ + guint8 func, subfunc = 0; + ncp_req_hash_value *request_value = NULL; + const ncp_record *ncp_rec = NULL; + conversation_t *conversation; + ptvcursor_t *ptvc = NULL; + proto_tree *temp_tree = NULL; + gint length_remaining = 0; + guint32 nds_flags; + guint32 ping_version; + nds_val pvalue; + char string_buffer[1024]; + + pvalue.vvalue = 0; + pvalue.vlength = 0; + pvalue.voffset = 0; + pvalue.hfname = 0; + pvalue.vdesc = ""; + string_buffer[0] = '\0'; + pvalue.vstring = string_buffer; + pvalue.mvtype = 0; + + func = tvb_get_guint8(tvb, 6); + subfunc = tvb_get_guint8(tvb, 7); + + ncp_rec = ncp_record_find(func, subfunc); + + /* Fill in the INFO column. */ + if (check_col(pinfo->cinfo, COL_INFO)) + { + if (ncp_rec) + { + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "NDS"); + col_add_fstr(pinfo->cinfo, COL_INFO, "C Ping for NDS"); + } + + } + if (!pinfo->fd->flags.visited) + { + + /* This is the first time we've looked at this packet. + Keep track of the address and connection whence the request + came, and the address and connection to which the request + is being sent, so that we can match up calls with replies. + (We don't include the sequence number, as we may want + to have all packets over the same connection treated + as being part of a single conversation so that we can + let the user select that conversation to be displayed.) */ + + conversation = find_conversation(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + + if (conversation == NULL) + { + /* It's not part of any conversation - create a new one. */ + conversation = conversation_new(&pinfo->src, &pinfo->dst, + PT_NCP, nw_connection, nw_connection, 0); + } + + request_value = ncp_hash_insert(conversation, sequence, ncp_rec); + request_value->req_frame_num = pinfo->fd->num; + request_value->req_frame_time.secs=pinfo->fd->abs_secs; + request_value->req_frame_time.nsecs=pinfo->fd->abs_usecs*1000; + + /* If this is the first time we're examining the packet, + * check to see if this NCP type uses a "request condition". + * If so, we have to build a proto_tree because request conditions + * use display filters to work, and without a proto_tree, + * display filters can't possibly work. If we already have + * a proto_tree, then wonderful. If we don't, we need to build + * one. */ + if (ncp_rec && !ncp_tree) { + proto_item *ti; + + temp_tree = proto_tree_create_root(); + proto_tree_set_visible(temp_tree, FALSE); + ti = proto_tree_add_item(temp_tree, proto_ncp, tvb, 0, -1, FALSE); + ncp_tree = proto_item_add_subtree(ti, ett_ncp); + } + } + + if (ncp_tree) { + /* If the dissection throws an exception, be sure to free + * the temporary proto_tree that was created. Because of the + * way the CLEANUP_PUSH macro works, we can't put it in an 'if' + * block; it has to be in the same scope as the terminating + * CLEANUP_POP or CLEANUP_POP_AND_ALLOC. So, we always + * call CLEANUP_POP and friends, but the value of temp_tree is + * NULL if no cleanup is needed, and non-null if cleanup is needed. + */ + CLEANUP_PUSH(free_proto_tree, temp_tree); + + switch (type) { + + case NCP_BROADCAST_SLOT: + ; /* nothing */ + break; + + case NCP_SERVICE_REQUEST: + proto_tree_add_uint_format(ncp_tree, hf_ncp_func, tvb, 6, 1, + func, "Function: %u (0x%02X), %s", + func, func, ncp_rec ? ncp_rec->name : "Unknown"); + + proto_tree_add_uint_format(ncp_tree, hf_ncp_subfunc, tvb, 7, 1, + subfunc, "SubFunction: %u (0x%02x)", + subfunc, subfunc); + + length_remaining = tvb_reported_length_remaining(tvb, 8); + if (length_remaining >= 8) { + ping_version = tvb_get_letohl(tvb, 8); + proto_tree_add_uint(ncp_tree, hf_nds_ping_version, tvb, 8, + 4, ping_version); + nds_flags = tvb_get_letohl(tvb, 12); + if (request_value) + request_value->req_nds_flags = nds_flags; + + + pvalue.vvalue = tvb_get_letohs(tvb, 12); + pvalue.vtype = VTYPE_BITFIELD; + pvalue.vstring = ""; + pvalue.vdesc = "Ping (low) Request Flags:"; + pvalue.vlength = 2; + pvalue.hfname= hf_nds_rflags; + pvalue.voffset = 12; + pvalue.bit1 = "Supported Fields"; + pvalue.bit1hfname = hf_bit1pingflags1; + pvalue.bit2 = "Depth"; + pvalue.bit2hfname = hf_bit2pingflags1; + pvalue.bit3 = "Revision"; + pvalue.bit3hfname = hf_bit3pingflags1; + pvalue.bit4 = "Flags"; + pvalue.bit4hfname = hf_bit4pingflags1; + pvalue.bit5 = "Verification Flags"; + pvalue.bit5hfname = hf_bit5pingflags1; + pvalue.bit6 = "Letter Version"; + pvalue.bit6hfname = hf_bit6pingflags1; + pvalue.bit7 = "OS Version"; + pvalue.bit7hfname = hf_bit7pingflags1; + pvalue.bit8 = "License Flags"; + pvalue.bit8hfname = hf_bit8pingflags1; + pvalue.bit9 = "DS Time"; + pvalue.bit9hfname = hf_bit9pingflags1; + pvalue.bit10 = "Not Defined"; + pvalue.bit10hfname = hf_bit10pingflags1; + pvalue.bit11 = "Not Defined"; + pvalue.bit11hfname = hf_bit11pingflags1; + pvalue.bit12 = "Not Defined"; + pvalue.bit12hfname = hf_bit12pingflags1; + pvalue.bit13 = "Not Defined"; + pvalue.bit13hfname = hf_bit13pingflags1; + pvalue.bit14 = "Not Defined"; + pvalue.bit14hfname = hf_bit14pingflags1; + pvalue.bit15 = "Not Defined"; + pvalue.bit15hfname = hf_bit15pingflags1; + pvalue.bit16 = "Not Defined"; + pvalue.bit16hfname = hf_bit16pingflags1; + + process_bitfield(ncp_tree, tvb, &pvalue); + + pvalue.vvalue = tvb_get_letohs(tvb, 14); + pvalue.vtype = VTYPE_BITFIELD; + pvalue.vstring = ""; + pvalue.vdesc = "Ping (high) Request Flags:"; + pvalue.vlength = 2; + pvalue.hfname= hf_nds_rflags; + pvalue.voffset = 14; + pvalue.bit1 = "Sap Name"; + pvalue.bit1hfname = hf_bit1pingflags2; + pvalue.bit2 = "Tree Name"; + pvalue.bit2hfname = hf_bit2pingflags2; + pvalue.bit3 = "OS Name"; + pvalue.bit3hfname = hf_bit3pingflags2; + pvalue.bit4 = "Hardware Name"; + pvalue.bit4hfname = hf_bit4pingflags2; + pvalue.bit5 = "Vendor Name"; + pvalue.bit5hfname = hf_bit5pingflags2; + pvalue.bit6 = "Not Defined"; + pvalue.bit6hfname = hf_bit6pingflags2; + pvalue.bit7 = "Not Defined"; + pvalue.bit7hfname = hf_bit7pingflags2; + pvalue.bit8 = "Not Defined"; + pvalue.bit8hfname = hf_bit8pingflags2; + pvalue.bit9 = "Not Defined"; + pvalue.bit9hfname = hf_bit9pingflags2; + pvalue.bit10 = "Not Defined"; + pvalue.bit10hfname = hf_bit10pingflags2; + pvalue.bit11 = "Not Defined"; + pvalue.bit11hfname = hf_bit11pingflags2; + pvalue.bit12 = "Not Defined"; + pvalue.bit12hfname = hf_bit12pingflags2; + pvalue.bit13 = "Not Defined"; + pvalue.bit13hfname = hf_bit13pingflags2; + pvalue.bit14 = "Not Defined"; + pvalue.bit14hfname = hf_bit14pingflags2; + pvalue.bit15 = "Not Defined"; + pvalue.bit15hfname = hf_bit15pingflags2; + pvalue.bit16 = "Not Defined"; + pvalue.bit16hfname = hf_bit16pingflags2; + + process_bitfield(ncp_tree, tvb, &pvalue); + } + break; + + default: + ; /* nothing */ + break; + } + ptvc = ptvcursor_new(ncp_tree, tvb, 7); + if (ncp_rec && ncp_rec->request_ptvc) { + clear_repeat_vars(); + process_ptvc_record(ptvc, ncp_rec->request_ptvc, NULL, TRUE, ncp_rec); + } + ptvcursor_free(ptvc); + + /* Free the temporary proto_tree */ + CLEANUP_CALL_AND_POP; + } +} |