require'net/ssh/connection/constants'require'net/ssh/transport/constants'moduleNet;moduleSSH;moduleTest# This is an abstract class, not to be instantiated directly, subclassed by# Net::SSH::Test::LocalPacket and Net::SSH::Test::RemotePacket. It implements# functionality common to those subclasses.## These packets are not true packets, in that they don't represent what was# actually sent between the hosst; rather, they represent what was expected# to be sent, as dictated by the script (Net::SSH::Test::Script). Thus,# though they are defined with data elements, these data elements are used# to either validate data that was sent by the local host (Net::SSH::Test::LocalPacket)# or to mimic the sending of data by the remote host (Net::SSH::Test::RemotePacket).classPacketincludeNet::SSH::Transport::ConstantsincludeNet::SSH::Connection::Constants# Ceate a new packet of the given +type+, and with +args+ being a list of# data elements in the order expected for packets of the given +type+# (see #types).definitialize(type,*args)@type=self.class.const_get(type.to_s.upcase)@data=argsend# The default for +remote?+ is false. Subclasses should override as necessary.defremote?falseend# The default for +local?+ is false. Subclasses should override as necessary.deflocal?falseend# Instantiates the packets data elements. When the packet was first defined,# some elements may not have been fully realized, and were described as# Proc objects rather than atomic types. This invokes those Proc objects# and replaces them with their returned values. This allows for values # like Net::SSH::Test::Channel#remote_id to be used in scripts before# the remote_id is known (since it is only known after a channel has been# confirmed open).definstantiate!@data.map!{|i|i.respond_to?(:call)?i.call:i}end# Returns an array of symbols describing the data elements for packets of# the same type as this packet. These types are used to either validate# sent packets (Net::SSH::Test::LocalPacket) or build received packets# (Net::SSH::Test::RemotePacket).## Not all packet types are defined here. As new packet types are required# (e.g., a unit test needs to test that the remote host sent a packet that# is not implemented here), the description of that packet should be# added. Unsupported packet types will otherwise raise an exception.deftypes@types||=case@typewhenKEXINITthen[:long,:long,:long,:long,:string,:string,:string,:string,:string,:string,:string,:string,:string,:string,:bool]whenNEWKEYSthen[]whenCHANNEL_OPENthen[:string,:long,:long,:long]whenCHANNEL_OPEN_CONFIRMATIONthen[:long,:long,:long,:long]whenCHANNEL_DATAthen[:long,:string]whenCHANNEL_EXTENDED_DATAthen[:long,:long,:string]whenCHANNEL_EOF,CHANNEL_CLOSE,CHANNEL_SUCCESS,CHANNEL_FAILUREthen[:long]whenCHANNEL_REQUESTparts=[:long,:string,:bool]case@data[1]when"exec","subsystem"thenparts<<:stringwhen"exit-status"thenparts<<:longelseraise"don't know what to do about #{@data[1]} channel request"endelseraise"don't know how to parse packet type #{@type}"endendendend;end;end