github.com/gopacket/gopacket@v1.1.0/layers/sctp.go (about)

     1  // Copyright 2012 Google, Inc. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file in the root of the source
     5  // tree.
     6  
     7  package layers
     8  
     9  import (
    10  	"encoding/binary"
    11  	"errors"
    12  	"fmt"
    13  	"hash/crc32"
    14  
    15  	"github.com/gopacket/gopacket"
    16  )
    17  
    18  // SCTP contains information on the top level of an SCTP packet.
    19  type SCTP struct {
    20  	BaseLayer
    21  	SrcPort, DstPort SCTPPort
    22  	VerificationTag  uint32
    23  	Checksum         uint32
    24  	sPort, dPort     []byte
    25  }
    26  
    27  // LayerType returns gopacket.LayerTypeSCTP
    28  func (s *SCTP) LayerType() gopacket.LayerType { return LayerTypeSCTP }
    29  
    30  func decodeSCTP(data []byte, p gopacket.PacketBuilder) error {
    31  	sctp := &SCTP{}
    32  	err := sctp.DecodeFromBytes(data, p)
    33  	p.AddLayer(sctp)
    34  	p.SetTransportLayer(sctp)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	return p.NextDecoder(sctpChunkTypePrefixDecoder)
    39  }
    40  
    41  var sctpChunkTypePrefixDecoder = gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)
    42  
    43  // TransportFlow returns a flow based on the source and destination SCTP port.
    44  func (s *SCTP) TransportFlow() gopacket.Flow {
    45  	return gopacket.NewFlow(EndpointSCTPPort, s.sPort, s.dPort)
    46  }
    47  
    48  func decodeWithSCTPChunkTypePrefix(data []byte, p gopacket.PacketBuilder) error {
    49  	chunkType := SCTPChunkType(data[0])
    50  	return chunkType.Decode(data, p)
    51  }
    52  
    53  // SerializeTo is for gopacket.SerializableLayer.
    54  func (s SCTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
    55  	bytes, err := b.PrependBytes(12)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	binary.BigEndian.PutUint16(bytes[0:2], uint16(s.SrcPort))
    60  	binary.BigEndian.PutUint16(bytes[2:4], uint16(s.DstPort))
    61  	binary.BigEndian.PutUint32(bytes[4:8], s.VerificationTag)
    62  	if opts.ComputeChecksums {
    63  		// Note:  MakeTable(Castagnoli) actually only creates the table once, then
    64  		// passes back a singleton on every other call, so this shouldn't cause
    65  		// excessive memory allocation.
    66  		binary.LittleEndian.PutUint32(bytes[8:12], crc32.Checksum(b.Bytes(), crc32.MakeTable(crc32.Castagnoli)))
    67  	}
    68  	return nil
    69  }
    70  
    71  func (sctp *SCTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
    72  	if len(data) < 12 {
    73  		return errors.New("Invalid SCTP common header length")
    74  	}
    75  	sctp.SrcPort = SCTPPort(binary.BigEndian.Uint16(data[:2]))
    76  	sctp.sPort = data[:2]
    77  	sctp.DstPort = SCTPPort(binary.BigEndian.Uint16(data[2:4]))
    78  	sctp.dPort = data[2:4]
    79  	sctp.VerificationTag = binary.BigEndian.Uint32(data[4:8])
    80  	sctp.Checksum = binary.BigEndian.Uint32(data[8:12])
    81  	sctp.BaseLayer = BaseLayer{data[:12], data[12:]}
    82  
    83  	return nil
    84  }
    85  
    86  func (t *SCTP) CanDecode() gopacket.LayerClass {
    87  	return LayerTypeSCTP
    88  }
    89  
    90  func (t *SCTP) NextLayerType() gopacket.LayerType {
    91  	return gopacket.LayerTypePayload
    92  }
    93  
    94  // SCTPChunk contains the common fields in all SCTP chunks.
    95  type SCTPChunk struct {
    96  	BaseLayer
    97  	Type   SCTPChunkType
    98  	Flags  uint8
    99  	Length uint16
   100  	// ActualLength is the total length of an SCTP chunk, including padding.
   101  	// SCTP chunks start and end on 4-byte boundaries.  So if a chunk has a length
   102  	// of 18, it means that it has data up to and including byte 18, then padding
   103  	// up to the next 4-byte boundary, 20.  In this case, Length would be 18, and
   104  	// ActualLength would be 20.
   105  	ActualLength int
   106  }
   107  
   108  func roundUpToNearest4(i int) int {
   109  	if i%4 == 0 {
   110  		return i
   111  	}
   112  	return i + 4 - (i % 4)
   113  }
   114  
   115  func decodeSCTPChunk(data []byte) (SCTPChunk, error) {
   116  	length := binary.BigEndian.Uint16(data[2:4])
   117  	if length < 4 {
   118  		return SCTPChunk{}, errors.New("invalid SCTP chunk length")
   119  	}
   120  	actual := roundUpToNearest4(int(length))
   121  	ct := SCTPChunkType(data[0])
   122  
   123  	// For SCTP Data, use a separate layer for the payload
   124  	delta := 0
   125  	if ct == SCTPChunkTypeData {
   126  		delta = int(actual) - int(length)
   127  		actual = 16
   128  	}
   129  
   130  	return SCTPChunk{
   131  		Type:         ct,
   132  		Flags:        data[1],
   133  		Length:       length,
   134  		ActualLength: actual,
   135  		BaseLayer:    BaseLayer{data[:actual], data[actual : len(data)-delta]},
   136  	}, nil
   137  }
   138  
   139  // SCTPParameter is a TLV parameter inside a SCTPChunk.
   140  type SCTPParameter struct {
   141  	Type         uint16
   142  	Length       uint16
   143  	ActualLength int
   144  	Value        []byte
   145  }
   146  
   147  func decodeSCTPParameter(data []byte) SCTPParameter {
   148  	length := binary.BigEndian.Uint16(data[2:4])
   149  	return SCTPParameter{
   150  		Type:         binary.BigEndian.Uint16(data[0:2]),
   151  		Length:       length,
   152  		Value:        data[4:length],
   153  		ActualLength: roundUpToNearest4(int(length)),
   154  	}
   155  }
   156  
   157  func (p SCTPParameter) Bytes() []byte {
   158  	length := 4 + len(p.Value)
   159  	data := make([]byte, roundUpToNearest4(length))
   160  	binary.BigEndian.PutUint16(data[0:2], p.Type)
   161  	binary.BigEndian.PutUint16(data[2:4], uint16(length))
   162  	copy(data[4:], p.Value)
   163  	return data
   164  }
   165  
   166  // SCTPUnknownChunkType is the layer type returned when we don't recognize the
   167  // chunk type.  Since there's a length in a known location, we can skip over
   168  // it even if we don't know what it is, and continue parsing the rest of the
   169  // chunks.  This chunk is stored as an ErrorLayer in the packet.
   170  type SCTPUnknownChunkType struct {
   171  	SCTPChunk
   172  	bytes []byte
   173  }
   174  
   175  func decodeSCTPChunkTypeUnknown(data []byte, p gopacket.PacketBuilder) error {
   176  	chunk, err := decodeSCTPChunk(data)
   177  	if err != nil {
   178  		return err
   179  	}
   180  	sc := &SCTPUnknownChunkType{SCTPChunk: chunk}
   181  	sc.bytes = data[:sc.ActualLength]
   182  	p.AddLayer(sc)
   183  	p.SetErrorLayer(sc)
   184  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   185  }
   186  
   187  // SerializeTo is for gopacket.SerializableLayer.
   188  func (s SCTPUnknownChunkType) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   189  	bytes, err := b.PrependBytes(s.ActualLength)
   190  	if err != nil {
   191  		return err
   192  	}
   193  	copy(bytes, s.bytes)
   194  	return nil
   195  }
   196  
   197  // LayerType returns gopacket.LayerTypeSCTPUnknownChunkType.
   198  func (s *SCTPUnknownChunkType) LayerType() gopacket.LayerType { return LayerTypeSCTPUnknownChunkType }
   199  
   200  // Payload returns all bytes in this header, including the decoded Type, Length,
   201  // and Flags.
   202  func (s *SCTPUnknownChunkType) Payload() []byte { return s.bytes }
   203  
   204  // Error implements ErrorLayer.
   205  func (s *SCTPUnknownChunkType) Error() error {
   206  	return fmt.Errorf("No decode method available for SCTP chunk type %s", s.Type)
   207  }
   208  
   209  // SCTPData is the SCTP Data chunk layer.
   210  type SCTPData struct {
   211  	SCTPChunk
   212  	Unordered, BeginFragment, EndFragment bool
   213  	TSN                                   uint32
   214  	StreamId                              uint16
   215  	StreamSequence                        uint16
   216  	PayloadProtocol                       SCTPPayloadProtocol
   217  }
   218  
   219  // LayerType returns gopacket.LayerTypeSCTPData.
   220  func (s *SCTPData) LayerType() gopacket.LayerType { return LayerTypeSCTPData }
   221  
   222  // SCTPPayloadProtocol represents a payload protocol
   223  type SCTPPayloadProtocol uint32
   224  
   225  // SCTPPayloadProtocol constonts from http://www.iana.org/assignments/sctp-parameters/sctp-parameters.xhtml
   226  const (
   227  	SCTPProtocolReserved  SCTPPayloadProtocol = 0
   228  	SCTPPayloadUIA                            = 1
   229  	SCTPPayloadM2UA                           = 2
   230  	SCTPPayloadM3UA                           = 3
   231  	SCTPPayloadSUA                            = 4
   232  	SCTPPayloadM2PA                           = 5
   233  	SCTPPayloadV5UA                           = 6
   234  	SCTPPayloadH248                           = 7
   235  	SCTPPayloadBICC                           = 8
   236  	SCTPPayloadTALI                           = 9
   237  	SCTPPayloadDUA                            = 10
   238  	SCTPPayloadASAP                           = 11
   239  	SCTPPayloadENRP                           = 12
   240  	SCTPPayloadH323                           = 13
   241  	SCTPPayloadQIPC                           = 14
   242  	SCTPPayloadSIMCO                          = 15
   243  	SCTPPayloadDDPSegment                     = 16
   244  	SCTPPayloadDDPStream                      = 17
   245  	SCTPPayloadS1AP                           = 18
   246  )
   247  
   248  func (p SCTPPayloadProtocol) String() string {
   249  	switch p {
   250  	case SCTPProtocolReserved:
   251  		return "Reserved"
   252  	case SCTPPayloadUIA:
   253  		return "UIA"
   254  	case SCTPPayloadM2UA:
   255  		return "M2UA"
   256  	case SCTPPayloadM3UA:
   257  		return "M3UA"
   258  	case SCTPPayloadSUA:
   259  		return "SUA"
   260  	case SCTPPayloadM2PA:
   261  		return "M2PA"
   262  	case SCTPPayloadV5UA:
   263  		return "V5UA"
   264  	case SCTPPayloadH248:
   265  		return "H.248"
   266  	case SCTPPayloadBICC:
   267  		return "BICC"
   268  	case SCTPPayloadTALI:
   269  		return "TALI"
   270  	case SCTPPayloadDUA:
   271  		return "DUA"
   272  	case SCTPPayloadASAP:
   273  		return "ASAP"
   274  	case SCTPPayloadENRP:
   275  		return "ENRP"
   276  	case SCTPPayloadH323:
   277  		return "H.323"
   278  	case SCTPPayloadQIPC:
   279  		return "QIPC"
   280  	case SCTPPayloadSIMCO:
   281  		return "SIMCO"
   282  	case SCTPPayloadDDPSegment:
   283  		return "DDPSegment"
   284  	case SCTPPayloadDDPStream:
   285  		return "DDPStream"
   286  	case SCTPPayloadS1AP:
   287  		return "S1AP"
   288  	}
   289  	return fmt.Sprintf("Unknown(%d)", p)
   290  }
   291  
   292  func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error {
   293  	chunk, err := decodeSCTPChunk(data)
   294  	if err != nil {
   295  		return err
   296  	}
   297  	sc := &SCTPData{
   298  		SCTPChunk:       chunk,
   299  		Unordered:       data[1]&0x4 != 0,
   300  		BeginFragment:   data[1]&0x2 != 0,
   301  		EndFragment:     data[1]&0x1 != 0,
   302  		TSN:             binary.BigEndian.Uint32(data[4:8]),
   303  		StreamId:        binary.BigEndian.Uint16(data[8:10]),
   304  		StreamSequence:  binary.BigEndian.Uint16(data[10:12]),
   305  		PayloadProtocol: SCTPPayloadProtocol(binary.BigEndian.Uint32(data[12:16])),
   306  	}
   307  	// Length is the length in bytes of the data, INCLUDING the 16-byte header.
   308  	p.AddLayer(sc)
   309  	return p.NextDecoder(gopacket.LayerTypePayload)
   310  }
   311  
   312  // SerializeTo is for gopacket.SerializableLayer.
   313  func (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   314  	payload := b.Bytes()
   315  	// Pad the payload to a 32 bit boundary
   316  	if rem := len(payload) % 4; rem != 0 {
   317  		b.AppendBytes(4 - rem)
   318  	}
   319  	length := 16
   320  	bytes, err := b.PrependBytes(length)
   321  	if err != nil {
   322  		return err
   323  	}
   324  	bytes[0] = uint8(sc.Type)
   325  	flags := uint8(0)
   326  	if sc.Unordered {
   327  		flags |= 0x4
   328  	}
   329  	if sc.BeginFragment {
   330  		flags |= 0x2
   331  	}
   332  	if sc.EndFragment {
   333  		flags |= 0x1
   334  	}
   335  	bytes[1] = flags
   336  	binary.BigEndian.PutUint16(bytes[2:4], uint16(length+len(payload)))
   337  	binary.BigEndian.PutUint32(bytes[4:8], sc.TSN)
   338  	binary.BigEndian.PutUint16(bytes[8:10], sc.StreamId)
   339  	binary.BigEndian.PutUint16(bytes[10:12], sc.StreamSequence)
   340  	binary.BigEndian.PutUint32(bytes[12:16], uint32(sc.PayloadProtocol))
   341  	return nil
   342  }
   343  
   344  // SCTPInitParameter is a parameter for an SCTP Init or InitAck packet.
   345  type SCTPInitParameter SCTPParameter
   346  
   347  // SCTPInit is used as the return value for both SCTPInit and SCTPInitAck
   348  // messages.
   349  type SCTPInit struct {
   350  	SCTPChunk
   351  	InitiateTag                     uint32
   352  	AdvertisedReceiverWindowCredit  uint32
   353  	OutboundStreams, InboundStreams uint16
   354  	InitialTSN                      uint32
   355  	Parameters                      []SCTPInitParameter
   356  }
   357  
   358  // LayerType returns either gopacket.LayerTypeSCTPInit or gopacket.LayerTypeSCTPInitAck.
   359  func (sc *SCTPInit) LayerType() gopacket.LayerType {
   360  	if sc.Type == SCTPChunkTypeInitAck {
   361  		return LayerTypeSCTPInitAck
   362  	}
   363  	// sc.Type == SCTPChunkTypeInit
   364  	return LayerTypeSCTPInit
   365  }
   366  
   367  func decodeSCTPInit(data []byte, p gopacket.PacketBuilder) error {
   368  	chunk, err := decodeSCTPChunk(data)
   369  	if err != nil {
   370  		return err
   371  	}
   372  	sc := &SCTPInit{
   373  		SCTPChunk:                      chunk,
   374  		InitiateTag:                    binary.BigEndian.Uint32(data[4:8]),
   375  		AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),
   376  		OutboundStreams:                binary.BigEndian.Uint16(data[12:14]),
   377  		InboundStreams:                 binary.BigEndian.Uint16(data[14:16]),
   378  		InitialTSN:                     binary.BigEndian.Uint32(data[16:20]),
   379  	}
   380  	paramData := data[20:sc.ActualLength]
   381  	for len(paramData) > 0 {
   382  		p := SCTPInitParameter(decodeSCTPParameter(paramData))
   383  		paramData = paramData[p.ActualLength:]
   384  		sc.Parameters = append(sc.Parameters, p)
   385  	}
   386  	p.AddLayer(sc)
   387  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   388  }
   389  
   390  // SerializeTo is for gopacket.SerializableLayer.
   391  func (sc SCTPInit) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   392  	var payload []byte
   393  	for _, param := range sc.Parameters {
   394  		payload = append(payload, SCTPParameter(param).Bytes()...)
   395  	}
   396  	length := 20 + len(payload)
   397  	bytes, err := b.PrependBytes(roundUpToNearest4(length))
   398  	if err != nil {
   399  		return err
   400  	}
   401  	bytes[0] = uint8(sc.Type)
   402  	bytes[1] = sc.Flags
   403  	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
   404  	binary.BigEndian.PutUint32(bytes[4:8], sc.InitiateTag)
   405  	binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)
   406  	binary.BigEndian.PutUint16(bytes[12:14], sc.OutboundStreams)
   407  	binary.BigEndian.PutUint16(bytes[14:16], sc.InboundStreams)
   408  	binary.BigEndian.PutUint32(bytes[16:20], sc.InitialTSN)
   409  	copy(bytes[20:], payload)
   410  	return nil
   411  }
   412  
   413  // SCTPSack is the SCTP Selective ACK chunk layer.
   414  type SCTPSack struct {
   415  	SCTPChunk
   416  	CumulativeTSNAck               uint32
   417  	AdvertisedReceiverWindowCredit uint32
   418  	NumGapACKs, NumDuplicateTSNs   uint16
   419  	GapACKs                        []uint16
   420  	DuplicateTSNs                  []uint32
   421  }
   422  
   423  // LayerType return LayerTypeSCTPSack
   424  func (sc *SCTPSack) LayerType() gopacket.LayerType {
   425  	return LayerTypeSCTPSack
   426  }
   427  
   428  func decodeSCTPSack(data []byte, p gopacket.PacketBuilder) error {
   429  	chunk, err := decodeSCTPChunk(data)
   430  	if err != nil {
   431  		return err
   432  	}
   433  	sc := &SCTPSack{
   434  		SCTPChunk:                      chunk,
   435  		CumulativeTSNAck:               binary.BigEndian.Uint32(data[4:8]),
   436  		AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),
   437  		NumGapACKs:                     binary.BigEndian.Uint16(data[12:14]),
   438  		NumDuplicateTSNs:               binary.BigEndian.Uint16(data[14:16]),
   439  	}
   440  	// We maximize gapAcks and dupTSNs here so we're not allocating tons
   441  	// of memory based on a user-controlable field.  Our maximums are not exact,
   442  	// but should give us sane defaults... we'll still hit slice boundaries and
   443  	// fail if the user-supplied values are too high (in the for loops below), but
   444  	// the amount of memory we'll have allocated because of that should be small
   445  	// (< sc.ActualLength)
   446  	gapAcks := sc.SCTPChunk.ActualLength / 2
   447  	dupTSNs := (sc.SCTPChunk.ActualLength - gapAcks*2) / 4
   448  	if gapAcks > int(sc.NumGapACKs) {
   449  		gapAcks = int(sc.NumGapACKs)
   450  	}
   451  	if dupTSNs > int(sc.NumDuplicateTSNs) {
   452  		dupTSNs = int(sc.NumDuplicateTSNs)
   453  	}
   454  	sc.GapACKs = make([]uint16, 0, gapAcks)
   455  	sc.DuplicateTSNs = make([]uint32, 0, dupTSNs)
   456  	bytesRemaining := data[16:]
   457  	for i := 0; i < int(sc.NumGapACKs); i++ {
   458  		sc.GapACKs = append(sc.GapACKs, binary.BigEndian.Uint16(bytesRemaining[:2]))
   459  		bytesRemaining = bytesRemaining[2:]
   460  	}
   461  	for i := 0; i < int(sc.NumDuplicateTSNs); i++ {
   462  		sc.DuplicateTSNs = append(sc.DuplicateTSNs, binary.BigEndian.Uint32(bytesRemaining[:4]))
   463  		bytesRemaining = bytesRemaining[4:]
   464  	}
   465  	p.AddLayer(sc)
   466  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   467  }
   468  
   469  // SerializeTo is for gopacket.SerializableLayer.
   470  func (sc SCTPSack) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   471  	length := 16 + 2*len(sc.GapACKs) + 4*len(sc.DuplicateTSNs)
   472  	bytes, err := b.PrependBytes(roundUpToNearest4(length))
   473  	if err != nil {
   474  		return err
   475  	}
   476  	bytes[0] = uint8(sc.Type)
   477  	bytes[1] = sc.Flags
   478  	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
   479  	binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)
   480  	binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)
   481  	binary.BigEndian.PutUint16(bytes[12:14], uint16(len(sc.GapACKs)))
   482  	binary.BigEndian.PutUint16(bytes[14:16], uint16(len(sc.DuplicateTSNs)))
   483  	for i, v := range sc.GapACKs {
   484  		binary.BigEndian.PutUint16(bytes[16+i*2:], v)
   485  	}
   486  	offset := 16 + 2*len(sc.GapACKs)
   487  	for i, v := range sc.DuplicateTSNs {
   488  		binary.BigEndian.PutUint32(bytes[offset+i*4:], v)
   489  	}
   490  	return nil
   491  }
   492  
   493  // SCTPHeartbeatParameter is the parameter type used by SCTP heartbeat and
   494  // heartbeat ack layers.
   495  type SCTPHeartbeatParameter SCTPParameter
   496  
   497  // SCTPHeartbeat is the SCTP heartbeat layer, also used for heatbeat ack.
   498  type SCTPHeartbeat struct {
   499  	SCTPChunk
   500  	Parameters []SCTPHeartbeatParameter
   501  }
   502  
   503  // LayerType returns gopacket.LayerTypeSCTPHeartbeat.
   504  func (sc *SCTPHeartbeat) LayerType() gopacket.LayerType {
   505  	if sc.Type == SCTPChunkTypeHeartbeatAck {
   506  		return LayerTypeSCTPHeartbeatAck
   507  	}
   508  	// sc.Type == SCTPChunkTypeHeartbeat
   509  	return LayerTypeSCTPHeartbeat
   510  }
   511  
   512  func decodeSCTPHeartbeat(data []byte, p gopacket.PacketBuilder) error {
   513  	chunk, err := decodeSCTPChunk(data)
   514  	if err != nil {
   515  		return err
   516  	}
   517  	sc := &SCTPHeartbeat{
   518  		SCTPChunk: chunk,
   519  	}
   520  	paramData := data[4:sc.Length]
   521  	for len(paramData) > 0 {
   522  		p := SCTPHeartbeatParameter(decodeSCTPParameter(paramData))
   523  		paramData = paramData[p.ActualLength:]
   524  		sc.Parameters = append(sc.Parameters, p)
   525  	}
   526  	p.AddLayer(sc)
   527  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   528  }
   529  
   530  // SerializeTo is for gopacket.SerializableLayer.
   531  func (sc SCTPHeartbeat) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   532  	var payload []byte
   533  	for _, param := range sc.Parameters {
   534  		payload = append(payload, SCTPParameter(param).Bytes()...)
   535  	}
   536  	length := 4 + len(payload)
   537  
   538  	bytes, err := b.PrependBytes(roundUpToNearest4(length))
   539  	if err != nil {
   540  		return err
   541  	}
   542  	bytes[0] = uint8(sc.Type)
   543  	bytes[1] = sc.Flags
   544  	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
   545  	copy(bytes[4:], payload)
   546  	return nil
   547  }
   548  
   549  // SCTPErrorParameter is the parameter type used by SCTP Abort and Error layers.
   550  type SCTPErrorParameter SCTPParameter
   551  
   552  // SCTPError is the SCTP error layer, also used for SCTP aborts.
   553  type SCTPError struct {
   554  	SCTPChunk
   555  	Parameters []SCTPErrorParameter
   556  }
   557  
   558  // LayerType returns LayerTypeSCTPAbort or LayerTypeSCTPError.
   559  func (sc *SCTPError) LayerType() gopacket.LayerType {
   560  	if sc.Type == SCTPChunkTypeAbort {
   561  		return LayerTypeSCTPAbort
   562  	}
   563  	// sc.Type == SCTPChunkTypeError
   564  	return LayerTypeSCTPError
   565  }
   566  
   567  func decodeSCTPError(data []byte, p gopacket.PacketBuilder) error {
   568  	// remarkably similar to decodeSCTPHeartbeat ;)
   569  	chunk, err := decodeSCTPChunk(data)
   570  	if err != nil {
   571  		return err
   572  	}
   573  	sc := &SCTPError{
   574  		SCTPChunk: chunk,
   575  	}
   576  	paramData := data[4:sc.Length]
   577  	for len(paramData) > 0 {
   578  		p := SCTPErrorParameter(decodeSCTPParameter(paramData))
   579  		paramData = paramData[p.ActualLength:]
   580  		sc.Parameters = append(sc.Parameters, p)
   581  	}
   582  	p.AddLayer(sc)
   583  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   584  }
   585  
   586  // SerializeTo is for gopacket.SerializableLayer.
   587  func (sc SCTPError) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   588  	var payload []byte
   589  	for _, param := range sc.Parameters {
   590  		payload = append(payload, SCTPParameter(param).Bytes()...)
   591  	}
   592  	length := 4 + len(payload)
   593  
   594  	bytes, err := b.PrependBytes(roundUpToNearest4(length))
   595  	if err != nil {
   596  		return err
   597  	}
   598  	bytes[0] = uint8(sc.Type)
   599  	bytes[1] = sc.Flags
   600  	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
   601  	copy(bytes[4:], payload)
   602  	return nil
   603  }
   604  
   605  // SCTPShutdown is the SCTP shutdown layer.
   606  type SCTPShutdown struct {
   607  	SCTPChunk
   608  	CumulativeTSNAck uint32
   609  }
   610  
   611  // LayerType returns gopacket.LayerTypeSCTPShutdown.
   612  func (sc *SCTPShutdown) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdown }
   613  
   614  func decodeSCTPShutdown(data []byte, p gopacket.PacketBuilder) error {
   615  	chunk, err := decodeSCTPChunk(data)
   616  	if err != nil {
   617  		return err
   618  	}
   619  	sc := &SCTPShutdown{
   620  		SCTPChunk:        chunk,
   621  		CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]),
   622  	}
   623  	p.AddLayer(sc)
   624  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   625  }
   626  
   627  // SerializeTo is for gopacket.SerializableLayer.
   628  func (sc SCTPShutdown) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   629  	bytes, err := b.PrependBytes(8)
   630  	if err != nil {
   631  		return err
   632  	}
   633  	bytes[0] = uint8(sc.Type)
   634  	bytes[1] = sc.Flags
   635  	binary.BigEndian.PutUint16(bytes[2:4], 8)
   636  	binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)
   637  	return nil
   638  }
   639  
   640  // SCTPShutdownAck is the SCTP shutdown layer.
   641  type SCTPShutdownAck struct {
   642  	SCTPChunk
   643  }
   644  
   645  // LayerType returns gopacket.LayerTypeSCTPShutdownAck.
   646  func (sc *SCTPShutdownAck) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdownAck }
   647  
   648  func decodeSCTPShutdownAck(data []byte, p gopacket.PacketBuilder) error {
   649  	chunk, err := decodeSCTPChunk(data)
   650  	if err != nil {
   651  		return err
   652  	}
   653  	sc := &SCTPShutdownAck{
   654  		SCTPChunk: chunk,
   655  	}
   656  	p.AddLayer(sc)
   657  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   658  }
   659  
   660  // SerializeTo is for gopacket.SerializableLayer.
   661  func (sc SCTPShutdownAck) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   662  	bytes, err := b.PrependBytes(4)
   663  	if err != nil {
   664  		return err
   665  	}
   666  	bytes[0] = uint8(sc.Type)
   667  	bytes[1] = sc.Flags
   668  	binary.BigEndian.PutUint16(bytes[2:4], 4)
   669  	return nil
   670  }
   671  
   672  // SCTPCookieEcho is the SCTP Cookie Echo layer.
   673  type SCTPCookieEcho struct {
   674  	SCTPChunk
   675  	Cookie []byte
   676  }
   677  
   678  // LayerType returns gopacket.LayerTypeSCTPCookieEcho.
   679  func (sc *SCTPCookieEcho) LayerType() gopacket.LayerType { return LayerTypeSCTPCookieEcho }
   680  
   681  func decodeSCTPCookieEcho(data []byte, p gopacket.PacketBuilder) error {
   682  	chunk, err := decodeSCTPChunk(data)
   683  	if err != nil {
   684  		return err
   685  	}
   686  	sc := &SCTPCookieEcho{
   687  		SCTPChunk: chunk,
   688  	}
   689  	sc.Cookie = data[4:sc.Length]
   690  	p.AddLayer(sc)
   691  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   692  }
   693  
   694  // SerializeTo is for gopacket.SerializableLayer.
   695  func (sc SCTPCookieEcho) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   696  	length := 4 + len(sc.Cookie)
   697  	bytes, err := b.PrependBytes(roundUpToNearest4(length))
   698  	if err != nil {
   699  		return err
   700  	}
   701  	bytes[0] = uint8(sc.Type)
   702  	bytes[1] = sc.Flags
   703  	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
   704  	copy(bytes[4:], sc.Cookie)
   705  	return nil
   706  }
   707  
   708  // This struct is used by all empty SCTP chunks (currently CookieAck and
   709  // ShutdownComplete).
   710  type SCTPEmptyLayer struct {
   711  	SCTPChunk
   712  }
   713  
   714  // LayerType returns either gopacket.LayerTypeSCTPShutdownComplete or
   715  // LayerTypeSCTPCookieAck.
   716  func (sc *SCTPEmptyLayer) LayerType() gopacket.LayerType {
   717  	if sc.Type == SCTPChunkTypeShutdownComplete {
   718  		return LayerTypeSCTPShutdownComplete
   719  	}
   720  	// sc.Type == SCTPChunkTypeCookieAck
   721  	return LayerTypeSCTPCookieAck
   722  }
   723  
   724  func decodeSCTPEmptyLayer(data []byte, p gopacket.PacketBuilder) error {
   725  	chunk, err := decodeSCTPChunk(data)
   726  	if err != nil {
   727  		return err
   728  	}
   729  	sc := &SCTPEmptyLayer{
   730  		SCTPChunk: chunk,
   731  	}
   732  	p.AddLayer(sc)
   733  	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
   734  }
   735  
   736  // SerializeTo is for gopacket.SerializableLayer.
   737  func (sc SCTPEmptyLayer) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   738  	bytes, err := b.PrependBytes(4)
   739  	if err != nil {
   740  		return err
   741  	}
   742  	bytes[0] = uint8(sc.Type)
   743  	bytes[1] = sc.Flags
   744  	binary.BigEndian.PutUint16(bytes[2:4], 4)
   745  	return nil
   746  }