packetgen 3.1.6 → 3.2.1

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/bin/pgconsole +3 -3
  4. data/lib/packetgen/capture.rb +5 -1
  5. data/lib/packetgen/header/arp.rb +24 -13
  6. data/lib/packetgen/header/asn1_base.rb +19 -9
  7. data/lib/packetgen/header/base.rb +1 -1
  8. data/lib/packetgen/header/dhcpv6/option.rb +11 -13
  9. data/lib/packetgen/header/dns/opt.rb +2 -2
  10. data/lib/packetgen/header/dns/rr.rb +61 -28
  11. data/lib/packetgen/header/dns.rb +13 -6
  12. data/lib/packetgen/header/dot11/data.rb +19 -29
  13. data/lib/packetgen/header/dot11/management.rb +2 -5
  14. data/lib/packetgen/header/dot11.rb +1 -1
  15. data/lib/packetgen/header/eap.rb +1 -1
  16. data/lib/packetgen/header/eth.rb +1 -1
  17. data/lib/packetgen/header/http/request.rb +5 -1
  18. data/lib/packetgen/header/http/response.rb +46 -20
  19. data/lib/packetgen/header/http/verbs.rb +1 -1
  20. data/lib/packetgen/header/igmp.rb +1 -1
  21. data/lib/packetgen/header/ip/option.rb +2 -1
  22. data/lib/packetgen/header/ipv6/addr.rb +3 -0
  23. data/lib/packetgen/header/mdns.rb +19 -25
  24. data/lib/packetgen/header/mld.rb +1 -1
  25. data/lib/packetgen/header/ospfv2/lsa.rb +7 -3
  26. data/lib/packetgen/header/ospfv2/lsa_header.rb +2 -4
  27. data/lib/packetgen/header/ospfv2.rb +1 -1
  28. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +14 -5
  29. data/lib/packetgen/header/ospfv3/lsa.rb +8 -4
  30. data/lib/packetgen/header/ospfv3/lsa_header.rb +2 -4
  31. data/lib/packetgen/header/ospfv3.rb +1 -1
  32. data/lib/packetgen/header/snmp.rb +20 -14
  33. data/lib/packetgen/header/tcp/option.rb +1 -1
  34. data/lib/packetgen/header/tcp.rb +12 -5
  35. data/lib/packetgen/header/tftp.rb +15 -9
  36. data/lib/packetgen/inspect.rb +15 -9
  37. data/lib/packetgen/packet.rb +51 -5
  38. data/lib/packetgen/pcapng/file.rb +17 -15
  39. data/lib/packetgen/pcapng.rb +1 -0
  40. data/lib/packetgen/pcaprub_wrapper.rb +0 -4
  41. data/lib/packetgen/types/abstract_tlv.rb +1 -1
  42. data/lib/packetgen/types/array.rb +8 -1
  43. data/lib/packetgen/types/cstring.rb +20 -7
  44. data/lib/packetgen/types/fields.rb +19 -19
  45. data/lib/packetgen/types/int.rb +7 -0
  46. data/lib/packetgen/types/oui.rb +1 -1
  47. data/lib/packetgen/types/string.rb +16 -3
  48. data/lib/packetgen/types/tlv.rb +17 -9
  49. data/lib/packetgen/unknown_packet.rb +84 -0
  50. data/lib/packetgen/utils.rb +60 -27
  51. data/lib/packetgen/version.rb +1 -1
  52. data/lib/packetgen.rb +13 -4
  53. metadata +7 -7
@@ -62,7 +62,7 @@ module PacketGen
62
62
  HUMAN_SEPARATOR = ','
63
63
 
64
64
  # rubocop:disable Naming/AccessorMethodName
65
- class <<self
65
+ class << self
66
66
  # Get class set with {.set_of}.
67
67
  # @return [Class]
68
68
  # @since 3.0.0
@@ -154,6 +154,8 @@ module PacketGen
154
154
  self
155
155
  end
156
156
 
