SCTP Headers

This will be a very brief introduction to the SCTP
headers. SCTP has a lot of different types of
packets, and hence I will try to follow the RFC's as
close as possible and how they depict the different headers, starting with a
general overview of the headers applicable to all
SCTP packets.

This is a generic overview of how a SCTP packet is
laid out. Basically, you have a common header first with information describing
the whole packet, and the source and destination ports etc. See more below for
information on the common header.

After the common header a variable number of chunks are sent, up to the maximum
possible in the MTU. All chunks can be bundled except
for INIT, INIT ACK and
SHUTDOWN COMPLETE, which must not be bundled.
DATA chunks may be broken down to fit inside the
MTU of the packets.

Every SCTP packet contains the Common header as seen above. The header contains
four different fields and is set for every SCTP packet.

Source port - bit 0-15. This field gives the source port of the packet, which
port it was sent from. The same as for TCP and
UDP source port.

Destination port - bit 16-31. This is the destination port of the packet, ie.,
the port that the packet is going to. It is the same as for the
TCP and UDP destination port.

Verification Tag - bit 32-63. The verification tag is used to verify that the
packet comes from the correct sender. It is always set to the same value as the
value received by the other peer in the Initiate Tag during the
association initialization, with a few exceptions:

An SCTP packet containing an
INIT chunk must have the Verification tag set to 0.

A SHUTDOWN COMPLETE chunk with the
T-bit set must have the verification tag copied from
the verification tag of the SHUTDOWN-ACK chunk.

Packets containing ABORT chunk may have the
verification tag set to the same verification tag as the packet causing the
ABORT.

All SCTP chunks has a special layout that they all
adhere to as can be seen above. This isn't an actual header, but rather a
formalized way of how they do look.

Type - bit 0-7. This field specifies the chunk type of the packet, for example
is it an INIT or SHUTDOWN
chunk or what? Each chunk type has a specific number, and is specified in the
image below. Here is a complete list of Chunk types:

Table 2-1. SCTP Types

Chunk Number

Chunk Name

0

Payload Data (DATA)

1

Initiation (INIT)

2

Initiation Acknowledgement (INIT ACK)

3

Selective Acknowledgement (SACK)

4

Heartbeat Request (HEARTBEAT)

5

Heartbeat Acknowledgement (HEARTBEAT ACK)

6

Abort (ABORT)

7

Shutdown (SHUTDOWN)

8

Shutdown Acknowledgement (SHUTDOWN ACK)

9

Operation Error (ERROR)

10

State Cookie (COOKIE ECHO)

11

Cookie Acknowledgement (COOKIE ACK)

12

Reserved for Explicit Congestion Notification Echo
(ECNE)

13

Reserved for Congestion Window Reduced (CWR)

14

Shutdown Complete (SHUTDOWN COMPLETE)

15-62

Reserved for IETF

63

IETF-defined chunk extensions

64-126

reserved to IETF

127

IETF-defined chunk extensions

128-190

reserved to IETF

191

IETF-defined chunk extensions

192-254

reserved to IETF

255

IETF-defined chunk extensions

Chunk Flags - bit 8-15. The chunk flags are generally not
used but are set up for future usage if nothing else. They are chunk specific
flags or bits of information that might be needed for the other peer.
According to specifications, flags are only used in
DATA, ABORT and
SHUTDOWN COMPLETE packets at this moment. This may
change however.

A lot of times when you read an RFC, you might run into some old proven
problems. The RFC 2960 - Stream Control Transmission Protocol document
is one example of this, where they specifically specify that the Chunk flags
should always be set to 0 and ignored unless used for something. This is
written all over the place, and it begs for problems in the future. If you do
firewalling or routing, watch out very carefully for this, since specifications
for fields like this may change in the future and hence break at your firewall
without any legit reason. This happened before with the implementation of ECN
in the IP headers for example. See more in the IP headers section of this chapter.

