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,347 @@
|
|
|
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
|
+
module PacketGen
|
|
10
|
+
module Header
|
|
11
|
+
class SCTP
|
|
12
|
+
# Common methods to all error causes
|
|
13
|
+
# @author Sylvain Daubert
|
|
14
|
+
module ErrorMixin
|
|
15
|
+
include Padded32
|
|
16
|
+
|
|
17
|
+
# Get error name
|
|
18
|
+
# @return [String]
|
|
19
|
+
def error_name
|
|
20
|
+
self.class.name.split('::').last.delete_suffix('Error')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [String]
|
|
24
|
+
def to_human
|
|
25
|
+
"<#{error_name}: #{value}>"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Error = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
30
|
+
length_class: Types::Int16,
|
|
31
|
+
field_in_length: 'TLV')
|
|
32
|
+
|
|
33
|
+
# Base class/factory for {AbortChunk} and {ErrorChunk} error causes
|
|
34
|
+
# @author Sylvain Daubert
|
|
35
|
+
class Error
|
|
36
|
+
include ErrorMixin
|
|
37
|
+
|
|
38
|
+
# Error Causes/Types
|
|
39
|
+
TYPES = {
|
|
40
|
+
'InvalidStreamId' => 1,
|
|
41
|
+
'MissingMandatoryParameter' => 2,
|
|
42
|
+
'StaleCookie' => 3,
|
|
43
|
+
'OutOfResource' => 4,
|
|
44
|
+
'UnresolvableAddress' => 5,
|
|
45
|
+
'UnrecognizedChunkType' => 6,
|
|
46
|
+
'InvalidMandatoryParameter' => 7,
|
|
47
|
+
'UnrecognizedParameters' => 8,
|
|
48
|
+
'NoUserData' => 9,
|
|
49
|
+
'CookieReceivedWhileShuttingDown' => 10,
|
|
50
|
+
'RestartAssociationWithNewAddress' => 11,
|
|
51
|
+
'UserInitiatedAbort' => 12,
|
|
52
|
+
'ProtocolViolation' => 13
|
|
53
|
+
}.freeze
|
|
54
|
+
|
|
55
|
+
# @param [Object] value
|
|
56
|
+
def from_human(value)
|
|
57
|
+
if value.is_a?(self[:value].class)
|
|
58
|
+
self[:value] = value
|
|
59
|
+
else
|
|
60
|
+
self[:value].from_human(value)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
Error.define_type_enum(Error::TYPES)
|
|
65
|
+
|
|
66
|
+
# Handle array of {Error} and {ErrorMixin} classes.
|
|
67
|
+
# @author Sylvain Daubert
|
|
68
|
+
class ArrayOfError < Types::Array
|
|
69
|
+
set_of Error
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
# @param [Error,ErrorMixin] error
|
|
74
|
+
def real_type(error)
|
|
75
|
+
type_name = Error::TYPES.key(error.type)
|
|
76
|
+
return error.class if type_name.nil?
|
|
77
|
+
|
|
78
|
+
SCTP.const_get(real_klass_name(type_name)) || error.class
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def real_klass_name(type_name)
|
|
82
|
+
type_name + 'Error' # rubocop:disable Style/StringConcatenation
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
InvalidStreamIdError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
87
|
+
length_class: Types::Int16,
|
|
88
|
+
value_class: Types::Int32,
|
|
89
|
+
field_in_length: 'TLV')
|
|
90
|
+
|
|
91
|
+
# InvalidStreamIdentifier error
|
|
92
|
+
# @author Sylvain Daubert
|
|
93
|
+
class InvalidStreamIdError
|
|
94
|
+
include ErrorMixin
|
|
95
|
+
|
|
96
|
+
# Get stream Id value
|
|
97
|
+
# @return [Integer]
|
|
98
|
+
def stream_identifier
|
|
99
|
+
self.value >> 16
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Set stream Id value
|
|
103
|
+
# @param [Integer] stream_id
|
|
104
|
+
# @return [Integer]
|
|
105
|
+
def stream_identifier=(stream_id)
|
|
106
|
+
self.value = (stream_id & 0xffff) << 16
|
|
107
|
+
stream_id
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @return [::String]
|
|
111
|
+
def to_human
|
|
112
|
+
"<#{error_name}: #{stream_identifier}>"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @param [Integer] val
|
|
116
|
+
def from_human(val)
|
|
117
|
+
super
|
|
118
|
+
self.value <<= 16 if self[:value] < Types::Int
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
InvalidStreamIdError.define_type_enum(Error::TYPES)
|
|
122
|
+
InvalidStreamIdError.define_type_default('InvalidStreamId')
|
|
123
|
+
|
|
124
|
+
MissingMandatoryParameterError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
125
|
+
length_class: Types::Int16,
|
|
126
|
+
value_class: Types::ArrayOfInt16,
|
|
127
|
+
field_in_length: 'TLV')
|
|
128
|
+
|
|
129
|
+
# MissingMandatoryParameter error. Indicate that one or more
|
|
130
|
+
# mandatory TLV parameters are missing in a received {InitChunk}
|
|
131
|
+
# or {InitAckChunk}.
|
|
132
|
+
# @author Sylvain Daubert
|
|
133
|
+
class MissingMandatoryParameterError
|
|
134
|
+
include ErrorMixin
|
|
135
|
+
|
|
136
|
+
# @return [::String]
|
|
137
|
+
def to_human
|
|
138
|
+
"<#{error_name}: #{self[:value].to_human}>"
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
MissingMandatoryParameterError.define_type_enum(Error::TYPES)
|
|
142
|
+
MissingMandatoryParameterError.define_type_default('MissingMandatoryParameter')
|
|
143
|
+
|
|
144
|
+
StaleCookieError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
145
|
+
length_class: Types::Int16,
|
|
146
|
+
value_class: Types::Int32,
|
|
147
|
+
field_in_length: 'TLV')
|
|
148
|
+
|
|
149
|
+
# StaleCookie error. Indicates the receipt of a valid State Cookie that
|
|
150
|
+
# has expired.
|
|
151
|
+
# @author Sylvain Daubert
|
|
152
|
+
class StaleCookieError
|
|
153
|
+
include ErrorMixin
|
|
154
|
+
end
|
|
155
|
+
StaleCookieError.define_type_enum(Error::TYPES)
|
|
156
|
+
StaleCookieError.define_type_default('StaleCookie')
|
|
157
|
+
|
|
158
|
+
OutOfResourceError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
159
|
+
length_class: Types::Int16,
|
|
160
|
+
field_in_length: 'TLV')
|
|
161
|
+
|
|
162
|
+
# Out of ressource error. Indicates that the sender is out of resource.
|
|
163
|
+
# @author Sylvain Daubert
|
|
164
|
+
class OutOfResourceError
|
|
165
|
+
include ErrorMixin
|
|
166
|
+
|
|
167
|
+
# @return [::String]
|
|
168
|
+
def to_human
|
|
169
|
+
"<#{error_name}>"
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
OutOfResourceError.define_type_enum(Error::TYPES)
|
|
173
|
+
OutOfResourceError.define_type_default('OutOfResource')
|
|
174
|
+
|
|
175
|
+
UnresolvableAddressError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
176
|
+
length_class: Types::Int16,
|
|
177
|
+
value_class: Parameter,
|
|
178
|
+
field_in_length: 'TLV')
|
|
179
|
+
|
|
180
|
+
# Out of ressource error. Indicates that the sender is out of resource.
|
|
181
|
+
# @author Sylvain Daubert
|
|
182
|
+
class UnresolvableAddressError
|
|
183
|
+
include ErrorMixin
|
|
184
|
+
|
|
185
|
+
# Set +value+ by accepting {ParameterMixin} classes.
|
|
186
|
+
# @param [ParameterMixin] val
|
|
187
|
+
# @return [ParameterMixin]
|
|
188
|
+
def value=(val)
|
|
189
|
+
if val.is_a?(ParameterMixin)
|
|
190
|
+
self[:value] = val
|
|
191
|
+
calc_length
|
|
192
|
+
val
|
|
193
|
+
else
|
|
194
|
+
super
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# @return [::String]
|
|
199
|
+
def to_human
|
|
200
|
+
"<#{error_name}: #{self[:value].to_human}>"
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
UnresolvableAddressError.define_type_enum(Error::TYPES)
|
|
204
|
+
UnresolvableAddressError.define_type_default('UnresolvableAddress')
|
|
205
|
+
|
|
206
|
+
UnrecognizedChunkTypeError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
207
|
+
length_class: Types::Int16,
|
|
208
|
+
value_class: BaseChunk,
|
|
209
|
+
field_in_length: 'TLV')
|
|
210
|
+
|
|
211
|
+
# Unrecognized chunk type error. The receiver does not understand the chunk and the upper bits of the 'Chunk Type'
|
|
212
|
+
# are set to 01 or 11.
|
|
213
|
+
# @author Sylvain Daubert
|
|
214
|
+
class UnrecognizedChunkTypeError
|
|
215
|
+
include ErrorMixin
|
|
216
|
+
|
|
217
|
+
# @return [::String]
|
|
218
|
+
def to_human
|
|
219
|
+
"<#{error_name}: #{self[:value].to_human}>"
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
UnrecognizedChunkTypeError.define_type_enum(Error::TYPES)
|
|
223
|
+
UnrecognizedChunkTypeError.define_type_default('UnrecognizedChunkType')
|
|
224
|
+
|
|
225
|
+
InvalidMandatoryParameterError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
226
|
+
length_class: Types::Int16,
|
|
227
|
+
field_in_length: 'TLV')
|
|
228
|
+
|
|
229
|
+
# Invalid mandatory parameter error. Returned to the originator of an INIT or INIT ACK chunk when one of the
|
|
230
|
+
# mandatory parameters is set to an invalid value.
|
|
231
|
+
# @author Sylvain Daubert
|
|
232
|
+
class InvalidMandatoryParameterError
|
|
233
|
+
include ErrorMixin
|
|
234
|
+
|
|
235
|
+
# @return [::String]
|
|
236
|
+
def to_human
|
|
237
|
+
"<#{error_name}>"
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
InvalidMandatoryParameterError.define_type_enum(Error::TYPES)
|
|
241
|
+
InvalidMandatoryParameterError.define_type_default('InvalidMandatoryParameter')
|
|
242
|
+
|
|
243
|
+
UnrecognizedParametersError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
244
|
+
length_class: Types::Int16,
|
|
245
|
+
value_class: ArrayOfParameter,
|
|
246
|
+
field_in_length: 'TLV')
|
|
247
|
+
|
|
248
|
+
# Unrecognized parameters error. Returned to the originator of the INIT ACK chunk if the receiver does not
|
|
249
|
+
# recognize one or more Optional TLV parameters in the INIT ACK chunk.
|
|
250
|
+
# @author Sylvain Daubert
|
|
251
|
+
class UnrecognizedParametersError
|
|
252
|
+
include ErrorMixin
|
|
253
|
+
|
|
254
|
+
# @return [::String]
|
|
255
|
+
def to_human
|
|
256
|
+
"<#{error_name}: #{self[:value].to_human}>"
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
UnrecognizedParametersError.define_type_enum(Error::TYPES)
|
|
260
|
+
UnrecognizedParametersError.define_type_default('UnrecognizedParameters')
|
|
261
|
+
|
|
262
|
+
NoUserDataError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
263
|
+
length_class: Types::Int16,
|
|
264
|
+
value_class: Types::Int32,
|
|
265
|
+
field_in_length: 'TLV')
|
|
266
|
+
|
|
267
|
+
# No user data error. Returned when a received {DataChunk} was received with no data.
|
|
268
|
+
# @author Sylvain Daubert
|
|
269
|
+
class NoUserDataError
|
|
270
|
+
include ErrorMixin
|
|
271
|
+
end
|
|
272
|
+
NoUserDataError.define_type_enum(Error::TYPES)
|
|
273
|
+
NoUserDataError.define_type_default('NoUserData')
|
|
274
|
+
|
|
275
|
+
CookieReceivedWhileShuttingDownError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
276
|
+
length_class: Types::Int16,
|
|
277
|
+
field_in_length: 'TLV')
|
|
278
|
+
|
|
279
|
+
# Cookie received while shutting down error.
|
|
280
|
+
# A COOKIE ECHO chunk was received while the endpoint was in the SHUTDOWN-ACK-SENT state.
|
|
281
|
+
# @author Sylvain Daubert
|
|
282
|
+
class CookieReceivedWhileShuttingDownError
|
|
283
|
+
include ErrorMixin
|
|
284
|
+
|
|
285
|
+
# @return [::String]
|
|
286
|
+
def to_human
|
|
287
|
+
"<#{error_name}>"
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
CookieReceivedWhileShuttingDownError.define_type_enum(Error::TYPES)
|
|
291
|
+
CookieReceivedWhileShuttingDownError.define_type_default('CookieReceivedWhileShuttingDown')
|
|
292
|
+
|
|
293
|
+
RestartAssociationWithNewAddressError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
294
|
+
length_class: Types::Int16,
|
|
295
|
+
value_class: ArrayOfParameter,
|
|
296
|
+
field_in_length: 'TLV')
|
|
297
|
+
|
|
298
|
+
# Cookie received while shutting down error.
|
|
299
|
+
# A COOKIE ECHO chunk was received while the endpoint was in the SHUTDOWN-ACK-SENT state.
|
|
300
|
+
# @author Sylvain Daubert
|
|
301
|
+
class RestartAssociationWithNewAddressError
|
|
302
|
+
include ErrorMixin
|
|
303
|
+
|
|
304
|
+
# @return [::String]
|
|
305
|
+
def to_human
|
|
306
|
+
"<#{error_name}: #{self[:value].to_human}>"
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
RestartAssociationWithNewAddressError.define_type_enum(Error::TYPES)
|
|
310
|
+
RestartAssociationWithNewAddressError.define_type_default('RestartAssociationWithNewAddress')
|
|
311
|
+
|
|
312
|
+
UserInitiatedAbortError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
313
|
+
length_class: Types::Int16,
|
|
314
|
+
field_in_length: 'TLV')
|
|
315
|
+
|
|
316
|
+
# User-Initiated abort error.
|
|
317
|
+
# @author Sylvain Daubert
|
|
318
|
+
class UserInitiatedAbortError
|
|
319
|
+
include ErrorMixin
|
|
320
|
+
|
|
321
|
+
# @return [::String]
|
|
322
|
+
def to_human
|
|
323
|
+
"<#{error_name}>"
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
UserInitiatedAbortError.define_type_enum(Error::TYPES)
|
|
327
|
+
UserInitiatedAbortError.define_type_default('UserInitiatedAbort')
|
|
328
|
+
|
|
329
|
+
ProtocolViolationError = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
330
|
+
length_class: Types::Int16,
|
|
331
|
+
field_in_length: 'TLV')
|
|
332
|
+
|
|
333
|
+
# Protocol violation error.
|
|
334
|
+
# @author Sylvain Daubert
|
|
335
|
+
class ProtocolViolationError
|
|
336
|
+
include ErrorMixin
|
|
337
|
+
|
|
338
|
+
# @return [::String]
|
|
339
|
+
def to_human
|
|
340
|
+
"<#{error_name}>"
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
ProtocolViolationError.define_type_enum(Error::TYPES)
|
|
344
|
+
ProtocolViolationError.define_type_default('ProtocolViolation')
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
module PacketGen
|
|
10
|
+
module Header
|
|
11
|
+
class SCTP
|
|
12
|
+
# Mixin to handle 32-bit padding in SCTP classes
|
|
13
|
+
module Padded32
|
|
14
|
+
# Handle padding
|
|
15
|
+
# @param [Bool] no_padding
|
|
16
|
+
# @return [::String]
|
|
17
|
+
def to_s(no_padding: false)
|
|
18
|
+
s = super()
|
|
19
|
+
return s if no_padding
|
|
20
|
+
|
|
21
|
+
padlen = -(s.size % -4)
|
|
22
|
+
s << force_binary("\x00" * padlen)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Say if binary string is padded
|
|
26
|
+
# @return [bool]
|
|
27
|
+
def padded?
|
|
28
|
+
str = to_s(no_padding: true)
|
|
29
|
+
(str.size % 4).positive?
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,229 @@
|
|
|
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
|
+
module PacketGen
|
|
10
|
+
module Header
|
|
11
|
+
class SCTP
|
|
12
|
+
# Common methods to Init and InitAck parameters
|
|
13
|
+
# @author Sylvain Daubert
|
|
14
|
+
module ParameterMixin
|
|
15
|
+
include Padded32
|
|
16
|
+
|
|
17
|
+
# Get parameter name
|
|
18
|
+
# @return [String]
|
|
19
|
+
def parameter_name
|
|
20
|
+
self.class.name.split('::').last.delete_suffix('Parameter')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [String]
|
|
24
|
+
def to_human
|
|
25
|
+
"<#{parameter_name}: #{value}>"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Parameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
30
|
+
length_class: Types::Int16,
|
|
31
|
+
field_in_length: 'TLV')
|
|
32
|
+
# Base class/factory for {InitChunk} and {InitAckChunk} parameters
|
|
33
|
+
# @author Sylvain Daubert
|
|
34
|
+
class Parameter
|
|
35
|
+
include ParameterMixin
|
|
36
|
+
|
|
37
|
+
# Paramter Types
|
|
38
|
+
TYPES = {
|
|
39
|
+
'IPv4' => 5,
|
|
40
|
+
'IPv6' => 6,
|
|
41
|
+
'StateCookie' => 7,
|
|
42
|
+
'Unrecognized' => 8,
|
|
43
|
+
'CookiePreservative' => 9,
|
|
44
|
+
'Hostname' => 11,
|
|
45
|
+
'SupportedAddrTypes' => 12,
|
|
46
|
+
'ECN' => 32_768
|
|
47
|
+
}.freeze
|
|
48
|
+
|
|
49
|
+
# @return [::String]
|
|
50
|
+
def to_human
|
|
51
|
+
"<#{human_type}: #{self[:value].inspect}>"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @param [Object] value
|
|
55
|
+
def from_human(value)
|
|
56
|
+
if value.is_a?(self[:value].class)
|
|
57
|
+
self[:value] = value
|
|
58
|
+
else
|
|
59
|
+
self[:value].from_human(value)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
Parameter.define_type_enum(Parameter::TYPES)
|
|
64
|
+
|
|
65
|
+
IPv4Parameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
66
|
+
length_class: Types::Int16,
|
|
67
|
+
value_class: IP::Addr,
|
|
68
|
+
field_in_length: 'TLV')
|
|
69
|
+
|
|
70
|
+
# IPv4 address parameter
|
|
71
|
+
# @author Sylvain Daubert
|
|
72
|
+
class IPv4Parameter
|
|
73
|
+
include ParameterMixin
|
|
74
|
+
end
|
|
75
|
+
IPv4Parameter.define_type_enum(Parameter::TYPES)
|
|
76
|
+
IPv4Parameter.define_type_default('IPv4')
|
|
77
|
+
|
|
78
|
+
IPv6Parameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
79
|
+
length_class: Types::Int16,
|
|
80
|
+
value_class: IPv6::Addr,
|
|
81
|
+
field_in_length: 'TLV')
|
|
82
|
+
|
|
83
|
+
# IPv6 address parameter
|
|
84
|
+
# @author Sylvain Daubert
|
|
85
|
+
class IPv6Parameter
|
|
86
|
+
include ParameterMixin
|
|
87
|
+
end
|
|
88
|
+
IPv6Parameter.define_type_enum(Parameter::TYPES)
|
|
89
|
+
IPv6Parameter.define_type_default('IPv6')
|
|
90
|
+
|
|
91
|
+
StateCookieParameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
92
|
+
length_class: Types::Int16,
|
|
93
|
+
value_class: Types::String,
|
|
94
|
+
field_in_length: 'TLV')
|
|
95
|
+
|
|
96
|
+
# State Cookie parameter
|
|
97
|
+
# @author Sylvain Daubert
|
|
98
|
+
class StateCookieParameter
|
|
99
|
+
include ParameterMixin
|
|
100
|
+
|
|
101
|
+
# @return [::String]
|
|
102
|
+
def to_human
|
|
103
|
+
"<#{parameter_name}: #{self[:value].inspect}>"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
StateCookieParameter.define_type_enum(Parameter::TYPES)
|
|
107
|
+
StateCookieParameter.define_type_default('StateCookie')
|
|
108
|
+
|
|
109
|
+
UnrecognizedParameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
110
|
+
length_class: Types::Int16,
|
|
111
|
+
value_class: Parameter,
|
|
112
|
+
field_in_length: 'TLV')
|
|
113
|
+
|
|
114
|
+
# Unrecognized parameter
|
|
115
|
+
# @author Sylvain Daubert
|
|
116
|
+
class UnrecognizedParameter
|
|
117
|
+
include ParameterMixin
|
|
118
|
+
|
|
119
|
+
# @return [::String]
|
|
120
|
+
def to_human
|
|
121
|
+
"<#{parameter_name}: #{self[:value].to_human}"
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
UnrecognizedParameter.define_type_enum(Parameter::TYPES)
|
|
125
|
+
UnrecognizedParameter.define_type_default('Unrecognized')
|
|
126
|
+
|
|
127
|
+
HostnameParameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
128
|
+
length_class: Types::Int16,
|
|
129
|
+
value_class: Types::CString,
|
|
130
|
+
field_in_length: 'TLV')
|
|
131
|
+
|
|
132
|
+
# Hostname address parameter
|
|
133
|
+
# @author Sylvain Daubert
|
|
134
|
+
class HostnameParameter
|
|
135
|
+
include ParameterMixin
|
|
136
|
+
end
|
|
137
|
+
HostnameParameter.define_type_enum(Parameter::TYPES)
|
|
138
|
+
HostnameParameter.define_type_default('Hostname')
|
|
139
|
+
|
|
140
|
+
SupportedAddrTypesParameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
141
|
+
length_class: Types::Int16,
|
|
142
|
+
value_class: Types::ArrayOfInt16,
|
|
143
|
+
field_in_length: 'TLV')
|
|
144
|
+
|
|
145
|
+
# Supported address types parameter
|
|
146
|
+
# @author Sylvain Daubert
|
|
147
|
+
class SupportedAddrTypesParameter
|
|
148
|
+
include ParameterMixin
|
|
149
|
+
|
|
150
|
+
# @return [::String]
|
|
151
|
+
def to_human
|
|
152
|
+
types = self[:value].map(&:to_i).map do |int16|
|
|
153
|
+
Parameter::TYPES.key(int16) || int16.to_s
|
|
154
|
+
end.join(',')
|
|
155
|
+
"<#{parameter_name}: #{types}>"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
SupportedAddrTypesParameter.define_type_enum(Parameter::TYPES)
|
|
159
|
+
SupportedAddrTypesParameter.define_type_default('SupportedAddrTypes')
|
|
160
|
+
|
|
161
|
+
CookiePreservativeParameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
162
|
+
length_class: Types::Int16,
|
|
163
|
+
value_class: Types::Int32,
|
|
164
|
+
field_in_length: 'TLV')
|
|
165
|
+
|
|
166
|
+
# Cookie Preservative parameter
|
|
167
|
+
# @author Sylvain Daubert
|
|
168
|
+
class CookiePreservativeParameter
|
|
169
|
+
include ParameterMixin
|
|
170
|
+
|
|
171
|
+
# @return [::String]
|
|
172
|
+
def to_human
|
|
173
|
+
"<#{parameter_name}: #{value}>"
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
CookiePreservativeParameter.define_type_enum(Parameter::TYPES)
|
|
177
|
+
CookiePreservativeParameter.define_type_default('CookiePreservative')
|
|
178
|
+
|
|
179
|
+
ECNParameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
180
|
+
length_class: Types::Int16,
|
|
181
|
+
field_in_length: 'TLV')
|
|
182
|
+
|
|
183
|
+
# ECN parameter
|
|
184
|
+
# @author Sylvain Daubert
|
|
185
|
+
class ECNParameter
|
|
186
|
+
include ParameterMixin
|
|
187
|
+
|
|
188
|
+
# @return [::String]
|
|
189
|
+
def to_human
|
|
190
|
+
"<#{parameter_name}>"
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
ECNParameter.define_type_enum(Parameter::TYPES)
|
|
194
|
+
ECNParameter.define_type_default('ECN')
|
|
195
|
+
|
|
196
|
+
HearbeatInfoParameter = Types::AbstractTLV.create(type_class: Types::Int16Enum,
|
|
197
|
+
length_class: Types::Int16,
|
|
198
|
+
field_in_length: 'TLV')
|
|
199
|
+
|
|
200
|
+
# Heartbeat Information parameter
|
|
201
|
+
# @author Sylvain Daubert
|
|
202
|
+
class HearbeatInfoParameter
|
|
203
|
+
include ParameterMixin
|
|
204
|
+
end
|
|
205
|
+
HearbeatInfoParameter.define_type_enum({ 'HearbeatInfo' => 1 }.freeze)
|
|
206
|
+
HearbeatInfoParameter.define_type_default('HearbeatInfo')
|
|
207
|
+
|
|
208
|
+
# Array of {Parameter}s and {ParameterMixin}.
|
|
209
|
+
# @author Sylvain Daubert
|
|
210
|
+
class ArrayOfParameter < Types::Array
|
|
211
|
+
set_of Parameter
|
|
212
|
+
|
|
213
|
+
private
|
|
214
|
+
|
|
215
|
+
# Get real type from {Parameter} type
|
|
216
|
+
def real_type(param)
|
|
217
|
+
type_name = Parameter::TYPES.key(param.type)
|
|
218
|
+
return param.class if type_name.nil?
|
|
219
|
+
|
|
220
|
+
SCTP.const_get(real_klass_name(type_name)) || param.class
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def real_klass_name(type_name)
|
|
224
|
+
type_name + 'Parameter' # rubocop:disable Style/StringConcatenation
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|