// Copyright 2018 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" "gvisor.dev/gvisor/pkg/tcpip" ) const ( nextHdrFrag = 0 fragOff = 2 more = 3 idV6 = 4 ) var _ IPv6SerializableExtHdr = (*IPv6SerializableFragmentExtHdr)(nil) // IPv6SerializableFragmentExtHdr is used to serialize an IPv6 fragment // extension header as defined in RFC 8200 section 4.5. type IPv6SerializableFragmentExtHdr struct { // FragmentOffset is the "fragment offset" field of an IPv6 fragment. FragmentOffset uint16 // M is the "more" field of an IPv6 fragment. M bool // Identification is the "identification" field of an IPv6 fragment. Identification uint32 } // identifier implements IPv6SerializableFragmentExtHdr. func (h *IPv6SerializableFragmentExtHdr) identifier() IPv6ExtensionHeaderIdentifier { return IPv6FragmentHeader } // length implements IPv6SerializableFragmentExtHdr. func (h *IPv6SerializableFragmentExtHdr) length() int { return IPv6FragmentHeaderSize } // serializeInto implements IPv6SerializableFragmentExtHdr. func (h *IPv6SerializableFragmentExtHdr) serializeInto(nextHeader uint8, b []byte) int { // Prevent too many bounds checks. _ = b[IPv6FragmentHeaderSize:] binary.BigEndian.PutUint32(b[idV6:], h.Identification) binary.BigEndian.PutUint16(b[fragOff:], h.FragmentOffset<= IPv6FragmentHeaderSize } // NextHeader returns the value of the "next header" field of the ipv6 fragment. func (b IPv6Fragment) NextHeader() uint8 { return b[nextHdrFrag] } // FragmentOffset returns the "fragment offset" field of the ipv6 fragment. func (b IPv6Fragment) FragmentOffset() uint16 { return binary.BigEndian.Uint16(b[fragOff:]) >> 3 } // More returns the "more" field of the ipv6 fragment. func (b IPv6Fragment) More() bool { return b[more]&1 > 0 } // Payload implements Network.Payload. func (b IPv6Fragment) Payload() []byte { return b[IPv6FragmentHeaderSize:] } // ID returns the value of the identifier field of the ipv6 fragment. func (b IPv6Fragment) ID() uint32 { return binary.BigEndian.Uint32(b[idV6:]) } // TransportProtocol implements Network.TransportProtocol. func (b IPv6Fragment) TransportProtocol() tcpip.TransportProtocolNumber { return tcpip.TransportProtocolNumber(b.NextHeader()) } // The functions below have been added only to satisfy the Network interface. // Checksum is not supported by IPv6Fragment. func (b IPv6Fragment) Checksum() uint16 { panic("not supported") } // SourceAddress is not supported by IPv6Fragment. func (b IPv6Fragment) SourceAddress() tcpip.Address { panic("not supported") } // DestinationAddress is not supported by IPv6Fragment. func (b IPv6Fragment) DestinationAddress() tcpip.Address { panic("not supported") } // SetSourceAddress is not supported by IPv6Fragment. func (b IPv6Fragment) SetSourceAddress(tcpip.Address) { panic("not supported") } // SetDestinationAddress is not supported by IPv6Fragment. func (b IPv6Fragment) SetDestinationAddress(tcpip.Address) { panic("not supported") } // SetChecksum is not supported by IPv6Fragment. func (b IPv6Fragment) SetChecksum(uint16) { panic("not supported") } // TOS is not supported by IPv6Fragment. func (b IPv6Fragment) TOS() (uint8, uint32) { panic("not supported") } // SetTOS is not supported by IPv6Fragment. func (b IPv6Fragment) SetTOS(t uint8, l uint32) { panic("not supported") }