packetgen 3.0.2 → 3.1.0

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: be94839db4cb9f9a818fdf5b948f34185198d7f8445545d13763cf57f313eb3a
4
- data.tar.gz: 0cf02398bb76d3bb9083f6bbcb1e873b81c686e822ac3e63790a0b5f5d5155b7
3
+ metadata.gz: 877d57dd457d4cde03fca6e13c0042168c8630b08073533b7b7fb95da49632a0
4
+ data.tar.gz: 5c18abe50abcb423edf22571e88241cddb6095a0c626fb6018bfbafac49278b1
5
5
  SHA512:
6
- metadata.gz: c72f91e241484140503a997aca5aa930cb8d3e357103b0af617231d7c49fa791b49537916fd68bb5c8d77b901c203500babf18cfe5c2df40900bfc2a30feb90b
7
- data.tar.gz: d76180f3c3089218d67a0840d4f94c802c94bd8990cc45b91062414bba175973cc6f97287c1be99ccd87c063d7ebb17f210f15cc49fdd9eb649ec3465b29ea8e
6
+ metadata.gz: '09c0197e3f3d1bf72dffbaf97abc4007902ade04b94a6893d1a79e97944e6560eb16aad024726497a064b9fdc59fed5efd8e456cffcaa3f7bf64b7b0c7a2604c'
7
+ data.tar.gz: 575402b40e5be3c8bf6d68e8dfd01fa3b4a9d3e917fda6cefa17b0759f99193bb69a5e3b5734cfa839e149856d7d98ea88e13bb8fa273c9ac295a94a79e7502b
@@ -4,7 +4,19 @@ module PacketGen
4
4
  # @author Sylvain Daubert
5
5
  # @api private
6
6
  module Deprecation
7
- def self.deprecated(klass, deprecated_method, new_method=nil, klass_method: false, remove_version: '4.0.0')
7
+ # Default remove version for deprecated classes/methods
8
+ # @since 3.1.0
9
+ REMOVE_VERSION = '4.0.0'
10
+
11
+ # Warn when using a deprecated method
12
+ # @param [Module] klass class/module of deprecated method
13
+ # @param [Symbol,String] deprecated_method
14
+ # @param [Symbol,String,nil] new_method method to use instead of deprecated one
15
+ # @param [Boolean] klass_method +deprecated_method+ is a class method (+true+)
16
+ # or a, instance one (+false+)
17
+ # @param [String] remove_version version from which +deprecated_method+ will
18
+ # no more exist.
19
+ def self.deprecated(klass, deprecated_method, new_method=nil, klass_method: false, remove_version: REMOVE_VERSION)
8
20
  separator = klass_method ? '.' : '#'
9
21
  base_name = klass.to_s + separator
10
22
  complete_deprecated_method_name = base_name + deprecated_method.to_s
@@ -12,7 +24,21 @@ module PacketGen
12
24
 
13
25
  file, line = caller(2).first.split(':')[0, 2]
14
26
  message = +"#{file}:#{line}: #{complete_deprecated_method_name} is deprecated"
15
- message << "in favor of #{complete_new_method_name}" unless new_method.nil?
27
+ message << " in favor of #{complete_new_method_name}" unless new_method.nil?
28
+ message << ". It will be remove in PacketGen #{remove_version}."
29
+ warn message
30
+ end
31
+
32
+ # Warn when using a deprecated method
33
+ # @param [Module] klass deprecated class/module
34
+ # @param [Module] new_klass class/module to use instead of +klass+
35
+ # @param [String] remove_version version from which +klass+ will
36
+ # no more exist.
37
+ # @since 3.1.0
38
+ def self.deprecated_class(klass, new_klass=nil, remove_version: REMOVE_VERSION)
39
+ file, line = caller(2..2).first.split(':')[0, 2]
40
+ message = +"#{file}:#{line}: #{klass} is deprecated"
41
+ message << " in favor od #{new_klass}" unless new_klass.nil?
16
42
  message << ". It will be remove in PacketGen #{remove_version}."
17
43
  warn message
18
44
  end
