Class: RubySMB::GenericPacket

Inherits:
BinData::Record
  • Object
show all
Defined in:
lib/ruby_smb/generic_packet.rb

Overview

Parent class for all SMB Packets.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.describeString

Outputs a nicely formatted string representation of the Packet's structure.

Returns:

  • (String)

    formatted string representation of the packet structure



8
9
10
11
12
13
14
# File 'lib/ruby_smb/generic_packet.rb', line 8

def self.describe
  description = ''
  fields_hashed.each do |field|
    description << format_field(field)
  end
  description
end

.fields_hashedArray<Hash>

Returns an array of hashes representing the fields for this record.

Returns:

  • (Array<Hash>)

    the array of hash representations of the record's fields



59
60
61
# File 'lib/ruby_smb/generic_packet.rb', line 59

def self.fields_hashed
  walk_fields(fields)
end

.format_field(field, depth = 0) ⇒ String

Takes a hash representation of a field and spits out a formatted string representation.

Parameters:

  • field (Hash)

    the hash representing the field

  • depth (Fixnum) (defaults to: 0)

    the recursive depth level to track indentation

Returns:

  • (String)

    the formatted string representation of the field



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/ruby_smb/generic_packet.rb', line 69

def self.format_field(field, depth = 0)
  name = field[:name].to_s
  if field[:class].ancestors.include? BinData::Record
    class_str = ''
    name.upcase!
  else
    class_str = field[:class].to_s.split('::').last
    class_str = "(#{class_str})"
    name.capitalize!
  end
  formatted_name = "\n" + ("\t" * depth) + name
  formatted_string = sprintf '%-30s %-10s %s', formatted_name, class_str, field[:label]
  field[:fields].each do |sub_field|
    formatted_string << format_field(sub_field, (depth + 1))
  end
  formatted_string
end

.walk_fields(fields) ⇒ Array<Hash>

Recursively walks through a field, building a hash representation of that field and all of it's sub-fields.

Parameters:

  • fields (Array<BinData::SanitizedField>)

    an array of fields to walk

Returns:

  • (Array<Hash>)

    an array of hashes representing the fields



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ruby_smb/generic_packet.rb', line 92

def self.walk_fields(fields)
  field_hashes = []
  fields.each do |field|
    field_hash = {}
    field_hash[:name] = field.name
    prototype = field.prototype
    field_hash[:class] = prototype.instance_variable_get(:@obj_class)
    params = prototype.instance_variable_get(:@obj_params)
    field_hash[:label] = params[:label]
    field_hash[:value] = params[:value]
    sub_fields = params[:fields]
    field_hash[:fields] = if sub_fields.nil?
                            []
                          else
                            walk_fields(sub_fields)
                          end
    field_hashes << field_hash
  end
  field_hashes
end

Instance Method Details

#displayObject



16
17
18
19
20
21
22
# File 'lib/ruby_smb/generic_packet.rb', line 16

def display
  display_str = ''
  self.class.fields_hashed.each do |field|
    display_str << display_field(field)
  end
  display_str
end

#packet_smb_versionObject



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ruby_smb/generic_packet.rb', line 25

def packet_smb_version
  class_name = self.class.to_s
  case class_name
    when /SMB1/
      'SMB1'
    when /SMB2/
      'SMB2'
    else
      ''
  end
end

#status_codeObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/ruby_smb/generic_packet.rb', line 37

def status_code
  value = -1
  smb_version = packet_smb_version
  case smb_version
    when 'SMB1'
      value = self.smb_header.nt_status.value
    when 'SMB2'
      value = self.smb2_header.nt_status.value
  end
  status_code = WindowsError::NTStatus.find_by_retval(value).first
  if status_code.nil?
    status_code = WindowsError::ErrorCode.new("0x#{value.to_s(16)}", value, "Unknown 0x#{value.to_s(16)}")
  end
  status_code
end