packetgen-plugin-smb 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/specs.yml +7 -3
  3. data/.rubocop.yml +22 -4
  4. data/Gemfile +7 -7
  5. data/README.md +8 -4
  6. data/examples/llmnr-responder +2 -2
  7. data/examples/smb-responder +8 -8
  8. data/lib/packetgen/plugin/gssapi.rb +15 -9
  9. data/lib/packetgen/plugin/netbios/datagram.rb +25 -27
  10. data/lib/packetgen/plugin/netbios/name.rb +3 -3
  11. data/lib/packetgen/plugin/netbios/session.rb +3 -3
  12. data/lib/packetgen/plugin/netbios.rb +0 -2
  13. data/lib/packetgen/plugin/ntlm/authenticate.rb +7 -7
  14. data/lib/packetgen/plugin/ntlm/av_pair.rb +17 -17
  15. data/lib/packetgen/plugin/ntlm/challenge.rb +4 -4
  16. data/lib/packetgen/plugin/ntlm/negotiate.rb +6 -6
  17. data/lib/packetgen/plugin/ntlm/ntlmv2_response.rb +10 -10
  18. data/lib/packetgen/plugin/ntlm.rb +21 -22
  19. data/lib/packetgen/plugin/smb/blocks.rb +8 -8
  20. data/lib/packetgen/plugin/smb/browser/domain_announcement.rb +1 -1
  21. data/lib/packetgen/plugin/smb/browser/host_announcement.rb +12 -12
  22. data/lib/packetgen/plugin/smb/browser/local_master_announcement.rb +1 -1
  23. data/lib/packetgen/plugin/smb/browser.rb +5 -5
  24. data/lib/packetgen/plugin/smb/close/request.rb +4 -4
  25. data/lib/packetgen/plugin/smb/close/response.rb +3 -3
  26. data/lib/packetgen/plugin/smb/filetime.rb +4 -6
  27. data/lib/packetgen/plugin/smb/negotiate/dialect.rb +5 -5
  28. data/lib/packetgen/plugin/smb/negotiate/request.rb +4 -4
  29. data/lib/packetgen/plugin/smb/ntcreateandx/request.rb +23 -23
  30. data/lib/packetgen/plugin/smb/ntcreateandx/response.rb +21 -21
  31. data/lib/packetgen/plugin/smb/string.rb +1 -1
  32. data/lib/packetgen/plugin/smb/trans/request.rb +24 -23
  33. data/lib/packetgen/plugin/smb/trans/response.rb +18 -17
  34. data/lib/packetgen/plugin/smb.rb +52 -62
  35. data/lib/packetgen/plugin/smb2/base.rb +4 -4
  36. data/lib/packetgen/plugin/smb2/error.rb +6 -6
  37. data/lib/packetgen/plugin/smb2/guid.rb +12 -12
  38. data/lib/packetgen/plugin/smb2/negotiate/context.rb +19 -19
  39. data/lib/packetgen/plugin/smb2/negotiate/request.rb +27 -27
  40. data/lib/packetgen/plugin/smb2/negotiate/response.rb +31 -26
  41. data/lib/packetgen/plugin/smb2/session_setup/request.rb +9 -11
  42. data/lib/packetgen/plugin/smb2/session_setup/response.rb +5 -6
  43. data/lib/packetgen/plugin/smb2.rb +49 -55
  44. data/lib/packetgen/plugin/smb_version.rb +1 -1
  45. data/packetgen-plugin-smb.gemspec +3 -3
  46. metadata +12 -38
@@ -21,7 +21,7 @@ module PacketGen::Plugin
21
21
  # | ... |
22
22
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23
23
  # @author Sylvain Daubert
24
- class Context < PacketGen::Types::Fields
24
+ class Context < BinStruct::Struct
25
25
  # Known types
26
26
  TYPES = {
27
27
  'PREAUTH_INTEGRITY_CAP' => 1,
@@ -31,23 +31,23 @@ module PacketGen::Plugin
31
31
  # @!attribute type
32
32
  # 16-bit context type
33
33
  # @return [Integer]
34
- define_field :type, PacketGen::Types::Int16leEnum, enum: TYPES
34
+ define_attr :type, BinStruct::Int16leEnum, enum: TYPES
35
35
  # @!attribute data_length
36
36
  # 16-bit data length
37
37
  # @return [Integer]
38
- define_field :data_length, PacketGen::Types::Int16le
38
+ define_attr :data_length, BinStruct::Int16le
39
39
  # @!attribute reserved
40
40
  # 32-bit reserved field
41
41
  # @return [Integer]
42
- define_field :reserved, PacketGen::Types::Int32le
42
+ define_attr :reserved, BinStruct::Int32le
43
43
  # @!attribute data
44
44
  # context data
45
45
  # @return [String]
46
- define_field :data, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: h[:data_length]) }
46
+ define_attr :data, BinStruct::String, builder: ->(h, t) { t.new(length_from: h[:data_length]) }
47
47
  # @!attribute pad
