// Copyright 2020 The gVisor Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package header import ( "encoding/binary" "fmt" "time" "gvisor.dev/gvisor/pkg/tcpip" ) const ( // mldMaximumResponseDelayOffset is the offset to the Maximum Response Delay // field within MLD. mldMaximumResponseDelayOffset = 0 // mldMulticastAddressOffset is the offset to the Multicast Address field // within MLD. mldMulticastAddressOffset = 4 ) // MLD is a Multicast Listener Discovery message in an ICMPv6 packet. // // MLD will only contain the body of an ICMPv6 packet. // // As per RFC 2710 section 3, MLD messages have the following format (MLD only // holds the bytes after the first four bytes in the diagram below): // // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | Type | Code | Checksum | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | Maximum Response Delay | Reserved | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | | // + + // | | // + Multicast Address + // | | // + + // | | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ type MLD []byte // MaximumResponseDelay returns the Maximum Response Delay. func (m MLD) MaximumResponseDelay() time.Duration { // As per RFC 2710 section 3.4: // // The Maximum Response Delay field is meaningful only in Query // messages, and specifies the maximum allowed delay before sending a // responding Report, in units of milliseconds. In all other messages, // it is set to zero by the sender and ignored by receivers. return time.Duration(binary.BigEndian.Uint16(m[mldMaximumResponseDelayOffset:])) * time.Millisecond } // SetMaximumResponseDelay sets the Maximum Response Delay field. // // maxRespDelayMS is the value in milliseconds. func (m MLD) SetMaximumResponseDelay(maxRespDelayMS uint16) { binary.BigEndian.PutUint16(m[mldMaximumResponseDelayOffset:], maxRespDelayMS) } // MulticastAddress returns the Multicast Address. func (m MLD) MulticastAddress() tcpip.Address { // As per RFC 2710 section 3.5: // // In a Query message, the Multicast Address field is set to zero when // sending a General Query, and set to a specific IPv6 multicast address // when sending a Multicast-Address-Specific Query. // // In a Report or Done message, the Multicast Address field holds a // specific IPv6 multicast address to which the message sender is // listening or is ceasing to listen, respectively. return tcpip.Address(m[mldMulticastAddressOffset:][:IPv6AddressSize]) } // SetMulticastAddress sets the Multicast Address field. func (m MLD) SetMulticastAddress(multicastAddress tcpip.Address) { if n := copy(m[mldMulticastAddressOffset:], multicastAddress); n != IPv6AddressSize { panic(fmt.Sprintf("copied %d bytes, expected to copy %d bytes", n, IPv6AddressSize)) } }