Chunk Length - bit 16-31. This is the chunk length
calculated in bytes. It includes all headers, including the chunk type, chunk
flags, chunk length and chunk value. If there is no chunk value, the chunk
length will be set to 4 (bytes).

Chunk Value - bit 32-n. This is specific to each chunk and
may contain more flags and data pertaining to the chunk type. Sometimes it
might be empty, in which case the chunk length will be set to 4.

The ABORT chunk is used to abort an association as
previously described in the Shutdown and abort section of this chapter.
ABORT is issued upon unrecoverable errors in the
association such as bad headers or data.

Type - bit 0-7. Always set to 6 for this chunk type.

Reserved - bit 8-14. Reserved for future chunk flags but not used as of writing
this. See the SCTP Common and generic headers for more information about the chunk
flags field.

T-bit - bit 15. If this bit is set to 0, the sender had a
TCB associated with this packet that it
has destroyed. If the sender had no TCB the
T-bit should be set to 1.

Length - bit 16-31. Sets the length of the chunk in bytes including error
causes.

The COOKIE ACK chunk is used during the initialization
of the connection and never anywhere else in the connection. It must precede
all DATA and SACK chunks but
may be sent in the same packet as the first of these packets.

Type - bit 0-7. Always set to 11 for this type.

Chunk flags - bit 8-15. Not used so far. Should always be set to 0 according to
RFC 2960 - Stream Control Transmission Protocol. You should always
watch out for this kind of specific behaviour stated by RFC's since it might
change in the future, and hence break your firewalls etc. Just the same as
happened with IP and ECN. See
the SCTP Common and generic headers
section for more information.

The COOKIE ECHO chunk is used during the
initialization of the SCTP connection by the
initiating party to reply to the cookie sent by the responding party in
the State cookie field in the INIT
ACK packet. It may be sent together with
DATA chunks in the same packet, but must precede the
DATA chunks in such case.

Type - bit 0-7. The chunk type is always set to 10 for this chunk.

Chunk flags - bit 8-15. This field is not used today. The
RFC specifies that the flags should always be set to
0, but this might cause trouble as can be seen in the SCTP Common and generic headers section
above, specifically the Chunk flags explanation.

Length - bit 16-31. Specifies the length of the chunk, including type,
chunk flags, length and cookie fields in bytes.

Cookie - bit 32-n. This field contains the cookie as sent in the previous
INIT ACK chunk. It must be the exact same as the
cookie sent by the responding party for the other end to actually open the
connection. The RFC 2960 - Stream Control Transmission Protocol
specifies that the cookie should be as small as possible to insure
interoperability, which is very vague and doesn't say much.

DATA chunks are used to send actual data through the
stream and have rather complex headers in some ways, but not really worse than
TCP headers in general. Each
DATA chunk may be part of a different stream, since
each SCTP connection can handle several different
streams.

Type - bit 0-7. The Type field should always be set to 0 for DATA chunks.

U-bit - bit 13. The U-bit is used to indicate
if this is an unordered DATA chunk. If it is, the
Stream Sequence Number must be ignored by the
receiving host and send it on to the upper layer without delay or tries to
re-order the DATA chunks.

B-bit - bit 14. The B-bit is used to indicate
the beginning of a fragmented DATA chunk. If this bit
is set and the E (ending) bit is not set, it indicates that this is the first
fragment of a chunk that has been fragmented into several
DATA chunks.

E-bit - bit 15. The E-bit is used to indicate
the ending of a fragmented DATA chunk. If this flag
is set on a chunk, it signals to the SCTP receiver
that it can start reassembling the fragments and pass them on to the upper
layer. If a packet has both the BE-bits set to set to
0, it signals that the chunk is a middle part of a fragmented chunk. If both
BE-bits are set to 1 it signals that the packet is
unfragmented and requires no reassembly et cetera.

Length - bit 16-31. The length of the whole DATA
chunk calculated in bytes,including the chunk type field and on until the end
of the chunk.