48
48
  # Padding to align next context on a 8-byte offset
49
49
  # @return [String]
50
- define_field :pad, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: -> { 8 - (h.offset_of(:data) + h.data_length) % 8 }) }
50
+ define_attr :pad, BinStruct::String, builder: ->(h, t) { t.new(length_from: -> { 8 - ((h.offset_of(:data) + h.data_length) % 8) }) }
51
51
 
52
52
  # @private
53
53
  alias old_read read
@@ -74,45 +74,45 @@ module PacketGen::Plugin
74
74
 
75
75
  # Specialized {Context} for PREAUTH_INTEGRITY_CAP type.
76
76
  class PreauthIntegrityCap < Context
77
- remove_field :data
77
+ remove_attr :data
78
78
  # @!attribute hash_alg_count
79
79
  # 16-bit number of hash algorithm in {#hash_alg}
80
80
  # @return [Integer]
81
- define_field_before :pad, :hash_alg_count, PacketGen::Types::Int16le
81
+ define_attr_before :pad, :hash_alg_count, BinStruct::Int16le
82
82
  # @!attribute salt_length
83
83
  # 16-bit length of {#salt} field, in bytes.
84
84
  # @return [Integer]
85
- define_field_before :pad, :salt_length, PacketGen::Types::Int16le
85
+ define_attr_before :pad, :salt_length, BinStruct::Int16le
86
86
  # @!attribute hash_alg
87
87
  # Array of 16-bit integer IDs specifying the supported preauthentication
88
88
  # hash algorithms
89
- # @return [PacketGen::Types::ArrayOfInt16le]
90
- define_field_before :pad, :hash_alg, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:hash_alg_count]) }
89
+ # @return [BinStruct::ArrayOfInt16le]
90
+ define_attr_before :pad, :hash_alg, BinStruct::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:hash_alg_count]) }
91
91
  # @!attribute salt
92
92
  # Salt value for hash
93
93
  # @return [String]
94
- define_field_before :pad, :salt, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: h[:salt_length]) }
95
- update_field :pad, builder: ->(h, t) { t.new(length_from: -> { (8 - (h.offset_of(:salt) + h.salt_length) % 8) % 8 }) }
94
+ define_attr_before :pad, :salt, BinStruct::String, builder: ->(h, t) { t.new(length_from: h[:salt_length]) }
95
+ update_attr :pad, builder: ->(h, t) { t.new(length_from: -> { (8 - ((h.offset_of(:salt) + h.salt_length) % 8)) }) }
96
96
  end
97
97
 
98
98
  # Specialized {Context} for ENCRYPTION_CAP type.
99
99
  class EncryptionCap < Context
100
- remove_field :data
100
+ remove_attr :data
101
101
  # @!attribute cipher_count
102
102
  # 16-bit number of cipher algorithm in {#ciphers}
103
103
  # @return [Integer]
104
- define_field_before :pad, :cipher_count, PacketGen::Types::Int16le
104
+ define_attr_before :pad, :cipher_count, BinStruct::Int16le
105
105
  # @!attribute ciphers
106
106
  # Array of 16-bit integer IDs specifying the supported encryption
107
107
  # algorithms
108
- # @return [PacketGen::Types::ArrayOfInt16le]
109
- define_field_before :pad, :ciphers, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:cipher_count]) }
110
- update_field :pad, builder: ->(h, t) { t.new(length_from: -> { (8 - (h.offset_of(:cipher_count) + h[:cipher_count].sz) % 8) % 8 }) }
108
+ # @return [BinStruct::ArrayOfInt16le]
109
+ define_attr_before :pad, :ciphers, BinStruct::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:cipher_count]) }
110
+ update_attr :pad, builder: ->(h, t) { t.new(length_from: -> { (8 - ((h.offset_of(:cipher_count) + h[:cipher_count].sz) % 8)) % 8 }) }
111
111
  end
112
112
 
113
113
  # Array of {Context}
114
114
  # @author Sylvain Daubert
115
- class ArrayOfContext < PacketGen::Types::Array
115
+ class ArrayOfContext < BinStruct::Array
116
116
  set_of Context
117
117
 
118
118
  private
@@ -53,23 +53,22 @@ module PacketGen::Plugin
53
53
  # @!attribute structure_size
54
54
  # 16-bit negotiate request structure size. Should be 36.
55
55
  # @return [Integer]
56
- define_field :structure_size, PacketGen::Types::Int16le, default: 36
56
+ define_attr :structure_size, BinStruct::Int16le, default: 36
57
57
  # @!attribute dialect_count
58
58
  # 16-bit number of dialects that are contained in {#dialects}.
59
59
  # @return [Integer]
