packetgen-plugin-ipsec 1.0.3 → 1.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.
@@ -53,11 +53,11 @@ module PacketGen::Plugin
53
53
  # @attribute [r] auth_method
54
54
  # 8-bit Auth Method
55
55
  # @return [Integer]
56
- define_field_before :content, :auth_method, PacketGen::Types::Int8Enum, enum: METHODS
56
+ define_attr_before :content, :auth_method, BinStruct::Int8Enum, enum: METHODS
57
57
  # @attribute reserved
58
58
  # 24-bit reserved field
59
59
  # @return [Integer]
60
- define_field_before :content, :reserved, PacketGen::Types::Int24
60
+ define_attr_before :content, :reserved, BinStruct::Int24
61
61
 
62
62
  # Check authentication (see RFC 7296 §2.15)
63
63
  # @param [Packet] init_msg first IKE message sent by peer
@@ -73,49 +73,17 @@ module PacketGen::Plugin
73
73
  # supported.
74
74
  # @note For certificates, only check AUTH authenticity with given (or guessed
75
75
  # from packet) certificate, but certificate chain is not verified.
76
- def check?(init_msg: nil, nonce: '', sk_p: '', prf: 1, shared_secret: '',
76
+ def check?(init_msg: nil, nonce: '', sk_p: '', prf: 1, shared_secret: '', # rubocop:disable Metrics/ParameterLists
77
77
  cert: nil)
78
78
  raise TypeError, 'init_msg should be a Packet' unless init_msg.is_a?(PacketGen::Packet)
79
79
 
80
- signed_octets = init_msg.ike.to_s
81
- signed_octets << nonce
82
- id = packet.ike.flag_i? ? packet.ike_idi : packet.ike_idr
83
- signed_octets << prf(prf, sk_p, id.to_s[4, id.length - 4])
84
-
80
+ signed_octets = build_signed_octets(init_msg, nonce, sk_p, prf)
85
81
  case auth_method
86
82
  when METHODS['SHARED_KEY']
87
- auth = prf(prf(shared_secret, 'Key Pad for IKEv2'), signed_octets)
88
- auth == content
83
+ check_shared_key?(shared_secret, signed_octets)
89
84
  when METHODS['RSA_SIGNATURE'], METHODS['ECDSA256'], METHODS['ECDSA384'],
90
85
  METHODS['ECDSA512']
91
- if packet.ike_cert
92
- # FIXME: Expect a ENCODING_X509_CERT_SIG
93
- # Others types not supported for now...
94
- cert = OpenSSL::X509::Certificate.new(packet.ike_cert.content)
95
- elsif cert.nil?
96
- raise CryptoError, 'a certificate should be provided'
97
- end
98
-
99
- text = cert.to_text
100
- m = text.match(/Public Key Algorithm: ([a-zA-Z0-9-]+)/)
101
- digest = case m[1]
102
- when 'id-ecPublicKey'
103
- m2 = text.match(/Public-Key: \((\d+) bit\)/)
104
- case m2[1]
105
- when '256'
106
- OpenSSL::Digest::SHA256.new
107
- when '384'
108
- OpenSSL::Digest::SHA384.new
109
- when '521'
110
- OpenSSL::Digest::SHA512.new
111
- end
112
- when /sha([235]\d+)/
113
- OpenSSL::Digest.const_get("SHA#{$1}").new
114
- when /sha1/, 'rsaEncryption'
115
- OpenSSL::Digest::SHA1.new
116
- end
117
- signature = format_signature(cert.public_key, content.to_s)
118
- cert.public_key.verify(digest, signature, signed_octets)
86
+ check_signature?(cert, signed_octets)
119
87
  when METHOD_NULL
120
88
  true
121
89
  else
@@ -131,6 +99,13 @@ module PacketGen::Plugin
131
99
 
132
100
  private
133
101
 
102
+ def build_signed_octets(init_msg, nonce, sk_p, prf)
103
+ signed_octets = init_msg.ike.to_s
104
+ signed_octets << nonce
105
+ id = packet.ike.flag_i? ? packet.ike_idi : packet.ike_idr
106
+ signed_octets << prf(prf, sk_p, id.to_s[4, id.length - 4])
107
+ end
108
+
134
109
  def prf(type, key, msg)
135
110
  case type
136
111
  when Transform::PRF_HMAC_MD5, Transform::PRF_HMAC_SHA1,
@@ -138,7 +113,7 @@ module PacketGen::Plugin
138
113
  Transform::PRF_HMAC_SHA2_512
139
114
  digestname = Transform.constants.grep(/PRF_/)
140
115
  .detect { |c| Transform.const_get(c) == type }
141
- .to_s.sub(/^PRF_HMAC_/, '').sub(/2_/, '')
116
+ .to_s.sub(/^PRF_HMAC_/, '').sub('2_', '')
142
117
  digest = OpenSSL::Digest.const_get(digestname).new
143
118
  else
144
119
  raise NotImplementedError, 'for now, only HMAC-based PRF are supported'
@@ -148,6 +123,44 @@ module PacketGen::Plugin
148
123
  hmac.digest
149
124
  end
150
125
 
126
+ def check_shared_key?(shared_secret, signed_octets)
127
+ auth = prf(prf(shared_secret, 'Key Pad for IKEv2'), signed_octets)
128
+ auth == content
129
+ end
130
+
131
+ def check_signature?(cert, signed_octets)
132
+ if packet.ike_cert
133
+ # FIXME: Expect a ENCODING_X509_CERT_SIG
134
+ # Others types not supported for now...
135
+ cert = OpenSSL::X509::Certificate.new(packet.ike_cert.content)
136
+ elsif cert.nil?
137
+ raise CryptoError, 'a certificate should be provided'
138
+ end
139
+
140
+ text = cert.to_text
141
+ digest = build_digest_object(text)
142
+ signature = format_signature(cert.public_key, content.to_s)
143
+ cert.public_key.verify(digest, signature, signed_octets)
144
+ end
145
+
146
+ def build_digest_object(text)
147
+ m = text.match(/Public Key Algorithm: ([a-zA-Z0-9-]+)/)
148
+ case m[1]
149
+ when 'id-ecPublicKey'
150
+ m2 = text.match(/Public-Key: \((\d+) bit\)/)
151
+ case m2[1]
152
+ when '256', '384'
153
+ OpenSSL::Digest.new("SHA#{m2[1]}")
154
+ when '521'
155
+ OpenSSL::Digest.new(SHA512)
156
+ end
157
+ when /sha([235]\d+)/
158
+ OpenSSL::Digest.new("SHA#{$1}")
159
+ when /sha1/, 'rsaEncryption'
160
+ OpenSSL::Digest.new('SHA1')
161
+ end
162
+ end
163
+
151
164
  def format_signature(pkey, sig)
152
165
  if pkey.is_a?(OpenSSL::PKey::EC)
153
166
  # PKey::EC need a signature as a DER string representing a sequence of
@@ -56,7 +56,7 @@ module PacketGen::Plugin
56
56
  # @attribute encoding
57
57
  # 8-bit certificate encoding
58
58
  # @return [Integer]
59
- define_field_before :content, :encoding, PacketGen::Types::Int8Enum, enum: ENCODINGS
59
+ define_attr_before :content, :encoding, BinStruct::Int8Enum, enum: ENCODINGS
60
60
 
61
61
  def initialize(options={})
62
62
  super
@@ -55,7 +55,7 @@ module PacketGen::Plugin
55
55
  next unless attr == :content
56
56
 
57
57
  str = PacketGen::Inspect.shift_level
58
- str << PacketGen::Inspect::FMT_ATTR % ['hashes', :content, human_content]
58
+ str << (PacketGen::Inspect::FMT_ATTR % ['hashes', :content, human_content])
59
59
  end
60
60
  end
61
61
  end
@@ -41,23 +41,23 @@ module PacketGen::Plugin
41
41
 
42
42
  # ID types
43
43
  TYPES = {
44
- 'IPV4_ADDR' => 1,
45
- 'FQDN' => 2,
44
+ 'IPV4_ADDR' => 1,
45
+ 'FQDN' => 2,
46
46
  'RFC822_ADDR' => 3,
47
- 'IPV6_ADDR' => 5,
47
+ 'IPV6_ADDR' => 5,
48
48
  'DER_ASN1_DN' => 9,
49
49
  'DER_ASN1_GN' => 10,
50
- 'KEY_ID' => 11
50
+ 'KEY_ID' => 11
51
51
  }.freeze
52
52
 
53
53
  # @attribute [r] type
54
54
  # 8-bit ID type
55
55
  # @return [Integer]
56
- define_field_before :content, :type, PacketGen::Types::Int8Enum, enum: TYPES
56
+ define_attr_before :content, :type, BinStruct::Int8Enum, enum: TYPES
57
57
  # @attribute reserved
58
58
  # 24-bit reserved field
59
59
  # @return [Integer]
60
- define_field_before :content, :reserved, PacketGen::Types::Int24
60
+ define_attr_before :content, :reserved, BinStruct::Int24
61
61
 
62
62
  # Get ID type name
63
63
  # @return [String]
@@ -69,7 +69,7 @@ module PacketGen::Plugin
69
69
  # @return [String]
70
70
  def human_content
71
71
  case type
72
- when TYPES['IPV4_ADDR'], TYPES['IPV4_ADDR']
72
+ when TYPES['IPV4_ADDR'], TYPES['IPV6_ADDR']
73
73
  IPAddr.ntop(content)
74
74
  when TYPES['DER_ASN1_DN'], TYPES['DER_ASN1_GN']
75
75
  OpenSSL::X509::Name.new(content).to_s
@@ -77,7 +77,6 @@ module PacketGen::Plugin
77
77
  content.inspect
78
78
  end
79
79
  end
80
-
81
80
  end
82
81
 
83
82
  # This class handles Identification - Responder payloads, denoted IDr.
@@ -24,9 +24,9 @@ module PacketGen::Plugin
24
24
  # | |
25
25
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26
26
  # These specific fields are:
27
- # * {#group_num} (type {PacketGen::Types::Int16}),
28
- # * {#reserved} (type {PacketGen::Types::Int16}),
29
- # * and {#content} (type {PacketGen::Types::String}).
27
+ # * {#group_num} (type {BinStruct::Int16}),
28
+ # * {#reserved} (type {BinStruct::Int16}),
29
+ # * and {#content} (type {BinStruct::String}).
30
30
  #
31
31
  # == Create a KE payload
32
32
  # # Create a IKE packet with a KE payload
@@ -44,11 +44,11 @@ module PacketGen::Plugin
44
44
  # @!attribute group_num
45
45
  # 16-bit DH group number
46
46
  # @return [Integer]
47
- define_field_before :content, :group_num, PacketGen::Types::Int16
47
+ define_attr_before :content, :group_num, BinStruct::Int16
48
48
  # @!attribute reserved
49
49
  # 16-bit reserved field
50
50
  # @return [Integer]
51
- define_field_before :content, :reserved, PacketGen::Types::Int16, default: 0
51
+ define_attr_before :content, :reserved, BinStruct::Int16, default: 0
52
52
 
53
53
  def initialize(options={})
54
54
  super
@@ -68,6 +68,7 @@ module PacketGen::Plugin
68
68
  Transform.const_defined?(cname) ? Transform.const_get(cname) : nil
69
69
  end
70
70
  raise ArgumentError, "unknown group #{value.inspect}" unless group
71
+
71
72
  self[:group_num].value = group
72
73
  end
73
74
  end
@@ -11,7 +11,7 @@ module PacketGen::Plugin
11
11
  # This class handles Nonce payloads, as defined in RFC 7296 §3.9.
12
12
  #
13
13
  # A Nonce payload contains a generic payload Plugin (see {Payload}) and
14
- # data field (type {PacketGen::Types::String}):
14
+ # data field (type {BinStruct::String}):
15
15
  # 1 2 3
16
16
  # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
17
17
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -28,11 +28,11 @@ module PacketGen::Plugin
28
28
  # | |
29
29
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30
30
  # These specific fields are:
31
- # * {#protocol} (type {PacketGen::Types::Int8}),
32
- # * {#spi_size} (type {PacketGen::Types::Int8}),
33
- # * {#message_type} (type {PacketGen::Types::Int16}),
34
- # * {#spi} (type {PacketGen::Types::String}),
35
- # * {#content} (type {PacketGen::Types::String}).
31
+ # * {#protocol} (type {BinStruct::Int8}),
32
+ # * {#spi_size} (type {BinStruct::Int8}),
33
+ # * {#message_type} (type {BinStruct::Int16}),
34
+ # * {#spi} (type {BinStruct::String}),
35
+ # * {#content} (type {BinStruct::String}).
36
36
  #
37
37
  # == Create a Notify payload
38
38
  # # Create a IKE packet with a Notify payload
@@ -43,7 +43,7 @@ module PacketGen::Plugin
43
43
  # == Create a Notify payload with a SPI
44
44
  # # Create a IKE packet with a Notify payload
45
45
  # pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::Notify', protocol: 'ESP', spi_size: 4, type: 'INVALID_SYNTAX')
46
- # pkt.ike_notify.spi.read PacketGen::Types::Int32.new(0x12345678).to_s
46
+ # pkt.ike_notify.spi.read BinStruct::Int32.new(0x12345678).to_s
47
47
  # pkt.calc_length
48
48
  # @author Sylvain Daubert
49
49
  class Notify < Payload
@@ -93,7 +93,7 @@ module PacketGen::Plugin
93
93
  # CHILD_SA_NOT_FOUND. If the SPI field is empty, this field MUST be
94
94
  # sent as zero and MUST be ignored on receipt.
95
95
  # @return [Integer]
96
- define_field_before :content, :protocol, PacketGen::Types::Int8Enum, enum: PROTOCOLS
96
+ define_attr_before :content, :protocol, BinStruct::Int8Enum, enum: PROTOCOLS
97
97
  # @!attribute spi_size
98
98
  # 8-bit SPI size. Give size of SPI field. Length in octets of the SPI as
99
99
  # defined by the IPsec protocol ID or zero if no SPI is applicable. For a
@@ -101,17 +101,17 @@ module PacketGen::Plugin
101
101
  # the field must be empty.Set to 0 for an initial IKE SA
102
102
  # negotiation, as SPI is obtained from outer Plugin.
103
103
  # @return [Integer]
104
- define_field_before :content, :spi_size, PacketGen::Types::Int8, default: 0
104
+ define_attr_before :content, :spi_size, BinStruct::Int8, default: 0
105
105
  # @!attribute message_type
106
106
  # 16-bit notify message type. Specifies the type of notification message.
107
107
  # @return [Integer]
108
- define_field_before :content, :message_type, PacketGen::Types::Int16Enum, enum: TYPES, default: 0
108
+ define_attr_before :content, :message_type, BinStruct::Int16Enum, enum: TYPES, default: 0
109
109
  # @!attribute spi
110
110
  # the sending entity's SPI. When the {#spi_size} field is zero,
111
111
  # this field is not present in the proposal.
112
112
  # @return [String]
113
- define_field_before :content, :spi, PacketGen::Types::String,
114
- builder: ->(h, t) { t.new(length_from: h[:spi_size]) }
113
+ define_attr_before :content, :spi, BinStruct::String,
114
+ builder: ->(h, t) { t.new(length_from: h[:spi_size]) }
115
115
 
116
116
  alias type message_type
117
117
 
@@ -144,8 +144,7 @@ module PacketGen::Plugin
144
144
  next unless attr == :protocol
145
145
 
146
146
  str = PacketGen::Inspect.shift_level
147
- str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr,
148
- human_protocol]
147
+ str << (PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr, human_protocol])
149
148
  end
