github.com/noisysockets/netstack@v0.6.0/pkg/tcpip/header/ipv6_fragment.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package header 16 17 import ( 18 "encoding/binary" 19 20 "github.com/noisysockets/netstack/pkg/tcpip" 21 ) 22 23 const ( 24 nextHdrFrag = 0 25 fragOff = 2 26 more = 3 27 idV6 = 4 28 ) 29 30 var _ IPv6SerializableExtHdr = (*IPv6SerializableFragmentExtHdr)(nil) 31 32 // IPv6SerializableFragmentExtHdr is used to serialize an IPv6 fragment 33 // extension header as defined in RFC 8200 section 4.5. 34 type IPv6SerializableFragmentExtHdr struct { 35 // FragmentOffset is the "fragment offset" field of an IPv6 fragment. 36 FragmentOffset uint16 37 38 // M is the "more" field of an IPv6 fragment. 39 M bool 40 41 // Identification is the "identification" field of an IPv6 fragment. 42 Identification uint32 43 } 44 45 // identifier implements IPv6SerializableFragmentExtHdr. 46 func (h *IPv6SerializableFragmentExtHdr) identifier() IPv6ExtensionHeaderIdentifier { 47 return IPv6FragmentHeader 48 } 49 50 // length implements IPv6SerializableFragmentExtHdr. 51 func (h *IPv6SerializableFragmentExtHdr) length() int { 52 return IPv6FragmentHeaderSize 53 } 54 55 // serializeInto implements IPv6SerializableFragmentExtHdr. 56 func (h *IPv6SerializableFragmentExtHdr) serializeInto(nextHeader uint8, b []byte) int { 57 // Prevent too many bounds checks. 58 _ = b[IPv6FragmentHeaderSize:] 59 binary.BigEndian.PutUint32(b[idV6:], h.Identification) 60 binary.BigEndian.PutUint16(b[fragOff:], h.FragmentOffset<<ipv6FragmentExtHdrFragmentOffsetShift) 61 b[nextHdrFrag] = nextHeader 62 if h.M { 63 b[more] |= ipv6FragmentExtHdrMFlagMask 64 } 65 return IPv6FragmentHeaderSize 66 } 67 68 // IPv6Fragment represents an ipv6 fragment header stored in a byte array. 69 // Most of the methods of IPv6Fragment access to the underlying slice without 70 // checking the boundaries and could panic because of 'index out of range'. 71 // Always call IsValid() to validate an instance of IPv6Fragment before using other methods. 72 type IPv6Fragment []byte 73 74 const ( 75 // IPv6FragmentHeader header is the number used to specify that the next 76 // header is a fragment header, per RFC 2460. 77 IPv6FragmentHeader = 44 78 79 // IPv6FragmentHeaderSize is the size of the fragment header. 80 IPv6FragmentHeaderSize = 8 81 ) 82 83 // IsValid performs basic validation on the fragment header. 84 func (b IPv6Fragment) IsValid() bool { 85 return len(b) >= IPv6FragmentHeaderSize 86 } 87 88 // NextHeader returns the value of the "next header" field of the ipv6 fragment. 89 func (b IPv6Fragment) NextHeader() uint8 { 90 return b[nextHdrFrag] 91 } 92 93 // FragmentOffset returns the "fragment offset" field of the ipv6 fragment. 94 func (b IPv6Fragment) FragmentOffset() uint16 { 95 return binary.BigEndian.Uint16(b[fragOff:]) >> 3 96 } 97 98 // More returns the "more" field of the ipv6 fragment. 99 func (b IPv6Fragment) More() bool { 100 return b[more]&1 > 0 101 } 102 103 // Payload implements Network.Payload. 104 func (b IPv6Fragment) Payload() []byte { 105 return b[IPv6FragmentHeaderSize:] 106 } 107 108 // ID returns the value of the identifier field of the ipv6 fragment. 109 func (b IPv6Fragment) ID() uint32 { 110 return binary.BigEndian.Uint32(b[idV6:]) 111 } 112 113 // TransportProtocol implements Network.TransportProtocol. 114 func (b IPv6Fragment) TransportProtocol() tcpip.TransportProtocolNumber { 115 return tcpip.TransportProtocolNumber(b.NextHeader()) 116 } 117 118 // The functions below have been added only to satisfy the Network interface. 119 120 // Checksum is not supported by IPv6Fragment. 121 func (b IPv6Fragment) Checksum() uint16 { 122 panic("not supported") 123 } 124 125 // SourceAddress is not supported by IPv6Fragment. 126 func (b IPv6Fragment) SourceAddress() tcpip.Address { 127 panic("not supported") 128 } 129 130 // DestinationAddress is not supported by IPv6Fragment. 131 func (b IPv6Fragment) DestinationAddress() tcpip.Address { 132 panic("not supported") 133 } 134 135 // SetSourceAddress is not supported by IPv6Fragment. 136 func (b IPv6Fragment) SetSourceAddress(tcpip.Address) { 137 panic("not supported") 138 } 139 140 // SetDestinationAddress is not supported by IPv6Fragment. 141 func (b IPv6Fragment) SetDestinationAddress(tcpip.Address) { 142 panic("not supported") 143 } 144 145 // SetChecksum is not supported by IPv6Fragment. 146 func (b IPv6Fragment) SetChecksum(uint16) { 147 panic("not supported") 148 } 149 150 // TOS is not supported by IPv6Fragment. 151 func (b IPv6Fragment) TOS() (uint8, uint32) { 152 panic("not supported") 153 } 154 155 // SetTOS is not supported by IPv6Fragment. 156 func (b IPv6Fragment) SetTOS(t uint8, l uint32) { 157 panic("not supported") 158 }