60
- define_field :dialect_count, PacketGen::Types::Int16le
60
+ define_attr :dialect_count, BinStruct::Int16le
61
61
  # @!attribute security_mode
62
62
  # 16-bit security mode field.
63
63
  # @return [Integer]
64
- define_field :security_mode, PacketGen::Types::Int16leEnum, enum: SECURITY_MODES
64
+ define_attr :security_mode, BinStruct::Int16leEnum, enum: SECURITY_MODES
65
65
  # @!attribute reserved
66
66
  # 16-bit reserved field.
67
67
  # @return [Integer]
68
- define_field :reserved, PacketGen::Types::Int16le
68
+ define_attr :reserved, BinStruct::Int16le
69
69
  # @!attribute capabilities
70
70
  # 32-bit capabilities field.
71
71
  # @return [Integer]
72
- define_field :capabilities, PacketGen::Types::Int32le
73
72
  # @!attribute cap_encryption
74
73
  # Indicates if encryption is supported
75
74
  # @return [Boolean]
@@ -91,28 +90,29 @@ module PacketGen::Plugin
91
90
  # @!attribute cap_dfs
92
91
  # Indicates if Distributed File system (DFS) is supported
93
92
  # @return [Boolean]
94
- define_bit_fields_on :capabilities, :cap_rsv, 25, :cap_encryption, :cap_dir_leasing,
95
- :cap_persistent_handles, :cap_multi_channel,
96
- :cap_large_mtu, :cap_leasing, :cap_dfs
93
+ define_bit_attr :capabilities, endian: :little,
94
+ cap_rsv: 25, cap_encryption: 1, cap_dir_leasing: 1,
95
+ cap_persistent_handles: 1, cap_multi_channel: 1,
96
+ cap_large_mtu: 1, cap_leasing: 1, cap_dfs: 1
97
97
  # @!attribute client_guid
98
98
  # @return []
99
- define_field :client_guid, GUID
99
+ define_attr :client_guid, GUID
100
100
  # @!attribute context_offset
101
101
  # Only for SMB3 dialect.
102
102
  # @return [Integer]
103
- define_field :context_offset, PacketGen::Types::Int32le
103
+ define_attr :context_offset, BinStruct::Int32le
104
104
  # @!attribute context_count
105
105
  # Only for SMB3 dialect.
106
106
  # @return [Integer]
107
- define_field :context_count, PacketGen::Types::Int16le
107
+ define_attr :context_count, BinStruct::Int16le
108
108
  # @!attribute reserved2
109
109
  # Only for SMB3 dialect.
110
110
  # @return [Integer]
111
- define_field :reserved2, PacketGen::Types::Int16le
111
+ define_attr :reserved2, BinStruct::Int16le
112
112
  # @!attribute dialects
113
113
  # Array of 16-bit integers specifying the supported dialtec revisions.
114
- # @return [Array<PacketGen::Types::Int16le>]
115
- define_field :dialects, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:dialect_count]) }
114
+ # @return [Array<BinStruct::Int16le>]
115
+ define_attr :dialects, BinStruct::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:dialect_count]) }
116
116
  # @!attribute pad
117
117
  # Optional padding between the end of the {#dialects} array and the first negotiate
118
118
  # context in {#context_list} so that the first negotiate context is 8-byte aligned.
@@ -122,7 +122,7 @@ module PacketGen::Plugin
122
122
  # If {#dialects} contains the value 0x0311, then this field must contain an array
123
123
  # of {Context}
124
124
  # @return [ArrayOfContext]
125
- define_field :context_list, ArrayOfContext, builder: ->(h, t) { t.new(counter: h[:context_count]) }
125
+ define_attr :context_list, ArrayOfContext, builder: ->(h, t) { t.new(counter: h[:context_count]) }
126
126
 
127
127
  # Protocol name
128
128
  # @return [String]
@@ -131,25 +131,18 @@ module PacketGen::Plugin
131
131
  end
132
132
 
133
133
  # @return [String]
134
- def inspect
134
+ def inspect # rubocop:disable Metrics/AbcSize
135
135
  super do |attr|
136
136
  case attr
137
137
  when :capabilities
138
- value = bits_on(attr).reject { |_, v| v > 1 }
139
- .keys
140
- .select { |b| send("#{b}?") }
141
- .map(&:to_s)
138
+ value = bits_on(attr).select { |b| respond_to?("#{b}?") && send("#{b}?") }
139
+ .map { |v| v.to_s.delete_prefix('cap_') }
142
140
  .join(',')
143
- .gsub!(/cap_/, '')
144
141
  value = '%-16s (0x%08x)' % [value, self[attr].to_i]
145
- str = PacketGen::Inspect.shift_level
146
- str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
147
- attr, value]
142
+ inspect_attr(attr, value)
148
143
  when :dialects