TSN - bit 32-63. The Transmission Sequence
Number (TSN) is sent in the
DATA chunk, and the receiving host uses the
TSN to acknowledge that the chunk got through
properly by replying with a SACK chunk. This is an
overall value for the whole SCTP association.

Stream Identifier - bit 64-79. The Stream
Identifier is sent along with the DATA
chunk to identify which stream the DATA chunk is
associated with. This is used since SCTP can
transport several streams within a single association.

Stream Sequence Number - bit 80-95. This is the sequence
number of the chunk for the specific stream identified by the
Stream Identifier. This sequence number is specific
for each stream identifier. If a chunk has been fragmented, the
Stream Sequence Number must be the same for all
fragments of the original chunk.

Payload Protocol Identifier - bit 96-127.
This value is filled in by the upper layers, or applications using the
SCTP protocol as a way to identify to each other the
content of the DATA chunk. The field must always be
sent, including in fragments since routers and firewalls, et cetera, on the
way might need the information. If the value was set to 0, the value was not
set by the upper layers.

User data - bit 128-n. This is the actual data that the chunk is
transporting. It can be of variable length, ending on an even octet. It is the
data in the stream as specified by the stream sequence number n in the stream
S.

The ERROR chunk is sent to inform the other peer of
any problems within the current stream. Each ERROR
chunk can contain one or more Error Causes, which are
more specifically detailed in the RFC 2960 - Stream Control Transmission Protocol document. I will not go into further details
here than the basic ERROR chunk, since it would be too
much information. The ERROR chunk is not fatal in and
of itself, but rather details an error that has happened. It may however be
used together with an ABORT chunk to inform the peer
of the error before killing the connection.

Length - bit 16-31. Specifies the length of the chunk in bytes, including
all the Error Causes.

Error causes - bit 32-n. Each ERROR
chunk may contain one or more Error Causes, which
notifies the opposite peer of a problem with the connection. Each
Error Cause follows a specific format, as described
in the RFC 2960 - Stream Control Transmission Protocol document. We
will not go into them here more than to say that they all contain an
Cause Code, cause length and cause specific
information field. The following Error Causes are
possible:

The HEARTBEAT chunk is sent by one of the peers to
probe and find out if a specific SCTP endpoint address
is up. This is sent to the different addresses that was negotiated during the
initialization of the association to find out if they are all up.

Length - bit 16-31. The length of the whole chunk, including the
Heartbeat Information TLV.

Heartbeat Information TLV - bit 32-n. This
is a variable-length parameter as defined inside the RFC 2960 - Stream Control Transmission Protocol document. This is a mandatory parameter for
the HEARTBEAT chunks that contains 3 fields, info
type = 1, info length and a sender-specific Heartbeat
Information parameter. The last field should be a sender-specific
information field of some kind, for example a timestamp when the heartbeat was
sent and a destination IP address. This is then returned in the
HEARTBEAT ACK chunk.

The INIT chunk is used to initiate a new association
with a destination host, and is the first chunk to be sent by the connecting
host. The INIT chunk contains several mandatory fixed
length parameters, and some optional variable length parameters. The fixed
length mandatory parameters are already in the above headers, and are the
Initiate Tag, Advertised Receiver Window
Credit, Number of Outbound Streams,
Number of Inbound Streams and the Initial
TSN parameters. After this comes a couple of optional parameters,
they will be listed with the optional parameters paragraph below.

Chunk Length - bit 16-31. The chunk length is the length of
the whole packet, including everything in the headers, including the optional
parameters.

Initiate Tag - bit 32-63. The Initiate
Tag is set within the INIT chunk and
must be used by the receiver to acknowledge all packets henceforth, within the
Verification Tag of the established association. The
Initiate Tag may take any value except 0. If the
value is 0 anyways, the receiver must react with an
ABORT.