157
+ # rubocop:disable Metrics/CyclomaticComplexity
158
+
157
159
  # Populate object from a string
158
160
  # @param [String] str
159
161
  # @return [self]
@@ -171,6 +173,7 @@ module PacketGen
171
173
  end
172
174
  self
173
175
  end
176
+ # rubocop:enable Metrics/CyclomaticComplexity
174
177
 
175
178
  # Get size in bytes
176
179
  # @return [Integer]
@@ -228,18 +231,22 @@ module PacketGen
228
231
  class ArrayOfInt8 < Array
229
232
  set_of Int8
230
233
  end
234
+
231
235
  # Specialized array to handle serie of {Int16}.
232
236
  class ArrayOfInt16 < Array
233
237
  set_of Int16
234
238
  end
239
+
235
240
  # Specialized array to handle serie of {Int16le}.
236
241
  class ArrayOfInt16le < Array
237
242
  set_of Int16le
238
243
  end
244
+
239
245
  # Specialized array to handle serie of {Int32}.
240
246
  class ArrayOfInt32 < Types::Array
241
247
  set_of Types::Int32
242
248
  end
249
+
243
250
  # Specialized array to handle serie of {Int32le}.
244
251
  class ArrayOfInt32le < Types::Array
245
252
  set_of Types::Int32le
@@ -17,8 +17,9 @@ module PacketGen
17
17
  extend Forwardable
18
18
  include Fieldable
19
19
 
20
- def_delegators :@string, :[], :length, :size, :inspect, :==, :<<,
21
- :unpack, :force_encoding, :encoding, :index, :empty?
20
+ def_delegators :@string, :[], :length, :size, :inspect, :==,
21
+ :unpack, :force_encoding, :encoding, :index, :empty?,
22
+ :encode, :slice, :slice!
22
23
 
23
24
  # @return [::String]
24
25
  attr_reader :string
@@ -28,7 +29,7 @@ module PacketGen
28
29
  # @param [Hash] options
29
30
  # @option options [Integer] :static_length set a static length for this string
30
31
  def initialize(options={})
31
- register_internal_string ''
32
+ register_internal_string(+'')
32
33
  @static_length = options[:static_length]
33
34
  end
34
35
 
@@ -37,9 +38,8 @@ module PacketGen
37
38
  def read(str)
38
39
  s = str.to_s
39
40
  s = s[0, static_length] if static_length?
40
- idx = s.index(0.chr)
41
- s = s[0, idx] unless idx.nil?
42
41
  register_internal_string s
42
+ remove_null_character
43
43
  self
44
44
  end
45
45
 
@@ -55,6 +55,15 @@ module PacketGen
55
55
  PacketGen.force_binary(s)
56
56
  end
57
57
 
58
+ # Append the given string to CString
59
+ # @param [#to_s] str
60
+ # @return [self]
61
+ def <<(str)
62
+ @string << str.to_s
63
+ remove_null_character
64
+ self
65
+ end
66
+
58
67
  # @return [Integer]
59
68
  def sz
60
69
  if static_length?
@@ -80,8 +89,7 @@ module PacketGen
80
89
 
81
90
  # @return [String]
82
91
  def to_human
83
- idx = self.index(+"\x00".encode(self.encoding)) || self.sz
84
- self[0, idx]
92
+ string
85
93
  end
86
94
 
87
95
  private
@@ -90,6 +98,11 @@ module PacketGen
90
98
  @string = str
91
99
  PacketGen.force_binary(@string)
92
100
  end
101
+
102
+ def remove_null_character
103
+ idx = string.index(0.chr)
104
+ register_internal_string(string[0, idx]) unless idx.nil?
105
+ end
93
106
  end
94
107
  end
95
108
  end
@@ -115,7 +115,7 @@ module PacketGen
115
115
  # @private bit field definitions
116
116
  @bit_fields = {}
117
117
 
118
- class <<self
118
+ class << self
119
119
  # Get field definitions for this class.
120
120
  # @return [Hash]
