packetgen 3.1.4 → 3.2.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -1
  3. data/bin/pgconsole +1 -0
  4. data/lib/packetgen.rb +19 -3
  5. data/lib/packetgen/capture.rb +30 -9
  6. data/lib/packetgen/config.rb +15 -9
  7. data/lib/packetgen/deprecation.rb +1 -1
  8. data/lib/packetgen/header/asn1_base.rb +19 -9
  9. data/lib/packetgen/header/base.rb +68 -70
  10. data/lib/packetgen/header/dhcpv6/duid.rb +3 -1
  11. data/lib/packetgen/header/dhcpv6/option.rb +4 -12
  12. data/lib/packetgen/header/dns/name.rb +18 -7
  13. data/lib/packetgen/header/dns/qdsection.rb +1 -1
  14. data/lib/packetgen/header/dns/question.rb +2 -0
  15. data/lib/packetgen/header/dot11.rb +25 -38
  16. data/lib/packetgen/header/dot11/data.rb +28 -34
  17. data/lib/packetgen/header/dot1x.rb +1 -14
  18. data/lib/packetgen/header/eap.rb +14 -17
  19. data/lib/packetgen/header/eth.rb +5 -6
  20. data/lib/packetgen/header/http/headers.rb +4 -2
  21. data/lib/packetgen/header/http/request.rb +37 -18
  22. data/lib/packetgen/header/http/response.rb +11 -5
  23. data/lib/packetgen/header/http/verbs.rb +1 -1
  24. data/lib/packetgen/header/igmpv3/group_record.rb +2 -0
  25. data/lib/packetgen/header/ip.rb +27 -26
  26. data/lib/packetgen/header/ip/addr.rb +3 -1
  27. data/lib/packetgen/header/ip/option.rb +4 -4
  28. data/lib/packetgen/header/ipv6/addr.rb +2 -0
  29. data/lib/packetgen/header/mldv2/mcast_address_record.rb +2 -0
  30. data/lib/packetgen/header/ospfv2/ls_request.rb +2 -0
  31. data/lib/packetgen/header/ospfv2/lsa.rb +13 -3
  32. data/lib/packetgen/header/ospfv2/lsa_header.rb +2 -1
  33. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +2 -0
  34. data/lib/packetgen/header/ospfv3/ls_request.rb +2 -0
  35. data/lib/packetgen/header/ospfv3/lsa.rb +9 -3
  36. data/lib/packetgen/header/ospfv3/lsa_header.rb +2 -1
  37. data/lib/packetgen/header/snmp.rb +3 -2
  38. data/lib/packetgen/header/tcp.rb +1 -20
  39. data/lib/packetgen/header/tcp/option.rb +8 -6
  40. data/lib/packetgen/inspect.rb +1 -17
  41. data/lib/packetgen/packet.rb +10 -6
  42. data/lib/packetgen/pcapng.rb +11 -11
  43. data/lib/packetgen/pcapng/block.rb +15 -2
  44. data/lib/packetgen/pcapng/epb.rb +22 -15
  45. data/lib/packetgen/pcapng/file.rb +166 -81
  46. data/lib/packetgen/pcapng/idb.rb +7 -9
  47. data/lib/packetgen/pcapng/shb.rb +35 -28
  48. data/lib/packetgen/pcapng/spb.rb +16 -12
  49. data/lib/packetgen/pcapng/unknown_block.rb +3 -11
  50. data/lib/packetgen/pcaprub_wrapper.rb +25 -11
  51. data/lib/packetgen/types.rb +1 -0
  52. data/lib/packetgen/types/abstract_tlv.rb +3 -1
  53. data/lib/packetgen/types/array.rb +17 -10
  54. data/lib/packetgen/types/cstring.rb +56 -19
  55. data/lib/packetgen/types/enum.rb +4 -0
  56. data/lib/packetgen/types/fieldable.rb +65 -0
  57. data/lib/packetgen/types/fields.rb +180 -113
  58. data/lib/packetgen/types/int.rb +15 -1
  59. data/lib/packetgen/types/int_string.rb +8 -0
  60. data/lib/packetgen/types/length_from.rb +18 -10
  61. data/lib/packetgen/types/oui.rb +2 -0
  62. data/lib/packetgen/types/string.rb +58 -7
  63. data/lib/packetgen/types/tlv.rb +2 -0
  64. data/lib/packetgen/unknown_packet.rb +84 -0
  65. data/lib/packetgen/utils.rb +6 -7
  66. data/lib/packetgen/version.rb +1 -1
  67. metadata +18 -15