Advertised Receiver Window Credit (a_rwnd)- bit
64-95. This is the minimum receiving buffer that the sender of the
INIT chunk will allocate for this association, in
bytes. This can then be used by the receiver of the
a_rwnd, to know how much data it can send out without
being SACK'ed. This window should not be lessened,
but it might by sending the new a_rwnd in a SACK
chunk.

Number of Outbound Streams - bit 96-111. This specifies the maximum number of
outbound streams that the connecting host wishes to create to the receiving
host. The value must not be 0, and if it is, the receiving host should
ABORT the association immediately. There is no
negotiation of the minimum number of outbound
or inbound streams, it is simply set to the lowest that either host has set in
the header.

Number of Inbound Streams - bit 112-127.
Specifies the maximum number of inbound connections that the sending peer will
allow the receiving host to create in this association. This must not be set
to 0, or the receiving host should ABORT the
connection. There is no negotiation of the minimum number of outbound or
inbound streams, it is simply set to the lowest that either host has set in
the header.

Initial TSN - bit 128-159. This value sets the initial
Transmit Sequence Number
(TSN) that the sender will use when sending data. The
field may be set to the same value as the Initiate
Tag.

On top of the above mandatory fixed length headers, there are also some
optional variable length parameters that might be set, and at least one of the
IPv4, IPv6 or
Hostname parameters must be set. Only one
Hostname may be set, and if a
Hostname is set, no IPv4 or
IPv6 parameters may be set. Multiple
IPv4 and IPv6 parameters may
also be set in the same INIT chunk. Also, none of
these parameters needs to be set in case the sender only has one address that
can be reached, which is where the chunk should be coming from. These
parameters are used to set up which addresses may be used to connect to the
other end of the association. This is a full list of all the parameters
available in the INIT chunk:

Table 2-3. INIT Variable Parameters

Parameter Name

Status

Type Value

IPv4 Address

Optional

5

IPv6 Address

Optional

6

Cookie Preservative

Optional

9

Host Name Address

Optional

11

Supported Address Types

Optional

12

Reserved for ECN Capable

Optional

32768

Below we describe the three most common Parameters used in the
INIT chunk.

The IPv4 parameter is used to send an
IPv4 address in the INIT
chunk. The IPv4 address can be used to send data
through the association. Multiple IPv4 and
IPv6 addresses can be specified for a single
SCTP association.

Parameter Type - bit 0-15. This is always set to 5 for
IPv4 address parameters.

Length - bit 16-31. This is always set to 8 for IPv4
address parameters.

IPv4 Address - bit 32-63. This is an IPv4 address of
the sending endpoint.

This parameter is used to send IPv6 addresses in the
INIT chunk. This address can then be used to contact
the sending endpoint with this association.

Type - bit 0-15. Always set to 6 for the IPv6
parameters.

Length bit 16-31. Always set to 20 for IPv6
parameters.

IPv6 address - bit 32-159. This is an IPv6 address of
the sending endpoint that can be used to connect to by the receiving endpoint.

The Hostname parameter is used to send a single
hostname as an address. Thea receiving host must then look up the hostname and
use any and/or all of the addresses it receives from there. If a hostname
parameter is sent, no other IPv4,
IPv6 or Hostname parameters
may be sent.

Type - bit 0-15. This is always set to 11 for Hostname
Parameters.

Length - bit 16-31. The length of the whole parameter, including type, length
and hostname field. The Hostname field is variable
length. The length is counted in bytes.

Hostname - bit 32-n. A variable length parameter containing a hostname. The
hostname is resolved by the receiving end to get the addresses that can be used
to contact the sending endpoint.

The INIT ACK chunk is sent in response to a
INIT chunk and contains basically the same headers,
but with values from the recipient of the original
INIT chunk. In addition, it has two extra variable
length parameters, the State Cookie and the
Unrecognized Parameter parameters.

Chunk Length - bit 16-31. The chunk length is the length of
the whole packet, including everything in the headers, and the optional
parameters.