149
144
  list = self.dialects.map { |v| '%#x' % v.to_i }.join(',')
150
- str = PacketGen::Inspect.shift_level
151
- str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
152
- attr, list]
145
+ inspect_attr(attr, list)
153
146
  end
154
147
  end
155
148
  end
@@ -164,6 +157,13 @@ module PacketGen::Plugin
164
157
  self.context_offset = SMB2::HEADER_SIZE + offset_of(:context_list) unless context_list.empty?
165
158
  context_list.each { |ctx| ctx.calc_length if ctx.respond_to? :calc_length }
166
159
  end
160
+
161
+ private
162
+
163
+ def inspect_attr(attr, value)
164
+ str = PacketGen::Inspect.shift_level
165
+ str << (PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr, value])
166
+ end
167
167
  end
168
168
  end
169
169
  end
@@ -61,26 +61,25 @@ module PacketGen::Plugin
61
61
  # @!attribute structure_size
62
62
  # 16-bit negotiate request structure size. Should be 65.
63
63
  # @return [Integer]
64
- define_field :structure_size, PacketGen::Types::Int16le, default: 65
64
+ define_attr :structure_size, BinStruct::Int16le, default: 65
65
65
  # @!attribute security_mode
66
66
  # 16-bit security mode field.
67
67
  # @return [Integer]
68
- define_field :security_mode, PacketGen::Types::Int16leEnum, enum: Negotiate::Request::SECURITY_MODES
68
+ define_attr :security_mode, BinStruct::Int16leEnum, enum: Negotiate::Request::SECURITY_MODES
69
69
  # @!attribute dialect
70
70
  # 16-bit prefered SMB2 protocol dialect number.
71
71
  # @return [Integer]
72
- define_field :dialect, PacketGen::Types::Int16le
72
+ define_attr :dialect, BinStruct::Int16le
73
73
  # @!attribute context_count
74
74
  # Only for SMB3 dialect.
75
75
  # @return [Integer]
76
- define_field :context_count, PacketGen::Types::Int16le
76
+ define_attr :context_count, BinStruct::Int16le
77
77
  # @!attribute server_guid
78
78
  # @return []
79
- define_field :server_guid, GUID
79
+ define_attr :server_guid, GUID
80
80
  # @!attribute capabilities
81
81
  # 32-bit capabilities field.
82
82
  # @return [Integer]
83
- define_field :capabilities, PacketGen::Types::Int32le
84
83
  # @!attribute cap_encryption
85
84
  # Indicates if encryption is supported
86
85
  # @return [Boolean]
@@ -102,45 +101,46 @@ module PacketGen::Plugin
102
101
  # @!attribute cap_dfs
103
102
  # Indicates if Distributed File system (DFS) is supported
104
103
  # @return [Boolean]
105
- define_bit_fields_on :capabilities, :cap_rsv, 25, :cap_encryption, :cap_dir_leasing,
106
- :cap_persistent_handles, :cap_multi_channel,
107
- :cap_large_mtu, :cap_leasing, :cap_dfs
104
+ define_bit_attr :capabilities, endian: :little,
105
+ cap_rsv: 25, cap_encryption: 1, cap_dir_leasing: 1,
106
+ cap_persistent_handles: 1, cap_multi_channel: 1,
107
+ cap_large_mtu: 1, cap_leasing: 1, cap_dfs: 1
108
108
  # @!attribute max_trans_size
109
109
  # 32-bit value indicating the maximum size of the buffer used for
110
110
  # QUERY_INFO, QUERY_DIRECTORY, SET_INFO and CHANGE_NOTIFY operations.
111
111
  # @return [Integer]
112
- define_field :max_trans_size, PacketGen::Types::Int32le
112
+ define_attr :max_trans_size, BinStruct::Int32le
113
113
  # @!attribute max_read_size
114
114
  # 32-bit value indicating the maximum size of a READ request
115
115
  # @return [Integer]
116
- define_field :max_read_size, PacketGen::Types::Int32le
116
+ define_attr :max_read_size, BinStruct::Int32le
117
117
  # @!attribute max_write_size
118
118
  # 32-bit value indicating the maximum size of a WRITE request
119
119
  # @return [Integer]
120
- define_field :max_write_size, PacketGen::Types::Int32le
120
+ define_attr :max_write_size, BinStruct::Int32le
121
121
  # @!attribute system_time
122
122
  # System time of the SMB2 server
123
123
  # @return [SMB::Filetime]
124
- define_field :system_time, SMB::Filetime
124
+ define_attr :system_time, SMB::Filetime
125
125
  # @!attribute start_time
126
126
  # Start time of the SMB2 server
127
127
  # @return [SMB::Filetime]
128
- define_field :start_time, SMB::Filetime
128
+ define_attr :start_time, SMB::Filetime
129
129
  # @!attribute buffer_offset