121
121
  # @since 3.1.0
@@ -282,7 +282,7 @@ module PacketGen
282
282
  type = field_defs[attr].type
283
283
  raise TypeError, "#{attr} is not a PacketGen::Types::Int" unless type < Types::Int
284
284
 
285
- total_size = type.new.width * 8
285
+ total_size = type.new.nbits
286
286
  idx = total_size - 1
287
287
 
288
288
  until args.empty?
@@ -358,15 +358,15 @@ module PacketGen
358
358
  clear_mask = compute_clear_mask(total_size, field_mask)
359
359
 
360
360
  class_eval <<-METHODS
361
- def #{name}?
362
- val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
363
- val != 0
364
- end
365
- def #{name}=(v)
366
- val = v ? 1 : 0
367
- self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
368
- self[:#{attr}].value |= val << #{shift}
369
- end
361
+ def #{name}? # def bit?
362
+ val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift} # val = (self[:attr}].to_i & 1}) >> 1
363
+ val != 0 # val != 0
364
+ end # end
365
+ def #{name}=(v) # def bit=(v)
366
+ val = v ? 1 : 0 # val = v ? 1 : 0
367
+ self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask} # self[:attr].value = self[:attr].to_i & 0xfffd
368
+ self[:#{attr}].value |= val << #{shift} # self[:attr].value |= val << 1
369
+ end # end
370
370
  METHODS
371
371
  end
372
372
 
@@ -375,13 +375,13 @@ module PacketGen
375
375
  clear_mask = compute_clear_mask(total_size, field_mask)
376
376
 
377
377
  class_eval <<-METHODS
378
- def #{name}
379
- (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
380
- end
381
- def #{name}=(v)
382
- self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
383
- self[:#{attr}].value |= (v & #{2**size - 1}) << #{shift}
384
- end
378
+ def #{name} # def multibit
379
+ (self[:#{attr}].to_i & #{field_mask}) >> #{shift} # (self[:attr].to_i & 6) >> 1
380
+ end # end
381
+ def #{name}=(v) # def multibit=(v)
382
+ self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask} # self[:attr].value = self[:attr].to_i & 0xfff9
383
+ self[:#{attr}].value |= (v & #{2**size - 1}) << #{shift} # self[:attr].value |= (v & 3) << 1
384
+ end # end
385
385
  METHODS
386
386
  end
387
387
 
@@ -523,7 +523,7 @@ module PacketGen
523
523
  # Return object as a hash
524
524
  # @return [Hash] keys: attributes, values: attribute values
525
525
  def to_h
526
- Hash[fields.map { |f| [f, @fields[f].to_human] }]
526
+ fields.map { |f| [f, @fields[f].to_human] }.to_h
527
527
  end
528
528
 
529
529
  # Get offset of given field in {Fields} structure.
@@ -89,6 +89,13 @@ module PacketGen
89
89
  format_str % [to_i.to_s, to_i]
90
90
  end
91
91
 
92
+ # Return the number of bits used to encode this Int
93
+ # @return [Integer]
94
+ # @since 3.2.1
95
+ def nbits
96
+ width * 8
97
+ end
98
+
92
99
  private
93
100
 
94
101
  def format_str
@@ -32,7 +32,7 @@ module PacketGen
32
32
  def from_human(str)
33
33
  return self if str.nil?
34
34
 
35
- bytes = str.split(/:/)
35
+ bytes = str.split(':')
36
36
  raise ArgumentError, 'not a OUI' unless bytes.size == 3
37
37
 
38
38
  self[:b2].read(bytes[0].to_i(16))
@@ -18,8 +18,9 @@ module PacketGen
18
18
  include Fieldable
19
19
  include LengthFrom
20
20
 
21
- def_delegators :@string, :[], :to_s, :length, :size, :inspect, :==, :<<,
22
- :unpack, :force_encoding, :encoding, :index, :empty?
21
+ def_delegators :@string, :[], :to_s, :length, :size, :inspect, :==,
22
+ :unpack, :force_encoding, :encoding, :index, :empty?,
23
+ :encode, :slice, :slice!, :[]=
23
24
 
24
25
  # @return [::String]
25
26
  attr_reader :string
@@ -31,11 +32,15 @@ module PacketGen
31
32
  # takes length when reading
32
33
  # @option options [Integer] :static_length set a static length for this string
33
34
  def initialize(options={})
34
- register_internal_string ''
35
+ register_internal_string(+'')
35
36
  initialize_length_from(options)
36
37
  @static_length = options[:static_length]
37
38
  end
38
39
 
40
+ def initialize_copy(_orig)
41
+ @string = @string.dup
42
+ end
43
+
39
44
  # @param [::String] str
40
45
  # @return [String] self
41
46
  def read(str)
@@ -68,6 +73,14 @@ module PacketGen
68
73
  inspect
69
74
  end
70
75
 
76
+ # Append the given string to String
77
+ # @param [#to_s] str
78
+ # @return [self]
79
+ def <<(str)
80
+ @string << str.to_s
81
+ self
82
+ end
83
+
71
84
  alias sz length
72
85
  alias to_human to_s
73
86
  alias from_human read
@@ -56,12 +56,8 @@ module PacketGen
56
56
  def initialize(options={})
57
57
  Deprecation.deprecated_class(self.class, AbstractTLV)
58
58
  super
59
- self[:type] = options[:t].new(self.type) if options[:t]
60
- self[:length] = options[:l].new(self.length) if options[:l]
61
- self[:value] = options[:v].new if options[:v]
62
- self.type = options[:type] if options[:type]
63
- self.value = options[:value] if options[:value]
64
- self.length = options[:length] if options[:length]
59
+ initialize_types(options)
60
+ initialize_values(options)
65
61
  end
66
62
 
67
63
  # Populate object from a binary string
@@ -137,9 +133,9 @@ module PacketGen
137
133
  else
138
134
  '%s'
139
135
  end
140
- @lenstr ||= "%-#{(2**(self[:length].width * 8) - 1).to_s.size}u"
141
- "#{name} type:#{@typestr} length:#{@lenstr} value:#{value.inspect}" % [human_type,
142
- length]
136
+ lenstr = "%-#{(2**self[:length].nbits - 1).to_s.size}u"
137
+ "#{name} type:#{@typestr} length:#{lenstr} value:#{value.inspect}" % [human_type,
138
+ length]
143
139
  end
144
140
 
145
141
  private
@@ -147,6 +143,18 @@ module PacketGen
147
143
  def human_types?
148
144
  self.class.const_defined? :TYPES
149
145
  end
146
+
147
+ def initialize_types(options)
148
+ self[:type] = options[:t].new(self.type) if options[:t]
149
+ self[:length] = options[:l].new(self.length) if options[:l]
150
+ self[:value] = options[:v].new if options[:v]
151
+ end
152
+
153
+ def initialize_values(options)
154
+ self.type = options[:type] if options[:type]
155
+ self.value = options[:value] if options[:value]
156
+ self.length = options[:length] if options[:length]
157
+ end
150
158
  end
151
159
  end
152
160
  end
@@ -0,0 +1,84 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ # This file is part of PacketGen
5
+ # See https://github.com/sdaubert/packetgen for more informations
6
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
7
+ # This program is published under MIT license.
8
+
9
+ module PacketGen
10
+ # Unknown packet, minimaly mimicking a {Packet}.
11
+ #
12
+ # An unknown packet is generated when capturing packets, and a packet cannot
13
+ # be parsed.
14
+ # @since 3.2.0
15
+ class UnknownPacket
16
+ # List of headers. Always empty
17
+ # @return [Array]
18
+ attr_reader :headers
19
+
20
+ def initialize
21
+ @headers = [].freeze
22
+ @binary_str = PacketGen.force_binary('')
23
+ end
24
+
25
+ # Unknown packet, so unknown protocol.
26
+ # @return [false]
27
+ def is?(_protocol)
28
+ false
29
+ end
30
+
31
+ # Get packet body
32
+ # @return [Types]
33
+ def body
34
+ @binary_str
35
+ end
36
+ alias to_s body
37
+
38
+ # Set packet body
39
+ # @param [String] str
40
+ # @return [void]
41
+ def body=(str)
42
+ @binary_str = PacketGen.force_binary(str)
43
+ end
44
+
45
+ # Write packet to a PCapNG file on disk.
46
+ # @param [String] filename
47
+ # @return [Array] see return from {PcapNG::File#to_file}
48
+ # @see File
49
+ def to_f(filename)
50
+ PcapNG::File.new.read_array([self]).to_f(filename)
51
+ end
52
+ alias write to_f
53
+
54
+ # Read binary string
55
+ # @param [String] binary_string
56
+ # @return [self]
57
+ def parse(binary_str, _first_header: nil)
58
+ @binary_str = PacketGen.force_binary(binary_str)
59
+ self
60
+ end
61
+
62
+ # @return [String]
63
+ def inspect
64
+ # TODO
65
+ end
66
+
67
+ # equality if {#to_s} is equal
68
+ # @return [Boolean]
69
+ def ==(other)
70
+ to_s == other.to_s
71
+ end
72
+
73
+ # True only if +other+ is an {UnknownPacket} and +other == self+
74
+ # @return [Boolean]
75
+ def ===(other)
76
+ case other
77
+ when UnknwonPacket
78
+ self == other
79
+ else
80
+ false
81
+ end
82
+ end
83
+ end
84
+ end
@@ -16,14 +16,31 @@ module PacketGen
16
16
  # @author Sylvain Daubert
17
17
  # @since 2.1.3
18
18
  module Utils
19
+ # @private
20
+ ARP_FILTER = 'arp src %<ipaddr>s and ether dst %<hwaddr>s'
21
+ # @private
22
+ MITM_FILTER = '((ip src %<target1>s and not ip dst %<local_ip>s) or' \
23
+ ' (ip src %<target2>s and not ip dst %<local_ip>s) or' \
24
+ ' (ip dst %<target1>s and not ip src %<local_ip>s) or' \
25
+ ' (ip dst %<target2>s and not ip src %<local_ip>s))' \
26
+ ' and ether dst %<local_mac>s'
27
+
19
28
  # Get local ARP cache
20
29
  # @return [Hash] key: IP address, value: array containing MAC address and
21
30
  # interface name
22
31
  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')
34
+
35
+ {}
36
+ end
37
+
38
+ # @private
39
+ def self.cache_from_arp_command
23
40
  raw_cache = `/usr/sbin/arp -an`
24
41
 
25
42
  cache = {}
26
- raw_cache.split(/\n/).each do |line|
43
+ raw_cache.split("\n").each do |line|
27
44
  match = line.match(/\((\d+\.\d+\.\d+\.\d+)\) at (([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})(?: \[ether\])? on (\w+)/)
28
45
  cache[match[1]] = [match[2], match[4]] if match
29
46
  end
@@ -31,6 +48,21 @@ module PacketGen
31
48
  cache
32
49
  end
33
50
 
51
+ # @private
52
+ def self.cache_from_ip_command
53
+ raw_cache = `ip neigh`
54
+
55
+ cache = {}
56
+ 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})/)
58
+ cache[match[1]] = [match[3], match[2]] if match
59
+ end
60
+
61
+ cache
62
+ end
63
+
64
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
65
+
34
66
  # Get MAC address from an IP address, or nil if this IP address is unknown
35
67
  # on local network.
36
68
  # @param [String] ipaddr dotted-octet IP address
@@ -40,13 +72,13 @@ module PacketGen
40
72
  # @option options [Boolean] :no_cache if +true+, do not query local ARP
41
73
  # cache and always send an ARP request on wire. Default to +false+
42
74
  # @option options [Integer] :timeout timeout in seconds before stopping
43
- # request. Default to 2.
75
+ # request. Default to 1.
44
76
  # @return [String,nil]
45
77
  # @raise [RuntimeError] user don't have permission to capture packets on network device.
46
78
  def self.arp(ipaddr, options={})
47
79
  unless options[:no_cache]
48
80
  local_cache = self.arp_cache
49
- return local_cache[ipaddr].first if local_cache.key? ipaddr
81
+ return local_cache[ipaddr].first if local_cache.key?(ipaddr)
50
82
  end
51
83
 
52
84
  iface = options[:iface] || PacketGen.default_iface
@@ -54,14 +86,13 @@ module PacketGen
54
86
  my_hwaddr = Config.instance.hwaddr(iface)
55
87
  arp_pkt = Packet.gen('Eth', dst: 'ff:ff:ff:ff:ff:ff', src: my_hwaddr)
56
88
  .add('ARP', sha: Config.instance.hwaddr(iface),
57
- spa: Config.instance.ipaddr(iface), tpa: ipaddr)
89
+ spa: Config.instance.ipaddr(iface),
90
+ tpa: ipaddr)
58
91
 
59
- capture = Capture.new(iface: iface, timeout: timeout, max: 1,
60
- filter: "arp src #{ipaddr} and ether dst #{my_hwaddr}")
61
- cap_thread = Thread.new do
62
- capture.start
63
- end
92
+ capture = Capture.new(iface: iface, timeout: timeout, max: 1, filter: ARP_FILTER % { ipaddr: ipaddr, hwaddr: my_hwaddr })
93
+ cap_thread = Thread.new { capture.start }
64
94
 
95
+ sleep 0.1
65
96
  arp_pkt.to_w(iface)
66
97
  cap_thread.join
67
98
 
@@ -71,6 +102,7 @@ module PacketGen
71
102
  break pkt.arp.sha.to_s if pkt.arp.spa.to_s == ipaddr
72
103
  end
73
104
  end
105
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
74
106
 
75
107
  # Do ARP spoofing on given IP address. Call to this method blocks.
76
108
  # @note This method is provided for test purpose.
@@ -126,36 +158,37 @@ module PacketGen
126
158
  def self.mitm(target1, target2, options={})
127
159
  options = { iface: PacketGen.default_iface }.merge(options)
128
160
 
129
- mac1 = arp(target1)
130
- mac2 = arp(target2)
131
-
132
161
  spoofer = Utils::ARPSpoofer.new(options)
133
162
  spoofer.add target1, target2, options
134
163
  spoofer.add target2, target1, options
135
164
 
136
- my_mac = Config.instance.hwaddr(options[:iface])
137
- my_ip = Config.instance.ipaddr(options[:iface])
165
+ cfg = Config.instance
166
+ my_mac = cfg.hwaddr(options[:iface])
138
167
  capture = Capture.new(iface: options[:iface],
139
- filter: "((ip src #{target1} and not ip dst #{my_ip}) or" \
140
- " (ip src #{target2} and not ip dst #{my_ip}) or" \
141
- " (ip dst #{target1} and not ip src #{my_ip}) or" \
142
- " (ip dst #{target2} and not ip src #{my_ip}))" \
143
- " and ether dst #{my_mac}")
168
+ filter: MITM_FILTER % { target1: target1, target2: target2, local_ip: cfg.ipaddr(options[:iface]), local_mac: my_mac })
144
169
 
145
170
  spoofer.start_all
171
+ mitm_core(capture, target1, target2, my_mac, &proc)
172
+ spoofer.stop_all
173
+ end
174
+
175
+ # @private
176
+ def self.mitm_core(capture, target1, target2, my_mac)
177
+ mac1 = arp(target1)
178
+ mac2 = arp(target2)
179
+
146
180
  capture.start do |pkt|
147
181
  modified_pkt = yield pkt
148
182
  iph = modified_pkt.ip
149
183
  l2 = modified_pkt.is?('Dot11') ? modified_pkt.dot11 : modified_pkt.eth
150
184
 
151
- if (iph.src == target1) || (iph.dst == target2)
152
- l2.dst = mac2
153
- elsif (iph.src == target2) || (iph.dst == target1)
154
- l2.dst = mac1
155
- else
156
- next
157
- end
158
- modified_pkt.to_w(options[:iface])
185
+ l2.src = my_mac
186
+ l2.dst = if (iph.src == target1) || (iph.dst == target2)
187
+ mac2
188
+ else # (iph.src == target2) || (iph.dst == target1)
189
+ mac1
190
+ end
191
+ modified_pkt.to_w(capture.iface)
159
192
  end
160
193
  end
161
194
  end
@@ -10,5 +10,5 @@
10
10
  # @author Sylvain Daubert
11
11
  module PacketGen
12
12
  # PacketGen version
13
- VERSION = '3.1.6'
13
+ VERSION = '3.2.1'
14
14
  end
data/lib/packetgen.rb CHANGED
@@ -39,9 +39,9 @@ module PacketGen
39
39
 
40
40
  def message
41
41
  "#{prev_hdr.class} knowns no layer association with #{hdr.protocol_name}. " \
42
- "Try #{prev_hdr.class}.bind_layer(#{hdr.class}, " \
43
- "#{prev_hdr.method_name}_proto_field: " \
44
- "<value_for_#{hdr.method_name}>)"
42
+ "Try #{prev_hdr.class}.bind_layer(#{hdr.class}, " \
43
+ "#{prev_hdr.method_name}_proto_field: " \
44
+ "<value_for_#{hdr.method_name}>)"
45
45
  end
46
46
  end
47
47
 
@@ -95,7 +95,15 @@ module PacketGen
95
95
  # Get default network interface (ie. first non-loopback declared interface)
96
96
  # @return [String]
97
97
  def self.default_iface
98
- Interfacez.default
98
+ return @default_iface if defined? @default_iface
99
+
100
+ @default_iface = Interfacez.raw_interface_addresses.each do |iface|
101
+ next unless iface.broadaddr
102
+ next unless Interfacez.ipv4_address_of(iface.name)
103
+ next unless Interfacez.ipv6_address_of(iface.name)
104
+
105
+ break iface.name
106
+ end
99
107
  end
100
108
 
101
109
  # Get loopback network interface
@@ -126,6 +134,7 @@ require 'packetgen/types'
126
134
  require 'packetgen/pcapng'
127
135
  require 'packetgen/pcap'
128
136
  require 'packetgen/packet'
137
+ require 'packetgen/unknown_packet'
129
138
  require 'packetgen/capture'
130
139
  require 'packetgen/inject'
131
140
  require 'packetgen/proto'
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.1.6
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-04 00:00:00.000000000 Z
11
+ date: 2021-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interfacez
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.13.0
33
+ version: 0.12.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.13.0
40
+ version: 0.12.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rasn1
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -233,6 +233,7 @@ files:
233
233
  - lib/packetgen/types/oui.rb
234
234
  - lib/packetgen/types/string.rb
235
235
  - lib/packetgen/types/tlv.rb
236
+ - lib/packetgen/unknown_packet.rb
236
237
  - lib/packetgen/utils.rb
237
238
  - lib/packetgen/utils/arp_spoofer.rb
238
239
  - lib/packetgen/version.rb
@@ -259,15 +260,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
259
260
  requirements:
260
261
  - - ">="
261
262
  - !ruby/object:Gem::Version
262
- version: 2.3.0
263
+ version: 2.5.0
263
264
  required_rubygems_version: !ruby/object:Gem::Requirement
264
265
  requirements:
265
266
  - - ">="
266
267
  - !ruby/object:Gem::Version
267
268
  version: '0'
268
269
  requirements: []
269
- rubyforge_project:
270
- rubygems_version: 2.7.6.2
270
+ rubygems_version: 3.2.5
271
271
  signing_key:
272
272
  specification_version: 4
273
273
  summary: Network packet generator and dissector