packetgen 3.3.0 → 3.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -0
- data/README.md +7 -7
- data/lib/packetgen/capture.rb +2 -1
- data/lib/packetgen/config.rb +2 -1
- data/lib/packetgen/header/arp.rb +2 -1
- data/lib/packetgen/header/asn1_base.rb +2 -1
- data/lib/packetgen/header/base.rb +4 -3
- data/lib/packetgen/header/bootp.rb +2 -1
- data/lib/packetgen/header/dhcp/option.rb +2 -1
- data/lib/packetgen/header/dhcp/options.rb +2 -1
- data/lib/packetgen/header/dhcp.rb +2 -1
- data/lib/packetgen/header/dhcpv6/duid.rb +2 -1
- data/lib/packetgen/header/dhcpv6/option.rb +2 -1
- data/lib/packetgen/header/dhcpv6/options.rb +2 -1
- data/lib/packetgen/header/dhcpv6/relay.rb +2 -1
- data/lib/packetgen/header/dhcpv6.rb +2 -1
- data/lib/packetgen/header/dns/name.rb +2 -1
- data/lib/packetgen/header/dns/opt.rb +3 -2
- data/lib/packetgen/header/dns/option.rb +3 -2
- data/lib/packetgen/header/dns/qdsection.rb +2 -1
- data/lib/packetgen/header/dns/question.rb +2 -1
- data/lib/packetgen/header/dns/rr.rb +2 -1
- data/lib/packetgen/header/dns/rrsection.rb +2 -1
- data/lib/packetgen/header/dns.rb +3 -2
- data/lib/packetgen/header/dot11/control.rb +2 -1
- data/lib/packetgen/header/dot11/data.rb +4 -3
- data/lib/packetgen/header/dot11/element.rb +2 -1
- data/lib/packetgen/header/dot11/management.rb +2 -1
- data/lib/packetgen/header/dot11/sub_mngt.rb +2 -1
- data/lib/packetgen/header/dot11.rb +2 -1
- data/lib/packetgen/header/dot1q.rb +2 -1
- data/lib/packetgen/header/dot1x.rb +2 -1
- data/lib/packetgen/header/eap/fast.rb +2 -1
- data/lib/packetgen/header/eap/md5.rb +2 -1
- data/lib/packetgen/header/eap/tls.rb +3 -2
- data/lib/packetgen/header/eap/ttls.rb +3 -2
- data/lib/packetgen/header/eap.rb +3 -2
- data/lib/packetgen/header/eth.rb +3 -2
- data/lib/packetgen/header/gre.rb +2 -1
- data/lib/packetgen/header/http/headers.rb +4 -3
- data/lib/packetgen/header/http/request.rb +2 -1
- data/lib/packetgen/header/http/response.rb +2 -1
- data/lib/packetgen/header/http/verbs.rb +2 -1
- data/lib/packetgen/header/http.rb +2 -1
- data/lib/packetgen/header/icmp.rb +2 -1
- data/lib/packetgen/header/icmpv6.rb +2 -1
- data/lib/packetgen/header/igmp.rb +2 -1
- data/lib/packetgen/header/igmpv3/group_record.rb +2 -1
- data/lib/packetgen/header/igmpv3/mq.rb +2 -1
- data/lib/packetgen/header/igmpv3/mr.rb +2 -1
- data/lib/packetgen/header/igmpv3.rb +2 -1
- data/lib/packetgen/header/ip/addr.rb +2 -1
- data/lib/packetgen/header/ip/option.rb +3 -2
- data/lib/packetgen/header/ip/options.rb +2 -1
- data/lib/packetgen/header/ip.rb +3 -2
- data/lib/packetgen/header/ipv6/addr.rb +2 -1
- data/lib/packetgen/header/ipv6/extension.rb +2 -1
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +2 -1
- data/lib/packetgen/header/ipv6.rb +2 -1
- data/lib/packetgen/header/llc.rb +2 -1
- data/lib/packetgen/header/mdns.rb +2 -1
- data/lib/packetgen/header/mld.rb +2 -1
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +2 -1
- data/lib/packetgen/header/mldv2/mlq.rb +2 -1
- data/lib/packetgen/header/mldv2/mlr.rb +2 -1
- data/lib/packetgen/header/mldv2.rb +2 -1
- data/lib/packetgen/header/ospfv2/db_description.rb +2 -1
- data/lib/packetgen/header/ospfv2/hello.rb +2 -1
- data/lib/packetgen/header/ospfv2/ls_ack.rb +2 -1
- data/lib/packetgen/header/ospfv2/ls_request.rb +2 -1
- data/lib/packetgen/header/ospfv2/ls_update.rb +2 -1
- data/lib/packetgen/header/ospfv2/lsa.rb +2 -1
- data/lib/packetgen/header/ospfv2/lsa_header.rb +2 -1
- data/lib/packetgen/header/ospfv2.rb +2 -1
- data/lib/packetgen/header/ospfv3/db_description.rb +2 -1
- data/lib/packetgen/header/ospfv3/hello.rb +2 -1
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +2 -1
- data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -1
- data/lib/packetgen/header/ospfv3/ls_request.rb +2 -1
- data/lib/packetgen/header/ospfv3/ls_update.rb +2 -1
- data/lib/packetgen/header/ospfv3/lsa.rb +2 -1
- data/lib/packetgen/header/ospfv3/lsa_header.rb +2 -1
- data/lib/packetgen/header/ospfv3.rb +2 -1
- data/lib/packetgen/header/sctp/chunk.rb +547 -0
- data/lib/packetgen/header/sctp/error.rb +347 -0
- data/lib/packetgen/header/sctp/padded32.rb +34 -0
- data/lib/packetgen/header/sctp/parameter.rb +229 -0
- data/lib/packetgen/header/sctp.rb +96 -0
- data/lib/packetgen/header/snmp.rb +3 -2
- data/lib/packetgen/header/tcp/option.rb +2 -1
- data/lib/packetgen/header/tcp/options.rb +2 -1
- data/lib/packetgen/header/tcp.rb +3 -2
- data/lib/packetgen/header/tftp.rb +2 -1
- data/lib/packetgen/header/udp.rb +2 -1
- data/lib/packetgen/header.rb +4 -2
- data/lib/packetgen/headerable.rb +2 -1
- data/lib/packetgen/inject.rb +2 -1
- data/lib/packetgen/inspect.rb +2 -1
- data/lib/packetgen/packet.rb +4 -3
- data/lib/packetgen/pcap.rb +2 -1
- data/lib/packetgen/pcapng/block.rb +3 -2
- data/lib/packetgen/pcapng/epb.rb +2 -1
- data/lib/packetgen/pcapng/file.rb +2 -1
- data/lib/packetgen/pcapng/idb.rb +2 -1
- data/lib/packetgen/pcapng/shb.rb +2 -1
- data/lib/packetgen/pcapng/spb.rb +2 -1
- data/lib/packetgen/pcapng/unknown_block.rb +2 -1
- data/lib/packetgen/pcapng.rb +2 -1
- data/lib/packetgen/pcaprub_wrapper.rb +2 -1
- data/lib/packetgen/proto.rb +2 -1
- data/lib/packetgen/types/abstract_tlv.rb +146 -56
- data/lib/packetgen/types/array.rb +20 -3
- data/lib/packetgen/types/cstring.rb +2 -1
- data/lib/packetgen/types/enum.rb +3 -2
- data/lib/packetgen/types/fieldable.rb +3 -2
- data/lib/packetgen/types/fields.rb +8 -7
- data/lib/packetgen/types/int.rb +114 -13
- data/lib/packetgen/types/int_string.rb +2 -1
- data/lib/packetgen/types/length_from.rb +2 -1
- data/lib/packetgen/types/oui.rb +2 -1
- data/lib/packetgen/types/string.rb +2 -1
- data/lib/packetgen/types/tlv.rb +2 -1
- data/lib/packetgen/types.rb +2 -1
- data/lib/packetgen/unknown_packet.rb +3 -2
- data/lib/packetgen/utils/arp_spoofer.rb +4 -3
- data/lib/packetgen/utils.rb +2 -1
- data/lib/packetgen/version.rb +3 -2
- data/lib/packetgen.rb +2 -1
- metadata +27 -16
@@ -0,0 +1,547 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of PacketGen
|
4
|
+
# See https://github.com/lemontree55/packetgen for more informations
|
5
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
|
+
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
|
+
# This program is published under MIT license.
|
8
|
+
|
9
|
+
require_relative 'padded32'
|
10
|
+
|
11
|
+
module PacketGen
|
12
|
+
module Header
|
13
|
+
class SCTP
|
14
|
+
# BaseChunk class, defining SCTP chunk common fields
|
15
|
+
# 0 1 2 3
|
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
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
18
|
+
# | Chunk Type | Chunk Flags | Chunk Length |
|
19
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
20
|
+
# @abstract Subclass and add more fields
|
21
|
+
# @author Sylvain Daubert
|
22
|
+
class BaseChunk < Base
|
23
|
+
include Padded32
|
24
|
+
|
25
|
+
# SCTP chunk types, as per RFC9260
|
26
|
+
TYPES = {
|
27
|
+
'DATA' => 0,
|
28
|
+
'INIT' => 1,
|
29
|
+
'INIT_ACK' => 2,
|
30
|
+
'SACK' => 3,
|
31
|
+
'HEARTBEAT' => 4,
|
32
|
+
'HEARTBEAT_ACK' => 5,
|
33
|
+
'ABORT' => 6,
|
34
|
+
'SHUTDOWN' => 7,
|
35
|
+
'SHUTDOWN_ACK' => 8,
|
36
|
+
'ERROR' => 9,
|
37
|
+
'COOKIE_ECHO' => 10,
|
38
|
+
'COOKIE_ACK' => 11,
|
39
|
+
'SHUTDOWN_COMPLETE' => 14,
|
40
|
+
}.freeze
|
41
|
+
|
42
|
+
# @!attribute type
|
43
|
+
# 8-bit SCTP chunk type
|
44
|
+
# @return [Integer]
|
45
|
+
define_field :type, Types::Int8Enum, enum: TYPES
|
46
|
+
# @!attribute type
|
47
|
+
# 8-bit SCTP chunk flags
|
48
|
+
# @return [Integer]
|
49
|
+
define_field :flags, Types::Int8
|
50
|
+
# @!attribute length
|
51
|
+
# 16-bit SCTP chunk length
|
52
|
+
# @return [Integer]
|
53
|
+
define_field :length, Types::Int16
|
54
|
+
|
55
|
+
# Get human-redable chunk
|
56
|
+
# @return [::String]
|
57
|
+
def to_human
|
58
|
+
str = +"<chunk:#{human_type}"
|
59
|
+
flags_str = flags_to_human
|
60
|
+
str << ",flags:#{flags_str}" unless flags_str.empty?
|
61
|
+
str << '>'
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [::String,Integer]
|
65
|
+
def human_type
|
66
|
+
self[:type].to_human
|
67
|
+
end
|
68
|
+
|
69
|
+
# Calculate and set chunk length
|
70
|
+
# @todo do not count last parameter padding
|
71
|
+
# @return [Integer]
|
72
|
+
def calc_length
|
73
|
+
self.length = to_s(no_padding: true).size
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def flags_to_human
|
79
|
+
''
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
require_relative 'parameter'
|
87
|
+
require_relative 'error'
|
88
|
+
|
89
|
+
module PacketGen
|
90
|
+
module Header
|
91
|
+
class SCTP
|
92
|
+
# Embed chunks for a given {SCTP} packet.
|
93
|
+
# @author Sylvain Daubert
|
94
|
+
class ArrayOfChunk < Types::Array
|
95
|
+
set_of BaseChunk
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
# Get real type from Chunk type
|
100
|
+
def real_type(opt)
|
101
|
+
type_name = BaseChunk::TYPES.key(opt.type)
|
102
|
+
return opt.class if type_name.nil?
|
103
|
+
|
104
|
+
klass_name = type_name.split('_').map(&:capitalize).join << 'Chunk'
|
105
|
+
SCTP.const_get(klass_name) || UnknownChunk
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# UnknownChunk, used when type cannot be decoded
|
110
|
+
# 0 1 2 3
|
111
|
+
# 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
|
112
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
113
|
+
# | Chunk Type | Chunk Flags | Chunk Length |
|
114
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
115
|
+
# \ \
|
116
|
+
# / Chunk Value /
|
117
|
+
# \ \
|
118
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
119
|
+
# @author Sylvain Daubert
|
120
|
+
class UnknownChunk < BaseChunk
|
121
|
+
# @!attribute body
|
122
|
+
# SCTP chunk value
|
123
|
+
# @return [String]
|
124
|
+
define_field :body, Types::String, builder: ->(h, t) { t.new(length_from: -> { h.length - 4 }) }
|
125
|
+
end
|
126
|
+
|
127
|
+
# Data chunk
|
128
|
+
# 0 1 2 3
|
129
|
+
# 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
|
130
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
131
|
+
# | Type = 0 | Res |I|U|B|E| Length |
|
132
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
133
|
+
# | TSN |
|
134
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
135
|
+
# | Stream Identifier S | Stream Sequence Number n |
|
136
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
137
|
+
# | Payload Protocol Identifier |
|
138
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
139
|
+
# \ \
|
140
|
+
# / User Data (seq n of Stream S) /
|
141
|
+
# \ \
|
142
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
143
|
+
# @author Sylvain Daubert
|
144
|
+
class DataChunk < BaseChunk
|
145
|
+
# @!attribute tsn
|
146
|
+
# 32-bit TSN for this DATA chunk
|
147
|
+
# @return [Integer]
|
148
|
+
define_field :tsn, Types::Int32
|
149
|
+
# @!attribute stream_id
|
150
|
+
# 16-bit stream identifier
|
151
|
+
# @return [Integer]
|
152
|
+
define_field :stream_id, Types::Int16
|
153
|
+
# @!attribute stream_sn
|
154
|
+
# 16-bit stream sequence number
|
155
|
+
# @return [Integer]
|
156
|
+
define_field :stream_sn, Types::Int16
|
157
|
+
# @!attribute ppid
|
158
|
+
# 32-bit payload protocol identifier
|
159
|
+
# @return [Integer]
|
160
|
+
define_field :ppid, Types::Int32
|
161
|
+
# @!attribute body
|
162
|
+
# SCTP chunk value
|
163
|
+
# @return [String]
|
164
|
+
define_field :body, Types::String, builder: ->(h, t) { t.new(length_from: -> { h.length - 4 }) }
|
165
|
+
|
166
|
+
# @!attribute flag_i
|
167
|
+
# IMMEDIATE flag
|
168
|
+
# @return [Boolean]
|
169
|
+
# @!attribute flag_u
|
170
|
+
# UNORDERED flag
|
171
|
+
# @return [Boolean]
|
172
|
+
# @!attribute flag_b
|
173
|
+
# BEGINNING fragment flag
|
174
|
+
# @return [Boolean]
|
175
|
+
# @!attribute flag_e
|
176
|
+
# ENDING fragment flag
|
177
|
+
# @return [Boolean]
|
178
|
+
define_bit_fields_on :flags, :flag_res, 4, :flag_i, :flag_u, :flag_b, :flag_e
|
179
|
+
|
180
|
+
private
|
181
|
+
|
182
|
+
def flags_to_human
|
183
|
+
flags = +'....'
|
184
|
+
flags[0] = 'i' if flag_i?
|
185
|
+
flags[1] = 'u' if flag_u?
|
186
|
+
flags[2] = 'b' if flag_b?
|
187
|
+
flags[3] = 'e' if flag_e?
|
188
|
+
flags
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# Init Chunk
|
193
|
+
# 0 1 2 3
|
194
|
+
# 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
|
195
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
196
|
+
# | Type = 1 | Chunk Flags | Chunk Length |
|
197
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
198
|
+
# | Initiate Tag |
|
199
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
200
|
+
# | Advertised Receiver Window Credit (a_rwnd) |
|
201
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
202
|
+
# | Number of Outbound Streams | Number of Inbound Streams |
|
203
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
204
|
+
# | Initial TSN |
|
205
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
206
|
+
# \ \
|
207
|
+
# / Optional/Variable-Length Parameters /
|
208
|
+
# \ \
|
209
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
210
|
+
# @author Sylvain Daubert
|
211
|
+
class InitChunk < BaseChunk
|
212
|
+
# @!attribute initiate_tag
|
213
|
+
# 32-bit Initiate Tag
|
214
|
+
# @return [Integer]
|
215
|
+
define_field :initiate_tag, Types::Int32
|
216
|
+
# @!attribute a_wrnd
|
217
|
+
# 32-bit Advertised Receiver Window Credit (a_rwnd)
|
218
|
+
# @return [Integer]
|
219
|
+
define_field :a_rwnd, Types::Int32
|
220
|
+
# @!attribute nos
|
221
|
+
# 16-bit Number of Outbound Streams
|
222
|
+
# @return [Integer]
|
223
|
+
define_field :nos, Types::Int16
|
224
|
+
# @!attribute nis
|
225
|
+
# 16-bit Number of Inbound Streams
|
226
|
+
# @return [Integer]
|
227
|
+
define_field :nis, Types::Int16
|
228
|
+
# @!attribute initial_tsn
|
229
|
+
# 32-bit Initial TSN
|
230
|
+
# @return [Integer]
|
231
|
+
define_field :initial_tsn, Types::Int32
|
232
|
+
# @!attribute parameters
|
233
|
+
# List of parameters
|
234
|
+
# @return [ArrayOfParameter]
|
235
|
+
define_field :parameters, ArrayOfParameter
|
236
|
+
|
237
|
+
def initialize(options={})
|
238
|
+
options[:type] = BaseChunk::TYPES['INIT'] unless options.key?(:type)
|
239
|
+
super
|
240
|
+
end
|
241
|
+
|
242
|
+
# Calculate lengths, including parameters ones.
|
243
|
+
# @return [void]
|
244
|
+
def calc_length
|
245
|
+
parameters.each(&:calc_length)
|
246
|
+
super
|
247
|
+
end
|
248
|
+
|
249
|
+
# @return [::String]
|
250
|
+
def to_human
|
251
|
+
str = +"<chunk:#{human_type}"
|
252
|
+
flags_str = flags_to_human
|
253
|
+
str << ",flags:#{flags_str}" unless flags_str.empty?
|
254
|
+
str << ",param:#{parameters.map(&:to_human).join(',')}" unless parameters.empty?
|
255
|
+
str << '>'
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# InitAck Chunk
|
260
|
+
# 0 1 2 3
|
261
|
+
# 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
|
262
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
263
|
+
# | Type = 1 | Chunk Flags | Chunk Length |
|
264
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
265
|
+
# | Initiate Tag |
|
266
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
267
|
+
# | Advertised Receiver Window Credit (a_rwnd) |
|
268
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
269
|
+
# | Number of Outbound Streams | Number of Inbound Streams |
|
270
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
271
|
+
# | Initial TSN |
|
272
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
273
|
+
# \ \
|
274
|
+
# / Optional/Variable-Length Parameters /
|
275
|
+
# \ \
|
276
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
277
|
+
# @author Sylvain Daubert
|
278
|
+
class InitAckChunk < InitChunk
|
279
|
+
def initialize(options={})
|
280
|
+
options[:type] = BaseChunk::TYPES['INIT_ACK'] unless options.key?(:type)
|
281
|
+
super
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# Selective Acknowledge Chunk
|
286
|
+
# 0 1 2 3
|
287
|
+
# 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
|
288
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
289
|
+
# | Type = 3 | Chunk Flags | Chunk Length |
|
290
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
291
|
+
# | Cumulative TSN Ack |
|
292
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
293
|
+
# | Advertised Receiver Window Credit (a_rwnd) |
|
294
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
295
|
+
# | Number of Gap Ack Blocks = N | Number of Duplicate TSNs = M |
|
296
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
297
|
+
# | Gap Ack Block #1 Start | Gap Ack Block #1 End |
|
298
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
299
|
+
# / /
|
300
|
+
# \ ... \
|
301
|
+
# / /
|
302
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
303
|
+
# | Gap Ack Block #N Start | Gap Ack Block #N End |
|
304
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
305
|
+
# | Duplicate TSN 1 |
|
306
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
307
|
+
# / /
|
308
|
+
# \ ... \
|
309
|
+
# / /
|
310
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
311
|
+
# | Duplicate TSN M |
|
312
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
313
|
+
# @author Sylvain Daubert
|
314
|
+
class SackChunk < BaseChunk
|
315
|
+
# @!attribute ctsn_ack
|
316
|
+
# 32-bit Cumulative TSN Ack
|
317
|
+
# @return [Integer]
|
318
|
+
define_field :ctsn_ack, Types::Int32
|
319
|
+
# @!attribute a_rwnd
|
320
|
+
# 32-bit Advertised Receiver Window Credit
|
321
|
+
# @return [Integer]
|
322
|
+
define_field :a_rwnd, Types::Int32
|
323
|
+
# @!attribute num_gap
|
324
|
+
# 16-bit Number of Gap Ack Blocks
|
325
|
+
# @return [Integer]
|
326
|
+
define_field :num_gap, Types::Int32
|
327
|
+
# @!attribute num_dup_tsn
|
328
|
+
# 16-bit Number of Duplicate TSNs
|
329
|
+
# @return [Integer]
|
330
|
+
define_field :num_dup_tsn, Types::Int32
|
331
|
+
# @!attribute gaps
|
332
|
+
# Array of 32-bit Integers, encoding boudaries of a Gap Ack Block.
|
333
|
+
# 16 most significant bits encode block start. 16 least significant bits encode block end.
|
334
|
+
# @return [Types::ArrayOfInt32]
|
335
|
+
define_field :gaps, Types::ArrayOfInt32
|
336
|
+
# @!attribute dup_tsns
|
337
|
+
# Array of 32-bit Duplicate TSNs.
|
338
|
+
# @return [Types::ArrayOfInt32]
|
339
|
+
define_field :dup_tsns, Types::ArrayOfInt32
|
340
|
+
|
341
|
+
def initialize(options={})
|
342
|
+
options[:type] = BaseChunk::TYPES['SACK'] unless options.key?(:type)
|
343
|
+
super
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
# Heartbeat Request Chunk
|
348
|
+
# 0 1 2 3
|
349
|
+
# 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
|
350
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
351
|
+
# | Type = 4 | Chunk Flags | Heartbeat Length |
|
352
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
353
|
+
# \ \
|
354
|
+
# / Heartbeat Information TLV (Variable-Length) /
|
355
|
+
# \ \
|
356
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
357
|
+
# @author Sylvain Daubert
|
358
|
+
class HeartbeatChunk < BaseChunk
|
359
|
+
# @!attribute info
|
360
|
+
# Array of Heartbeat information TLV.
|
361
|
+
# @return [Types::ArrayOfInt32]
|
362
|
+
define_field :info, HearbeatInfoParameter
|
363
|
+
|
364
|
+
def initialize(options={})
|
365
|
+
options[:type] = BaseChunk::TYPES['HEARTBEAT'] unless options.key?(:type)
|
366
|
+
super
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
# Heartbeat Acknoledgement Chunk
|
371
|
+
# 0 1 2 3
|
372
|
+
# 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
|
373
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
374
|
+
# | Type = 4 | Chunk Flags | Heartbeat Length |
|
375
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
376
|
+
# \ \
|
377
|
+
# / Heartbeat Information TLV (Variable-Length) /
|
378
|
+
# \ \
|
379
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
380
|
+
# @author Sylvain Daubert
|
381
|
+
class HeartbeatAckChunk < HeartbeatChunk
|
382
|
+
def initialize(options={})
|
383
|
+
options[:type] = BaseChunk::TYPES['HEARTBEAT_ACK'] unless options.key?(:type)
|
384
|
+
super
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
# Operation Error Chunk
|
389
|
+
# 0 1 2 3
|
390
|
+
# 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
|
391
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
392
|
+
# | Type = 9 | Chunk Flags | Length |
|
393
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
394
|
+
# \ \
|
395
|
+
# / zero or more Error Causes /
|
396
|
+
# \ \
|
397
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
398
|
+
# @author Sylvain Daubert
|
399
|
+
class ErrorChunk < BaseChunk
|
400
|
+
# @!attribute error_causes
|
401
|
+
# @return [ArrayofError]
|
402
|
+
define_field :error_causes, ArrayOfError
|
403
|
+
|
404
|
+
def initialize(options={})
|
405
|
+
options[:type] = BaseChunk::TYPES['ERROR'] unless options.key?(:type)
|
406
|
+
super
|
407
|
+
end
|
408
|
+
|
409
|
+
# Calculate lengths, including parameters ones.
|
410
|
+
# @return [void]
|
411
|
+
def calc_length
|
412
|
+
error_causes.each(&:calc_length)
|
413
|
+
super
|
414
|
+
end
|
415
|
+
|
416
|
+
# @return [::String]
|
417
|
+
def to_human
|
418
|
+
str = +"<chunk:#{human_type}"
|
419
|
+
flags_str = flags_to_human
|
420
|
+
str << ",flags:#{flags_str}" unless flags_str.empty?
|
421
|
+
str << ",causes:#{error_causes.map(&:to_human).join(',')}" unless error_causes.empty?
|
422
|
+
str << '>'
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
# Abort Association Chunk
|
427
|
+
# 0 1 2 3
|
428
|
+
# 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
|
429
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
430
|
+
# | Type = 6 | Reserved |T| Length |
|
431
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
432
|
+
# \ \
|
433
|
+
# / zero or more Error Causes /
|
434
|
+
# \ \
|
435
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
436
|
+
# @author Sylvain Daubert
|
437
|
+
class AbortChunk < ErrorChunk
|
438
|
+
# @!attribute flag_t
|
439
|
+
# @return [Boolean]
|
440
|
+
define_bit_fields_on :flags, :flag_res, 7, :flag_t
|
441
|
+
|
442
|
+
def initialize(options={})
|
443
|
+
options[:type] = BaseChunk::TYPES['ABORT'] unless options.key?(:type)
|
444
|
+
super
|
445
|
+
end
|
446
|
+
|
447
|
+
private
|
448
|
+
|
449
|
+
def flags_to_human
|
450
|
+
flag_t? ? 't' : '.'
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
# Shutdown association Chunk
|
455
|
+
# 0 1 2 3
|
456
|
+
# 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
|
457
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
458
|
+
# | Type = 7 | Chunk Flags | Length = 8 |
|
459
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
460
|
+
# | Cumulative TSN Ack |
|
461
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
462
|
+
# @author Sylvain Daubert
|
463
|
+
class ShutdownChunk < BaseChunk
|
464
|
+
# @!attribute cstn_ack
|
465
|
+
# 32-bit cumulative TSN ack
|
466
|
+
# @return [Integer]
|
467
|
+
define_field :ctsn_ack, Types::Int32
|
468
|
+
|
469
|
+
def initialize(options={})
|
470
|
+
options[:type] = BaseChunk::TYPES['SHUTDOWN'] unless options.key?(:type)
|
471
|
+
options[:length] = 8 unless options.key?(:length)
|
472
|
+
super
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
# Shutdown acknowledgement Chunk
|
477
|
+
# 0 1 2 3
|
478
|
+
# 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
|
479
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
480
|
+
# | Type = 8 | Chunk Flags | Length = 4 |
|
481
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
482
|
+
# @author Sylvain Daubert
|
483
|
+
class ShutdownAckChunk < BaseChunk
|
484
|
+
def initialize(options={})
|
485
|
+
options[:type] = BaseChunk::TYPES['SHUTDOWN_ACK'] unless options.key?(:type)
|
486
|
+
options[:length] = 4 unless options.key?(:length)
|
487
|
+
super
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
# Cookie Echo Chunk
|
492
|
+
# 0 1 2 3
|
493
|
+
# 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
|
494
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
495
|
+
# | Type = 10 | Chunk Flags | Length |
|
496
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
497
|
+
# / Cookie /
|
498
|
+
# \ \
|
499
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
500
|
+
# @author Sylvain Daubert
|
501
|
+
class CookieEchoChunk < BaseChunk
|
502
|
+
# @!attribute cookie
|
503
|
+
# @return [String]
|
504
|
+
define_field :cookie, Types::String
|
505
|
+
|
506
|
+
def initialize(options={})
|
507
|
+
options[:type] = BaseChunk::TYPES['COOKIE_ECHO'] unless options.key?(:type)
|
508
|
+
super
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
# Cookie Acknownledgement Chunk
|
513
|
+
# 0 1 2 3
|
514
|
+
# 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
|
515
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
516
|
+
# | Type = 11 | Chunk Flags | Length |
|
517
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
518
|
+
# @author Sylvain Daubert
|
519
|
+
class CookieAckChunk < BaseChunk
|
520
|
+
def initialize(options={})
|
521
|
+
options[:type] = BaseChunk::TYPES['COOKIE_ACK'] unless options.key?(:type)
|
522
|
+
options[:length] = 4 unless options.key?(:length)
|
523
|
+
super
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
# Shutdown Complete Chunk
|
528
|
+
# 0 1 2 3
|
529
|
+
# 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
|
530
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
531
|
+
# | Type = 14 | Reserved |T| Length = 4 |
|
532
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
533
|
+
# @author Sylvain Daubert
|
534
|
+
class ShutdownCompleteChunk < BaseChunk
|
535
|
+
# @!attribute flag_t
|
536
|
+
# @return [Boolean]
|
537
|
+
define_bit_fields_on :flags, :flag_res, 7, :flag_t
|
538
|
+
|
539
|
+
def initialize(options={})
|
540
|
+
options[:type] = BaseChunk::TYPES['SHUTDOWN_COMPLETE'] unless options.key?(:type)
|
541
|
+
options[:length] = 4 unless options.key?(:length)
|
542
|
+
super
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
end
|
547
|
+
end
|