130
130
  # The offset, from the beginning of the SMB2 header of the {#buffer}.
131
131
  # @return [Integer]
132
- define_field :buffer_offset, PacketGen::Types::Int16le
132
+ define_attr :buffer_offset, BinStruct::Int16le
133
133
  # @!attribute buffer_length
134
134
  # The length of the {#buffer} field.
135
135
  # @return [Integer]
136
- define_field :buffer_length, PacketGen::Types::Int16le
136
+ define_attr :buffer_length, BinStruct::Int16le
137
137
  # @!attribute context_offset
138
138
  # Only for SMB3 dialect.
139
139
  # @return [Integer]
140
- define_field :context_offset, PacketGen::Types::Int32le
140
+ define_attr :context_offset, BinStruct::Int32le
141
141
  # @!attribute buffer
142
142
  # @return [GSSAPI]
143
- define_field :buffer, GSSAPI, token: :init, optional: ->(h) { h.buffer_offset.positive? }
143
+ define_attr :buffer, GSSAPI, token: :init, optional: ->(h) { h.buffer_offset.positive? }
144
144
  # @!attribute pad
145
145
  # Optional padding between the end of the {#buffer} field and the first negotiate
146
146
  # context in {#context_list} so that the first negotiate context is 8-byte aligned
@@ -151,7 +151,7 @@ module PacketGen::Plugin
151
151
  # If {#dialect} has the value 0x0311, then this field must contain an array
152
152
  # of {Context}
153
153
  # @return [ArrayOfContext]
154
- define_field :context_list, ArrayOfContext, builder: ->(h, t) { t.new(counter: h[:context_count]) }
154
+ define_attr :context_list, ArrayOfContext, builder: ->(h, t) { t.new(counter: h[:context_count]) }
155
155
 
156
156
  # Protocol name
157
157
  # @return [String]
@@ -164,16 +164,13 @@ module PacketGen::Plugin
164
164
  super do |attr|
165
165
  next unless attr == :capabilities
166
166
 
167
- value = bits_on(attr).reject { |_, v| v > 1 }
168
- .keys
169
- .select { |b| send("#{b}?") }
167
+ value = bits_on(attr).select { |b| respond_to?("#{b}?") && send("#{b}?") }
170
168
  .map(&:to_s)
171
169
  .join(',')
172
- .gsub!(/cap_/, '')
170
+ .gsub!('cap_', '')
173
171
  value = '%-16s (0x%08x)' % [value, self[attr].to_i]
174
172
  str = PacketGen::Inspect.shift_level
175
- str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
176
- attr, value]
173
+ str << (PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr, value])
177
174
  end
178
175
  end
179
176
 
@@ -182,15 +179,23 @@ module PacketGen::Plugin
182
179
  # Also calculate lengths in {Context contexts}.
183
180
  # @return [void]
184
181
  def calc_length
185
- self[:pad].read SMB2::MAX_PADDING
182
+ self[:pad].read(SMB2::MAX_PADDING)
183
+ calc_buffer_fields
184
+ calc_context_fields
185
+ end
186
+
187
+ private
186
188
 
189
+ def calc_buffer_fields
187
190
  self.buffer_length = self[:buffer].sz
188
191
  self.buffer_offset = if self.buffer_length.zero?
189
192
  0
190
193
  else
191
194
  SMB2::HEADER_SIZE + offset_of(:buffer)
192
195
  end
196
+ end
193
197
 
198
+ def calc_context_fields
194
199
  self.context_offset = 0
195
200
  self.context_offset = SMB2::HEADER_SIZE + offset_of(:context_list) unless context_list.empty?
196
201
  context_list.each { |ctx| ctx.calc_length if ctx.respond_to? :calc_length }
@@ -36,50 +36,48 @@ module PacketGen::Plugin
36
36
  # @!attribute structure_size
37
37
  # 16-bit session setup request structure size. Should be 25.
38
38
  # @return [Integer]
39
- define_field :structure_size, PacketGen::Types::Int16le, default: 25
39
+ define_attr :structure_size, BinStruct::Int16le, default: 25
40
40
  # @!attribute flags
41
41
  # 8-bit flags for SMB 3 dialect.
42
42
  # @return [Integer]
43
- define_field :flags, PacketGen::Types::Int8
44
43
  # @!attribute flags_rsv
45
44
  # @return [Integer]
46
45
  # @!attribute flags_binding?
47
46
  # @return [Boolean]
48
- define_bit_fields_on :flags, :flags_rsv, 7, :flags_binding
47
+ define_bit_attr :flags, flags_rsv: 7, flags_binding: 1
49
48
  # @!attribute security_mode
50
49
  # 16-bit security mode field.
51
50
  # @return [Integer]