150
149
  end
151
150
  end
@@ -30,42 +30,40 @@ module PacketGen::Plugin
30
30
  # @!attribute next
31
31
  # 8-bit next payload
32
32
  # @return [Integer]
33
- define_field :next, PacketGen::Types::Int8
33
+ define_attr :next, BinStruct::Int8
34
34
  # @!attribute flags
35
35
  # 8-bit flags
36
36
  # @return [Integer]
37
- define_field :flags, PacketGen::Types::Int8
37
+ # @!attribute critical
38
+ # critical flag
39
+ # @return [Boolean]
40
+ # @!attribute hreserved
41
+ # reserved part of {#flags} field
42
+ # @return [Integer]
43
+ define_bit_attr :flags, critical: 1, hreserved: 7
38
44
  # @!attribute length
39
45
  # 16-bit payload total length, including generic payload Plugin
40
46
  # @return [Integer]
41
- define_field :length, PacketGen::Types::Int16
47
+ define_attr :length, BinStruct::Int16
42
48
  # @!attribute content
43
49
  # Payload content. Depends on payload. Variable length.
44
50
  # @return [String]
45
- define_field :content, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: -> { h.length - h.offset_of(:content) }) }
51
+ define_attr :content, BinStruct::String, builder: ->(h, t) { t.new(length_from: -> { h.length - h.offset_of(:content) }) }
46
52
 
47
53
  # Defining a body permits using Packet#parse to parse next IKE payloads.
48
- define_field :body, PacketGen::Types::String
49
-
50
- # @!attribute critical
51
- # critical flag
52
- # @return [Boolean]
53
- # @!attribute hreserved
54
- # reserved part of {#flags} field
55
- # @return [Integer]
56
- define_bit_fields_on :flags, :critical, :hreserved, 7
54
+ define_attr :body, BinStruct::String
57
55
 
58
56
  def initialize(options={})
59
57
  super
60
58
  if options[:content]
61
- self[:content] = PacketGen::Types::String.new
59
+ self[:content] = BinStruct::String.new
62
60
  self[:content].read options[:content]
63
61
  end
64
62
  calc_length unless options[:length]
65
63
  end
66
64
 
67
- # Compute length and set {#length} field
68
- # @return [Integer] new length
65
+ # Compute length and set {#length} field
66
+ # @return [Integer] new length
69
67
  def calc_length
70
68
  # Here, #body is next payload, so body size should not be taken in
71
69
  # account (payload's real body is #content).
@@ -89,7 +87,7 @@ require_relative 'auth'
89
87
  require_relative 'ts'
90
88
  require_relative 'vendor_id'
91
89
 
92
- module PacketGen::Plugin
90
+ module PacketGen::Plugin # rubocop:disable Metrics/ModuleLength
93
91
  IKE.bind IKE::SA, next: IKE::SA::PAYLOAD_TYPE
94
92
  IKE::Payload.bind IKE::SA, next: IKE::SA::PAYLOAD_TYPE
95
93
  IKE::KE.bind IKE::SA, next: IKE::SA::PAYLOAD_TYPE
@@ -287,19 +285,19 @@ module PacketGen::Plugin
287
285
  IKE::TSr.bind IKE::VendorID, next: IKE::VendorID::PAYLOAD_TYPE
288
286
 
289
287
  # Last defined. To be used as default if no other may be parsed.
290
- IKE::SA.bind IKE::Payload, next: ->(v) { v > 0 }
291
- IKE::KE.bind IKE::Payload, next: ->(v) { v > 0 }
292
- IKE::Nonce.bind IKE::Payload, next: ->(v) { v > 0 }
293
- IKE::Notify.bind IKE::Payload, next: ->(v) { v > 0 }
294
- IKE::SK.bind IKE::Payload, next: ->(v) { v > 0 }
295
- IKE::IDi.bind IKE::Payload, next: ->(v) { v > 0 }
296
- IKE::IDr.bind IKE::Payload, next: ->(v) { v > 0 }
297
- IKE::Cert.bind IKE::Payload, next: ->(v) { v > 0 }
298
- IKE::CertReq.bind IKE::Payload, next: ->(v) { v > 0 }
299
- IKE::Auth.bind IKE::Payload, next: ->(v) { v > 0 }
300
- IKE::TSi.bind IKE::Payload, next: ->(v) { v > 0 }
301
- IKE::TSr.bind IKE::Payload, next: ->(v) { v > 0 }
302
- IKE::VendorID.bind IKE::Payload, next: ->(v) { v > 0 }
303
- IKE.bind IKE::Payload, next: ->(v) { v > 0 }
304
- IKE::Payload.bind IKE::Payload, next: ->(v) { v > 0 }
288
+ IKE::SA.bind IKE::Payload, next: lambda(&:positive?)
289
+ IKE::KE.bind IKE::Payload, next: lambda(&:positive?)
290
+ IKE::Nonce.bind IKE::Payload, next: lambda(&:positive?)
291
+ IKE::Notify.bind IKE::Payload, next: lambda(&:positive?)
292
+ IKE::SK.bind IKE::Payload, next: lambda(&:positive?)
293
+ IKE::IDi.bind IKE::Payload, next: lambda(&:positive?)
294
+ IKE::IDr.bind IKE::Payload, next: lambda(&:positive?)
295
+ IKE::Cert.bind IKE::Payload, next: lambda(&:positive?)
296
+ IKE::CertReq.bind IKE::Payload, next: lambda(&:positive?)
297
+ IKE::Auth.bind IKE::Payload, next: lambda(&:positive?)
298
+ IKE::TSi.bind IKE::Payload, next: lambda(&:positive?)
299
+ IKE::TSr.bind IKE::Payload, next: lambda(&:positive?)
300
+ IKE::VendorID.bind IKE::Payload, next: lambda(&:positive?)
301
+ IKE.bind IKE::Payload, next: lambda(&:positive?)
302
+ IKE::Payload.bind IKE::Payload, next: lambda(&:positive?)
305
303
  end
@@ -21,22 +21,22 @@ module PacketGen::Plugin
21
21
  # Such an attribute may have a TLV (Type/length/value) format if AF=0,
22
22
  # or a TV format (AF=1).
23
23
  # @author Sylvain Daubert
24
- class Attribute < PacketGen::Types::Fields
24
+ class Attribute < BinStruct::Struct
25
25
  # KeyLength attribute type
26
26
  TYPE_KEY_LENGTH = 14
27
27
 
28
28
  # @!attribute type
29
29
  # attribute type
30
30
  # @return [Integer]
31
- define_field :type, PacketGen::Types::Int16
31
+ define_attr :type, BinStruct::Int16
32
32
  # @!attribute length
33
33
  # attribute length
34
34
  # @return [Integer]
35
- define_field :length, PacketGen::Types::Int16
35
+ define_attr :length, BinStruct::Int16
36
36
  # @!attribute value
37
37
  # attribute value
38
38
  # @return [Integer]
39
- define_field :value, PacketGen::Types::Int32, optional: ->(h) { !h.tv_format? }
39
+ define_attr :value, BinStruct::Int32, optional: ->(h) { !h.tv_format? }
40
40
 
41
41
  def initialize(options={})
42
42
  super
@@ -64,7 +64,7 @@ module PacketGen::Plugin
64
64
  def to_human
65
65
  name = self.class.constants.grep(/TYPE_/)
66
66
  .detect { |c| self.class.const_get(c) == (type & 0x7fff) } || "attr[#{type & 0x7fff}]"
67
- name = name.to_s.sub(/TYPE_/, '')
67
+ name = name.to_s.sub('TYPE_', '')
68
68
  "#{name}=#{value}"
69
69
  end
70
70
 
@@ -77,7 +77,7 @@ module PacketGen::Plugin
77
77
 
78
78
  # Set of {Attribute} in a {Transform}
79
79
  # @author Sylvain Daubert
80
- class Attributes < PacketGen::Types::Array
80
+ class Attributes < BinStruct::Array
81
81
  set_of Attribute
82
82
  end
83
83
 
@@ -102,11 +102,11 @@ module PacketGen::Plugin
102
102
  # == Add attributes to a transform
103
103
  # # using an Attribute object
104
104
  # attr = PacketGen::Plugin::IKE::Attribute.new(type: 14, value: 128)
105
- # trans.attributes << attr
105
+ # trans.tattributes << attr
106
106
  # # using a hash
107
- # trans.attributes << { type: 14, value: 128 }
107
+ # trans.tattributes << { type: 14, value: 128 }
108
108
  # @author Sylvain Daubert
109
- class Transform < PacketGen::Types::Fields
109
+ class Transform < BinStruct::Struct
110
110
  # Transform types
111
111
  TYPES = {
112
112
  'ENCR' => 1,
@@ -253,33 +253,33 @@ module PacketGen::Plugin
253
253
  # if this was the last Transform Substructure, and a value of 3 if
254
254
  # there are more Transform Substructures.
255
255
  # @return [Integer]
256
- define_field :last, PacketGen::Types::Int8
256
+ define_attr :last, BinStruct::Int8
257
257
  # @!attribute rsv1
258
258
  # 8-bit reserved field
259
259
  # @return [Integer]
260
- define_field :rsv1, PacketGen::Types::Int8
260
+ define_attr :rsv1, BinStruct::Int8
261
261
  # @!attribute length
262
262
  # 16-bit transform length
263
263
  # @return [Integer]
264
- define_field :length, PacketGen::Types::Int16
264
+ define_attr :length, BinStruct::Int16
265
265
  # @!attribute [r] type
266
266
  # 8-bit transform type. The Transform Type is the cryptographic
267
267
  # algorithm type (i.e. encryption, PRF, integrity, etc.)
268
268
  # @return [Integer]
269
- define_field :type, PacketGen::Types::Int8Enum, enum: TYPES
269
+ define_attr :type, BinStruct::Int8Enum, enum: TYPES
270
270
  # @!attribute rsv2
271
271
  # 8-bit reserved field
272
272
  # @return [Integer]
273
- define_field :rsv2, PacketGen::Types::Int8
273
+ define_attr :rsv2, BinStruct::Int8
274
274
  # @!attribute [r] id
275
275
  # 16-bit transform ID. The Transform ID is the specific instance of
276
276
  # the proposed transform type.
277
277
  # @return [Integer]
278
- define_field :id, PacketGen::Types::Int16
279
- # @!attribute attributes
278
+ define_attr :id, BinStruct::Int16
279
+ # @!attribute tattributes
280
280
  # Set of attributes for this transform
281
281
  # @return [Attributes]
282
- define_field :attributes, Attributes, builder: ->(h, t) { t.new(length_from: -> { h.length - h.offset_of(:attributes) }) }
282
+ define_attr :tattributes, Attributes, builder: ->(h, t) { t.new(length_from: -> { h.length - h.offset_of(:tattributes) }) }
283
283
 
284
284
  def initialize(options={})
285
285
  super
@@ -315,8 +315,8 @@ module PacketGen::Plugin
315
315
  # Get a human readable string
316
316
  # @return [String]
317
317
  def to_human
318
- h = +"#{human_type}(#{human_id}"
319
- h << ",#{attributes.to_human}" unless attributes.empty?
318
+ h = "#{human_type}(#{human_id}"
319
+ h << ",#{tattributes.to_human}" unless tattributes.empty?
320
320
 
321
321
  h << ')'
322
322
  end
@@ -353,11 +353,11 @@ module PacketGen::Plugin
353
353
 
354
354
  # Set of {Transform} in a {SAProposal}
355
355
  # @author Sylvain Daubert
356
- class Transforms < PacketGen::Types::Array
356
+ class Transforms < BinStruct::Array
357
357
  set_of Transform
358
358
 
359
- # Same as {PacketGen::Types::Array#push} but update previous {Transform#last} attribute
360
- # @see PacketGen::Types::Array#push
359
+ # Same as {BinStruct::Array#push} but update previous {Transform#last} attribute
360
+ # @see BinStruct::Array#push
361
361
  def push(trans)
362
362
  super
363
363
  self[-2].last = 3 if size > 1
@@ -393,22 +393,22 @@ module PacketGen::Plugin
393
393
  # # using a hash
394
394
  # proposal.transforms << { type: 'ENCR', id: '3DES' }
395
395
  # @author Sylvain Daubert
396
- class SAProposal < PacketGen::Types::Fields
396
+ class SAProposal < BinStruct::Struct
397
397
  # @!attribute last
398
398
  # 8-bit last substructure. Specifies whether or not this is the
399
399
  # last Proposal Substructure in the SA. This field has a value of 0
400
400
  # if this was the last Proposal Substructure, and a value of 2 if
401
401
  # there are more Proposal Substructures.
402
402
  # @return [Integer]
403
- define_field :last, PacketGen::Types::Int8
403
+ define_attr :last, BinStruct::Int8
404
404
  # @!attribute reserved
405
405
  # 8-bit reserved field
406
406
  # @return [Integer]
407
- define_field :reserved, PacketGen::Types::Int8
407
+ define_attr :reserved, BinStruct::Int8
408
408
  # @!attribute length
409
409
  # 16-bit proposal length
410
410
  # @return [Integer]
411
- define_field :length, PacketGen::Types::Int16
411
+ define_attr :length, BinStruct::Int16
412
412
  # @!attribute num
413
413
  # 8-bit proposal number. When a proposal is made, the first
414
414
  # proposal in an SA payload MUST be 1, and subsequent proposals MUST
@@ -417,30 +417,30 @@ module PacketGen::Plugin
417
417
  # in the SA payload MUST match the number on the proposal sent that
418
418
  # was accepted.
419
419
  # @return [Integer]
420
- define_field :num, PacketGen::Types::Int8, default: 1
420
+ define_attr :num, BinStruct::Int8, default: 1
421
421
  # @!attribute [r] protocol
422
422
  # 8-bit protocol ID. Specify IPsec protocol currently negociated.
423
423
  # May 1 (IKE), 2 (AH) or 3 (ESP).
424
424
  # @return [Integer]
425
- define_field :protocol, PacketGen::Types::Int8Enum, enum: PROTOCOLS
425
+ define_attr :protocol, BinStruct::Int8Enum, enum: PROTOCOLS
426
426
  # @!attribute spi_size
427
427
  # 8-bit SPI size. Give size of SPI field. Set to 0 for an initial IKE SA
428
428
  # negotiation, as SPI is obtained from outer Plugin.
429
429
  # @return [Integer]
430
- define_field :spi_size, PacketGen::Types::Int8, default: 0
430
+ define_attr :spi_size, BinStruct::Int8, default: 0
431
431
  # @!attribute num_trans
432
432
  # 8-bit number of transformations
433
433
  # @return [Integer]
434
- define_field :num_trans, PacketGen::Types::Int8, default: 0
434
+ define_attr :num_trans, BinStruct::Int8, default: 0
435
435
  # @!attribute spi
436
436
  # the sending entity's SPI. When the {#spi_size} field is zero,
437
437
  # this field is not present in the proposal.
438
438
  # @return [String]
439
- define_field :spi, PacketGen::Types::String, builder: ->(h, t) { t.new(length_from: h[:spi_size]) }
439
+ define_attr :spi, BinStruct::String, builder: ->(h, t) { t.new(length_from: h[:spi_size]) }
440
440
  # @!attribute transforms
441
441
  # 8-bit set of tranforms for this proposal
442
442
  # @return [Transforms]
443
- define_field :transforms, Transforms, builder: ->(h, t) { t.new(counter: h[:num_trans]) }
443
+ define_attr :transforms, Transforms, builder: ->(h, t) { t.new(counter: h[:num_trans]) }
444
444
 
445
445
  def initialize(options={})
446
446
  options[:spi_size] = options[:spi].size if options[:spi] && options[:spi_size].nil?
@@ -459,12 +459,12 @@ module PacketGen::Plugin
459
459
  # Get a human readable string
460
460
  # @return [String]
461
461
  def to_human
462
- str = +"##{num} #{human_protocol}"
462
+ str = "##{num} #{human_protocol}"
463
463
  case spi_size
464
464
  when 4
465
- str << '(spi:0x%08x)' % PacketGen::Types::Int32.new.read(spi).to_i
465
+ str << ('(spi:0x%08x)' % BinStruct::Int32.new.read(spi).to_i)
466
466
  when 8
467
- str << '(spi:0x%016x)' % PacketGen::Types::Int64.new.read(spi).to_i
467
+ str << ('(spi:0x%016x)' % BinStruct::Int64.new.read(spi).to_i)
468
468
  end
469
469
  str << ":#{transforms.to_human}"
470
470
  end
@@ -490,14 +490,14 @@ module PacketGen::Plugin
490
490
 
491
491
  # Set of {SAProposal}
492
492
  # @author Sylvain Daubert
493
- class SAProposals < PacketGen::Types::Array
493
+ class SAProposals < BinStruct::Array
494
494
  set_of SAProposal
495
495
 
496
496
  # Separator used between proposals in {#to_human}
497
497
  HUMAN_SEPARATOR = '; '
498
498
 
499
- # Same as {PacketGen::Types::Array#push} but update previous {SAProposal#last} attribute
500
- # @see PacketGen::Types::Array#push
499
+ # Same as {BinStruct::Array#push} but update previous {SAProposal#last} attribute
500
+ # @see BinStruct::Array#push
501
501
  def push(prop)
502
502
  super
503
503
  self[-2].last = 2 if size > 1
@@ -530,19 +530,19 @@ module PacketGen::Plugin
530
530
  # # ID is taken from Transform::<TYPE>_* constants.
531
531
  # pkt.ike_sa.proposals.first.transforms << { type: 'ENCR', id: 'AES_CTR' }
532
532
  # # and finally, add an attribute to this transform (here, KEY_SIZE = 128 bits)
533
- # pkt.ike_sa.proposals[0].transforms[0].attributes << { type: 0x800e, value: 128 }
533
+ # pkt.ike_sa.proposals[0].transforms[0].tattributes << { type: 0x800e, value: 128 }
534
534
  # pkt.calc_length
535
535
  # @author Sylvain Daubert
536
536
  class SA < Payload
537
537
  # Payload type number
538
538
  PAYLOAD_TYPE = 33
539
539
 
540
- remove_field :content
540
+ remove_attr :content
541
541
 
542
542
  # @!attribute proposals
543
543
  # Set of SA proposals
544
544
  # @return [SAProposals]
545
- define_field_before :body, :proposals, SAProposals, builder: ->(h, t) { t.new(length_from: -> { h.length - h.offset_of(:proposals) }) }
545
+ define_attr_before :body, :proposals, SAProposals, builder: ->(h, t) { t.new(length_from: -> { h.length - h.offset_of(:proposals) }) }
546
546
 
547
547
  # Compute length and set {#length} field
548
548
  # @return [Integer] new length