@@ -12,6 +12,8 @@ module PacketGen
12
12
  # @abstract
13
13
  # @author Sylvain Daubert
14
14
  class Int
15
+ include Fieldable
16
+
15
17
  # Integer value
16
18
  # @return [Integer]
17
19
  attr_accessor :value
@@ -45,7 +47,7 @@ module PacketGen
45
47
  @value = if value.is_a?(Integer)
46
48
  value.to_i
47
49
  elsif defined? @packstr
48
- value.to_s.unpack(@packstr[@endian]).first
50
+ value.to_s.unpack1(@packstr[@endian])
49
51
  else
50
52
  raise ParseError, 'Int#read is abstract and cannot read'
51
53
  end
@@ -80,6 +82,18 @@ module PacketGen
80
82
  def sz
81
83
  width
82
84
  end
85
+
86
+ # Format Int type when inspecting header or packet
87
+ # @return [String]
88
+ def format_inspect
89
+ format_str % [to_i.to_s, to_i]
90
+ end
91
+
92
+ private
93
+
94
+ def format_str
95
+ "%-16s (0x%0#{width * 2}x)"
96
+ end
83
97
  end
84
98
 
85
99
  # One byte unsigned integer
@@ -12,6 +12,8 @@ module PacketGen
12
12
  # By default, a null string will have one byte length (length byte set to 0).
13
13
  # @author Sylvain Daubert
14
14
  class IntString
15
+ include Fieldable
16
+
15
17
  # internal string
16
18
  # @return [String]
17
19
  attr_reader :string
@@ -88,6 +90,12 @@ module PacketGen
88
90
  def sz
89
91
  to_s.size
90
92
  end
93
+
94
+ # Say if IntString is empty
95
+ # @return [Boolean]
96
+ def empty?
97
+ length.zero?
98
+ end
91
99
  end
92
100
  end
93
101
  end
@@ -14,6 +14,9 @@ module PacketGen
14
14
  # @author Sylvain Daubert
15
15
  # @since 3.0.0
16
16
  module LengthFrom
17
+ # Max value returned by {#sz_to_read}.
18
+ MAX_SZ_TO_READ = 65_535
19
+
17
20
  # Initialize +length from+ capacity.
18
21
  # Should be call by extensed object's initialize.
19
22
  # @param [Hash] options
@@ -29,16 +32,21 @@ module PacketGen
29
32
  # @return [String]
30
33
  def read_with_length_from(str)
31
34
  s = PacketGen.force_binary(str.to_s)
32
- str_end = case @length_from
33
- when Types::Int
34
- @length_from.to_i
35
- when Proc
36
- @length_from.call
37
- else
38
- s.size
39
- end
40
- str_end = 0 if str_end.negative?
41
- s[0, str_end]
35
+ s[0, sz_to_read]
36
+ end
37
+
38
+ # Size to read, from length_from
39
+ # @return [Integer]
40
+ def sz_to_read
41
+ len = case @length_from
42
+ when Types::Int
43
+ @length_from.to_i
44
+ when Proc
45
+ @length_from.call
46
+ else
47
+ MAX_SZ_TO_READ
48
+ end
49
+ [0, len].max
42
50
  end
43
51
  end
44
52
  end
@@ -14,6 +14,8 @@ module PacketGen
14
14
  # oui.to_human # => "00:01:02"
15
15
  # @author Sylvain Daubert
16
16
  class OUI < Types::Fields
17
+ include Fieldable
18
+
17
19
  # @attribute b2
18
20
  # @return [Integer] left-most byte
19
21
  define_field :b2, Types::Int8
@@ -6,15 +6,24 @@
6
6
  # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
7
7
  # This program is published under MIT license.
8
8
 
9
+ require 'forwardable'
10
+
9
11
  module PacketGen
10
12
  module Types
11
- # This class is just like regular String. It only adds {#read}, {#sz},
12
- # #{to_human} and {#from_human} methods
13
- # to be compatible with others {Types}.
13
+ # This class mimics regular String, but it is {Fieldable}.
14
14
  # @author Sylvain Daubert
15
- class String < ::String
15
+ # @since 3.1.6 no more a subclass or regular String
16
+ class String
17
+ extend Forwardable
18
+ include Fieldable
16
19
  include LengthFrom
17
20
 
21
+ def_delegators :@string, :[], :to_s, :length, :size, :inspect, :==,
22
+ :unpack, :force_encoding, :encoding, :index, :empty?,
23
+ :encode, :slice, :slice!, :[]=
24
+
25
+ # @return [::String]
26
+ attr_reader :string
18
27
  # @return [Integer]
19
28
  attr_reader :static_length
20
29
 
@@ -23,23 +32,65 @@ module PacketGen
23
32
  # takes length when reading
24
33
  # @option options [Integer] :static_length set a static length for this string
25
34
  def initialize(options={})
26
- super()
35
+ register_internal_string(+'')
27
36
  initialize_length_from(options)
28
37
  @static_length = options[:static_length]
29
38
  end
30
39
 
40
+ def initialize_copy(_orig)
41
+ @string = @string.dup
42
+ end
43
+
31
44
  # @param [::String] str
32
45
  # @return [String] self
33
46
  def read(str)
34
47
  s = read_with_length_from(str)
35
- s = s[0, static_length] if static_length
36
- self.replace(s)
48
+ register_internal_string s
49
+ self
50
+ end
51
+
52
+ alias old_sz_to_read sz_to_read
53
+ private :old_sz_to_read
54
+
55
+ # Size to read.
56
+ # Computed from static_length or length_from, if defined.
57
+ # @return [Integer]
58
+ # @since 3.1.6
59
+ def sz_to_read
60
+ return static_length if static_length?
61
+
62
+ old_sz_to_read
63
+ end
64
+
65
+ # Say if a static length is defined
66
+ # @return [Boolean]
67
+ # @since 3.1.6
68
+ def static_length?
69
+ !static_length.nil?
70
+ end
71
+
72
+ def format_inspect
73
+ inspect
74
+ end
75
+
76
+ # Append the given string to String
77
+ # @param [#to_s] str
78
+ # @return [self]
79
+ def <<(str)
80
+ @string << str.to_s
37
81
  self
38
82
  end
39
83
 
40
84
  alias sz length
41
85
  alias to_human to_s
42
86
  alias from_human read
87
+
88
+ private
89
+
90
+ def register_internal_string(str)
91
+ @string = str
92
+ PacketGen.force_binary(@string)
93
+ end
43
94
  end
44
95
  end
45
96
  end
@@ -31,6 +31,8 @@ module PacketGen
31
31
  # @deprecated Use {AbstractTLV} instead.
32
32
  # @since 3.1.0 deprecated
33
33
  class TLV < Fields
34
+ include Fieldable
35
+
34
36
  # @!attribute type
35
37
  # @return [Integer]
36
38
  define_field :type, Int8
@@ -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
@@ -23,7 +23,7 @@ module PacketGen
23
23
  raw_cache = `/usr/sbin/arp -an`
24
24
 
25
25
  cache = {}