52
- define_field :security_mode, PacketGen::Types::Int8Enum, enum: SECURITY_MODES
51
+ define_attr :security_mode, BinStruct::Int8Enum, enum: SECURITY_MODES
53
52
  # @!attribute capabilities
54
53
  # 32-bit capabilities field.
55
54
  # @return [Integer]
56
- define_field :capabilities, PacketGen::Types::Int32le
57
55
  # @!attribute cap_rsv
58
56
  # 31-bit reserved field
59
57
  # @return [Boolean]
60
58
  # @!attribute cap_dfs
61
59
  # Indicates if Distributed File system (DFS) is supported
62
60
  # @return [Boolean]
63
- define_bit_fields_on :capabilities, :cap_rsv, 31, :cap_dfs
61
+ define_bit_attr :capabilities, endian: :little, cap_rsv: 31, cap_dfs: 1
64
62
  # @!attribute channel
65
63
  # 32-bit reserved field
66
64
  # @return [Integer]
67
- define_field :channel, PacketGen::Types::Int32le
65
+ define_attr :channel, BinStruct::Int32le
68
66
  # @!attribute buffer_offset
69
67
  # The offset, from the beginning of the SMB2 header of the {#buffer}.
70
68
  # @return [Integer]
71
- define_field :buffer_offset, PacketGen::Types::Int16le, default: SMB2::HEADER_SIZE + 6 * 4
69
+ define_attr :buffer_offset, BinStruct::Int16le, default: SMB2::HEADER_SIZE + (6 * 4)
72
70
  # @!attribute buffer_length
73
71
  # The length of the {#buffer} field.
74
72
  # @return [Integer]
75
- define_field :buffer_length, PacketGen::Types::Int16le
73
+ define_attr :buffer_length, BinStruct::Int16le
76
74
  # @!attribute prev_session_id
77
75
  # 64-bit previously established session id
78
76
  # @return [Integer]
79
- define_field :prev_session_id, PacketGen::Types::Int64le
77
+ define_attr :prev_session_id, BinStruct::Int64le
80
78
  # @!attribute buffer
81
79
  # @return [GSSAPI]
82
- define_field :buffer, GSSAPI, token: :response, optional: ->(h) { h.buffer_offset.positive? }
80
+ define_attr :buffer, GSSAPI, token: :response, optional: ->(h) { h.buffer_offset.positive? }
83
81
 
84
82
  # Calculate and set {#buffer_length} and {#buffer_offset} fields.
85
83
  # @return [void]
@@ -25,11 +25,10 @@ module PacketGen::Plugin
25
25
  # @!attribute structure_size
26
26
  # 16-bit session setup request structure size. Should be 9.
27
27
  # @return [Integer]
28
- define_field :structure_size, PacketGen::Types::Int16le, default: 9
28
+ define_attr :structure_size, BinStruct::Int16le, default: 9
29
29
  # @!attribute flags
30
30
  # 16-bit session flags
31
31
  # @return [Integer]
32
- define_field :flags, PacketGen::Types::Int16le
33
32
  # @!attribute flags_rsv
34
33
  # 13-bit reserved field
35
34
  # @return [Integer]
@@ -39,18 +38,18 @@ module PacketGen::Plugin
39
38
  # @return [Boolean]
40
39
  # @!attribute flags_is_guest?
41
40
  # @return [Boolean]
42
- define_bit_fields_on :flags, :flags_rsv, 13, :flags_encrypt_data, :flags_is_null, :flags_is_guest
41
+ define_bit_attr :flags, endian: :little, flags_rsv: 13, flags_encrypt_data: 1, lags_is_null: 1, flags_is_guest: 1
43
42
  # @!attribute buffer_offset
44
43
  # The offset, from the beginning of the SMB2 header of the {#buffer}.
45
44
  # @return [Integer]
46
- define_field :buffer_offset, PacketGen::Types::Int16le, default: SMB2::HEADER_SIZE + 8
45
+ define_attr :buffer_offset, BinStruct::Int16le, default: SMB2::HEADER_SIZE + 8
47
46
  # @!attribute buffer_length
48
47
  # The length of the {#buffer} field.
49
48
  # @return [Integer]
50
- define_field :buffer_length, PacketGen::Types::Int16le
49
+ define_attr :buffer_length, BinStruct::Int16le
51
50
  # @!attribute buffer
52
51
  # @return [GSSAPI]
53
- define_field :buffer, GSSAPI, token: :response, optional: ->(h) { h.buffer_offset.positive? }
52
+ define_attr :buffer, GSSAPI, token: :response, optional: ->(h) { h.buffer_offset.positive? }
54
53
 
55
54
  # Calculate and set {#buffer_length} and {#buffer_offset} fields.
56
55
  # @return [void]
@@ -33,7 +33,7 @@ module PacketGen::Plugin
33
33
  }.freeze
34
34
 
35
35
  # SMB marker, on start of header
