github.com/flowerwrong/netstack@v0.0.0-20191009141956-e5848263af28/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/FlowerWrong/netstack/tcpip"
    21  )
    22  
    23  const (
    24  	nextHdrFrag = 0
    25  	fragOff     = 2
    26  	more        = 3
    27  	idV6        = 4
    28  )
    29  
    30  // IPv6FragmentFields contains the fields of an IPv6 fragment. It is used to describe the
    31  // fields of a packet that needs to be encoded.
    32  type IPv6FragmentFields struct {
    33  	// NextHeader is the "next header" field of an IPv6 fragment.
    34  	NextHeader uint8
    35  
    36  	// FragmentOffset is the "fragment offset" field of an IPv6 fragment.
    37  	FragmentOffset uint16
    38  
    39  	// M is the "more" field of an IPv6 fragment.
    40  	M bool
    41  
    42  	// Identification is the "identification" field of an IPv6 fragment.
    43  	Identification uint32
    44  }
    45  
    46  // IPv6Fragment represents an ipv6 fragment header stored in a byte array.
    47  // Most of the methods of IPv6Fragment access to the underlying slice without
    48  // checking the boundaries and could panic because of 'index out of range'.
    49  // Always call IsValid() to validate an instance of IPv6Fragment before using other methods.
    50  type IPv6Fragment []byte
    51  
    52  const (
    53  	// IPv6FragmentHeader header is the number used to specify that the next
    54  	// header is a fragment header, per RFC 2460.
    55  	IPv6FragmentHeader = 44
    56  
    57  	// IPv6FragmentHeaderSize is the size of the fragment header.
    58  	IPv6FragmentHeaderSize = 8
    59  )
    60  
    61  // Encode encodes all the fields of the ipv6 fragment.
    62  func (b IPv6Fragment) Encode(i *IPv6FragmentFields) {
    63  	b[nextHdrFrag] = i.NextHeader
    64  	binary.BigEndian.PutUint16(b[fragOff:], i.FragmentOffset<<3)
    65  	if i.M {
    66  		b[more] |= 1
    67  	}
    68  	binary.BigEndian.PutUint32(b[idV6:], i.Identification)
    69  }
    70  
    71  // IsValid performs basic validation on the fragment header.
    72  func (b IPv6Fragment) IsValid() bool {
    73  	return len(b) >= IPv6FragmentHeaderSize
    74  }
    75  
    76  // NextHeader returns the value of the "next header" field of the ipv6 fragment.
    77  func (b IPv6Fragment) NextHeader() uint8 {
    78  	return b[nextHdrFrag]
    79  }
    80  
    81  // FragmentOffset returns the "fragment offset" field of the ipv6 fragment.
    82  func (b IPv6Fragment) FragmentOffset() uint16 {
    83  	return binary.BigEndian.Uint16(b[fragOff:]) >> 3
    84  }
    85  
    86  // More returns the "more" field of the ipv6 fragment.
    87  func (b IPv6Fragment) More() bool {
    88  	return b[more]&1 > 0
    89  }
    90  
    91  // Payload implements Network.Payload.
    92  func (b IPv6Fragment) Payload() []byte {
    93  	return b[IPv6FragmentHeaderSize:]
    94  }
    95  
    96  // ID returns the value of the identifier field of the ipv6 fragment.
    97  func (b IPv6Fragment) ID() uint32 {
    98  	return binary.BigEndian.Uint32(b[idV6:])
    99  }
   100  
   101  // TransportProtocol implements Network.TransportProtocol.
   102  func (b IPv6Fragment) TransportProtocol() tcpip.TransportProtocolNumber {
   103  	return tcpip.TransportProtocolNumber(b.NextHeader())
   104  }
   105  
   106  // The functions below have been added only to satisfy the Network interface.
   107  
   108  // Checksum is not supported by IPv6Fragment.
   109  func (b IPv6Fragment) Checksum() uint16 {
   110  	panic("not supported")
   111  }
   112  
   113  // SourceAddress is not supported by IPv6Fragment.
   114  func (b IPv6Fragment) SourceAddress() tcpip.Address {
   115  	panic("not supported")
   116  }
   117  
   118  // DestinationAddress is not supported by IPv6Fragment.
   119  func (b IPv6Fragment) DestinationAddress() tcpip.Address {
   120  	panic("not supported")
   121  }
   122  
   123  // SetSourceAddress is not supported by IPv6Fragment.
   124  func (b IPv6Fragment) SetSourceAddress(tcpip.Address) {
   125  	panic("not supported")
   126  }
   127  
   128  // SetDestinationAddress is not supported by IPv6Fragment.
   129  func (b IPv6Fragment) SetDestinationAddress(tcpip.Address) {
   130  	panic("not supported")
   131  }
   132  
   133  // SetChecksum is not supported by IPv6Fragment.
   134  func (b IPv6Fragment) SetChecksum(uint16) {
   135  	panic("not supported")
   136  }
   137  
   138  // TOS is not supported by IPv6Fragment.
   139  func (b IPv6Fragment) TOS() (uint8, uint32) {
   140  	panic("not supported")
   141  }
   142  
   143  // SetTOS is not supported by IPv6Fragment.
   144  func (b IPv6Fragment) SetTOS(t uint8, l uint32) {
   145  	panic("not supported")
   146  }