packetgen 3.1.4 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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