// Copyright 2019 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 tcpip import ( "gvisor.dev/gvisor/pkg/tcpip/buffer" ) // A PacketBuffer contains all the data of a network packet. // // As a PacketBuffer traverses up the stack, it may be necessary to pass it to // multiple endpoints. Clone() should be called in such cases so that // modifications to the Data field do not affect other copies. // // +stateify savable type PacketBuffer struct { // Data holds the payload of the packet. For inbound packets, it also // holds the headers, which are consumed as the packet moves up the // stack. Headers are guaranteed not to be split across views. // // The bytes backing Data are immutable, but Data itself may be trimmed // or otherwise modified. Data buffer.VectorisedView // DataOffset is used for GSO output. It is the offset into the Data // field where the payload of this packet starts. DataOffset int // DataSize is used for GSO output. It is the size of this packet's // payload. DataSize int // Header holds the headers of outbound packets. As a packet is passed // down the stack, each layer adds to Header. Header buffer.Prependable // These fields are used by both inbound and outbound packets. They // typically overlap with the Data and Header fields. // // The bytes backing these views are immutable. Each field may be nil // if either it has not been set yet or no such header exists (e.g. // packets sent via loopback may not have a link header). // // These fields may be Views into other slices (either Data or Header). // SR dosen't support this, so deep copies are necessary in some cases. LinkHeader buffer.View NetworkHeader buffer.View TransportHeader buffer.View } // Clone makes a copy of pk. It clones the Data field, which creates a new // VectorisedView but does not deep copy the underlying bytes. // // Clone also does not deep copy any of its other fields. func (pk PacketBuffer) Clone() PacketBuffer { pk.Data = pk.Data.Clone(nil) return pk } //// TransportProtocol returns the transport protocol of pk. //// //// Precondition: pk.NetworkHeader is set. //func (pk PacketBuffer) TransportProtocolIPv4() uint16 { // if pk.NetworkHeader == nil { // panic("This should only be called when pk.NetworkHeader is set.") // } // return header.IPv4(pk.NetworkHeader).TransportProtocol() //} // func (pk Packet) findNetHeader() header.IPv4 { // // Inbound: // // Data holds everything, but may have had some headers shaved off. // // Figure out whether it's set or still somewhere in data and return // // appropriately. // // Outbound: // // NetworkHeader will be set if we've added one. Otherwise there's no // // header. // }