26
- raw_cache.split(/\n/).each do |line|
26
+ raw_cache.split("\n").each do |line|
27
27
  match = line.match(/\((\d+\.\d+\.\d+\.\d+)\) at (([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})(?: \[ether\])? on (\w+)/)
28
28
  cache[match[1]] = [match[2], match[4]] if match
29
29
  end
@@ -46,21 +46,20 @@ module PacketGen
46
46
  def self.arp(ipaddr, options={})
47
47
  unless options[:no_cache]
48
48
  local_cache = self.arp_cache
49
- return local_cache[ipaddr].first if local_cache.key? ipaddr
49
+ return local_cache[ipaddr].first if local_cache.key?(ipaddr)
50
50
  end
51
51
 
52
52
  iface = options[:iface] || PacketGen.default_iface
53
53
  timeout = options[:timeout] || 1
54
54
  my_hwaddr = Config.instance.hwaddr(iface)
55
55
  arp_pkt = Packet.gen('Eth', dst: 'ff:ff:ff:ff:ff:ff', src: my_hwaddr)
56
- arp_pkt.add('ARP', sha: Config.instance.hwaddr, spa: Config.instance.ipaddr,
57
- tpa: ipaddr)
56
+ .add('ARP', sha: Config.instance.hwaddr(iface),
57
+ spa: Config.instance.ipaddr(iface),
58
+ tpa: ipaddr)
58
59
 
59
60
  capture = Capture.new(iface: iface, timeout: timeout, max: 1,
60
61
  filter: "arp src #{ipaddr} and ether dst #{my_hwaddr}")
61
- cap_thread = Thread.new do
62
- capture.start
63
- end
62
+ cap_thread = Thread.new { capture.start }
64
63
 
65
64
  arp_pkt.to_w(iface)
66
65
  cap_thread.join
@@ -10,5 +10,5 @@
10
10
  # @author Sylvain Daubert
11
11
  module PacketGen
12
12
  # PacketGen version
13
- VERSION = '3.1.4'
13
+ VERSION = '3.2.0'
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.1.4
4
+ version: 3.2.0
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-03-22 00:00:00.000000000 Z
11
+ date: 2021-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interfacez
@@ -30,48 +30,48 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.12.4
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.12.4
40
+ version: 0.12.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rasn1
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.7'
47
+ version: '0.8'
48
48
  - - ">="
49
49
  - !ruby/object:Gem::Version
50
- version: 0.7.1
50
+ version: 0.8.0
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - "~>"
56
56
  - !ruby/object:Gem::Version
57
- version: '0.7'
57
+ version: '0.8'
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 0.7.1
60
+ version: 0.8.0
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: rake
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '12.3'
67
+ version: '13.0'
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '12.3'
74
+ version: '13.0'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: rspec
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -225,6 +225,7 @@ files:
225
225
  - lib/packetgen/types/array.rb
226
226
  - lib/packetgen/types/cstring.rb
227
227
  - lib/packetgen/types/enum.rb
228
+ - lib/packetgen/types/fieldable.rb
228
229
  - lib/packetgen/types/fields.rb
229
230
  - lib/packetgen/types/int.rb
230
231
  - lib/packetgen/types/int_string.rb
@@ -232,16 +233,19 @@ files:
232
233
  - lib/packetgen/types/oui.rb
233
234
  - lib/packetgen/types/string.rb
234
235
  - lib/packetgen/types/tlv.rb
236
+ - lib/packetgen/unknown_packet.rb
235
237
  - lib/packetgen/utils.rb
236
238
  - lib/packetgen/utils/arp_spoofer.rb
237
239
  - lib/packetgen/version.rb
238
- homepage: https://github.com/sdaubert/packetgen
240
+ homepage:
239
241
  licenses:
240
242
  - MIT
241
243
  metadata:
244
+ homepage_uri: https://github.com/sdaubert/packetgen
245
+ source_code_uri: https://github.com/sdaubert/packetgen
242
246
  bug_tracker_uri: https://github.com/sdaubert/packetgen/issues
243
247
  documentation_uri: https://www.rubydoc.info/gems/packetgen
244
- source_code_uri: https://github.com/sdaubert/packetgen
248
+ wiki_uri: https://github.com/sdaubert/packetgen/wiki
245
249
  post_install_message:
246
250
  rdoc_options:
247
251
  - "--title"
@@ -256,15 +260,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
256
260
  requirements:
257
261
  - - ">="
258
262
  - !ruby/object:Gem::Version
259
- version: 2.3.0
263
+ version: 2.4.0
260
264
  required_rubygems_version: !ruby/object:Gem::Requirement
261
265
  requirements:
262
266
  - - ">="
263
267
  - !ruby/object:Gem::Version
264
268
  version: '0'
265
269
  requirements: []
266
- rubyforge_project:
267
- rubygems_version: 2.7.6.2
270
+ rubygems_version: 3.2.5
268
271
  signing_key:
269
272
  specification_version: 4
270
273
  summary: Network packet generator and dissector