forked from osmocom/wireshark
Handle a few of the NCP types from the traces sent in by Pete,
<psailor@uswest.net> svn path=/trunk/; revision=3617
This commit is contained in:
parent
68f6c4d9b9
commit
c70cdb456f
637
ncp2222.py
637
ncp2222.py
|
@ -20,7 +20,7 @@ http://developer.novell.com/ndk/doc/docui/index.htm#../ncp/ncp__enu/data/
|
|||
for a badly-formatted HTML version of the same PDF.
|
||||
|
||||
|
||||
$Id: ncp2222.py,v 1.9 2001/06/18 02:17:44 guy Exp $
|
||||
$Id: ncp2222.py,v 1.10 2001/06/28 02:42:48 gram Exp $
|
||||
|
||||
Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
|
||||
|
||||
|
@ -40,6 +40,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
"""
|
||||
|
||||
import sys
|
||||
import string
|
||||
|
||||
errors = {}
|
||||
groups = {}
|
||||
packets = None
|
||||
compcode_lists = None
|
||||
ptvc_lists = None
|
||||
|
||||
##############################################################################
|
||||
# Global containers
|
||||
|
@ -82,9 +89,6 @@ class UniqueCollection:
|
|||
return 0
|
||||
|
||||
|
||||
packets = UniqueCollection('NCP Packet Descriptions')
|
||||
compcode_lists = UniqueCollection('Completion Code Lists')
|
||||
ptvc_lists = UniqueCollection('PTVC Lists')
|
||||
|
||||
|
||||
##############################################################################
|
||||
|
@ -255,7 +259,7 @@ class PTVCRecord:
|
|||
|
||||
class NCP:
|
||||
"NCP Packet class"
|
||||
def __init__(self, func_code, description, group):
|
||||
def __init__(self, func_code, description, group, has_length=1):
|
||||
"Constructor"
|
||||
self.func_code = func_code
|
||||
self.description = description
|
||||
|
@ -263,6 +267,7 @@ class NCP:
|
|||
self.codes = None
|
||||
self.request_records = None
|
||||
self.reply_records = None
|
||||
self.has_length = has_length
|
||||
|
||||
if not groups.has_key(group):
|
||||
sys.stderr.write("NCP 0x%x has invalid group '%s'\n" % (self.func_code, group))
|
||||
|
@ -300,6 +305,9 @@ class NCP:
|
|||
else:
|
||||
return 1
|
||||
|
||||
def HasLength(self):
|
||||
return self.has_length
|
||||
|
||||
def Description(self):
|
||||
return self.description
|
||||
|
||||
|
@ -316,7 +324,10 @@ class NCP:
|
|||
self.request_size = size
|
||||
self.request_records = records
|
||||
if self.HasSubFunction():
|
||||
if self.HasLength():
|
||||
self.CheckRecords(size, records, "Request", 10)
|
||||
else:
|
||||
self.CheckRecords(size, records, "Request", 8)
|
||||
else:
|
||||
self.CheckRecords(size, records, "Request", 7)
|
||||
self.ptvc_request = self.MakePTVC(records, "request")
|
||||
|
@ -610,10 +621,18 @@ class bytes(Type):
|
|||
##############################################################################
|
||||
# NCP Field Types. Defined in Appendix A of "Programmer's Guide..."
|
||||
##############################################################################
|
||||
AcceptedMaxSize = uint16("accepted_max_size", "Accepted Max Size")
|
||||
AcctVersion = byte("acct_version", "Acct Version")
|
||||
BufferSize = uint16("buffer_size", "Buffer Size")
|
||||
ConnectionNumber = uint32("connection_number", "Connection Number")
|
||||
ConnectionsSupportedMax = uint16("connections_supported_max", "Connections Supported Max")
|
||||
ConnectionsInUse = uint16("connections_in_use", "Connections In Use")
|
||||
ConnectionsMaxUsed = uint16("connections_max_used", "Connections Max Used")
|
||||
DirHandle = byte("dir_handle", "Directory Handle")
|
||||
|
||||
EchoSocket = uint16("echo_socket", "Echo Socket")
|
||||
EchoSocket.Display('BASE_HEX')
|
||||
|
||||
FileHandle = bytes("file_handle", "File Handle", 6)
|
||||
|
||||
FileLock = val_string8("file_lock", "File Lock", [
|
||||
|
@ -625,8 +644,10 @@ FileLock = val_string8("file_lock", "File Lock", [
|
|||
FileOffset = uint32("file_offset", "File Offset")
|
||||
FilePath = nstring8("file_path", "File Path")
|
||||
FileSize = uint32("file_size", "File Size")
|
||||
InternetBridgeVersion = byte("internet_bridge_version", "Internet Bridge Version")
|
||||
JobType = uint16("job_type", "Job Type")
|
||||
|
||||
LocalLoginInfoCcode = byte("local_login_info_ccode", "Local Login Info C Code")
|
||||
LogicalLockType = val_string8("logical_lock_type", "Logical Lock Type", [
|
||||
[ 0x00, "Log file" ],
|
||||
[ 0x01, "Log and lock file for exclusive read/write use" ],
|
||||
|
@ -637,6 +658,7 @@ LogicalRecordName = nstring8("logical_record_name", "Logical Record Name")
|
|||
LogLockType = byte("log_lock_type", "Log Lock Type")
|
||||
|
||||
MaxBytes = uint16("max_bytes", "Maximum Number of Bytes")
|
||||
MixedModePathFlag = byte("mixed_mode_path_flag", "Mixed Mode Path Flag")
|
||||
NumBytes = uint16("num_bytes", "Number of Bytes")
|
||||
|
||||
ObjectFlags = val_string8("object_flags", "Object Flags", [
|
||||
|
@ -685,6 +707,18 @@ ObjectType = val_string16("object_type", "Object Type", [
|
|||
[ 0x0027, "TCP/IP gateway" ],
|
||||
])
|
||||
|
||||
OSLanguageID = byte("os_language_id", "OS Language ID")
|
||||
OSMajorVersion = byte("os_major_version", "OS Major Version")
|
||||
OSMinorVersion = byte("os_minor_version", "OS Minor Version")
|
||||
OSRevision = byte("os_revision", "OS Revision")
|
||||
PingVersion = uint16("ping_version", "Ping Version", endianness=LE)
|
||||
PingVersion.Display("BASE_HEX")
|
||||
|
||||
PrintServerVersion = byte("print_server_version", "Print Server Version")
|
||||
ProductMajorVersion = uint16("product_major_version", "Product Major Version")
|
||||
ProductMinorVersion = uint16("product_minor_version", "Product Minor Version")
|
||||
ProductRevisionVersion = byte("product_revision_version", "Product Revision Version")
|
||||
|
||||
PropertyHasMoreSegments = val_string8("property_has_more_segments",
|
||||
"Property Has More Segments", [
|
||||
[ 0x00, "Is last segment" ],
|
||||
|
@ -702,15 +736,33 @@ PropertyType = val_string8("property_type", "Property Type", [
|
|||
[ 0x03, "Dynamic set" ],
|
||||
])
|
||||
|
||||
ProposedMaxSize = uint16("proposed_max_size", "Proposed Max Size")
|
||||
|
||||
Reserved3 = bytes("reserved3", "Reserved", 3)
|
||||
Reserved51 = bytes("reserved51", "Reserved", 51)
|
||||
|
||||
QMSVersion = byte("qms_version", "QMS Version")
|
||||
|
||||
# XXX - needs bitfield
|
||||
SecurityFlag = byte("security_flag", "Security Flag")
|
||||
SecurityRestrictionVersion = byte("security_restriction_version", "Security Restriction Version")
|
||||
|
||||
ServerName = stringz("server_name", "Server Name")
|
||||
SFTLevel = byte("sft_level", "SFT Level")
|
||||
|
||||
TaskNumber = uint32("task_number", "Task Number")
|
||||
TimeoutLimit = uint16("timeout_limit", "Timeout Limit")
|
||||
TTSLevel = byte("tts_level", "TTS Level")
|
||||
UnknownByte = byte("unknown_byte", "Unknown Byte")
|
||||
|
||||
VAPVersion = byte("vap_version", "VAP Version")
|
||||
VirtualConsoleVersion = byte("virtual_console_version", "Virtual Console Version")
|
||||
VolumesSupportedMax = uint16("volumes_supported_max", "Volumes Supported Max")
|
||||
|
||||
##############################################################################
|
||||
# NCP Groups
|
||||
##############################################################################
|
||||
groups = {}
|
||||
def define_groups():
|
||||
groups['accounting'] = "Accounting"
|
||||
groups['afp'] = "AFP"
|
||||
groups['auditing'] = "Auditing"
|
||||
|
@ -729,11 +781,12 @@ groups['print'] = "Print"
|
|||
groups['queue'] = "Queue"
|
||||
groups['sync'] = "Synchronization"
|
||||
groups['tss'] = "Transaction Tracking"
|
||||
groups['unknown'] = "Unknown"
|
||||
|
||||
##############################################################################
|
||||
# NCP Errors
|
||||
##############################################################################
|
||||
errors = {}
|
||||
def define_errors():
|
||||
errors[0x0000] = "Ok"
|
||||
errors[0x0001] = "Transaction tracking is available"
|
||||
errors[0x0002] = "Ok. The data has been written"
|
||||
|
@ -938,6 +991,7 @@ errors[0xfb00] = "No such property"
|
|||
errors[0xfb01] = "The file server does not support this request"
|
||||
errors[0xfb02] = "The specified property does not exist"
|
||||
errors[0xfb03] = "The PASSWORD property does not exist for this bindery object"
|
||||
errors[0xfb04] = "NDS NCP not available"
|
||||
|
||||
errors[0xfc00] = "The message queue cannot accept another message"
|
||||
errors[0xfc01] = "The trustee associated with ObjectId does not exist"
|
||||
|
@ -965,6 +1019,7 @@ errors[0xfe08] = "Bindery locked"
|
|||
errors[0xfe09] = "Invalid semaphore name length"
|
||||
errors[0xfe0a] = "The file server was unable to complete the operation within the specified time limit"
|
||||
errors[0xfe0b] = "Transaction restart"
|
||||
errors[0xfe0c] = "Bad packet"
|
||||
|
||||
errors[0xff00] = "Failure"
|
||||
errors[0xff01] = "Lock error"
|
||||
|
@ -993,236 +1048,14 @@ errors[0xff17] = "A file or directory matching the search criteria was not found
|
|||
errors[0xff18] = "The file already exists"
|
||||
errors[0xff19] = "No files found"
|
||||
|
||||
##############################################################################
|
||||
# NCP Packets. Here I list functions and subfunctions in hexadecimal like the
|
||||
# NCP book (and I believe LanAlyzer does this too).
|
||||
# However, Novell lists these in decimal in their on-line documentation.
|
||||
##############################################################################
|
||||
# 2222/02
|
||||
pkt = NCP(0x02, "File Release Lock", 'sync')
|
||||
pkt.Request(7)
|
||||
pkt.Reply(8)
|
||||
pkt.CompletionCodes([0x0000, 0xff00])
|
||||
|
||||
#
|
||||
# Untested
|
||||
#
|
||||
# 2222/03
|
||||
#pkt = NCP(0x03, "Log File", 'sync')
|
||||
#pkt.request( (12, 267), [
|
||||
# [ 7, 1, DirHandle ],
|
||||
# [ 8, 1, LogLockType ],
|
||||
# [ 9, 2, TimeoutLimit, LE ],
|
||||
# [ 11, (1, 256), FilePath ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x0000, 0x8200, 0x9600, 0xfe00, 0xff01])
|
||||
#
|
||||
## 2222/04
|
||||
#pkt = NCP(0x04, "Lock File Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, TimeoutLimit ],
|
||||
# ])
|
||||
#pkt.completion_codes([0xfe, 0xff01])
|
||||
#
|
||||
## 2222/05
|
||||
#pkt = NCP(0x05, "Release File", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, DirHandle ],
|
||||
# [ 8, FilePath ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x7e, 0x98, 0x9b, 0x9c, 0xff02])
|
||||
#
|
||||
## 2222/06
|
||||
#pkt = NCP(0x06, "Release File Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, UnknownByte ],
|
||||
# ])
|
||||
#pkt.completion_codes()
|
||||
#
|
||||
## 2222/07
|
||||
#pkt = NCP(0x07, "Clear File", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, DirHandle ],
|
||||
# [ 8, FilePath ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x7e, 0x96, 0x98, 0x9b, 0x9c,
|
||||
# 0xa1, 0xfd, 0xff])
|
||||
#
|
||||
## 2222/08
|
||||
#pkt = NCP(0x08, "Clear File Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, FileLock ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x7e])
|
||||
#
|
||||
## 2222/09
|
||||
#pkt = NCP(0x09, "Log Logical Record", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, LogicalLockType ],
|
||||
# [ 8, TimeoutLimit_be ],
|
||||
# [ 10, LogicalRecordName ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x96, 0xfe, 0xff])
|
||||
#
|
||||
## 2222/0a
|
||||
#pkt = NCP(0x0a, "Lock Logical Record Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, LogicalLockType ],
|
||||
# [ 8, TimeoutLimit_le ],
|
||||
# ])
|
||||
#pkt.completion_codes([0xfe, 0xff])
|
||||
#
|
||||
## 2222/0b
|
||||
#pkt = NCP(0x0b, "Clear Logical Record", 'sync')
|
||||
#pkt.request([
|
||||
# [7, LogicalRecordName ],
|
||||
# ])
|
||||
#pkt.completion_codes([0xff]
|
||||
## 2222/0c
|
||||
## 2222/0d
|
||||
## 2222/0e
|
||||
## 2222/0f
|
||||
## 2222/11
|
||||
#
|
||||
## 2222/1100
|
||||
#pkt = NCP(0x1100, "Lock Logical Record Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 10, var_length_data("data").length_var("packetlength") ]
|
||||
# ])
|
||||
#pkt.completion_codes()
|
||||
#
|
||||
|
||||
# 2222/1735
|
||||
pkt = NCP(0x1735, "Get Bindery Object ID", 'bindery')
|
||||
pkt.Request((13,60), [
|
||||
[ 10, 2, ObjectType ],
|
||||
[ 12, (1,48), ObjectName ],
|
||||
])
|
||||
pkt.Reply(62, [
|
||||
[ 8, 4, ObjectID ],
|
||||
[ 12, 2, ObjectType ],
|
||||
[ 14, 48, ObjectName1 ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x9600, 0xef01, 0xf000, 0xfc02,
|
||||
0xfe01, 0xff00])
|
||||
|
||||
# 2222/1737
|
||||
pkt = NCP(0x1737, "Scan Bindery Object", 'bindery')
|
||||
pkt.Request((17,64), [
|
||||
[ 10, 4, ObjectID ],
|
||||
[ 14, 2, ObjectType ],
|
||||
[ 16, (1,48), ObjectName ],
|
||||
])
|
||||
pkt.Reply(65, [
|
||||
[ 8, 4, ObjectID ],
|
||||
[ 12, 2, ObjectType ],
|
||||
[ 14, 48, ObjectName1 ],
|
||||
[ 62, 1, ObjectFlags ],
|
||||
[ 63, 1, ObjectSecurity ],
|
||||
[ 64, 1, ObjectHasProperties ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x9600, 0xef01, 0xfc02,
|
||||
0xfe01, 0xff00])
|
||||
|
||||
# 2222/173D
|
||||
pkt = NCP(0x173D, "Read Property Value", 'bindery')
|
||||
pkt.Request((15,77), [
|
||||
[ 10, 2, ObjectType ],
|
||||
[ 12, (1,48), ObjectName ],
|
||||
[ -1, 1, PropertySegment ],
|
||||
[ -1, (1,16), PropertyName ],
|
||||
])
|
||||
pkt.Reply(138, [
|
||||
[ 8, 128, PropertyData ],
|
||||
[ 136, 1, PropertyHasMoreSegments ],
|
||||
[ 137, 1, PropertyType ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x8800, 0x9300, 0x9600, 0xec01,
|
||||
0xf000, 0xf100, 0xf900, 0xfb02, 0xfc02, 0xfe01, 0xff00 ])
|
||||
|
||||
# 2222/177C
|
||||
pkt = NCP(0x177C, "Service Queue Job", 'queue')
|
||||
pkt.Request(16, [
|
||||
[ 10, 4, ObjectID ],
|
||||
[ 14, 2, JobType ],
|
||||
])
|
||||
pkt.Reply(24, [ # XXX - 76, [
|
||||
[ 8, 4, ConnectionNumber ],
|
||||
[ 12, 4, TaskNumber ],
|
||||
[ 16, 4, ObjectID ],
|
||||
[ 20, 4, ObjectID ],
|
||||
# XXX - DateTime
|
||||
])
|
||||
# These completion codes are not documented, but guessed.
|
||||
pkt.CompletionCodes([0x0000, 0x9900, 0xd000, 0xd100, 0xd201, 0xd300,
|
||||
0xd401, 0xd502, 0xd601, 0xd704, 0xd800, 0xd901, 0xda01, 0xdb01,
|
||||
0xff00 ])
|
||||
|
||||
# 2222/18
|
||||
pkt = NCP(0x18, "End of Job", 'connection')
|
||||
pkt.Request(7)
|
||||
pkt.Reply(8)
|
||||
pkt.CompletionCodes([0x0000])
|
||||
|
||||
# 2222/19
|
||||
pkt = NCP(0x19, "Logout", 'connection')
|
||||
pkt.Request(7)
|
||||
pkt.Reply(8)
|
||||
pkt.CompletionCodes([0x0000])
|
||||
|
||||
# 2222/21
|
||||
pkt = NCP(0x21, "Negotiate Buffer Size", 'connection')
|
||||
pkt.Request(9, [
|
||||
[ 7, 2, BufferSize ],
|
||||
])
|
||||
pkt.Reply(10, [
|
||||
[ 8, 2, BufferSize ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000])
|
||||
|
||||
# 2222/42
|
||||
pkt = NCP(0x42, "Close File", 'file')
|
||||
pkt.Request(13, [
|
||||
[ 7, 6, FileHandle ],
|
||||
])
|
||||
pkt.Reply(8)
|
||||
pkt.CompletionCodes([0x0000, 0xff00])
|
||||
|
||||
# 2222/47
|
||||
pkt = NCP(0x47, "Get Current Size of File", 'file')
|
||||
pkt.Request(13, [
|
||||
[ 7, 6, FileHandle ],
|
||||
])
|
||||
pkt.Reply(12, [
|
||||
[ 8, 4, FileSize ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x8800])
|
||||
|
||||
# 2222/48
|
||||
pkt = NCP(0x48, "Read From A File", 'file')
|
||||
pkt.Request(20, [
|
||||
[ 7, 1, UnknownByte ],
|
||||
[ 8, 6, FileHandle ],
|
||||
[ 14, 4, FileOffset ], # my nomenclature
|
||||
[ 18, 2, MaxBytes ], # my nomenclature
|
||||
])
|
||||
pkt.Reply(10, [ # XXX - (10,-1), [
|
||||
[ 8, 2, NumBytes ], # my nomenclature
|
||||
# XXX
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x8800, 0x9300, 0xff00])
|
||||
|
||||
# 2222/5701 - no info
|
||||
# 2222/5702 - no info
|
||||
# 2222/5706 - no info
|
||||
# 2222/5714 - no info
|
||||
# 2222/68 - no info
|
||||
# 2222/72 - no info
|
||||
|
||||
##############################################################################
|
||||
# Produce C code
|
||||
##############################################################################
|
||||
if __name__ == '__main__':
|
||||
def produce_code():
|
||||
|
||||
global errors
|
||||
|
||||
print "/*"
|
||||
print " * Generated automatically from %s" % (sys.argv[0])
|
||||
print " * Do not edit this file manually, as all changes will be lost."
|
||||
|
@ -1394,6 +1227,12 @@ proto_register_ncp2222(void)
|
|||
print '\t/* %02d (%s) */ "%s",' % (groups_used_hash[group], group, groups[group])
|
||||
print "};\n"
|
||||
|
||||
# Print the group macros
|
||||
for group in groups_used_list:
|
||||
name = string.upper(group)
|
||||
print "#define NCP_GROUP_%s\t%d" % (name, groups_used_hash[group])
|
||||
print "\n"
|
||||
|
||||
# Print PTVC's
|
||||
print "/* PTVC records. These are re-used to save space. */"
|
||||
for ptvc in ptvc_lists.Members():
|
||||
|
@ -1419,17 +1258,31 @@ proto_register_ncp2222(void)
|
|||
print "\t{ 0x00, -1 }\n};\n"
|
||||
|
||||
|
||||
# Functions without length parameter
|
||||
funcs_without_length = {}
|
||||
|
||||
|
||||
# Print ncp_record packet records
|
||||
print "#define SUBFUNC 0xff"
|
||||
print "#define NOSUB 0x00"
|
||||
print "#define SUBFUNC_WITH_LENGTH 0x02"
|
||||
print "#define SUBFUNC_NO_LENGTH 0x01"
|
||||
print "#define NO_SUBFUNC 0x00"
|
||||
|
||||
print "/* ncp_record structs for packets */"
|
||||
print "static const ncp_record ncp_packets[] = {"
|
||||
for pkt in packets.Members():
|
||||
if pkt.HasSubFunction():
|
||||
subfunc_string = "SUBFUNC"
|
||||
func = pkt.FunctionCode('high')
|
||||
if pkt.HasLength():
|
||||
subfunc_string = "SUBFUNC_WITH_LENGTH"
|
||||
# Ensure that the function either has a length param or not
|
||||
if funcs_without_length.has_key(func):
|
||||
sys.exit("Function 0x%04x sometimes has length param, sometimes not." \
|
||||
% (pkt.FunctionCode(),))
|
||||
else:
|
||||
subfunc_string = "NOSUB"
|
||||
subfunc_string = "SUBFUNC_NO_LENGTH"
|
||||
funcs_without_length[func] = 1
|
||||
else:
|
||||
subfunc_string = "NO_SUBFUNC"
|
||||
print '\t{ 0x%02x, 0x%02x, %s, "%s",' % (pkt.FunctionCode('high'),
|
||||
pkt.FunctionCode('low'), subfunc_string, pkt.Description()),
|
||||
|
||||
|
@ -1467,6 +1320,316 @@ proto_register_ncp2222(void)
|
|||
print "};\n"
|
||||
|
||||
|
||||
print "/* ncp funs that have no length parameter */"
|
||||
print "static const guint8 ncp_func_has_no_length_parameter[] = {"
|
||||
funcs = funcs_without_length.keys()
|
||||
funcs.sort()
|
||||
for func in funcs:
|
||||
print "\t0x%02x," % (func,)
|
||||
print "\t0"
|
||||
print "};\n"
|
||||
|
||||
|
||||
print '#include "packet-ncp2222.inc"'
|
||||
|
||||
|
||||
def main():
|
||||
global packets
|
||||
global compcode_lists
|
||||
global ptvc_lists
|
||||
|
||||
packets = UniqueCollection('NCP Packet Descriptions')
|
||||
compcode_lists = UniqueCollection('Completion Code Lists')
|
||||
ptvc_lists = UniqueCollection('PTVC Lists')
|
||||
|
||||
define_errors()
|
||||
define_groups()
|
||||
define_ncp2222()
|
||||
|
||||
produce_code()
|
||||
|
||||
def define_ncp2222():
|
||||
##############################################################################
|
||||
# NCP Packets. Here I list functions and subfunctions in hexadecimal like the
|
||||
# NCP book (and I believe LanAlyzer does this too).
|
||||
# However, Novell lists these in decimal in their on-line documentation.
|
||||
##############################################################################
|
||||
# 2222/02
|
||||
pkt = NCP(0x02, "File Release Lock", 'sync')
|
||||
pkt.Request(7)
|
||||
pkt.Reply(8)
|
||||
pkt.CompletionCodes([0x0000, 0xff00])
|
||||
|
||||
#
|
||||
# Untested
|
||||
#
|
||||
# 2222/03
|
||||
#pkt = NCP(0x03, "Log File", 'sync')
|
||||
#pkt.request( (12, 267), [
|
||||
# [ 7, 1, DirHandle ],
|
||||
# [ 8, 1, LogLockType ],
|
||||
# [ 9, 2, TimeoutLimit, LE ],
|
||||
# [ 11, (1, 256), FilePath ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x0000, 0x8200, 0x9600, 0xfe00, 0xff01])
|
||||
#
|
||||
## 2222/04
|
||||
#pkt = NCP(0x04, "Lock File Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, TimeoutLimit ],
|
||||
# ])
|
||||
#pkt.completion_codes([0xfe, 0xff01])
|
||||
#
|
||||
## 2222/05
|
||||
#pkt = NCP(0x05, "Release File", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, DirHandle ],
|
||||
# [ 8, FilePath ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x7e, 0x98, 0x9b, 0x9c, 0xff02])
|
||||
#
|
||||
## 2222/06
|
||||
#pkt = NCP(0x06, "Release File Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, UnknownByte ],
|
||||
# ])
|
||||
#pkt.completion_codes()
|
||||
#
|
||||
## 2222/07
|
||||
#pkt = NCP(0x07, "Clear File", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, DirHandle ],
|
||||
# [ 8, FilePath ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x7e, 0x96, 0x98, 0x9b, 0x9c,
|
||||
# 0xa1, 0xfd, 0xff])
|
||||
#
|
||||
## 2222/08
|
||||
#pkt = NCP(0x08, "Clear File Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, FileLock ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x7e])
|
||||
#
|
||||
## 2222/09
|
||||
#pkt = NCP(0x09, "Log Logical Record", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, LogicalLockType ],
|
||||
# [ 8, TimeoutLimit_be ],
|
||||
# [ 10, LogicalRecordName ],
|
||||
# ])
|
||||
#pkt.completion_codes([0x96, 0xfe, 0xff])
|
||||
#
|
||||
## 2222/0a
|
||||
#pkt = NCP(0x0a, "Lock Logical Record Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 7, LogicalLockType ],
|
||||
# [ 8, TimeoutLimit_le ],
|
||||
# ])
|
||||
#pkt.completion_codes([0xfe, 0xff])
|
||||
#
|
||||
## 2222/0b
|
||||
#pkt = NCP(0x0b, "Clear Logical Record", 'sync')
|
||||
#pkt.request([
|
||||
# [7, LogicalRecordName ],
|
||||
# ])
|
||||
#pkt.completion_codes([0xff]
|
||||
## 2222/0c
|
||||
## 2222/0d
|
||||
## 2222/0e
|
||||
## 2222/0f
|
||||
## 2222/11
|
||||
#
|
||||
## 2222/1100
|
||||
#pkt = NCP(0x1100, "Lock Logical Record Set", 'sync')
|
||||
#pkt.request([
|
||||
# [ 10, var_length_data("data").length_var("packetlength") ]
|
||||
# ])
|
||||
#pkt.completion_codes()
|
||||
#
|
||||
|
||||
# 2222/1711
|
||||
pkt = NCP(0x1711, "Get File Server Information", 'fileserver')
|
||||
pkt.Request(10)
|
||||
pkt.Reply(136, [
|
||||
[ 8, 48, ServerName ],
|
||||
[ 56, 1, OSMajorVersion ],
|
||||
[ 57, 1, OSMinorVersion ],
|
||||
[ 58, 2, ConnectionsSupportedMax ],
|
||||
[ 60, 2, ConnectionsInUse ],
|
||||
[ 62, 2, VolumesSupportedMax ],
|
||||
[ 64, 1, OSRevision ],
|
||||
[ 65, 1, SFTLevel ],
|
||||
[ 66, 1, TTSLevel ],
|
||||
[ 67, 2, ConnectionsMaxUsed ],
|
||||
[ 69, 1, AcctVersion ],
|
||||
[ 70, 1, VAPVersion ],
|
||||
[ 71, 1, QMSVersion ],
|
||||
[ 72, 1, PrintServerVersion ],
|
||||
[ 73, 1, VirtualConsoleVersion ],
|
||||
[ 74, 1, SecurityRestrictionVersion ],
|
||||
[ 75, 1, InternetBridgeVersion ],
|
||||
[ 76, 1, MixedModePathFlag ],
|
||||
[ 77, 1, LocalLoginInfoCcode ],
|
||||
[ 78, 2, ProductMajorVersion ],
|
||||
[ 80, 2, ProductMinorVersion ],
|
||||
[ 82, 2, ProductRevisionVersion ],
|
||||
[ 84, 1, OSLanguageID ],
|
||||
[ 85, 51, Reserved51 ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x9600])
|
||||
|
||||
|
||||
# 2222/1735
|
||||
pkt = NCP(0x1735, "Get Bindery Object ID", 'bindery')
|
||||
pkt.Request((13,60), [
|
||||
[ 10, 2, ObjectType ],
|
||||
[ 12, (1,48), ObjectName ],
|
||||
])
|
||||
pkt.Reply(62, [
|
||||
[ 8, 4, ObjectID ],
|
||||
[ 12, 2, ObjectType ],
|
||||
[ 14, 48, ObjectName1 ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x9600, 0xef01, 0xf000, 0xfc02,
|
||||
0xfe01, 0xff00])
|
||||
|
||||
# 2222/1737
|
||||
pkt = NCP(0x1737, "Scan Bindery Object", 'bindery')
|
||||
pkt.Request((17,64), [
|
||||
[ 10, 4, ObjectID ],
|
||||
[ 14, 2, ObjectType ],
|
||||
[ 16, (1,48), ObjectName ],
|
||||
])
|
||||
pkt.Reply(65, [
|
||||
[ 8, 4, ObjectID ],
|
||||
[ 12, 2, ObjectType ],
|
||||
[ 14, 48, ObjectName1 ],
|
||||
[ 62, 1, ObjectFlags ],
|
||||
[ 63, 1, ObjectSecurity ],
|
||||
[ 64, 1, ObjectHasProperties ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x9600, 0xef01, 0xfc02,
|
||||
0xfe01, 0xff00])
|
||||
|
||||
# 2222/173D
|
||||
pkt = NCP(0x173D, "Read Property Value", 'bindery')
|
||||
pkt.Request((15,77), [
|
||||
[ 10, 2, ObjectType ],
|
||||
[ 12, (1,48), ObjectName ],
|
||||
[ -1, 1, PropertySegment ],
|
||||
[ -1, (1,16), PropertyName ],
|
||||
])
|
||||
pkt.Reply(138, [
|
||||
[ 8, 128, PropertyData ],
|
||||
[ 136, 1, PropertyHasMoreSegments ],
|
||||
[ 137, 1, PropertyType ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x8800, 0x9300, 0x9600, 0xec01,
|
||||
0xf000, 0xf100, 0xf900, 0xfb02, 0xfc02, 0xfe01, 0xff00 ])
|
||||
|
||||
# 2222/177C
|
||||
pkt = NCP(0x177C, "Service Queue Job", 'queue')
|
||||
pkt.Request(16, [
|
||||
[ 10, 4, ObjectID ],
|
||||
[ 14, 2, JobType ],
|
||||
])
|
||||
pkt.Reply(24, [ # XXX - 76, [
|
||||
[ 8, 4, ConnectionNumber ],
|
||||
[ 12, 4, TaskNumber ],
|
||||
[ 16, 4, ObjectID ],
|
||||
[ 20, 4, ObjectID ],
|
||||
# XXX - DateTime
|
||||
])
|
||||
# These completion codes are not documented, but guessed.
|
||||
pkt.CompletionCodes([0x0000, 0x9900, 0xd000, 0xd100, 0xd201, 0xd300,
|
||||
0xd401, 0xd502, 0xd601, 0xd704, 0xd800, 0xd901, 0xda01, 0xdb01,
|
||||
0xff00 ])
|
||||
|
||||
# 2222/18
|
||||
pkt = NCP(0x18, "End of Job", 'connection')
|
||||
pkt.Request(7)
|
||||
pkt.Reply(8)
|
||||
pkt.CompletionCodes([0x0000])
|
||||
|
||||
# 2222/19
|
||||
pkt = NCP(0x19, "Logout", 'connection')
|
||||
pkt.Request(7)
|
||||
pkt.Reply(8)
|
||||
pkt.CompletionCodes([0x0000])
|
||||
|
||||
# 2222/21
|
||||
pkt = NCP(0x21, "Negotiate Buffer Size", 'connection')
|
||||
pkt.Request(9, [
|
||||
[ 7, 2, BufferSize ],
|
||||
])
|
||||
pkt.Reply(10, [
|
||||
[ 8, 2, BufferSize ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000])
|
||||
|
||||
# 2222/42
|
||||
pkt = NCP(0x42, "Close File", 'file')
|
||||
pkt.Request(13, [
|
||||
[ 7, 6, FileHandle ],
|
||||
])
|
||||
pkt.Reply(8)
|
||||
pkt.CompletionCodes([0x0000, 0xff00])
|
||||
|
||||
# 2222/47
|
||||
pkt = NCP(0x47, "Get Current Size of File", 'file')
|
||||
pkt.Request(13, [
|
||||
[ 7, 6, FileHandle ],
|
||||
])
|
||||
pkt.Reply(12, [
|
||||
[ 8, 4, FileSize ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x8800])
|
||||
|
||||
# 2222/48
|
||||
pkt = NCP(0x48, "Read From A File", 'file')
|
||||
pkt.Request(20, [
|
||||
[ 7, 1, UnknownByte ],
|
||||
[ 8, 6, FileHandle ],
|
||||
[ 14, 4, FileOffset ], # my nomenclature
|
||||
[ 18, 2, MaxBytes ], # my nomenclature
|
||||
])
|
||||
pkt.Reply(10, [ # XXX - (10,-1), [
|
||||
[ 8, 2, NumBytes ], # my nomenclature
|
||||
# XXX
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0x8800, 0x9300, 0xff00])
|
||||
|
||||
# 2222/5701 - no info
|
||||
# 2222/5702 - no info
|
||||
# 2222/5706 - no info
|
||||
# 2222/5714 - no info
|
||||
# 2222/72 - no info
|
||||
|
||||
# 2222/61
|
||||
pkt = NCP(0x61, "Get Big Packet NCP Max Packet Size", 'unknown')
|
||||
pkt.Request(10, [
|
||||
[ 7, 2, ProposedMaxSize ],
|
||||
[ 9, 1, SecurityFlag ],
|
||||
])
|
||||
pkt.Reply(13, [
|
||||
[ 8, 2, AcceptedMaxSize ],
|
||||
[ 10, 2, EchoSocket ],
|
||||
[ 12, 1, SecurityFlag ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000])
|
||||
|
||||
# 2222/6801
|
||||
pkt = NCP(0x6801, "Ping for NDS NCP", "nds", has_length=0)
|
||||
pkt.Request(11, [
|
||||
[ 8, 3, Reserved3 ]
|
||||
])
|
||||
# XXX - expand, Unicode
|
||||
pkt.Reply(10, [
|
||||
[ 8, 2, PingVersion ],
|
||||
])
|
||||
pkt.CompletionCodes([0x0000, 0xfb04, 0xfe0c])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Structures and functions for NetWare Core Protocol.
|
||||
* Gilbert Ramirez <gram@xiexie.org>
|
||||
*
|
||||
* $Id: packet-ncp-int.h,v 1.2 2000/08/11 13:34:06 deniel Exp $
|
||||
* $Id: packet-ncp-int.h,v 1.3 2001/06/28 02:42:48 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -41,7 +41,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
guint8 func;
|
||||
guint8 subfunc;
|
||||
guint8 submask;
|
||||
guint8 has_subfunc;
|
||||
gchar* name;
|
||||
gint group;
|
||||
const ptvc_record *request_ptvc;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* Gilbert Ramirez <gram@xiexie.org>
|
||||
*
|
||||
* $Id: packet-ncp2222.inc,v 1.2 2000/10/21 05:52:21 guy Exp $
|
||||
* $Id: packet-ncp2222.inc,v 1.3 2001/06/28 02:42:48 gram Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -43,6 +43,22 @@ ncp_requires_subfunc(guint8 func)
|
|||
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)
|
||||
|
@ -51,10 +67,16 @@ ncp_record_find(guint8 func, guint8 subfunc)
|
|||
|
||||
while(ncp_rec->func != 0 || ncp_rec->subfunc != 0 ||
|
||||
ncp_rec->name != NULL ) {
|
||||
if (ncp_rec->func == func &&
|
||||
ncp_rec->subfunc == (subfunc & ncp_rec->submask)) {
|
||||
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;
|
||||
|
@ -87,6 +109,12 @@ ncp_error_string(const error_equivalency *errors, guint8 completion_code)
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
static const ncp_record ncp1111_request =
|
||||
{ 0x01, 0x00, NO_SUBFUNC, "Create Connection Service", NCP_GROUP_CONNECTION,
|
||||
NULL, NULL, NULL, NULL,
|
||||
ncp_0x2_errors };
|
||||
|
||||
|
||||
void
|
||||
dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
|
||||
guint16 nw_connection, guint8 sequence,
|
||||
|
@ -94,19 +122,37 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
|
|||
{
|
||||
guint8 func, subfunc = 0;
|
||||
gboolean requires_subfunc;
|
||||
const ncp_record *ncp_rec;
|
||||
gboolean has_length = TRUE;
|
||||
const ncp_record *ncp_rec = NULL;
|
||||
conversation_t *conversation;
|
||||
ptvcursor_t *ptvc = NULL;
|
||||
|
||||
func = tvb_get_guint8(tvb, 6);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine which ncp_record to use. */
|
||||
switch (type) {
|
||||
case 0x1111:
|
||||
ncp_rec = &ncp1111_request;
|
||||
break;
|
||||
case 0x2222:
|
||||
ncp_rec = ncp_record_find(func, subfunc);
|
||||
break;
|
||||
default:
|
||||
ncp_rec = NULL;
|
||||
}
|
||||
|
||||
/* Fill in the INFO column. */
|
||||
if (check_col(pinfo->fd, COL_INFO)) {
|
||||
if (ncp_rec) {
|
||||
col_add_fstr(pinfo->fd, COL_INFO, "C %s", ncp_rec->name);
|
||||
|
@ -114,13 +160,13 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
|
|||
else {
|
||||
if (requires_subfunc) {
|
||||
col_add_fstr(pinfo->fd, COL_INFO,
|
||||
"C Unknown Function 0x%02X/0x%02x",
|
||||
func, subfunc);
|
||||
"C Unknown Function 0x%02X/0x%02x (%d %d)",
|
||||
func, subfunc, func, subfunc);
|
||||
}
|
||||
else {
|
||||
col_add_fstr(pinfo->fd, COL_INFO,
|
||||
"C Unknown Function 0x%02x",
|
||||
func);
|
||||
"C Unknown Function 0x%02x (%d)",
|
||||
func, func);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,17 +191,36 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
|
|||
}
|
||||
|
||||
if (ncp_tree) {
|
||||
switch (type) {
|
||||
case 0x1111:
|
||||
; /* nothing */
|
||||
break;
|
||||
|
||||
case 0x2222:
|
||||
proto_tree_add_uint_format(ncp_tree, hf_ncp_func, tvb, 6, 1,
|
||||
func, "Function Code: 0x%02X (%s)",
|
||||
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_item(ncp_tree, hf_ncp_subfunc, tvb, 9,
|
||||
1, FALSE);
|
||||
ptvc = ptvcursor_new(ncp_tree, tvb, 10);
|
||||
}
|
||||
else {
|
||||
proto_tree_add_item(ncp_tree, hf_ncp_subfunc, tvb, 7,
|
||||
1, FALSE);
|
||||
ptvc = ptvcursor_new(ncp_tree, tvb, 8);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptvc = ptvcursor_new(ncp_tree, tvb, 7);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue