packetgen 2.8.7 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -1
  3. data/README.md +5 -4
  4. data/lib/packetgen.rb +6 -12
  5. data/lib/packetgen/capture.rb +43 -39
  6. data/lib/packetgen/config.rb +0 -1
  7. data/lib/packetgen/deprecation.rb +1 -1
  8. data/lib/packetgen/header.rb +9 -9
  9. data/lib/packetgen/header/asn1_base.rb +10 -10
  10. data/lib/packetgen/header/base.rb +42 -101
  11. data/lib/packetgen/header/dhcp/option.rb +5 -11
  12. data/lib/packetgen/header/dhcpv6/duid.rb +2 -0
  13. data/lib/packetgen/header/dhcpv6/option.rb +2 -19
  14. data/lib/packetgen/header/dhcpv6/options.rb +7 -0
  15. data/lib/packetgen/header/dns.rb +5 -23
  16. data/lib/packetgen/header/dns/name.rb +1 -0
  17. data/lib/packetgen/header/dns/qdsection.rb +1 -0
  18. data/lib/packetgen/header/dns/question.rb +3 -7
  19. data/lib/packetgen/header/dns/rr.rb +3 -0
  20. data/lib/packetgen/header/dns/rrsection.rb +1 -0
  21. data/lib/packetgen/header/dot11.rb +1 -17
  22. data/lib/packetgen/header/dot1x.rb +1 -0
  23. data/lib/packetgen/header/eap.rb +4 -7
  24. data/lib/packetgen/header/eth.rb +2 -0
  25. data/lib/packetgen/header/http/headers.rb +3 -0
  26. data/lib/packetgen/header/http/request.rb +5 -4
  27. data/lib/packetgen/header/http/response.rb +5 -4
  28. data/lib/packetgen/header/icmp.rb +6 -0
  29. data/lib/packetgen/header/icmpv6.rb +6 -0
  30. data/lib/packetgen/header/igmpv3/mq.rb +2 -0
  31. data/lib/packetgen/header/ip.rb +32 -30
  32. data/lib/packetgen/header/ip/addr.rb +1 -0
  33. data/lib/packetgen/header/ip/option.rb +23 -20
  34. data/lib/packetgen/header/ip/options.rb +11 -24
  35. data/lib/packetgen/header/ipv6.rb +45 -34
  36. data/lib/packetgen/header/ipv6/addr.rb +2 -0
  37. data/lib/packetgen/header/ipv6/hop_by_hop.rb +7 -31
  38. data/lib/packetgen/header/mdns.rb +1 -0
  39. data/lib/packetgen/header/mldv2/mlq.rb +2 -0
  40. data/lib/packetgen/header/ospfv2/lsa.rb +15 -25
  41. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +1 -1
  42. data/lib/packetgen/header/ospfv3/lsa.rb +8 -25
  43. data/lib/packetgen/header/snmp.rb +2 -0
  44. data/lib/packetgen/header/tcp.rb +23 -2
  45. data/lib/packetgen/header/tcp/option.rb +51 -52
  46. data/lib/packetgen/header/tcp/options.rb +17 -52
  47. data/lib/packetgen/header/tftp.rb +3 -0
  48. data/lib/packetgen/header/udp.rb +8 -0
  49. data/lib/packetgen/packet.rb +119 -102
  50. data/lib/packetgen/pcapng/block.rb +4 -10
  51. data/lib/packetgen/pcapng/epb.rb +4 -4
  52. data/lib/packetgen/pcapng/file.rb +7 -3
  53. data/lib/packetgen/pcapng/idb.rb +2 -2
  54. data/lib/packetgen/pcapng/shb.rb +3 -3
  55. data/lib/packetgen/pcapng/spb.rb +1 -8
  56. data/lib/packetgen/pcapng/unknown_block.rb +0 -7
  57. data/lib/packetgen/types.rb +1 -0
  58. data/lib/packetgen/types/array.rb +73 -71
  59. data/lib/packetgen/types/cstring.rb +1 -1
  60. data/lib/packetgen/types/enum.rb +3 -3
  61. data/lib/packetgen/types/fields.rb +66 -106
  62. data/lib/packetgen/types/int.rb +9 -5
  63. data/lib/packetgen/types/length_from.rb +45 -0
  64. data/lib/packetgen/types/oui.rb +2 -0
  65. data/lib/packetgen/types/string.rb +10 -16
  66. data/lib/packetgen/types/tlv.rb +7 -15
  67. data/lib/packetgen/utils.rb +8 -8
  68. data/lib/packetgen/utils/arp_spoofer.rb +1 -2
  69. data/lib/packetgen/version.rb +1 -1
  70. metadata +3 -21
  71. data/lib/packetgen/header/crypto.rb +0 -62
  72. data/lib/packetgen/header/esp.rb +0 -413
  73. data/lib/packetgen/header/ike.rb +0 -243
  74. data/lib/packetgen/header/ike/auth.rb +0 -165
  75. data/lib/packetgen/header/ike/cert.rb +0 -76
  76. data/lib/packetgen/header/ike/certreq.rb +0 -66
  77. data/lib/packetgen/header/ike/id.rb +0 -99
  78. data/lib/packetgen/header/ike/ke.rb +0 -79
  79. data/lib/packetgen/header/ike/nonce.rb +0 -40
  80. data/lib/packetgen/header/ike/notify.rb +0 -176
  81. data/lib/packetgen/header/ike/payload.rb +0 -315
  82. data/lib/packetgen/header/ike/sa.rb +0 -561
  83. data/lib/packetgen/header/ike/sk.rb +0 -261
  84. data/lib/packetgen/header/ike/ts.rb +0 -270
  85. data/lib/packetgen/header/ike/vendor_id.rb +0 -39
  86. data/lib/packetgen/header/netbios.rb +0 -20
  87. data/lib/packetgen/header/netbios/datagram.rb +0 -105
  88. data/lib/packetgen/header/netbios/name.rb +0 -67
  89. data/lib/packetgen/header/netbios/session.rb +0 -64
@@ -1,261 +0,0 @@
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 Header
11
- class IKE
12
- # This class handles encrypted payloads, denoted SK.
13
- #
14
- # The encrypted payload contains other payloads in encrypted form.
15
- # The Encrypted payload consists of the IKE generic payload header followed
16
- # by individual fields as follows:
17
- # 1 2 3
18
- # 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
19
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20
- # | Next Payload |C| RESERVED | Payload Length |
21
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22
- # | Initialization Vector |
23
- # | (length is block size for encryption algorithm) |
24
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25
- # ~ Encrypted IKE Payloads ~
26
- # + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
- # | | Padding (0-255 octets) |
28
- # +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
29
- # | | Pad Length |
30
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31
- # ~ Integrity Checksum Data ~
32
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33
- # Encrypted payloads are set in {#content} field, as a {Types::String}.
34
- # All others fields are only set when decrypting a previously read SK
35
- # payload. They also may be set manually to encrypt IKE payloads.
36
- #
37
- # == Read and decrypt a SK payload
38
- # # Read a IKE packet
39
- # pkt = PacketGen.read(str)
40
- # # decrypt SK payload
41
- # cipher = OpenSSL::Cipher.new('aes-128-ctr')
42
- # cipher.decrypt
43
- # cipher_key = aes_key
44
- # hmac = OpenSSL::HMAC.new(hmac_key, OpenSSL::Digest::SHA256.new)
45
- # pkt.ike_sk.decrypt! cipher, intmode: hmac, icv_length: 16 # => true if authentication is verified
46
- # pkt.ike_sk.body # => kind of PacketGen::Header::IKE::Payload
47
- #
48
- # == Set and encrypt a SK payload
49
- # # Create a IKE packet
50
- # pkt = PacketGen.gen('IP').add('IP').add('UDP').add('IKE', init_spi: 0x123456789, resp_spi: 0x987654321, type: 'IKE_AUTH', message_id: 1)
51
- # # Add SK payload
52
- # pkt.add('IKE::SK', icv_length: 16)
53
- # # Add others unencrypted payloads
54
- # pkt.add('IKE::IDi').add('IKE::Auth').add('IKE::SA').add('IKE::TSi').add('IKE::TSr')
55
- # # encrypt SK payload
56
- # cipher = OpenSSL::Cipher.new('aes-128-ctr')
57
- # cipher.encrypt
58
- # cipher_key = aes_key
59
- # hmac = OpenSSL::HMAC.new(hmac_key, OpenSSL::Digest::SHA256.new)
60
- # pkt.ike_sk.encrypt! cipher, iv, salt: salt, intmode: hmac
61
- # pkt.ike_sk.body # => String
62
- # pkt.calc_length
63
- #
64
- # @author Sylvain Daubert
65
- class SK < Payload
66
- include Crypto
67
-
68
- # Payload type number
69
- PAYLOAD_TYPE = 46
70
-
71
- # ICV (Integrity Check Value) length
72
- # @return [Integer]
73
- attr_accessor :icv_length
74
-
75
- # @param [Hash] options
76
- # @option options [Integer] :icv_length ICV length
77
- def initialize(options={})
78
- @icv_length = options[:icv_length] || 0
79
- super
80
- end
81
-
82
- # Decrypt in-place SK payload.
83
- # @param [OpenSSL::Cipher] cipher keyed cipher
84
- # This cipher is confidentiality-only one, or AEAD one. To use a second
85
- # cipher to add integrity, use +:intmode+ option.
86
- # @param [Hash] options
87
- # @option options [Boolean] :parse parse deciphered payload to retrieve
88
- # headers (default: +true+)
89
- # @option options [Fixnum] :icv_length ICV length for captured packets,
90
- # or read from PCapNG files
91
- # @option options [String] :salt salt value for CTR and GCM modes
92
- # @option options [OpenSSL::HMAC] :intmode integrity mode to use with a
93
- # confidentiality-only cipher. Only HMAC are supported.
94
- # @return [Boolean] +true+ if SK payload is authenticated
95
- def decrypt!(cipher, options={})
96
- opt = { salt: '', parse: true }.merge!(options)
97
-
98
- set_crypto cipher, opt[:intmode]
99
-
100
- case confidentiality_mode
101
- when 'gcm'
102
- iv = self.content.slice!(0, 8)
103
- real_iv = force_binary(opt[:salt]) + iv
104
- when 'cbc'
105
- cipher.padding = 0
106
- real_iv = iv = self.content.slice!(0, 16)
107
- when 'ctr'
108
- iv = self.content.slice!(0, 8)
109
- real_iv = force_binary(opt[:salt]) + iv + [1].pack('N')
110
- else
111
- real_iv = iv = self.content.slice!(0, 16)
112
- end
113
- cipher.iv = real_iv
114
-
115
- if authenticated?
116
- if @icv_length.zero?
117
- @icv_length = opt[:icv_length].to_i if opt[:icv_length]
118
- raise ParseError, 'unknown ICV size' if @icv_length.zero?
119
- end
120
- icv = self.content.slice!(-@icv_length, @icv_length)
121
- end
122
-
123
- authenticate_if_needed iv, icv
124
- private_decrypt opt
125
- end
126
-
127
- # Encrypt in-place SK payload.
128
- # @param [OpenSSL::Cipher] cipher keyed cipher
129
- # This cipher is confidentiality-only one, or AEAD one. To use a second
130
- # cipher to add integrity, use +:intmode+ option.
131
- # @param [String] iv IV to encipher SK payload content
132
- # * CTR and GCM modes: +iv+ is 8-bytes long.
133
- # @param [Hash] options
134
- # @option options [Fixnum] :icv_length ICV length for captured packets,
135
- # or read from PCapNG files
136
- # @option options [String] :salt salt value for CTR and GCM modes
137
- # @option options [Fixnum] :pad_length set a padding length
138
- # @option options [String] :padding set a padding. No check with
139
- # +:pad_length+ is made. If +:pad_length+ is not set, +:padding+
140
- # length is shortened to correct padding length
141
- # @option options [OpenSSL::HMAC] :intmode integrity mode to use with a
142
- # confidentiality-only cipher. Only HMAC are supported.
143
- # @return [self]
144
- def encrypt!(cipher, iv, options={})
145
- opt = { salt: '' }.merge!(options)
146
-
147
- set_crypto cipher, opt[:intmode]
148
-
149
- real_iv = force_binary(opt[:salt]) + force_binary(iv)
150
- real_iv += [1].pack('N') if confidentiality_mode == 'ctr'
151
- cipher.iv = real_iv
152
-
153
- authenticate_if_needed iv
154
-
155
- if opt[:pad_length]
156
- pad_length = opt[:pad_length]
157
- padding = force_binary(opt[:padding] || ([0] * pad_length).pack('C*'))
158
- else
159
- pad_length = cipher.block_size
160
- pad_length = 16 if cipher.block_size == 1 # Some AES mode returns 1...
161
- pad_length -= (self.body.sz + iv.size + 1) % cipher.block_size
162
- pad_length = 0 if pad_length == 16
163
- padding = force_binary(opt[:padding] || ([0] * pad_length).pack('C*'))
164
- padding = padding[0, pad_length]
165
- end
166
- msg = self.body.to_s + padding + Types::Int8.new(pad_length).to_s
167
- encrypted_msg = encipher(msg)
168
- cipher.final # message is already padded. No need for mode padding
169
-
170
- if authenticated?
171
- @icv_length = opt[:icv_length] if opt[:icv_length]
172
- encrypted_msg << if @conf.authenticated?
173
- @conf.auth_tag[0, @icv_length]
174
- else
175
- @intg.digest[0, @icv_length]
176
- end
177
- end
178
- self[:content].read(iv + encrypted_msg)
179
-
180
- # Remove plain payloads
181
- self[:body] = Types::String.new
182
-
183
- # Remove enciphered payloads from packet
184
- id = header_id(self)
185
- if id < packet.headers.size - 1
186
- (packet.headers.size - 1).downto(id + 1) do |index|
187
- packet.headers.delete_at index
188
- end
189
- end
190
-
191
- self.calc_length
192
- self
193
- end
194
-
195
- private
196
-
197
- def authenticate_if_needed(iv, icv=nil)
198
- if @conf.authenticated?
199
- @conf.auth_tag = icv if icv
200
- @conf.auth_data = get_ad
201
- elsif @intg
202
- @intg.reset
203
- @intg.update get_ad
204
- @intg.update iv
205
- @icv = icv
206
- else
207
- @icv = nil
208
- end
209
- end
210
-
211
- # From RFC 7206, §5.1: The associated data MUST consist of the partial
212
- # contents of the IKEv2 message, starting from the first octet of the
213
- # Fixed IKE Header through the last octet of the Payload Header of the
214
- # Encrypted Payload (i.e., the fourth octet of the Encrypted Payload).
215
- def get_ad
216
- str = packet.ike.to_s[0, IKE.new.sz]
217
- current_payload = packet.ike.body
218
- until current_payload.is_a? SK
219
- str << current_payload.to_s[0, current_payload.length]
220
- current_payload = current_payload.body
221
- end
222
- str << self.to_s[0, SK.new.sz]
223
- end
224
-
225
- def private_decrypt(options)
226
- # decrypt
227
- plain_msg = decipher(content.to_s)
228
- # Remove cipher text
229
- self.content.read ''
230
-
231
- # check authentication tag
232
- if authenticated?
233
- return false unless authenticate!
234
- end
235
-
236
- # remove padding
237
- pad_len = Types::Int8.new.read(plain_msg[-1]).to_i
238
- payloads = plain_msg[0, plain_msg.size - 1 - pad_len]
239
-
240
- # parse IKE payloads
241
- if options[:parse]
242
- klass = IKE.constants.select do |c|
243
- cst = IKE.const_get(c)
244
- cst.is_a?(Class) && (cst < Payload) && (cst::PAYLOAD_TYPE == self.next)
245
- end
246
- klass = klass.nil? ? Payload : IKE.const_get(klass.first)
247
- firsth = klass.protocol_name
248
- pkt = Packet.parse(payloads, first_header: firsth)
249
- packet.encapsulate(pkt, parsing: true) unless pkt.nil?
250
- else
251
- self[:body].read payloads
252
- end
253
-
254
- true
255
- end
256
- end
257
- end
258
-
259
- self.add_class IKE::SK
260
- end
261
- end
@@ -1,270 +0,0 @@
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 Header
11
- class IKE
12
- # TrafficSelector substructure, as defined in RFC 7296, §3.13.1:
13
- # 1 2 3
14
- # 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
15
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16
- # | TS Type |IP Protocol ID*| Selector Length |
17
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18
- # | Start Port* | End Port* |
19
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20
- # | |
21
- # ~ Starting Address* ~
22
- # | |
23
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24
- # | |
25
- # ~ Ending Address* ~
26
- # | |
27
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28
- # @author Sylvain Daubert
29
- class TrafficSelector < Types::Fields
30
- # IPv4 traffic selector type
31
- TS_IPV4_ADDR_RANGE = 7
32
- # IPv6 traffic selector type
33
- TS_IPV6_ADDR_RANGE = 8
34
-
35
- # @!attribute [r] type
36
- # 8-bit TS type
37
- # @return [Integer]
38
- define_field :type, Types::Int8, default: 7
39
- # @!attribute [r] protocol
40
- # 8-bit protocol ID
41
- # @return [Integer]
42
- define_field :protocol, Types::Int8, default: 0
43
- # @!attribute length
44
- # 16-bit Selector Length
45
- # @return [Integer]
46
- define_field :length, Types::Int16
47
- # @!attribute start_port
48
- # 16-bit Start port
49
- # @return [Integer]
50
- define_field :start_port, Types::Int16, default: 0
51
- # @!attribute end_port
52
- # 16-bit End port
53
- # @return [Integer]
54
- define_field :end_port, Types::Int16, default: 65_535
55
- # @!attribute start_addr
56
- # starting address
57
- # @return [IP::Addr, IPv6::Addr]
58
- define_field :start_addr, IP::Addr
59
- # @!attribute end_addr
60
- # starting address
61
- # @return [IP::Addr, IPv6::Addr]
62
- define_field :end_addr, IP::Addr
63
-
64
- # @param [Hash] options
65
- # @option [Range] :ports port range
66
- # @option [Integer] :start_port start port
67
- # @option [Integer] :end_port end port
68
- def initialize(options={})
69
- super
70
- select_addr options
71
- self[:start_addr].from_human(options[:start_addr]) if options[:start_addr]
72
- self[:end_addr].from_human(options[:end_addr]) if options[:end_addr]
73
- self[:length].value = sz unless options[:length]
74
- self.type = options[:type] if options[:type]
75
- self.protocol = options[:protocol] if options[:protocol]
76
-
77
- return unless options[:ports]
78
- self.start_port = options[:ports].begin
79
- self.end_port = options[:ports].end
80
- end
81
-
82
- # Populate object from a string
83
- # @param [String] str
84
- # @return [self]
85
- def read(str)
86
- super
87
- select_addr_from_type type
88
- super
89
- end
90
-
91
- # Set type
92
- # @param [Integer,String] value
93
- # @return [Integer]
94
- def type=(value)
95
- type = case value
96
- when Integer
97
- value
98
- else
99
- c = self.class.constants.grep(/TS_#{value.upcase}/).first
100
- c ? self.class.const_get(c) : nil
101
- end
102
- raise ArgumentError, "unknown type #{value.inspect}" unless type
103
- select_addr_from_type type
104
- self[:type].value = type
105
- end
106
-
107
- # Set protocol
108
- # @param [Integer,String] value
109
- # @return [Integer]
110
- def protocol=(value)
111
- protocol = case value
112
- when Integer
113
- value
114
- else
115
- Proto.getprotobyname(value)
116
- end
117
- raise ArgumentError, "unknown protocol #{value.inspect}" unless protocol
118
- self[:protocol].value = protocol
119
- end
120
-
121
- # Get a human readable string
122
- # @return [String]
123
- def to_human
124
- h = start_addr << '-' << end_addr
125
- unless human_protocol.empty?
126
- h << "/#{human_protocol}"
127
- h << "[#{start_port}-#{end_port}]" if (start_port..end_port) != (0..65_535)
128
- end
129
- h
130
- end
131
-
132
- # Get human readable protocol name. If protocol ID is 0, an empty string
133
- # is returned.
134
- # @return [String]
135
- def human_protocol
136
- if protocol.zero?
137
- ''
138
- else
139
- Proto.getprotobynumber(protocol) || protocol.to_s
140
- end
141
- end
142
-
143
- # Get human readable TS type
144
- # @return [String]
145
- def human_type
146
- case type
147
- when TS_IPV4_ADDR_RANGE
148
- 'IPv4'
149
- when TS_IPV6_ADDR_RANGE
150
- 'IPv6'
151
- else
152
- "type #{type}"
153
- end
154
- end
155
-
156
- private
157
-
158
- def select_addr_from_type(type)
159
- case type
160
- when TS_IPV4_ADDR_RANGE, 'IPV4', 'IPv4', 'ipv4', nil
161
- self[:start_addr] = IP::Addr.new unless self[:start_addr].is_a?(IP::Addr)
162
- self[:end_addr] = IP::Addr.new unless self[:end_addr].is_a?(IP::Addr)
163
- when TS_IPV6_ADDR_RANGE, 'IPV6', 'IPv6', 'ipv6'
164
- self[:start_addr] = IPv6::Addr.new unless self[:start_addr].is_a?(IPv6::Addr)
165
- self[:end_addr] = IPv6::Addr.new unless self[:end_addr].is_a?(IPv6::Addr)
166
- else
167
- raise ArgumentError, "unknown type #{type}"
168
- end
169
- end
170
-
171
- def select_addr(options)
172
- if options[:type]
173
- select_addr_from_type options[:type]
174
- elsif options[:start_addr]
175
- ipv4 = IPAddr.new(options[:start_addr]).ipv4?
176
- self.type = ipv4 ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE
177
- elsif options[:end_addr]
178
- ipv4 = IPAddr.new(options[:end_addr]).ipv4?
179
- self.type = ipv4 ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE
180
- end
181
- end
182
- end
183
-
184
- # Set of {TrafficSelector}, used by {TSi} and {TSr}.
185
- # @author Sylvain Daubert
186
- class TrafficSelectors < Types::Array
187
- set_of TrafficSelector
188
- end
189
-
190
- # This class handles Traffic Selector - Initiator payloads, denoted TSi.
191
- #
192
- # A TSi payload consists of the IKE generic payload header (see {Payload})
193
- # and some specific fields:
194
- # 1 2 3
195
- # 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
196
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
197
- # | Next Payload |C| RESERVED | Payload Length |
198
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199
- # | Number of TSs | RESERVED |
200
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
201
- # | |
202
- # ~ <Traffic Selectors> ~
203
- # | |
204
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
205
- # These specific fields are:
206
- # * {#num_ts},
207
- # * {#rsv1},
208
- # * {#rsv2},
209
- # * and {#traffic_selectors}.
210
- #
211
- # == Create a TSi payload
212
- # # Create a IKE packet with a TSi payload
213
- # pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::TSi')
214
- # # add a traffic selector to this payload
215
- # pkt.ike_tsi.traffic_selectors << { protocol: 'tcp', ports: 1..1024, start_addr: '20.0.0.1', end_addr: '21.255.255.254' }
216
- # # add another traffic selector (IPv6, all protocols)
217
- # pkt.ike_tsi.traffic_selectors << { start_addr: '2001::1', end_addr: '200a:ffff:ffff:ffff:ffff:ffff:ffff:ffff' }
218
- # @author Sylvain Daubert
219
- class TSi < Payload
220
- # Payload type number
221
- PAYLOAD_TYPE = 44
222
-
223
- remove_field :content
224
-
225
- # @!attribute num_ts
226
- # 8-bit Number of TSs
227
- # @return [Integer]
228
- define_field_before :body, :num_ts, Types::Int8
229
- # @!attribute rsv
230
- # 24-bit RESERVED field
231
- # @return [Integer]
232
- define_field_before :body, :rsv, Types::Int24
233
-
234
- # @!attribute traffic_selectors
235
- # Set of {TrafficSelector}
236
- # @return {TrafficSelectors}
237
- define_field_before :body, :traffic_selectors, TrafficSelectors,
238
- builder: ->(h, t) { t.new(counter: h[:num_ts]) }
239
- alias selectors traffic_selectors
240
-
241
- # Populate object from a string
242
- # @param [String] str
243
- # @return [self]
244
- def read(str)
245
- super(str[0, 8])
246
- hlen = self.class.new.sz
247
- tslen = length - hlen
248
- selectors.read str[hlen, tslen]
249
- body.read str[hlen + tslen..-1]
250
- self
251
- end
252
-
253
- # Compute length and set {#length} field
254
- # @return [Integer] new length
255
- def calc_length
256
- selectors.each(&:calc_length)
257
- super
258
- end
259
- end
260
-
261
- class TSr < TSi
262
- # Payload type number
263
- PAYLOAD_TYPE = 45
264
- end
265
- end
266
-
267
- self.add_class IKE::TSi
268
- self.add_class IKE::TSr
269
- end
270
- end