Initiate Tag - bit 32-63. The receiver of the
Initiate Tag of the INIT ACK
chunk must save this value and copy it into the Verification
Tag field of every packet that it sends to the sender of the
INIT ACK chunk. The Initiate
Tag must not be 0, and if it is, the receiver of the
INIT ACK chunk must close the connection with an
ABORT.

Advertised Receiver Window Credit (a_rwnd) - bit
64-95. The dedicated buffers that the sender of this chunk has located for
traffic, counted in bytes. The dedicated buffers should never be lowered to
below this value.

Number of Outbound Streams - bit 96-111.
How many outbound streams that the sending host wishes to create. Must not be
0, or the receiver of the INIT ACK should
ABORT the association. There is no negotiation of the
minimum number of outbound or inbound streams, it is simply set to the lowest
that either host has set in the header.

Number of Inbound Streams - bit 112-127.
How many inbound streams that the sending endpoint is willing to accept. Must
not be 0, or the receiver of the INIT ACK should
ABORT the association. There is no negotiation of the
minimum number of outbound or inbound streams, it is simply set to the lowest
that either host has set in the header.

Initial TSN - bit 128-159. This is set to the
Initial Transmission Sequence Number
(I-TSN) which will be used by the sending party in
the association to start with.

After this point, the INIT ACK chunk continues with
optional variable-length parameters. The parameters are exactly the same as for
the INIT chunk, with the exception of the addition of
the State Cookie and the Unrecognized
Parameters parameter, and the deletion of the
Supported Address Types parameter. The list in other
words look like this:

Table 2-4. INIT ACK Variable Parameters

Parameter Name

Status

Type Value

IPv4 Address

Optional

5

IPv6 Address

Optional

6

State Cookie

Mandatory

7

Unrecognized Parameters

Optional

8

Cookie Preservative

Optional

9

Host Name Address

Optional

11

Reserved for ECN Capable

Optional

32768

The State Cookie is used in INIT
ACK to send a cookie to the other host, and until the receiving
host has replied with a COOKIE ECHO chunk, the
association is not guaranteed. This is to prevent basically the same as a
SYN attack in TCP protocol.

Type - bit 0-15. Always set to 7 for all State Cookie
parameters.

Length - bit 16-31. The size of the whole parameter, including the type, length
and State Cookie field in bytes.

The SACK chunk is used to tell the sender of
DATA chunks which chunks has been received and where
there has been a gap in the stream, based on the received
TSN's. Basically, the SACK
chunk acknowledges that it has received data up to a certain point (the
Cumulative TSN Ack parameter), and then adds
Gap Ack Blocks for all of the data that it has
received after the Cumulative TSN Ack point. A
SACK chunk must not be sent more than once for every
DATA chunk that is received.

Chunk Length - bit 16-31. The chunk length is the length of
the whole chunk, including everything in the headers and all the parameters.

Cumulative TSN Ack - bit 32-63. This is the
Cumulative TSN Ack parameter, which is used to
acknowledge data. The DATA chunk receiver will use
this field to tell the sending host that it has received all data up to this
point of the association. After this point, all data that has not been
specifically acknowledged by the Gap Ack Blocks will,
basically, be considered unaccounted for.

Advertised Receiver Window Credit (a_rwnd) - bit
64-95. The a_rwnd field is basically the same as the
a_rwnd in the INIT and
INIT ACK chunks, but can be used to raise or lower
the a_rwnd value. Please read more in the RFC 2960 - Stream Control Transmission Protocol document about this.

Number of Gap Ack Blocks - bit 96-111. The number of
Gap Ack Blocks listed in this chunk. Each
Gap Ack Block takes up 32 bits in the chunk.

Number of Duplicate TSNs - bit 112-127. The number of
DATA chunks that has been duplicated. Each duplicated
TSN is listed after the Gap Ack
Blocks in the chunk, and each TSN takes
32 bits to send.