36
- MARKER = PacketGen.force_binary("\xfeSMB").freeze
36
+ MARKER = "\xfeSMB".b.freeze
37
37
 
38
38
  # SMB2 header size
39
39
  HEADER_SIZE = 64
@@ -44,99 +44,96 @@ module PacketGen::Plugin
44
44
  # @!attribute protocol
45
45
  # This field must contain {MARKER SMB2 marker}
46
46
  # @return [String]
47
- define_field :protocol, PacketGen::Types::String, static_length: 4, default: MARKER
47
+ define_attr :protocol, BinStruct::String, static_length: 4, default: MARKER
48
48
  # @!attribute structure_size
49
49
  # 16-bit SMB2 header size. Should be 64.
50
50
  # @return [Integer]
51
- define_field :structure_size, PacketGen::Types::Int16le, default: HEADER_SIZE
51
+ define_attr :structure_size, BinStruct::Int16le, default: HEADER_SIZE
52
52
  # @!attribute credit charge
53
53
  # 16-bit credit charge field. Must not be used and must be set to 0.
54
54
  # @return [Integer]
55
- define_field :credit_charge, PacketGen::Types::Int16le
55
+ define_attr :credit_charge, BinStruct::Int16le
56
56
  # @!attribute status
57
57
  # 32-bit status field (SMB 2 dialect only).
58
58
  # @return [Integer]
59
- define_field :status, PacketGen::Types::Int32le
59
+ define_attr :status, BinStruct::Int32le
60
60
  # @!attribute command
61
61
  # 16-bit command field
62
62
  # @return [Integer]
63
- define_field :command, PacketGen::Types::Int16leEnum, enum: COMMANDS
63
+ define_attr :command, BinStruct::Int16leEnum, enum: COMMANDS
64
64
  # @!attribute credit
65
65
  # 16-bit credit field. This is the number of credits a client is requesting in
66
66
  # a request, and the number of credits granted in a response.
67
67
  # @return [Integer]
68
- define_field :credit, PacketGen::Types::Int16le
69
- # @!attribute flags
70
- # 32-bit flags field
68
+ define_attr :credit, BinStruct::Int16le
69
+ # @!attribute flags_rsv1
70
+ # 2-bit reserved field
71
+ # @return [Integer]
72
+ # @!attribute flags_smb3_replay_op?
73
+ # When set, the command is a replay operation (only SMB 3 dialect).
74
+ # @return [Boolean]
75
+ # @!attribute flags_dsf_op?
76
+ # When set, the command is a Distributed File System (DFS) operation..
77
+ # @return [Boolean]
78
+ # @!attribute flags_rsv2
79
+ # 21-bit reserved field
80
+ # @return [Integer]
81
+ # @!attribute flags_smb3_priority
82
+ # 3-bit value of I/O priority (only SMB 3 dialect).
71
83
  # @return [Integer]
72
- define_field :flags, PacketGen::Types::Int32le
84
+ # @!attribute flags_signed?
85
+ # When set, the message is signed.
86
+ # @return [Boolean]
87
+ # @!attribute flags_related_op?
88
+ # When set, the message is a related operation in a compounded chain.
89
+ # @return [Boolean]
90
+ # @!attribute flags_async?
91
+ # When set, the message is a asynchronous.
92
+ # @return [Boolean]
93
+ # @!attribute flags_response?
94
+ # When set, the message is a response from server to client.
95
+ # @return [Boolean]
96
+ define_bit_attr :flags, endian: :little,
97
+ flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
98
+ flags_rsv2: 21, flags_smb3_priority: 3,
99
+ flags_signed: 1, flags_related_op: 1, flags_async: 1,
100
+ flags_response: 1
73
101
  # @!attribute next_command
74
102
  # 32-bit offset from the beginning of this SMB2 header to the start of the subsequent
75
103
  # 8-byte aligned SMB2 header (only for compounded requests).
76
104
  # @return [Integer]
77
- define_field :next_command, PacketGen::Types::Int32le
105
+ define_attr :next_command, BinStruct::Int32le
78
106
  # @!attribute message_id
79
107
  # 64-bit alue that identifies a message request and response uniquely across all
80
108
  # messages that are sent on the same SMB 2 Protocol transport connection.
81
109
  # @return [Integer]
82
- define_field :message_id, PacketGen::Types::Int64le
110
+ define_attr :message_id, BinStruct::Int64le
83
111
  # @!attribute async_id
84
112
  # 64-bit unique ID that is created by the server to handle operations
85
113
  # asynchronously. Only present for asynchronous messages.
86
114
  # @return [Integer]
87
- define_field :async_id, PacketGen::Types::Int64le, optional: ->(h) { h.flags & 2 == 2 }
115
+ define_attr :async_id, BinStruct::Int64le, optional: ->(h) { h.flags & 2 == 2 }
88
116
  # @!attribute reserved
