packetgen 3.2.1 → 3.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79dc573da10eb15bbd9f38e0c84ecdf9a92d076980628635d1b9e240e3ca2210
4
- data.tar.gz: 0ae2bafa08e5a4a0b176276a141b8c8326265873bb20d86a75e07bb7018275ac
3
+ metadata.gz: ad942df146df9daf8c38e049fc112b13c93fd38a45362e8dd2a43c6e8382b224
4
+ data.tar.gz: 77b48a6af0170a912e91b888456c31881bfe1fd30a693796c849a946b5e27bac
5
5
  SHA512:
6
- metadata.gz: 7c405a57b79c4a9bf0d9032b34d7381b33e8c0705c554023f6a8131c19c48fb0118201d94da62e4f74b9d53551cdbcd434cb6363f27a84e5c3e8459cb28d613b
7
- data.tar.gz: 835969235415864e05b227dd5f0fb48535e3f414e60852cf788d6d90bf29be9a3a8dcf9b636ce8d500d29720753246e11459da925fea3f72f6cb8e11291565b8
6
+ metadata.gz: 98f7f9d7dd652741cdce08cbe081310c4f4ca6745702efc5755806614f30c7930498610f9925a6d7abeef1b8b64abfa2857c77bcc638872f31577fe587ad1e63
7
+ data.tar.gz: cc4e18519b09f7eaa753f9f2e4a500c5b3d0de2aed5bbd275b636d5c21ec763dca2a34da27a16336d65e2ec86d827812c0f546c5e67dfd9b500d683f8baac7ac
@@ -58,6 +58,12 @@ module PacketGen
58
58
  def to_human
59
59
  "DUID<#{type},#{body.inspect}>"
60
60
  end
61
+
62
+ # Get human-readable type
63
+ # @return [String]
64
+ def human_type
65
+ self[:type].to_human
66
+ end
61
67
  end
62
68
 
63
69
  # rubocop:disable Naming/ClassAndModuleCamelCase
@@ -34,13 +34,28 @@ module PacketGen
34
34
 
35
35
  k, v = h.split(':', 2)
36
36
  [k, v.strip]
37
- end.reject(&:nil?).to_h
37
+ end.compact.to_h
38
38
  when Hash
39
39
  @data = s_or_h
40
40
  end
41
41
  self
42
42
  end
43
43
 
44
+ # Get header value from its name
45
+ # @param [String] header header name
46
+ # @return [String] header value
47
+ def [](header)
48
+ data[header]
49
+ end
50
+
51
+ # Say if +self+ include +header+ header
52
+ # @param [String] header header name
53
+ # @return [Boolean]
54
+ def header?(header)
55
+ data.key?(header)
56
+ end
57
+ alias has_header? header?
58
+
44
59
  # Get binary string.
45
60
  # @return [String]
46
61
  def to_s
@@ -86,25 +86,23 @@ module PacketGen
86
86
  # Factory to build an option from its type
87
87
  # @return [Option]
88
88
  def self.build(options={})
89
- type = options.delete(:type)
89
+ type = options[:type]
90
90
  klass = case type
91
91
  when String
92
92
  types.key?(type) ? IP.const_get(type) : self
93
- when Integer
94
- types.value?(type) ? IP.const_get(types.key(type)) : self
95
93
  else
96
- self
94
+ types.value?(type) ? IP.const_get(types.key(type.to_i)) : self
97
95
  end
96
+ options.delete(:type) if klass != self
98
97
  klass.new(options)
99
98
  end
100
99
 
101
100
  def initialize(options={})
102
- unless options[:type]
103
- opt_name = self.class.to_s.gsub(/.*::/, '')
104
- options[:type] = Option.const_get("#{opt_name}_TYPE") if Option.const_defined? "#{opt_name}_TYPE"
105
- end
101
+ options[:type] = class2type unless options[:type]
102
+
106
103
  super
107
- self.length = sz if respond_to?(:length) && options[:length].nil?
104
+ initialize_length_if_needed(options)
105
+ initialize_data_if_needed(options)
108
106
  end
109
107
 
110
108
  # Get binary string. Set {#length} field.
@@ -121,6 +119,25 @@ module PacketGen
121
119
  str << ":#{self[:data].to_s.inspect}" if respond_to?(:length) && (length > 2) && !self[:data].to_s.empty?
122
120
  str
123
121
  end