Gap Ack Block #1 Start - bit 128-143. This is the first
Gap Ack Block in the SACK
chunk. If there are no gaps in the received DATA
chunk TSN numbers, there will be no Gap
Ack Blocks at all. However, if DATA
chunks are received out of order or some DATA chunks
where lost during transit to the host, there will be gaps. The gaps that has
been seen will be reported with Gap Ack Blocks. The
Gap Ack Block start point is calculated by adding the
Gap Ack Block Start parameter to the
Cumulative TSN value. The calculated value is the
start of the block.

Gap Ack Block #1 End - bit 144-159. This value reports the end
of the first Gap Ack Block in the stream. All the
DATA chunks with the TSN
between the Gap Ack Block Start and the
Gap Ack Block End has been received. The
Gap Ack Block End value is added to the
Cumulative TSN, just as the Start parameter, to get
the actual last TSN of the block chunks to be
Acknowledged.

Gap Ack Block #N Start - bits variable. For every
Gap Ack Block counted in the Number of
Gap Ack Blocks parameter, one Gap Ack
Block is added, until the final N block. Ie, if
Number of Gap Ack Blocks = 2, then there will be two
Gap Ack Blocks in the SACK
chunk. This is the last one simply, and contains the same type of value as the
Gap Ack Block #1 Start.

Gap Ack Block #N End - bits variable. Same as for the
Gap Ack Block #N End, but for the end of the gap.

Duplicate TSN #1 - bits variable. These fields report a duplicate
TSN, in which case we have already received a
specific chunk, but receive the same TSN several
times more. This can either be router glitches (retransmitting already sent
data) or a case of retransmission from the sending endpoint, or a score of
other possibilities. Each instance of a duplicate TSN
should be reported once. For example, if 2 duplicate
TSN's has been received after acknowledging the first
one, each of these duplicate TSN's should be sent
sent in the next SACK message that is being sent. If
even more duplicate TSN's should appear after this
second SACK is sent, the new duplicates should be
added in the next SACK, and so on.

Duplicate TSN #X - bits variable. This is the last duplicate
TSN parameter, containing the same type of
information as the first parameter.

The SHUTDOWN chunk is issued when one of the endpoints
of a connection wants to close the current association. The sending party must
empty all of its sending buffers before sending the
SHUTDOWN chunk, and must not send any more
DATA chunks afterwards. The receiver must also empty
its sending buffers and must then send the responding SHUTDOWN
ACK chunk.

Chunk Length - bit 16-31. The chunk length is the length of
the whole packet, including the Cumulative TSN Ack
parameter. The length of the SHUTDOWN chunk should
always be 8.

Cumulative TSN Ack - bit 32-63. This is a Cumulative
TSN Ack field, just the same as in the
SACK chunk. The Cumulative TSN
Ack acknowledges the last TSN received
in sequence from the opposite endpoint. This parameter does not, nor can the
rest of the SHUTDOWN chunk either, acknowledge
Gap Ack Blocks. The lack of a Gap Ack
Block in the SHUTDOWN chunk that was
acknowledged before should not be interpreted as if the previously
acknowledged block was lost again.

The SHUTDOWN ACK chunk is used to acknowledge a
SHUTDOWN chunk that has been received. Before the
SHUTDOWN ACK chunk is sent, all data in the sending
buffers should be sent, but the buffers must not accept any new data from the
application. SCTP does not support half-open
connections as TCP does.

Type - bit 0-7. This header is always set to 8 for
SHUTDOWN ACK chunks.

T-bit - bit 15. The T-bit is not set to signal
that the sending host had a Transmission Control
Block (TCB) associated with this
connection and that it destroyed. If the T-bit was
set, it had no TCB to destroy.

Length - bit 16-31. This is always set to 4 for SHUTDOWN
COMPLETE chunks, since the chunk should never be any larger, as
long as no updates to the standards are made.