@@ -8,54 +8,70 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class DHCP
11
- # define DHCP Options.
12
- # keys are option type, value are arrays containing option names
13
- # as strings, and a hash passed to {Option#initialize}.
14
- # @since 2.7.0
11
+ # Known DHCP options
12
+ # @since 3.1.0
15
13
  DHCP_OPTIONS = {
16
- 1 => ['subnet_mask', length: 4, v: IP::Addr],
17
- 2 => ['time_zone'],
18
- 3 => ['router', length: 4, v: IP::Addr],
19
- 4 => ['time_server', length: 4, v: IP::Addr],
20
- 5 => ['IEN_name_server', length: 4, v: IP::Addr],
21
- 6 => ['name_server', length: 4, v: IP::Addr],
22
- 7 => ['log_server', length: 4, v: IP::Addr],
23
- 8 => ['cookie_server', length: 4, v: IP::Addr],
24
- 9 => ['lpr_server', length: 4, v: IP::Addr],
25
- 12 => ['hostname'],
26
- 14 => ['dump_path'],
27
- 15 => ['domain'],
28
- 17 => ['root_disk_path'],
29
- 23 => ['default_ttl'],
30
- 24 => ['pmtu_timeout'],
31
- 28 => ['broadcast_address', length: 4, v: IP::Addr],
32
- 40 => ['NIS_domain'],
33
- 41 => ['NIS_server', length: 4, v: IP::Addr],
34
- 42 => ['NTP_server', length: 4, v: IP::Addr],
35
- 43 => ['vendor_specific'],
36
- 44 => ['NetBIOS_server', length: 4, v: IP::Addr],
37
- 45 => ['NetBIOS_dist_server', length: 4, v: IP::Addr],
38
- 50 => ['requested_addr', length: 4, v: IP::Addr],
39
- 51 => ['lease_time', length: 4, v: Types::Int32, value: 43_200],
40
- 53 => ['message-type', length: 1, v: Types::Int8],
41
- 54 => ['server_id', length: 4, v: IP::Addr],
42
- 55 => ['param_req_list'],
43
- 56 => ['error_message'],
44
- 57 => ['max_dhcp_size', length: 2, v: Types::Int16, value: 1_500],
45
- 58 => ['renewal_time', length: 4, v: Types::Int32, value: 21_600],
46
- 59 => ['rebinding_time', length: 4, v: Types::Int32, value: 37_800],
47
- 60 => ['vendor_class_id'],
48
- 61 => ['client_id'],
49
- 64 => ['NISplus_domain'],
50
- 65 => ['NISplus_server', length: 4, v: IP::Addr],
51
- 69 => ['SMTP_server', length: 4, v: IP::Addr],
52
- 70 => ['POP3_server', length: 4, v: IP::Addr],
53
- 71 => ['NNTP_server', length: 4, v: IP::Addr],
54
- 72 => ['WWW_server', length: 4, v: IP::Addr],
55
- 73 => ['finger_server', length: 4, v: IP::Addr],
56
- 74 => ['IRC_server', length: 4, v: IP::Addr]
14
+ 'pad' => 0,
15
+ 'subnet_mask' => 1,
16
+ 'time_zone' => 2,
17
+ 'router' => 3,
18
+ 'time_server' => 4,
19
+ 'IEN_name_server' => 5,
20
+ 'name_server' => 6,
21
+ 'log_server' => 7,
22
+ 'cookie_server' => 8,
23
+ 'lpr_server' => 9,
24
+ 'hostname' => 12,
25
+ 'dump_path' => 14,
26
+ 'domain' => 15,
27
+ 'root_disk_path' => 17,
28
+ 'default_ttl' => 23,
29
+ 'pmtu_timeout' => 24,
30
+ 'broadcast_address' => 28,
31
+ 'NIS_domain' => 40,
32
+ 'NIS_server' => 41,
33
+ 'NTP_server' => 42,
34
+ 'vendor_specific' => 43,
35
+ 'NetBIOS_server' => 44,
36
+ 'NetBIOS_dist_server' => 45,
37
+ 'requested_addr' => 50,
38
+ 'lease_time' => 51,
39
+ 'message-type' => 53,
40
+ 'server_id' => 54,
41
+ 'param_req_list' => 55,
42
+ 'error_message' => 56,
43
+ 'max_dhcp_size' => 57,
44
+ 'renewal_time' => 58,
45
+ 'rebinding_time' => 59,
46
+ 'vendor_class_id' => 60,
47
+ 'client_id' => 61,
48
+ 'NISplus_domain' => 64,
49
+ 'NISplus_server' => 65,
50
+ 'SMTP_server' => 69,
51
+ 'POP3_server' => 70,
52
+ 'NNTP_server' => 71,
53
+ 'WWW_server' => 72,
54
+ 'finger_server' => 73,
55
+ 'IRC_server' => 74,
56
+ 'end' => 255
57
57
  }.freeze
