packetgen 3.0.2 → 3.1.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.
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