89
117
  # 32-bit reserved field.
90
118
  # Only present for synchronous messages.
91
119
  # @return [Integer]
92
- define_field :reserved, PacketGen::Types::Int32le, optional: ->(h) { (h.flags & 2).zero? }
120
+ define_attr :reserved, BinStruct::Int32le, optional: ->(h) { h.flags.nobits?(2) }
93
121
  # @!attribute tree_id
94
122
  # 32-bit integer that uniquely identifies the tree connect for the command.
95
123
  # Only present for synchronous messages.
96
124
  # @return [Integer]
97
- define_field :tree_id, PacketGen::Types::Int32le, optional: ->(h) { (h.flags & 2).zero? }
125
+ define_attr :tree_id, BinStruct::Int32le, optional: ->(h) { h.flags.nobits?(2) }
98
126
  # @!attribute session_id
99
127
  # 64-bit integer that uniquely identifies the established session for the command.
100
128
  # @return [Integer]
101
- define_field :session_id, PacketGen::Types::Int64le
129
+ define_attr :session_id, BinStruct::Int64le
102
130
  # @!attribute signature
103
131
  # 16-byte message signature
104
132
  # @return [String]
105
- define_field :signature, PacketGen::Types::String, static_length: 16, default: [0, 0].pack('qq')
133
+ define_attr :signature, BinStruct::String, static_length: 16, default: [0, 0].pack('qq')
106
134
  # @!attribute body
107
135
  # @return [String]
108
- define_field :body, PacketGen::Types::String
109
- # @!attribute flags_rsv1
110
- # 2-bit reserved field
111
- # @return [Integer]
112
- # @!attribute flags_smb3_replay_op?
113
- # When set, the command is a replay operation (only SMB 3 dialect).
114
- # @return [Boolean]
115
- # @!attribute flags_dsf_op?
116
- # When set, the command is a Distributed File System (DFS) operation..
117
- # @return [Boolean]
118
- # @!attribute flags_rsv2
119
- # 21-bit reserved field
120
- # @return [Integer]
121
- # @!attribute flags_smb3_priority
122
- # 3-bit value of I/O priority (only SMB 3 dialect).
123
- # @return [Integer]
124
- # @!attribute flags_signed?
125
- # When set, the message is signed.
126
- # @return [Boolean]
127
- # @!attribute flags_related_op?
128
- # When set, the message is a related operation in a compounded chain.
129
- # @return [Boolean]
130
- # @!attribute flags_async?
131
- # When set, the message is a asynchronous.
132
- # @return [Boolean]
133
- # @!attribute flags_response?
134
- # When set, the message is a response from server to client.
135
- # @return [Boolean]
136
- define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
137
- :flags_rsv2, 21, :flags_smb3_priority, 3,
138
- :flags_signed, :flags_related_op, :flags_async,
139
- :flags_response
136
+ define_attr :body, BinStruct::String
140
137
 
141
138
  # Helper to bind a SMB2 command to {SMB2} header.
142
139
  # @param [String] command name
@@ -146,7 +143,7 @@ module PacketGen::Plugin
146
143
  krequest = self.const_get("#{contantized}::Request")
147
144
  kresponse = self.const_get("#{contantized}::Response")
148
145
  PacketGen::Header.add_class krequest
149
- self.bind krequest, command: SMB2::COMMANDS[command], flags: ->(v) { v.nil? ? 0 : (v & 1).zero? }
146
+ self.bind krequest, command: SMB2::COMMANDS[command], flags: ->(v) { v.nil? ? 0 : v.nobits?(1) }
150
147
  PacketGen::Header.add_class kresponse
151
148
  self.bind kresponse, command: SMB2::COMMANDS[command], flags: ->(v) { v.nil? ? 1 : (v & 1 == 1) }
152
149
  end
@@ -168,16 +165,13 @@ module PacketGen::Plugin
168
165
  super do |attr|
169
166
  next unless attr == :flags
170
167
 
171
- value = bits_on(attr).reject { |_, v| v > 1 }
172
- .keys
173
- .select { |b| send("#{b}?") }
168
+ value = bits_on(attr).select { |b| respond_to?("#{b}?") && send("#{b}?") }
174
169
  .map(&:to_s)
175
170
  .join(',')
176
171
  .gsub!(/#{attr}_/, '')
177
172
  value = '%-16s (0x%02x)' % [value, self[attr].to_i]
178
173
  str = PacketGen::Inspect.shift_level
179
- str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
180
- attr, value]
174
+ str << (PacketGen::Inspect::FMT_ATTR % [self[attr].type_name, attr, value])
181
175
  end
182
176
  end
183
177
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module PacketGen
4
4
  module Plugin
5
- SMB_VERSION = '0.6.2'
5
+ SMB_VERSION = '0.7.0'
6
6
  end
7
7
  end