diff --git a/vendor/github.com/google/gopacket/layers/mldv2.go b/vendor/github.com/google/gopacket/layers/mldv2.go
new file mode 100644
index 0000000..248cf74
--- /dev/null
+++ b/vendor/github.com/google/gopacket/layers/mldv2.go
@@ -0,0 +1,619 @@
+// Copyright 2018 GoPacket Authors. 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"
+	"math"
+	"net"
+	"time"
+
+	"github.com/google/gopacket"
+)
+
+const (
+	// S Flag bit is 1
+	mldv2STrue uint8 = 0x8
+
+	// S Flag value mask
+	//   mldv2STrue & mldv2SMask == mldv2STrue  // true
+	//          0x1 & mldv2SMask == mldv2STrue  // true
+	//          0x0 & mldv2SMask == mldv2STrue  // false
+	mldv2SMask uint8 = 0x8
+
+	// QRV value mask
+	mldv2QRVMask uint8 = 0x7
+)
+
+// MLDv2MulticastListenerQueryMessage are sent by multicast routers to query the
+// multicast listening state of neighboring interfaces.
+// https://tools.ietf.org/html/rfc3810#section-5.1
+//
+// Some information, like Maximum Response Code and Multicast Address are in the
+// previous layer LayerTypeMLDv1MulticastListenerQuery
+type MLDv2MulticastListenerQueryMessage struct {
+	BaseLayer
+	// 5.1.3. Maximum Response Delay COde
+	MaximumResponseCode uint16
+	// 5.1.5. Multicast Address
+	// Zero in general query
+	// Specific IPv6 multicast address otherwise
+	MulticastAddress net.IP
+	// 5.1.7. S Flag (Suppress Router-Side Processing)
+	SuppressRoutersideProcessing bool
+	// 5.1.8. QRV (Querier's Robustness Variable)
+	QueriersRobustnessVariable uint8
+	// 5.1.9. QQIC (Querier's Query Interval Code)
+	QueriersQueryIntervalCode uint8
+	// 5.1.10. Number of Sources (N)
+	NumberOfSources uint16
+	// 5.1.11 Source Address [i]
+	SourceAddresses []net.IP
+}
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (m *MLDv2MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 24 {
+		df.SetTruncated()
+		return errors.New("ICMP layer less than 24 bytes for Multicast Listener Query Message V2")
+	}
+
+	m.MaximumResponseCode = binary.BigEndian.Uint16(data[0:2])
+	// ignore data[2:4] as per https://tools.ietf.org/html/rfc3810#section-5.1.4
+	m.MulticastAddress = data[4:20]
+	m.SuppressRoutersideProcessing = (data[20] & mldv2SMask) == mldv2STrue
+	m.QueriersRobustnessVariable = data[20] & mldv2QRVMask
+	m.QueriersQueryIntervalCode = data[21]
+
+	m.NumberOfSources = binary.BigEndian.Uint16(data[22:24])
+
+	var end int
+	for i := uint16(0); i < m.NumberOfSources; i++ {
+		begin := 24 + (int(i) * 16)
+		end = begin + 16
+
+		if end > len(data) {
+			df.SetTruncated()
+			return fmt.Errorf("ICMP layer less than %d bytes for Multicast Listener Query Message V2", end)
+		}
+
+		m.SourceAddresses = append(m.SourceAddresses, data[begin:end])
+	}
+
+	return nil
+}
+
+// NextLayerType returns the layer type contained by this DecodingLayer.
+func (*MLDv2MulticastListenerQueryMessage) NextLayerType() gopacket.LayerType {
+	return gopacket.LayerTypeZero
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (m *MLDv2MulticastListenerQueryMessage) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	if err := m.serializeSourceAddressesTo(b, opts); err != nil {
+		return err
+	}
+
+	buf, err := b.PrependBytes(24)
+	if err != nil {
+		return err
+	}
+
+	binary.BigEndian.PutUint16(buf[0:2], m.MaximumResponseCode)
+	copy(buf[2:4], []byte{0x00, 0x00}) // set reserved bytes to zero
+
+	ma16 := m.MulticastAddress.To16()
+	if ma16 == nil {
+		return fmt.Errorf("invalid MulticastAddress '%s'", m.MulticastAddress)
+	}
+	copy(buf[4:20], ma16)
+
+	byte20 := m.QueriersRobustnessVariable & mldv2QRVMask
+	if m.SuppressRoutersideProcessing {
+		byte20 |= mldv2STrue
+	} else {
+		byte20 &= ^mldv2STrue // the complement of mldv2STrue
+	}
+	byte20 &= 0x0F // set reserved bits to zero
+	buf[20] = byte20
+
+	binary.BigEndian.PutUint16(buf[22:24], m.NumberOfSources)
+	buf[21] = m.QueriersQueryIntervalCode
+
+	return nil
+}
+
+// writes each source address to the buffer preserving the order
+func (m *MLDv2MulticastListenerQueryMessage) serializeSourceAddressesTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	numberOfSourceAddresses := len(m.SourceAddresses)
+	if numberOfSourceAddresses > math.MaxUint16 {
+		return fmt.Errorf(
+			"there are more than %d source addresses, but 65535 is the maximum number of supported addresses",
+			numberOfSourceAddresses)
+	}
+
+	if opts.FixLengths {
+		m.NumberOfSources = uint16(numberOfSourceAddresses)
+	}
+
+	lastSAIdx := numberOfSourceAddresses - 1
+	for k := range m.SourceAddresses {
+		i := lastSAIdx - k // reverse order
+
+		buf, err := b.PrependBytes(16)
+		if err != nil {
+			return err
+		}
+
+		sa16 := m.SourceAddresses[i].To16()
+		if sa16 == nil {
+			return fmt.Errorf("invalid source address [%d] '%s'", i, m.SourceAddresses[i])
+		}
+		copy(buf[0:16], sa16)
+	}
+
+	return nil
+}
+
+// String sums this layer up nicely formatted
+func (m *MLDv2MulticastListenerQueryMessage) String() string {
+	return fmt.Sprintf(
+		"Maximum Response Code: %#x (%dms), Multicast Address: %s, Suppress Routerside Processing: %t, QRV: %#x, QQIC: %#x (%ds), Number of Source Address: %d (actual: %d), Source Addresses: %s",
+		m.MaximumResponseCode,
+		m.MaximumResponseDelay(),
+		m.MulticastAddress,
+		m.SuppressRoutersideProcessing,
+		m.QueriersRobustnessVariable,
+		m.QueriersQueryIntervalCode,
+		m.QQI()/time.Second,
+		m.NumberOfSources,
+		len(m.SourceAddresses),
+		m.SourceAddresses)
+}
+
+// LayerType returns LayerTypeMLDv2MulticastListenerQuery.
+func (*MLDv2MulticastListenerQueryMessage) LayerType() gopacket.LayerType {
+	return LayerTypeMLDv2MulticastListenerQuery
+}
+
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (*MLDv2MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass {
+	return LayerTypeMLDv2MulticastListenerQuery
+}
+
+// QQI calculates the Querier's Query Interval based on the QQIC
+// according to https://tools.ietf.org/html/rfc3810#section-5.1.9
+func (m *MLDv2MulticastListenerQueryMessage) QQI() time.Duration {
+	data := m.QueriersQueryIntervalCode
+	if data < 128 {
+		return time.Second * time.Duration(data)
+	}
+
+	exp := uint16(data) & 0x70 >> 4
+	mant := uint16(data) & 0x0F
+	return time.Second * time.Duration(mant|0x1000<<(exp+3))
+}
+
+// SetQQI calculates and updates the Querier's Query Interval Code (QQIC)
+// according to https://tools.ietf.org/html/rfc3810#section-5.1.9
+func (m *MLDv2MulticastListenerQueryMessage) SetQQI(d time.Duration) error {
+	if d < 0 {
+		m.QueriersQueryIntervalCode = 0
+		return errors.New("QQI duration is negative")
+	}
+
+	if d == 0 {
+		m.QueriersQueryIntervalCode = 0
+		return nil
+	}
+
+	dms := d / time.Second
+	if dms < 128 {
+		m.QueriersQueryIntervalCode = uint8(dms)
+	}
+
+	if dms > 31744 { // mant=0xF, exp=0x7
+		m.QueriersQueryIntervalCode = 0xFF
+		return fmt.Errorf("QQI duration %ds is, maximum allowed is 31744s", dms)
+	}
+
+	value := uint16(dms) // ok, because 31744 < math.MaxUint16
+	exp := uint8(7)
+	for mask := uint16(0x4000); exp > 0; exp-- {
+		if mask&value != 0 {
+			break
+		}
+
+		mask >>= 1
+	}
+
+	mant := uint8(0x000F & (value >> (exp + 3)))
+	sig := uint8(0x10)
+	m.QueriersQueryIntervalCode = sig | exp<<4 | mant
+
+	return nil
+}
+
+// MaximumResponseDelay returns the Maximum Response Delay based on the
+// Maximum Response Code according to
+// https://tools.ietf.org/html/rfc3810#section-5.1.3
+func (m *MLDv2MulticastListenerQueryMessage) MaximumResponseDelay() time.Duration {
+	if m.MaximumResponseCode < 0x8000 {
+		return time.Duration(m.MaximumResponseCode)
+	}
+
+	exp := m.MaximumResponseCode & 0x7000 >> 12
+	mant := m.MaximumResponseCode & 0x0FFF
+
+	return time.Millisecond * time.Duration(mant|0x1000<<(exp+3))
+}
+
+// SetMLDv2MaximumResponseDelay updates the Maximum Response Code according to
+// https://tools.ietf.org/html/rfc3810#section-5.1.3
+func (m *MLDv2MulticastListenerQueryMessage) SetMLDv2MaximumResponseDelay(d time.Duration) error {
+	if d == 0 {
+		m.MaximumResponseCode = 0
+		return nil
+	}
+
+	if d < 0 {
+		return errors.New("maximum response delay must not be negative")
+	}
+
+	dms := d / time.Millisecond
+
+	if dms < 32768 {
+		m.MaximumResponseCode = uint16(dms)
+	}
+
+	if dms > 4193280 { // mant=0xFFF, exp=0x7
+		return fmt.Errorf("maximum response delay %dms is bigger the than maximum of 4193280ms", dms)
+	}
+
+	value := uint32(dms) // ok, because 4193280 < math.MaxUint32
+	exp := uint8(7)
+	for mask := uint32(0x40000000); exp > 0; exp-- {
+		if mask&value != 0 {
+			break
+		}
+
+		mask >>= 1
+	}
+
+	mant := uint16(0x00000FFF & (value >> (exp + 3)))
+	sig := uint16(0x1000)
+	m.MaximumResponseCode = sig | uint16(exp)<<12 | mant
+	return nil
+}
+
+// MLDv2MulticastListenerReportMessage is sent by an IP node to report the
+// current multicast listening state, or changes therein.
+// https://tools.ietf.org/html/rfc3810#section-5.2
+type MLDv2MulticastListenerReportMessage struct {
+	BaseLayer
+	// 5.2.3. Nr of Mcast Address Records
+	NumberOfMulticastAddressRecords uint16
+	// 5.2.4. Multicast Address Record [i]
+	MulticastAddressRecords []MLDv2MulticastAddressRecord
+}
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (m *MLDv2MulticastListenerReportMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 4 {
+		df.SetTruncated()
+		return errors.New("ICMP layer less than 4 bytes for Multicast Listener Report Message V2")
+	}
+
+	// ignore data[0:2] as per RFC
+	// https://tools.ietf.org/html/rfc3810#section-5.2.1
+	m.NumberOfMulticastAddressRecords = binary.BigEndian.Uint16(data[2:4])
+
+	begin := 4
+	for i := uint16(0); i < m.NumberOfMulticastAddressRecords; i++ {
+		mar := MLDv2MulticastAddressRecord{}
+		read, err := mar.decode(data[begin:], df)
+		if err != nil {
+			return err
+		}
+
+		m.MulticastAddressRecords = append(m.MulticastAddressRecords, mar)
+
+		begin += read
+	}
+
+	return nil
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (m *MLDv2MulticastListenerReportMessage) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	lastItemIdx := len(m.MulticastAddressRecords) - 1
+	for k := range m.MulticastAddressRecords {
+		i := lastItemIdx - k // reverse order
+
+		err := m.MulticastAddressRecords[i].serializeTo(b, opts)
+		if err != nil {
+			return err
+		}
+	}
+
+	if opts.FixLengths {
+		numberOfMAR := len(m.MulticastAddressRecords)
+		if numberOfMAR > math.MaxUint16 {
+			return fmt.Errorf(
+				"%d multicast address records added, but the maximum is 65535",
+				numberOfMAR)
+		}
+
+		m.NumberOfMulticastAddressRecords = uint16(numberOfMAR)
+	}
+
+	buf, err := b.PrependBytes(4)
+	if err != nil {
+		return err
+	}
+
+	copy(buf[0:2], []byte{0x0, 0x0})
+	binary.BigEndian.PutUint16(buf[2:4], m.NumberOfMulticastAddressRecords)
+	return nil
+}
+
+// Sums this layer up nicely formatted
+func (m *MLDv2MulticastListenerReportMessage) String() string {
+	return fmt.Sprintf(
+		"Number of Mcast Addr Records: %d (actual %d), Multicast Address Records: %+v",
+		m.NumberOfMulticastAddressRecords,
+		len(m.MulticastAddressRecords),
+		m.MulticastAddressRecords)
+}
+
+// LayerType returns LayerTypeMLDv2MulticastListenerQuery.
+func (*MLDv2MulticastListenerReportMessage) LayerType() gopacket.LayerType {
+	return LayerTypeMLDv2MulticastListenerReport
+}
+
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (*MLDv2MulticastListenerReportMessage) CanDecode() gopacket.LayerClass {
+	return LayerTypeMLDv2MulticastListenerReport
+}
+
+// NextLayerType returns the layer type contained by this DecodingLayer.
+func (*MLDv2MulticastListenerReportMessage) NextLayerType() gopacket.LayerType {
+	return gopacket.LayerTypePayload
+}
+
+// MLDv2MulticastAddressRecordType holds the type of a
+// Multicast Address Record, according to
+// https://tools.ietf.org/html/rfc3810#section-5.2.5 and
+// https://tools.ietf.org/html/rfc3810#section-5.2.12
+type MLDv2MulticastAddressRecordType uint8
+
+const (
+	// MLDv2MulticastAddressRecordTypeModeIsIncluded stands for
+	// MODE_IS_INCLUDE - indicates that the interface has a filter
+	// mode of INCLUDE for the specified multicast address.
+	MLDv2MulticastAddressRecordTypeModeIsIncluded MLDv2MulticastAddressRecordType = 1
+	// MLDv2MulticastAddressRecordTypeModeIsExcluded stands for
+	// MODE_IS_EXCLUDE - indicates that the interface has a filter
+	// mode of EXCLUDE for the specified multicast address.
+	MLDv2MulticastAddressRecordTypeModeIsExcluded MLDv2MulticastAddressRecordType = 2
+	// MLDv2MulticastAddressRecordTypeChangeToIncludeMode stands for
+	// CHANGE_TO_INCLUDE_MODE - indicates that the interface has
+	// changed to INCLUDE filter mode for the specified multicast
+	// address.
+	MLDv2MulticastAddressRecordTypeChangeToIncludeMode MLDv2MulticastAddressRecordType = 3
+	// MLDv2MulticastAddressRecordTypeChangeToExcludeMode stands for
+	// CHANGE_TO_EXCLUDE_MODE - indicates that the interface has
+	// changed to EXCLUDE filter mode for the specified multicast
+	// address
+	MLDv2MulticastAddressRecordTypeChangeToExcludeMode MLDv2MulticastAddressRecordType = 4
+	// MLDv2MulticastAddressRecordTypeAllowNewSources stands for
+	// ALLOW_NEW_SOURCES - indicates that the Source Address [i]
+	// fields in this Multicast Address Record contain a list of
+	// the additional sources that the node wishes to listen to,
+	// for packets sent to the specified multicast address.
+	MLDv2MulticastAddressRecordTypeAllowNewSources MLDv2MulticastAddressRecordType = 5
+	// MLDv2MulticastAddressRecordTypeBlockOldSources stands for
+	// BLOCK_OLD_SOURCES - indicates that the Source Address [i]
+	// fields in this Multicast Address Record contain a list of
+	// the sources that the node no longer wishes to listen to,
+	// for packets sent to the specified multicast address.
+	MLDv2MulticastAddressRecordTypeBlockOldSources MLDv2MulticastAddressRecordType = 6
+)
+
+// Human readable record types
+// Naming follows https://tools.ietf.org/html/rfc3810#section-5.2.12
+func (m MLDv2MulticastAddressRecordType) String() string {
+	switch m {
+	case MLDv2MulticastAddressRecordTypeModeIsIncluded:
+		return "MODE_IS_INCLUDE"
+	case MLDv2MulticastAddressRecordTypeModeIsExcluded:
+		return "MODE_IS_EXCLUDE"
+	case MLDv2MulticastAddressRecordTypeChangeToIncludeMode:
+		return "CHANGE_TO_INCLUDE_MODE"
+	case MLDv2MulticastAddressRecordTypeChangeToExcludeMode:
+		return "CHANGE_TO_EXCLUDE_MODE"
+	case MLDv2MulticastAddressRecordTypeAllowNewSources:
+		return "ALLOW_NEW_SOURCES"
+	case MLDv2MulticastAddressRecordTypeBlockOldSources:
+		return "BLOCK_OLD_SOURCES"
+	default:
+		return fmt.Sprintf("UNKNOWN(%d)", m)
+	}
+}
+
+// MLDv2MulticastAddressRecord contains information on the sender listening to a
+// single multicast address on the interface the report is sent.
+// https://tools.ietf.org/html/rfc3810#section-5.2.4
+type MLDv2MulticastAddressRecord struct {
+	// 5.2.5. Record Type
+	RecordType MLDv2MulticastAddressRecordType
+	// 5.2.6. Auxiliary Data Length (number of 32-bit words)
+	AuxDataLen uint8
+	// 5.2.7. Number Of Sources (N)
+	N uint16
+	// 5.2.8. Multicast Address
+	MulticastAddress net.IP
+	// 5.2.9 Source Address [i]
+	SourceAddresses []net.IP
+	// 5.2.10 Auxiliary Data
+	AuxiliaryData []byte
+}
+
+// decodes a multicast address record from bytes
+func (m *MLDv2MulticastAddressRecord) decode(data []byte, df gopacket.DecodeFeedback) (int, error) {
+	if len(data) < 4 {
+		df.SetTruncated()
+		return 0, errors.New(
+			"Multicast Listener Report Message V2 layer less than 4 bytes for Multicast Address Record")
+	}
+
+	m.RecordType = MLDv2MulticastAddressRecordType(data[0])
+	m.AuxDataLen = data[1]
+	m.N = binary.BigEndian.Uint16(data[2:4])
+	m.MulticastAddress = data[4:20]
+
+	for i := uint16(0); i < m.N; i++ {
+		begin := 20 + (int(i) * 16)
+		end := begin + 16
+
+		if len(data) < end {
+			df.SetTruncated()
+			return begin, fmt.Errorf(
+				"Multicast Listener Report Message V2 layer less than %d bytes for Multicast Address Record", end)
+		}
+
+		m.SourceAddresses = append(m.SourceAddresses, data[begin:end])
+	}
+
+	expectedLengthWithouAuxData := 20 + (int(m.N) * 16)
+	expectedTotalLength := (int(m.AuxDataLen) * 4) + expectedLengthWithouAuxData // *4 because AuxDataLen are 32bit words
+	if len(data) < expectedTotalLength {
+		return expectedLengthWithouAuxData, fmt.Errorf(
+			"Multicast Listener Report Message V2 layer less than %d bytes for Multicast Address Record",
+			expectedLengthWithouAuxData)
+	}
+
+	m.AuxiliaryData = data[expectedLengthWithouAuxData:expectedTotalLength]
+
+	return expectedTotalLength, nil
+}
+
+// String sums this layer up nicely formatted
+func (m *MLDv2MulticastAddressRecord) String() string {
+	return fmt.Sprintf(
+		"RecordType: %d (%s), AuxDataLen: %d [32-bit words], N: %d, Multicast Address: %s, SourceAddresses: %s, Auxiliary Data: %#x",
+		m.RecordType,
+		m.RecordType.String(),
+		m.AuxDataLen,
+		m.N,
+		m.MulticastAddress.To16(),
+		m.SourceAddresses,
+		m.AuxiliaryData)
+}
+
+// serializes a multicast address record
+func (m *MLDv2MulticastAddressRecord) serializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	if err := m.serializeAuxiliaryDataTo(b, opts); err != nil {
+		return err
+	}
+
+	if err := m.serializeSourceAddressesTo(b, opts); err != nil {
+		return err
+	}
+
+	buf, err := b.PrependBytes(20)
+	if err != nil {
+		return err
+	}
+
+	buf[0] = uint8(m.RecordType)
+	buf[1] = m.AuxDataLen
+	binary.BigEndian.PutUint16(buf[2:4], m.N)
+
+	ma16 := m.MulticastAddress.To16()
+	if ma16 == nil {
+		return fmt.Errorf("invalid multicast address '%s'", m.MulticastAddress)
+	}
+	copy(buf[4:20], ma16)
+
+	return nil
+}
+
+// serializes the auxiliary data of a multicast address record
+func (m *MLDv2MulticastAddressRecord) serializeAuxiliaryDataTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	if remainder := len(m.AuxiliaryData) % 4; remainder != 0 {
+		zeroWord := []byte{0x0, 0x0, 0x0, 0x0}
+		m.AuxiliaryData = append(m.AuxiliaryData, zeroWord[:remainder]...)
+	}
+
+	if opts.FixLengths {
+		auxDataLen := len(m.AuxiliaryData) / 4
+
+		if auxDataLen > math.MaxUint8 {
+			return fmt.Errorf("auxilary data is %d 32-bit words, but the maximum is 255 32-bit words", auxDataLen)
+		}
+
+		m.AuxDataLen = uint8(auxDataLen)
+	}
+
+	buf, err := b.PrependBytes(len(m.AuxiliaryData))
+	if err != nil {
+		return err
+	}
+
+	copy(buf, m.AuxiliaryData)
+	return nil
+}
+
+// serializes the source addresses of a multicast address record preserving the order
+func (m *MLDv2MulticastAddressRecord) serializeSourceAddressesTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	if opts.FixLengths {
+		numberOfSourceAddresses := len(m.SourceAddresses)
+
+		if numberOfSourceAddresses > math.MaxUint16 {
+			return fmt.Errorf(
+				"%d source addresses added, but the maximum is 65535",
+				numberOfSourceAddresses)
+		}
+
+		m.N = uint16(numberOfSourceAddresses)
+	}
+
+	lastItemIdx := len(m.SourceAddresses) - 1
+	for k := range m.SourceAddresses {
+		i := lastItemIdx - k // reverse order
+
+		buf, err := b.PrependBytes(16)
+		if err != nil {
+			return err
+		}
+
+		sa16 := m.SourceAddresses[i].To16()
+		if sa16 == nil {
+			return fmt.Errorf("invalid source address [%d] '%s'", i, m.SourceAddresses[i])
+		}
+		copy(buf, sa16)
+	}
+
+	return nil
+}
+
+func decodeMLDv2MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error {
+	m := &MLDv2MulticastListenerReportMessage{}
+	return decodingLayerDecoder(m, data, p)
+}
+
+func decodeMLDv2MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error {
+	m := &MLDv2MulticastListenerQueryMessage{}
+	return decodingLayerDecoder(m, data, p)
+}