58
58
 
59
+ # Option class with string value
60
+ Option = Types::AbstractTLV.create
61
+ Option.define_type_enum DHCP_OPTIONS
62
+ # Option class with IP address value
63
+ IPAddrOption = Types::AbstractTLV.create(value_class: IP::Addr)
64
+ IPAddrOption.define_type_enum DHCP_OPTIONS
65
+ # Option class with int8 value
66
+ Int8Option = Types::AbstractTLV.create(value_class: Types::Int8)
67
+ Int8Option.define_type_enum DHCP_OPTIONS
68
+ # Option class with int16 value
69
+ Int16Option = Types::AbstractTLV.create(value_class: Types::Int16)
70
+ Int16Option.define_type_enum DHCP_OPTIONS
71
+ # Option class with int32 value
72
+ Int32Option = Types::AbstractTLV.create(value_class: Types::Int32)
73
+ Int32Option.define_type_enum DHCP_OPTIONS
74
+
59
75
  # Class to indicate DHCP options end
60
76
  class End < Types::Int8
61
77
  def initialize(value=255)
@@ -74,90 +90,6 @@ module PacketGen
74
90
  super
75
91
  end
76
92
  end
77
-
78
- # DHCP option
79
- #
80
- # A DHCP option is a {Types::TLV TLV}, so it has:
81
- # * a {#type} ({Types::Int8}),
82
- # * a {#length} ({Types::Int8}),
83
- # * and a {#value}. Defalt type is {Types::String} but some options
84
- # may use more suitable type (by example, a {IP::Addr} for +router+
85
- # option).
86
- # @author Sylvain Daubert
87
- class Option < Types::TLV
88
- # Option types
89
- TYPES = Hash[DHCP_OPTIONS.to_a.map { |type, ary| [type, ary[0]] }]
90
-
91
- # @param [Hash] options
92
- # @option options [Integer] :type
93
- # @option options [Integer] :length
94
- # @option options [String] :value
95
- def initialize(options={})
96
- super
97
- return unless DHCP_OPTIONS.key?(self.type)
98
-
99
- h = DHCP_OPTIONS[self.type].last
100
- return unless h.is_a? Hash
101
-
102
- h.each do |k, v|
103
- self.length = v if k == :length
104
- if k == :v
105
- self[:value] = v.new
106
- self.value = options[:value] if options[:value]
107
- end
108
- end
109
- end
110
-
111
- # @private
112
- alias private_read read
113
-
114
- # Populate object from a binary string
115
- # @param [String] str
116
- # @return [Option,End,Pad] may return another object than itself
117
- def read(str)
118
- read_type = str[0].unpack('C').first
119
- if read_type.zero?
120
- Pad.new.read(str)
121
- elsif read_type == 255
122
- End.new.read(str)
123
- elsif DHCP_OPTIONS.key?(read_type)
124
- Option.new(DHCP_OPTIONS[read_type][1] || {}).private_read(str)
125
- else
126
- super
127
- end
128
- end
129
-
130
- # @since 2.7.0
131
- # @return [true]
132
- def human_types?
133
- true
134
- end
135
-
136
- # Get human-readable type
137
- # @return [String]
138
- def human_type
139
- if DHCP_OPTIONS.key?(type)
140
- DHCP_OPTIONS[type].first.dup
141
- else
142
- type.to_s
143
- end
144
- end
145
-
146
- # @return [String]
147
- def to_human
148
- s = human_type
149
- if length > 0
150
- s << if value.respond_to? :to_human
151
- ":#{value.to_human}"
152
- elsif self[:value].is_a? Types::Int
153
- ":#{self.value.to_i}"
154
- else
155
- ":#{value.inspect}"
156
- end
157
- end
158
- s
159
- end
160
- end
161
93
  end
162
94
  end
163
95
  end
@@ -26,15 +26,23 @@ module PacketGen
26
26
 
27
27
  private
28
28
 
29
- def record_from_hash(hsh)
30
- case hsh[:type]
31
- when 'pad', 0
32
- Pad.new
33
- when 'end', 255
34
- End.new
29
+ def real_type(obj)
30
+ case obj.type
31
+ when 0
32
+ Pad
33
+ when 1, 3, 4, 5, 6, 7, 8, 9, 28, 41, 42, 44, 45, 50, 54, 65, 69,
34
+ 70, 71, 72, 73, 74
35
+ IPAddrOption
36
+ when 53
37
+ Int8Option
38
+ when 57
39
+ Int16Option
40
+ when 51, 58, 59
41
+ Int32Option
42
+ when 255
43
+ End
35
44
  else
