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 "gvisor.dev/gvisor/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 }
159