122
+
123
+ private
124
+
125
+ def class2type
126
+ opt_name = self.class.to_s.gsub(/.*::/, '')
127
+ Option.const_get("#{opt_name}_TYPE") if Option.const_defined? "#{opt_name}_TYPE"
128
+ end
129
+
130
+ def initialize_length_if_needed(options)
131
+ self.length = sz if respond_to?(:length) && options[:length].nil?
132
+ end
133
+
134
+ def initialize_data_if_needed(options)
135
+ return unless fields.include?(:data) && self[:data].respond_to?(:from_human) && options.key?(:data)
136
+
137
+ # Force data if data is set in options but not length
138
+ self.length += options[:data].size
139
+ self[:data].from_human(options[:data])
140
+ end
124
141
  end
125
142
 
126
143
  # End-of-option-List IP option
@@ -173,6 +190,10 @@ module PacketGen
173
190
  # 16-bit stream ID
174
191
  # @return [Integer]
175
192
  define_field :id, Types::Int16
193
+
194
+ def to_human
195
+ super << ":#{self.id}"
196
+ end
176
197
  end
177
198
 
178
199
  # Router Alert IP option
@@ -183,6 +204,10 @@ module PacketGen
183
204
  # 16-bit value. Should be 0.
184
205
  # @return [Integer]
185
206
  define_field :value, Types::Int16, default: 0
207
+
208
+ def to_human
209
+ super << ":#{self.value}"
210
+ end
186
211
  end
187
212
  end
188
213
  end
@@ -74,6 +74,18 @@ module PacketGen
74
74
  # @author Sylvain Daubert
75
75
  class VariableBindings < RASN1::Model
76
76
  sequence_of :bindings, VarBind
77
+
78
+ # Get 'idx'th element from the list
79
+ # @return [VarBind,nil]
80
+ def [](idx)
81
+ value[idx]
82
+ end
83
+
84
+ # Get element counts in list
85
+ # @return [Integer]
86
+ def size
87
+ value.size
88
+ end
77
89
  end
78
90
 
79
91
  # Class to handle GetRequest PDU
@@ -119,6 +131,10 @@ module PacketGen
119
131
  integer(:error, value: 0, enum: ERRORS),
120
132
  integer(:error_index, value: 0),
121
133
  model(:varbindlist, VariableBindings)]
134
+
135
+ def initialize(args={})
136
+ super
137
+ end
122
138
  end
123
139
 
124
140
  # Class to handle GetNextRequest PDU
@@ -264,11 +280,12 @@ module PacketGen
264
280
  data.chosen = options[:chosen_pdu] if options[:chosen_pdu]
265
281
  return unless options[:pdu]
266
282
 
267
- data.root.value[data.chosen] = data.root.chosen_value.class.new(options[:pdu])
283
+ klass = data.root.chosen_value.class
284
+ data.root.value[data.chosen] = klass.new(options[:pdu])
268
285
  end
269
286
 
270
287
  # accessor to data payload
271
- # @return [GetRequest]
288
+ # @return [ASN1::Types::Choice]
272
289
  def data
273
290
  @elements[:data]
274
291
  end
@@ -154,26 +154,19 @@ module PacketGen
154
154
  self
155
155
  end
156
156
 
157
- # rubocop:disable Metrics/CyclomaticComplexity
158
-
159
- # Populate object from a string
160
- # @param [String] str
157
+ # Populate object from a string or from an array of hashes
158
+ # @param [String, Array<Hash>] data
161
159
  # @return [self]
162
- def read(str)
160
+ def read(data)
163
161
  clear
164
- return self if str.nil?
165
- return self if @counter&.to_i&.zero?
166
-
167
- str = read_with_length_from(str)
168
- until str.empty?
169
- obj = create_object_from_str(str)
170
- @array << obj
171
- str.slice!(0, obj.sz)
172
- break if @counter && self.size == @counter.to_i
162
+ case data
163
+ when ::Array
164
+ read_from_array(data)
165
+ else
166
+ read_from_string(data)
173
167
  end
174
168
  self
175
169
  end
176
- # rubocop:enable Metrics/CyclomaticComplexity
177
170
 
178
171
  # Get size in bytes
179
172
  # @return [Integer]
@@ -201,6 +194,28 @@ module PacketGen
201
194
 
202
195
  private
203
196
 
197
+ # rubocop:disable Metrics/CyclomaticComplexity
198
+
199
+ def read_from_string(str)
200
+ return self if str.nil? || @counter&.to_i&.zero?
201
+
202
+ str = read_with_length_from(str)
203
+ until str.empty? || (@counter && self.size == @counter.to_i)
204
+ obj = create_object_from_str(str)
205
+ @array << obj
206
+ str.slice!(0, obj.sz)
207
+ end
208
+ end
209
+ # rubocop:enable Metrics/CyclomaticComplexity
210
+
211
+ def read_from_array(ary)
212
+ return self if ary.empty?
213
+
214
+ ary.each do |hsh|
215
+ self << hsh
216
+ end
217
+ end
218
+
204
219
  def record_from_hash(hsh)