36
- obj_klass = self.class.set_of_klass
37
- obj_klass.new(hsh)
45
+ Option
38
46
  end
39
47
  end
40
48
  end
@@ -9,14 +9,8 @@ module PacketGen
9
9
  module Header
10
10
  class DNS
11
11
  # DNS option
12
- # @author Sylvain Daubert
13
- class Option < Types::TLV
14
- # Force {#type} and {#length} fields to be {Types::Int16}
15
- # @see TLV#initialize
16
- def initialize(options={})
17
- super options.merge!(t: Types::Int16, l: Types::Int16)
18
- end
19
- end
12
+ Option = Types::AbstractTLV.create(type_class: Types::Int16,
13
+ length_class: Types::Int16)
20
14
  end
21
15
  end
22
16
  end
@@ -12,8 +12,9 @@ module PacketGen
12
12
  # IEEE 802.11 information element
13
13
  #
14
14
  # An {Element} is a piece of data contained in a Dot11 management frame.
15
- # @author Sylvain Daubert
16
- class Element < Types::TLV
15
+ Element = Types::AbstractTLV.create
16
+
17
+ class Element
17
18
  # Known element types
18
19
  TYPES = {
19
20
  0 => 'SSID',
@@ -33,6 +34,7 @@ module PacketGen
33
34
  221 => 'vendor'
34
35
  }.freeze
35
36
  end
37
+ Element.define_type_enum Element::TYPES.invert
36
38
  end
37
39
  end
38
40
  end
@@ -9,7 +9,7 @@ module PacketGen
9
9
  module Header
10
10
  module HTTP
11
11
  # An HTTP/1.1 Request packet consists of:
12
- # * the http method ({Types::String}).
12
+ # * the http verb ({Types::String}).
13
13
  # * the path ({Types::String}).
14
14
  # * the version ({Types::String}).
15
15
  # * associated http headers ({HTTP::Headers}).
@@ -27,16 +27,19 @@ module PacketGen
27
27
  #
28
28
  # == HTTP Request attributes
29
29
  # http_rqst.version = "HTTP/1.1"
30
- # http_rqst.method = "GET"
30
+ # http_rqst.verb = "GET"
31
31
  # http_rqst.path = "/meow.html"
32
32
  # http_rqst.headers = "Host: tcpdump.org" # string or
33
33
  # http_rqst.headers = { "Host": "tcpdump.org" } # even a hash
34
34
  #
35
35
  # @author Kent 'picat' Gruber
36
+ # @author Sylvain Daubert
37
+ # @since 3.1.0 Rename +#method+ into {#verb} to not mask +Object#method+.
36
38
  class Request < Base
37
- # @!attribute method
39
+ # @!attribute verb
38
40
  # @return [Types::String]
39
- define_field :method, Types::String
41
+ # @since 3.1.0
42
+ define_field :verb, Types::String
40
43
  # @!attribute path
41
44
  # @return [Types::String]
42
45
  define_field :path, Types::String
@@ -52,7 +55,7 @@ module PacketGen
52
55
  define_field :body, Types::String
53
56
 
54
57
  # @param [Hash] options
55
- # @option options [String] :method
58
+ # @option options [String] :verb
56
59
  # @option options [String] :path
57
60
  # @option options [String] :version
58
61
  # @option options [Hash] :headers
@@ -69,7 +72,7 @@ module PacketGen
69
72
  str = vrb + str.split(vrb)[-1]
70
73
  str = str.split("\n").map(&:chomp)
71
74
  first_line = str.shift.split
72
- self[:method].read first_line[0]
75
+ self[:verb].read first_line[0]
73
76
  self[:path].read first_line[1]
74
77
  self[:version].read first_line[2]
75
78
  # requests can sometimes have a payload
@@ -87,12 +90,12 @@ module PacketGen
87
90
  # String representation of data.
88
91
  # @return [String]
89
92
  def to_s
90
- raise FormatError, 'Missing #method.' if self.method.empty?
93
+ raise FormatError, 'Missing #verb.' if self.verb.empty?
91
94
  raise FormatError, 'Missing #path.' if self.path.empty?
