diff --git a/vendor/github.com/google/gopacket/layers/sctp.go b/vendor/github.com/google/gopacket/layers/sctp.go
new file mode 100644
index 0000000..511176e
--- /dev/null
+++ b/vendor/github.com/google/gopacket/layers/sctp.go
@@ -0,0 +1,746 @@
+// Copyright 2012 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+package layers
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"hash/crc32"
+
+	"github.com/google/gopacket"
+)
+
+// SCTP contains information on the top level of an SCTP packet.
+type SCTP struct {
+	BaseLayer
+	SrcPort, DstPort SCTPPort
+	VerificationTag  uint32
+	Checksum         uint32
+	sPort, dPort     []byte
+}
+
+// LayerType returns gopacket.LayerTypeSCTP
+func (s *SCTP) LayerType() gopacket.LayerType { return LayerTypeSCTP }
+
+func decodeSCTP(data []byte, p gopacket.PacketBuilder) error {
+	sctp := &SCTP{}
+	err := sctp.DecodeFromBytes(data, p)
+	p.AddLayer(sctp)
+	p.SetTransportLayer(sctp)
+	if err != nil {
+		return err
+	}
+	return p.NextDecoder(sctpChunkTypePrefixDecoder)
+}
+
+var sctpChunkTypePrefixDecoder = gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)
+
+// TransportFlow returns a flow based on the source and destination SCTP port.
+func (s *SCTP) TransportFlow() gopacket.Flow {
+	return gopacket.NewFlow(EndpointSCTPPort, s.sPort, s.dPort)
+}
+
+func decodeWithSCTPChunkTypePrefix(data []byte, p gopacket.PacketBuilder) error {
+	chunkType := SCTPChunkType(data[0])
+	return chunkType.Decode(data, p)
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (s SCTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	bytes, err := b.PrependBytes(12)
+	if err != nil {
+		return err
+	}
+	binary.BigEndian.PutUint16(bytes[0:2], uint16(s.SrcPort))
+	binary.BigEndian.PutUint16(bytes[2:4], uint16(s.DstPort))
+	binary.BigEndian.PutUint32(bytes[4:8], s.VerificationTag)
+	if opts.ComputeChecksums {
+		// Note:  MakeTable(Castagnoli) actually only creates the table once, then
+		// passes back a singleton on every other call, so this shouldn't cause
+		// excessive memory allocation.
+		binary.LittleEndian.PutUint32(bytes[8:12], crc32.Checksum(b.Bytes(), crc32.MakeTable(crc32.Castagnoli)))
+	}
+	return nil
+}
+
+func (sctp *SCTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 12 {
+		return errors.New("Invalid SCTP common header length")
+	}
+	sctp.SrcPort = SCTPPort(binary.BigEndian.Uint16(data[:2]))
+	sctp.sPort = data[:2]
+	sctp.DstPort = SCTPPort(binary.BigEndian.Uint16(data[2:4]))
+	sctp.dPort = data[2:4]
+	sctp.VerificationTag = binary.BigEndian.Uint32(data[4:8])
+	sctp.Checksum = binary.BigEndian.Uint32(data[8:12])
+	sctp.BaseLayer = BaseLayer{data[:12], data[12:]}
+
+	return nil
+}
+
+func (t *SCTP) CanDecode() gopacket.LayerClass {
+	return LayerTypeSCTP
+}
+
+func (t *SCTP) NextLayerType() gopacket.LayerType {
+	return gopacket.LayerTypePayload
+}
+
+// SCTPChunk contains the common fields in all SCTP chunks.
+type SCTPChunk struct {
+	BaseLayer
+	Type   SCTPChunkType
+	Flags  uint8
+	Length uint16
+	// ActualLength is the total length of an SCTP chunk, including padding.
+	// SCTP chunks start and end on 4-byte boundaries.  So if a chunk has a length
+	// of 18, it means that it has data up to and including byte 18, then padding
+	// up to the next 4-byte boundary, 20.  In this case, Length would be 18, and
+	// ActualLength would be 20.
+	ActualLength int
+}
+
+func roundUpToNearest4(i int) int {
+	if i%4 == 0 {
+		return i
+	}
+	return i + 4 - (i % 4)
+}
+
+func decodeSCTPChunk(data []byte) (SCTPChunk, error) {
+	length := binary.BigEndian.Uint16(data[2:4])
+	if length < 4 {
+		return SCTPChunk{}, errors.New("invalid SCTP chunk length")
+	}
+	actual := roundUpToNearest4(int(length))
+	ct := SCTPChunkType(data[0])
+
+	// For SCTP Data, use a separate layer for the payload
+	delta := 0
+	if ct == SCTPChunkTypeData {
+		delta = int(actual) - int(length)
+		actual = 16
+	}
+
+	return SCTPChunk{
+		Type:         ct,
+		Flags:        data[1],
+		Length:       length,
+		ActualLength: actual,
+		BaseLayer:    BaseLayer{data[:actual], data[actual : len(data)-delta]},
+	}, nil
+}
+
+// SCTPParameter is a TLV parameter inside a SCTPChunk.
+type SCTPParameter struct {
+	Type         uint16
+	Length       uint16
+	ActualLength int
+	Value        []byte
+}
+
+func decodeSCTPParameter(data []byte) SCTPParameter {
+	length := binary.BigEndian.Uint16(data[2:4])
+	return SCTPParameter{
+		Type:         binary.BigEndian.Uint16(data[0:2]),
+		Length:       length,
+		Value:        data[4:length],
+		ActualLength: roundUpToNearest4(int(length)),
+	}
+}
+
+func (p SCTPParameter) Bytes() []byte {
+	length := 4 + len(p.Value)
+	data := make([]byte, roundUpToNearest4(length))
+	binary.BigEndian.PutUint16(data[0:2], p.Type)
+	binary.BigEndian.PutUint16(data[2:4], uint16(length))
+	copy(data[4:], p.Value)
+	return data
+}
+
+// SCTPUnknownChunkType is the layer type returned when we don't recognize the
+// chunk type.  Since there's a length in a known location, we can skip over
+// it even if we don't know what it is, and continue parsing the rest of the
+// chunks.  This chunk is stored as an ErrorLayer in the packet.
+type SCTPUnknownChunkType struct {
+	SCTPChunk
+	bytes []byte
+}
+
+func decodeSCTPChunkTypeUnknown(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPUnknownChunkType{SCTPChunk: chunk}
+	sc.bytes = data[:sc.ActualLength]
+	p.AddLayer(sc)
+	p.SetErrorLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (s SCTPUnknownChunkType) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	bytes, err := b.PrependBytes(s.ActualLength)
+	if err != nil {
+		return err
+	}
+	copy(bytes, s.bytes)
+	return nil
+}
+
+// LayerType returns gopacket.LayerTypeSCTPUnknownChunkType.
+func (s *SCTPUnknownChunkType) LayerType() gopacket.LayerType { return LayerTypeSCTPUnknownChunkType }
+
+// Payload returns all bytes in this header, including the decoded Type, Length,
+// and Flags.
+func (s *SCTPUnknownChunkType) Payload() []byte { return s.bytes }
+
+// Error implements ErrorLayer.
+func (s *SCTPUnknownChunkType) Error() error {
+	return fmt.Errorf("No decode method available for SCTP chunk type %s", s.Type)
+}
+
+// SCTPData is the SCTP Data chunk layer.
+type SCTPData struct {
+	SCTPChunk
+	Unordered, BeginFragment, EndFragment bool
+	TSN                                   uint32
+	StreamId                              uint16
+	StreamSequence                        uint16
+	PayloadProtocol                       SCTPPayloadProtocol
+}
+
+// LayerType returns gopacket.LayerTypeSCTPData.
+func (s *SCTPData) LayerType() gopacket.LayerType { return LayerTypeSCTPData }
+
+// SCTPPayloadProtocol represents a payload protocol
+type SCTPPayloadProtocol uint32
+
+// SCTPPayloadProtocol constonts from http://www.iana.org/assignments/sctp-parameters/sctp-parameters.xhtml
+const (
+	SCTPProtocolReserved  SCTPPayloadProtocol = 0
+	SCTPPayloadUIA                            = 1
+	SCTPPayloadM2UA                           = 2
+	SCTPPayloadM3UA                           = 3
+	SCTPPayloadSUA                            = 4
+	SCTPPayloadM2PA                           = 5
+	SCTPPayloadV5UA                           = 6
+	SCTPPayloadH248                           = 7
+	SCTPPayloadBICC                           = 8
+	SCTPPayloadTALI                           = 9
+	SCTPPayloadDUA                            = 10
+	SCTPPayloadASAP                           = 11
+	SCTPPayloadENRP                           = 12
+	SCTPPayloadH323                           = 13
+	SCTPPayloadQIPC                           = 14
+	SCTPPayloadSIMCO                          = 15
+	SCTPPayloadDDPSegment                     = 16
+	SCTPPayloadDDPStream                      = 17
+	SCTPPayloadS1AP                           = 18
+)
+
+func (p SCTPPayloadProtocol) String() string {
+	switch p {
+	case SCTPProtocolReserved:
+		return "Reserved"
+	case SCTPPayloadUIA:
+		return "UIA"
+	case SCTPPayloadM2UA:
+		return "M2UA"
+	case SCTPPayloadM3UA:
+		return "M3UA"
+	case SCTPPayloadSUA:
+		return "SUA"
+	case SCTPPayloadM2PA:
+		return "M2PA"
+	case SCTPPayloadV5UA:
+		return "V5UA"
+	case SCTPPayloadH248:
+		return "H.248"
+	case SCTPPayloadBICC:
+		return "BICC"
+	case SCTPPayloadTALI:
+		return "TALI"
+	case SCTPPayloadDUA:
+		return "DUA"
+	case SCTPPayloadASAP:
+		return "ASAP"
+	case SCTPPayloadENRP:
+		return "ENRP"
+	case SCTPPayloadH323:
+		return "H.323"
+	case SCTPPayloadQIPC:
+		return "QIPC"
+	case SCTPPayloadSIMCO:
+		return "SIMCO"
+	case SCTPPayloadDDPSegment:
+		return "DDPSegment"
+	case SCTPPayloadDDPStream:
+		return "DDPStream"
+	case SCTPPayloadS1AP:
+		return "S1AP"
+	}
+	return fmt.Sprintf("Unknown(%d)", p)
+}
+
+func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPData{
+		SCTPChunk:       chunk,
+		Unordered:       data[1]&0x4 != 0,
+		BeginFragment:   data[1]&0x2 != 0,
+		EndFragment:     data[1]&0x1 != 0,
+		TSN:             binary.BigEndian.Uint32(data[4:8]),
+		StreamId:        binary.BigEndian.Uint16(data[8:10]),
+		StreamSequence:  binary.BigEndian.Uint16(data[10:12]),
+		PayloadProtocol: SCTPPayloadProtocol(binary.BigEndian.Uint32(data[12:16])),
+	}
+	// Length is the length in bytes of the data, INCLUDING the 16-byte header.
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.LayerTypePayload)
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	payload := b.Bytes()
+	// Pad the payload to a 32 bit boundary
+	if rem := len(payload) % 4; rem != 0 {
+		b.AppendBytes(4 - rem)
+	}
+	length := 16
+	bytes, err := b.PrependBytes(length)
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	flags := uint8(0)
+	if sc.Unordered {
+		flags |= 0x4
+	}
+	if sc.BeginFragment {
+		flags |= 0x2
+	}
+	if sc.EndFragment {
+		flags |= 0x1
+	}
+	bytes[1] = flags
+	binary.BigEndian.PutUint16(bytes[2:4], uint16(length+len(payload)))
+	binary.BigEndian.PutUint32(bytes[4:8], sc.TSN)
+	binary.BigEndian.PutUint16(bytes[8:10], sc.StreamId)
+	binary.BigEndian.PutUint16(bytes[10:12], sc.StreamSequence)
+	binary.BigEndian.PutUint32(bytes[12:16], uint32(sc.PayloadProtocol))
+	return nil
+}
+
+// SCTPInitParameter is a parameter for an SCTP Init or InitAck packet.
+type SCTPInitParameter SCTPParameter
+
+// SCTPInit is used as the return value for both SCTPInit and SCTPInitAck
+// messages.
+type SCTPInit struct {
+	SCTPChunk
+	InitiateTag                     uint32
+	AdvertisedReceiverWindowCredit  uint32
+	OutboundStreams, InboundStreams uint16
+	InitialTSN                      uint32
+	Parameters                      []SCTPInitParameter
+}
+
+// LayerType returns either gopacket.LayerTypeSCTPInit or gopacket.LayerTypeSCTPInitAck.
+func (sc *SCTPInit) LayerType() gopacket.LayerType {
+	if sc.Type == SCTPChunkTypeInitAck {
+		return LayerTypeSCTPInitAck
+	}
+	// sc.Type == SCTPChunkTypeInit
+	return LayerTypeSCTPInit
+}
+
+func decodeSCTPInit(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPInit{
+		SCTPChunk:                      chunk,
+		InitiateTag:                    binary.BigEndian.Uint32(data[4:8]),
+		AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),
+		OutboundStreams:                binary.BigEndian.Uint16(data[12:14]),
+		InboundStreams:                 binary.BigEndian.Uint16(data[14:16]),
+		InitialTSN:                     binary.BigEndian.Uint32(data[16:20]),
+	}
+	paramData := data[20:sc.ActualLength]
+	for len(paramData) > 0 {
+		p := SCTPInitParameter(decodeSCTPParameter(paramData))
+		paramData = paramData[p.ActualLength:]
+		sc.Parameters = append(sc.Parameters, p)
+	}
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPInit) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	var payload []byte
+	for _, param := range sc.Parameters {
+		payload = append(payload, SCTPParameter(param).Bytes()...)
+	}
+	length := 20 + len(payload)
+	bytes, err := b.PrependBytes(roundUpToNearest4(length))
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	bytes[1] = sc.Flags
+	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
+	binary.BigEndian.PutUint32(bytes[4:8], sc.InitiateTag)
+	binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)
+	binary.BigEndian.PutUint16(bytes[12:14], sc.OutboundStreams)
+	binary.BigEndian.PutUint16(bytes[14:16], sc.InboundStreams)
+	binary.BigEndian.PutUint32(bytes[16:20], sc.InitialTSN)
+	copy(bytes[20:], payload)
+	return nil
+}
+
+// SCTPSack is the SCTP Selective ACK chunk layer.
+type SCTPSack struct {
+	SCTPChunk
+	CumulativeTSNAck               uint32
+	AdvertisedReceiverWindowCredit uint32
+	NumGapACKs, NumDuplicateTSNs   uint16
+	GapACKs                        []uint16
+	DuplicateTSNs                  []uint32
+}
+
+// LayerType return LayerTypeSCTPSack
+func (sc *SCTPSack) LayerType() gopacket.LayerType {
+	return LayerTypeSCTPSack
+}
+
+func decodeSCTPSack(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPSack{
+		SCTPChunk:                      chunk,
+		CumulativeTSNAck:               binary.BigEndian.Uint32(data[4:8]),
+		AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),
+		NumGapACKs:                     binary.BigEndian.Uint16(data[12:14]),
+		NumDuplicateTSNs:               binary.BigEndian.Uint16(data[14:16]),
+	}
+	// We maximize gapAcks and dupTSNs here so we're not allocating tons
+	// of memory based on a user-controlable field.  Our maximums are not exact,
+	// but should give us sane defaults... we'll still hit slice boundaries and
+	// fail if the user-supplied values are too high (in the for loops below), but
+	// the amount of memory we'll have allocated because of that should be small
+	// (< sc.ActualLength)
+	gapAcks := sc.SCTPChunk.ActualLength / 2
+	dupTSNs := (sc.SCTPChunk.ActualLength - gapAcks*2) / 4
+	if gapAcks > int(sc.NumGapACKs) {
+		gapAcks = int(sc.NumGapACKs)
+	}
+	if dupTSNs > int(sc.NumDuplicateTSNs) {
+		dupTSNs = int(sc.NumDuplicateTSNs)
+	}
+	sc.GapACKs = make([]uint16, 0, gapAcks)
+	sc.DuplicateTSNs = make([]uint32, 0, dupTSNs)
+	bytesRemaining := data[16:]
+	for i := 0; i < int(sc.NumGapACKs); i++ {
+		sc.GapACKs = append(sc.GapACKs, binary.BigEndian.Uint16(bytesRemaining[:2]))
+		bytesRemaining = bytesRemaining[2:]
+	}
+	for i := 0; i < int(sc.NumDuplicateTSNs); i++ {
+		sc.DuplicateTSNs = append(sc.DuplicateTSNs, binary.BigEndian.Uint32(bytesRemaining[:4]))
+		bytesRemaining = bytesRemaining[4:]
+	}
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPSack) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	length := 16 + 2*len(sc.GapACKs) + 4*len(sc.DuplicateTSNs)
+	bytes, err := b.PrependBytes(roundUpToNearest4(length))
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	bytes[1] = sc.Flags
+	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
+	binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)
+	binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)
+	binary.BigEndian.PutUint16(bytes[12:14], uint16(len(sc.GapACKs)))
+	binary.BigEndian.PutUint16(bytes[14:16], uint16(len(sc.DuplicateTSNs)))
+	for i, v := range sc.GapACKs {
+		binary.BigEndian.PutUint16(bytes[16+i*2:], v)
+	}
+	offset := 16 + 2*len(sc.GapACKs)
+	for i, v := range sc.DuplicateTSNs {
+		binary.BigEndian.PutUint32(bytes[offset+i*4:], v)
+	}
+	return nil
+}
+
+// SCTPHeartbeatParameter is the parameter type used by SCTP heartbeat and
+// heartbeat ack layers.
+type SCTPHeartbeatParameter SCTPParameter
+
+// SCTPHeartbeat is the SCTP heartbeat layer, also used for heatbeat ack.
+type SCTPHeartbeat struct {
+	SCTPChunk
+	Parameters []SCTPHeartbeatParameter
+}
+
+// LayerType returns gopacket.LayerTypeSCTPHeartbeat.
+func (sc *SCTPHeartbeat) LayerType() gopacket.LayerType {
+	if sc.Type == SCTPChunkTypeHeartbeatAck {
+		return LayerTypeSCTPHeartbeatAck
+	}
+	// sc.Type == SCTPChunkTypeHeartbeat
+	return LayerTypeSCTPHeartbeat
+}
+
+func decodeSCTPHeartbeat(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPHeartbeat{
+		SCTPChunk: chunk,
+	}
+	paramData := data[4:sc.Length]
+	for len(paramData) > 0 {
+		p := SCTPHeartbeatParameter(decodeSCTPParameter(paramData))
+		paramData = paramData[p.ActualLength:]
+		sc.Parameters = append(sc.Parameters, p)
+	}
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPHeartbeat) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	var payload []byte
+	for _, param := range sc.Parameters {
+		payload = append(payload, SCTPParameter(param).Bytes()...)
+	}
+	length := 4 + len(payload)
+
+	bytes, err := b.PrependBytes(roundUpToNearest4(length))
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	bytes[1] = sc.Flags
+	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
+	copy(bytes[4:], payload)
+	return nil
+}
+
+// SCTPErrorParameter is the parameter type used by SCTP Abort and Error layers.
+type SCTPErrorParameter SCTPParameter
+
+// SCTPError is the SCTP error layer, also used for SCTP aborts.
+type SCTPError struct {
+	SCTPChunk
+	Parameters []SCTPErrorParameter
+}
+
+// LayerType returns LayerTypeSCTPAbort or LayerTypeSCTPError.
+func (sc *SCTPError) LayerType() gopacket.LayerType {
+	if sc.Type == SCTPChunkTypeAbort {
+		return LayerTypeSCTPAbort
+	}
+	// sc.Type == SCTPChunkTypeError
+	return LayerTypeSCTPError
+}
+
+func decodeSCTPError(data []byte, p gopacket.PacketBuilder) error {
+	// remarkably similar to decodeSCTPHeartbeat ;)
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPError{
+		SCTPChunk: chunk,
+	}
+	paramData := data[4:sc.Length]
+	for len(paramData) > 0 {
+		p := SCTPErrorParameter(decodeSCTPParameter(paramData))
+		paramData = paramData[p.ActualLength:]
+		sc.Parameters = append(sc.Parameters, p)
+	}
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPError) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	var payload []byte
+	for _, param := range sc.Parameters {
+		payload = append(payload, SCTPParameter(param).Bytes()...)
+	}
+	length := 4 + len(payload)
+
+	bytes, err := b.PrependBytes(roundUpToNearest4(length))
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	bytes[1] = sc.Flags
+	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
+	copy(bytes[4:], payload)
+	return nil
+}
+
+// SCTPShutdown is the SCTP shutdown layer.
+type SCTPShutdown struct {
+	SCTPChunk
+	CumulativeTSNAck uint32
+}
+
+// LayerType returns gopacket.LayerTypeSCTPShutdown.
+func (sc *SCTPShutdown) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdown }
+
+func decodeSCTPShutdown(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPShutdown{
+		SCTPChunk:        chunk,
+		CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]),
+	}
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPShutdown) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	bytes, err := b.PrependBytes(8)
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	bytes[1] = sc.Flags
+	binary.BigEndian.PutUint16(bytes[2:4], 8)
+	binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)
+	return nil
+}
+
+// SCTPShutdownAck is the SCTP shutdown layer.
+type SCTPShutdownAck struct {
+	SCTPChunk
+}
+
+// LayerType returns gopacket.LayerTypeSCTPShutdownAck.
+func (sc *SCTPShutdownAck) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdownAck }
+
+func decodeSCTPShutdownAck(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPShutdownAck{
+		SCTPChunk: chunk,
+	}
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPShutdownAck) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	bytes, err := b.PrependBytes(4)
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	bytes[1] = sc.Flags
+	binary.BigEndian.PutUint16(bytes[2:4], 4)
+	return nil
+}
+
+// SCTPCookieEcho is the SCTP Cookie Echo layer.
+type SCTPCookieEcho struct {
+	SCTPChunk
+	Cookie []byte
+}
+
+// LayerType returns gopacket.LayerTypeSCTPCookieEcho.
+func (sc *SCTPCookieEcho) LayerType() gopacket.LayerType { return LayerTypeSCTPCookieEcho }
+
+func decodeSCTPCookieEcho(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPCookieEcho{
+		SCTPChunk: chunk,
+	}
+	sc.Cookie = data[4:sc.Length]
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPCookieEcho) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	length := 4 + len(sc.Cookie)
+	bytes, err := b.PrependBytes(roundUpToNearest4(length))
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	bytes[1] = sc.Flags
+	binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
+	copy(bytes[4:], sc.Cookie)
+	return nil
+}
+
+// This struct is used by all empty SCTP chunks (currently CookieAck and
+// ShutdownComplete).
+type SCTPEmptyLayer struct {
+	SCTPChunk
+}
+
+// LayerType returns either gopacket.LayerTypeSCTPShutdownComplete or
+// LayerTypeSCTPCookieAck.
+func (sc *SCTPEmptyLayer) LayerType() gopacket.LayerType {
+	if sc.Type == SCTPChunkTypeShutdownComplete {
+		return LayerTypeSCTPShutdownComplete
+	}
+	// sc.Type == SCTPChunkTypeCookieAck
+	return LayerTypeSCTPCookieAck
+}
+
+func decodeSCTPEmptyLayer(data []byte, p gopacket.PacketBuilder) error {
+	chunk, err := decodeSCTPChunk(data)
+	if err != nil {
+		return err
+	}
+	sc := &SCTPEmptyLayer{
+		SCTPChunk: chunk,
+	}
+	p.AddLayer(sc)
+	return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
+}
+
+// SerializeTo is for gopacket.SerializableLayer.
+func (sc SCTPEmptyLayer) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	bytes, err := b.PrependBytes(4)
+	if err != nil {
+		return err
+	}
+	bytes[0] = uint8(sc.Type)
+	bytes[1] = sc.Flags
+	binary.BigEndian.PutUint16(bytes[2:4], 4)
+	return nil
+}
