packetgen 3.3.0 → 3.3.2
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 +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
|