92
95
  raise FormatError, 'Missing #version.' if self.version.empty?
93
96
 
94
97
  str = ''.dup # build 'dat string
95
- str << self[:method] << ' ' << self[:path] << ' ' << self[:version] << "\r\n" << self[:headers].to_s << self[:body]
98
+ str << self[:verb] << ' ' << self[:path] << ' ' << self[:version] << "\r\n" << self[:headers].to_s << self[:body]
96
99
  end
97
100
  end
98
101
  end
@@ -8,9 +8,10 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class IPv6
11
- # Option for {HopByHop} IPv6 extension header
12
- # @author Sylvain Daubert
13
- class Option < Types::TLV
11
+ # Option for {HopByHop} IPv6 extension header.
12
+ Option = Types::AbstractTLV.create
13
+
14
+ class Option
14
15
  # Known option types
15
16
  TYPES = {
16
17
  1 => 'padn',
@@ -27,6 +28,7 @@ module PacketGen
27
28
  end
28
29
  end
29
30
  end
31
+ Option.define_type_enum Option::TYPES.invert
30
32
 
31
33
  # Special option pad1, for {HopByHop} IPv6 extension header
32
34
  # @author Sylvain Daubert
@@ -181,7 +181,7 @@ module PacketGen
181
181
  # Recalculate all packet length fields
182
182
  # @return [void]
183
183
  def calc_length
184
- headers.each do |header|
184
+ headers.reverse_each do |header|
185
185
  header.calc_length if header.respond_to? :calc_length
186
186
  end
187
187
  end
@@ -0,0 +1,137 @@
1
+ # coding: utf-8
2
+ # This file is part of PacketGen
3
+ # See https://github.com/sdaubert/packetgen for more informations
4
+ # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
+ # This program is published under MIT license.
6
+
7
+ # frozen_string_literal: true
8
+
9
+ module PacketGen
10
+ module Types
11
+ # This class is an abstract class to define type-length-value data.
12
+ #
13
+ # This class supersede {TLV} class, which is not well defined on some corner
14
+ # cases.
15
+ #
16
+ # ===Usage
17
+ # To simply define a new TLV class, do:
18
+ # MyTLV = PacketGen::Types::AbstractTLV.create
19
+ # MyTLV.define_type_enum 'one' => 1, 'two' => 2
20
+ # This will define a new +MyTLV+ class, subclass of {Fields}. This class will
21
+ # define 3 fields:
22
+ # * +#type+, as a {Int8Enum} by default,
23
+ # * +#length+, as a {Int8} by default,
24
+ # * and +#value+, as a {String} by default.
25
+ # +.define_type_enum+ is, here, necessary to define enum hash to be used
26
+ # for +#type+ accessor, as this one is defined as an {Enum}.
27
+ #
28
+ # This class may then be used as older {TLV} class:
29
+ # tlv = MyTLV.new(type: 1, value: 'abcd') # automagically set #length from value
30
+ # tlv.type #=> 1
31
+ # tlv.human_type #=> 'one'
32
+ # tlv.length #=> 4
33
+ # tlv.value #=> "abcd"
34
+ #
35
+ # ===Advanced usage
36
+ # Each field's type may be change at generating TLV class:
37
+ # MyTLV = PacketGen::Types::AbstractTLV.create(type_class: PacketGen::Types::Int16,
38
+ # length_class: PacketGen::Types::Int16,
39
+ # value_class: PacketGen::Header::IP::Addr)
40
+ # tlv = MyTLV.new(type: 1, value: '1.2.3.4')
41
+ # tlv.type #=> 1
42
+ # tlv.length #=> 4
43
+ # tlv.value #=> 42
44
+ # tlv.to_s #=> "\x00\x01\x00\x04\x01\x02\x03\x04"
45
+ # @author Sylvain Daubert
46
+ # @since 3.1.0
47
+ class AbstractTLV < Types::Fields
48
+ # Generate a TLV class
49
+ # @param [Class] type_class Class to use for +type+
50
+ # @param [Class] length_class Class to use for +length+
51
+ # @param [Class] value_class Class to use for +value+
52
+ # @return [Class]
53
+ def self.create(type_class: Int8Enum, length_class: Int8, value_class: String)
54
+ raise Error, '.create cannot be called on a subclass of PacketGen::Types::AbstractTLV' unless self.equal? AbstractTLV
55
+
56
+ klass = Class.new(self)
57
+
58
+ if type_class < Enum
59
+ klass.define_field :type, type_class, enum: {}
60
+ else
61
+ klass.define_field :type, type_class
62
+ end
63
+ klass.define_field :length, length_class
64
+ klass.define_field :value, value_class
65
+
66
+ klass
67
+ end
68
+ # @!attribute type
69
+ # @abstract Type attribute for real TLV class
70
+ # @return [Integer]
71
+ # @!attribute length
72
+ # @abstract Length attribute for real TLV class
73
+ # @return [Integer]
74
+ # @!attribute value
75
+ # @abstract Value attribute for real TLV class
76
+ # @return [Object]
77
+
78
+ # @abstract Should only be called on real TLV classes, created by {.create}.
79
+ # Set enum hash for {#type} field.
80
+ # @param [Hash] hsh enum hash
81
+ # @return [void]
82
+ def self.define_type_enum(hsh)
83
+ field_defs[:type][:enum].clear
84
+ field_defs[:type][:enum].merge!(hsh)
85
+ end
86
+
87
+ # @abstract Should only be called on real TLV classes, created by {.create}.
88
+ # @param [Hash] options
89
+ # @option options [Integer] :type
90
+ # @option options [Integer] :length
91
+ # @option options [Object] :value
92
+ def initialize(options={})
93
+ super
94
+ # used #value= defined below, which set length if needed
95
+ self.value = options[:value] if options[:value]
96
+ end
97
+
98
+ # @abstract Should only be called on real TLV class instances.
99
+ # Populate object from a binary string
100
+ # @param [String] str
101
+ # @return [Fields] self
102
+ def read(str)
103
+ idx = 0
104
+ self[:type].read str[idx, self[:type].sz]
105
+ idx += self[:type].sz
106
+ self[:length].read str[idx, self[:length].sz]
107
+ idx += self[:length].sz
108
+ self[:value].read str[idx, self.length]
109
+ self
110
+ end
111
+
112
+ # @abstract Should only be called on real TLV class instances.
113
+ # Set +value+. May set +length+ if value is a {Types::String}.
114
+ # @param [::String,Integer] val
115
+ # @return [::String,Integer]
116
+ def value=(val)
117
+ self[:value].from_human val
118
+ self.length = self[:value].sz
119
+ val
120
+ end
121
+
122
+ # @abstract Should only be called on real TLV class instances.
123
+ # Get human-readable type
124
+ # @return [String]
125
+ def human_type
126
+ self[:type].to_human.to_s
127
+ end
128
+
129
+ # @abstract Should only be called on real TLV class instances.
130
+ # @return [String]
131
+ def to_human
132
+ my_value = self[:value].is_a?(String) ? value.inspect : value.to_human
133
+ "type:%s,length:%u,value:#{my_value}" % [human_type, length]
134
+ end
135
+ end
136
+ end
137
+ end
@@ -115,6 +115,11 @@ module PacketGen
115
115
  @bit_fields = {}
116
116
 
117
117
  class <<self
118
+ # Get field definitions for this class.
119
+ # @return [Hash]
120
+ # @since 3.1.0
121
+ attr_reader :field_defs
122
+
118
123
  # On inheritage, create +@field_defs+ class variable
119
124
  # @param [Class] klass
120
125
  # @return [void]
@@ -188,15 +193,15 @@ module PacketGen
188
193
  "end"
189
194
  end
190
195
 
191
- define.delete(1) if type.instance_methods.include? "#{name}=".to_sym
192
- define.delete(0) if type.instance_methods.include? name
196
+ define.delete_at(1) if instance_methods.include? "#{name}=".to_sym
197
+ define.delete_at(0) if instance_methods.include? name
193
198
  class_eval define.join("\n")
194
- @field_defs[name] = FieldDef.new(type,
195
- options.delete(:default),
196
- options.delete(:builder),
197
- options.delete(:optional),
198
- options.delete(:enum),
199
- options)
199
+ field_defs[name] = FieldDef.new(type,
200
+ options.delete(:default),
201
+ options.delete(:builder),
202
+ options.delete(:optional),
203
+ options.delete(:enum),
204
+ options)
200
205
  fields << name
201
206
  end
202
207
 
@@ -257,13 +262,13 @@ module PacketGen
257
262
  # @raise [ArgumentError] unknown +field+
258
263
  # @since 2.8.4
259
264
  def update_field(field, options)
260
- raise ArgumentError, "unkown #{field} field for #{self}" unless @field_defs.key?(field)
265
+ raise ArgumentError, "unkown #{field} field for #{self}" unless field_defs.key?(field)
261
266
 
262
- @field_defs[field].default = options.delete(:default) if options.key?(:default)
263
- @field_defs[field].builder = options.delete(:builder) if options.key?(:builder)
264
- @field_defs[field].optional = options.delete(:optional) if options.key?(:optional)
265
- @field_defs[field].enum = options.delete(:enum) if options.key?(:enum)
266
- @field_defs[field].options.merge!(options)
267
+ field_defs[field].default = options.delete(:default) if options.key?(:default)
268
+ field_defs[field].builder = options.delete(:builder) if options.key?(:builder)
269
+ field_defs[field].optional = options.delete(:optional) if options.key?(:optional)
270
+ field_defs[field].enum = options.delete(:enum) if options.key?(:enum)
271
+ field_defs[field].options.merge!(options)
267
272
  end
268
273
 
269
274
  # Define a bitfield on given attribute
@@ -286,7 +291,7 @@ module PacketGen
286
291
  # by bitfield size. If no size is given, 1 bit is assumed.
287
292
  # @return [void]
288
293
  def define_bit_fields_on(attr, *args)
289
- attr_def = @field_defs[attr]
294
+ attr_def = field_defs[attr]
290
295
  raise ArgumentError, "unknown #{attr} field" if attr_def.nil?
291
296
 
292
297
  type = attr_def.type
@@ -366,7 +371,7 @@ module PacketGen
366
371
  @fields = {}
367
372
  @optional_fields = {}
368
373
 
369
- field_defs = self.class.class_eval { @field_defs }
374
+ field_defs = self.class.field_defs
370
375
  self.class.fields.each do |field|
371
376
  type = field_defs[field].type
372
377
  default = field_defs[field].default
@@ -8,7 +8,8 @@
8
8
 
9
9
  module PacketGen
10
10
  module Types
11
- # This class is just like regular String. It only adds {#read} and {#sz} methods
11
+ # This class is just like regular String. It only adds {#read}, {#sz},
12
+ # #{to_human} and {#from_human} methods
12
13
  # to be compatible with others {Types}.
13
14
  # @author Sylvain Daubert
14
15
  class String < ::String
@@ -28,6 +28,8 @@ module PacketGen
28
28
  # * print human readable type using {#human_type},
29
29
  # * set type as String with {#type=}.
30
30
  # @author Sylvain Daubert
31
+ # @deprecated Use {AbstractTLV} instead.
32
+ # @since 3.1.0 deprecated
31
33
  class TLV < Fields
32
34
  # @!attribute type
33
35
  # @return [Integer]
@@ -50,6 +52,7 @@ module PacketGen
50
52
  # @option options [Class] :v {String} subclass for +:value+ attribute.
51
53
  # Default: {Types::String}.
52
54
  def initialize(options={})
55
+ Deprecation.deprecated_class(self.class, AbstractTLV)
53
56
  super
54
57
  self[:type] = options[:t].new(self.type) if options[:t]
55
58
  self[:length] = options[:l].new(self.length) if options[:l]
@@ -17,5 +17,6 @@ require_relative 'types/int_string'
17
17
  require_relative 'types/cstring'
18
18
  require_relative 'types/fields'
19
19
  require_relative 'types/array'
20
- require_relative 'types/tlv'
21
20
  require_relative 'types/oui'
21
+ require_relative 'types/abstract_tlv'
22
+ require_relative 'types/tlv'
@@ -10,5 +10,5 @@
10
10
  # @author Sylvain Daubert
11
11
  module PacketGen
12
12
  # PacketGen version
13
- VERSION = '3.0.2'
13
+ VERSION = '3.1.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.0.2
4
+ version: 3.1.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: 2018-11-05 00:00:00.000000000 Z
11
+ date: 2018-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interfacez
@@ -247,6 +247,7 @@ files:
247
247
  - lib/packetgen/pcapng/unknown_block.rb
248
248
  - lib/packetgen/proto.rb
249
249
  - lib/packetgen/types.rb
250
+ - lib/packetgen/types/abstract_tlv.rb
250
251
  - lib/packetgen/types/array.rb
251
252
  - lib/packetgen/types/cstring.rb
252
253
  - lib/packetgen/types/enum.rb