205
220
  obj_klass = self.class.set_of_klass
206
221
  raise NotImplementedError, 'class should define #record_from_hash or declare type of elements in set with .set_of' unless obj_klass
@@ -61,7 +61,8 @@ module PacketGen
61
61
 
62
62
  # @return [String]
63
63
  def inspect
64
- # TODO
64
+ str = Inspect.dashed_line(self.class)
65
+ str << Inspect.inspect_body(body)
65
66
  end
66
67
 
67
68
  # equality if {#to_s} is equal
@@ -74,7 +75,7 @@ module PacketGen
74
75
  # @return [Boolean]
75
76
  def ===(other)
76
77
  case other
77
- when UnknwonPacket
78
+ when UnknownPacket
78
79
  self == other
79
80
  else
80
81
  false
@@ -25,23 +25,32 @@ module PacketGen
25
25
  ' (ip dst %<target2>s and not ip src %<local_ip>s))' \
26
26
  ' and ether dst %<local_mac>s'
27
27
 
28
+ # @private
29
+ ARP_PATH = '/usr/sbin/arp'
30
+ # @private
31
+ IP_PATH = '/usr/bin/ip'
32
+ # @private
33
+ ARP_LINE_RE = /\((\d+\.\d+\.\d+\.\d+)\) at (([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})(?: \[ether\])? on (\w+)/.freeze
34
+ # @private
35
+ IP_LINE_RE = /^(\d+\.\d+\.\d+\.\d+) dev (\w+) lladdr (([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})/.freeze
36
+
28
37
  # Get local ARP cache
29
38
  # @return [Hash] key: IP address, value: array containing MAC address and
30
39
  # interface name
31
40
  def self.arp_cache
32
- return self.cache_from_arp_command if File.exist?('/usr/sbin/arp')
33
- return self.cache_from_ip_command if File.exist?('/usr/bin/ip')
41
+ return self.cache_from_arp_command if File.exist?(ARP_PATH)
42
+ return self.cache_from_ip_command if File.exist?(IP_PATH)
34
43
 
35
44
  {}
36
45
  end
37
46
 
38
47
  # @private
39
- def self.cache_from_arp_command
40
- raw_cache = `/usr/sbin/arp -an`
48
+ def self.cache_from_arp_command(raw_cache=nil)
49
+ raw_cache ||= `#{ARP_PATH} -an`
41
50
 
42
51
  cache = {}
43
52
  raw_cache.split("\n").each do |line|
44
- match = line.match(/\((\d+\.\d+\.\d+\.\d+)\) at (([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})(?: \[ether\])? on (\w+)/)
53
+ match = line.match(ARP_LINE_RE)
45
54
  cache[match[1]] = [match[2], match[4]] if match
46
55
  end
47
56
 
@@ -49,12 +58,12 @@ module PacketGen
49
58
  end
50
59
 
51
60
  # @private
52
- def self.cache_from_ip_command
53
- raw_cache = `ip neigh`
61
+ def self.cache_from_ip_command(raw_cache=nil)
62
+ raw_cache ||= `#{IP_PATH} neigh`
54
63
 
55
64
  cache = {}
56
65
  raw_cache.split("\n").each do |line|
57
- match = line.match(/^(\d+\.\d+\.\d+\.\d+) dev (\w+) lladdr (([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})/)
66
+ match = line.match(IP_LINE_RE)
58
67
  cache[match[1]] = [match[3], match[2]] if match
59
68
  end
60
69
 
@@ -155,7 +164,7 @@ module PacketGen
155
164
  # end
156
165
  # @since 2.2.0
157
166
  # @raise [RuntimeError] user don't have permission to capture packets on network device.
158
- def self.mitm(target1, target2, options={})
167
+ def self.mitm(target1, target2, options={}, &block)
159
168
  options = { iface: PacketGen.default_iface }.merge(options)
160
169
 
161
170
  spoofer = Utils::ARPSpoofer.new(options)
@@ -168,7 +177,7 @@ module PacketGen
168
177
  filter: MITM_FILTER % { target1: target1, target2: target2, local_ip: cfg.ipaddr(options[:iface]), local_mac: my_mac })
169
178
 
170
179
  spoofer.start_all
171
- mitm_core(capture, target1, target2, my_mac, &proc)
180
+ mitm_core(capture, target1, target2, my_mac, &block)
172
181
  spoofer.stop_all
173
182
  end
174
183
 
@@ -10,5 +10,5 @@
10
10
  # @author Sylvain Daubert
11
11
  module PacketGen
12
12
  # PacketGen version
13
- VERSION = '3.2.1'
13
+ VERSION = '3.2.2'
14
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packetgen
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 3.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-27 00:00:00.000000000 Z
11
+ date: 2022-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interfacez