github.com/gopacket/gopacket@v1.1.0/layers/erspan2.go (about)

     1  // Copyright 2018 Google, Inc. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file in the root of the source
     5  // tree.
     6  
     7  package layers
     8  
     9  import (
    10  	"encoding/binary"
    11  
    12  	"github.com/gopacket/gopacket"
    13  )
    14  
    15  const (
    16  	//ERSPANIIVersionObsolete - The obsolete value for the version field
    17  	ERSPANIIVersionObsolete = 0x0
    18  	// ERSPANIIVersion - The current value for the version field
    19  	ERSPANIIVersion = 0x1
    20  )
    21  
    22  // ERSPANII contains all of the fields found in an ERSPAN Type II header
    23  // https://tools.ietf.org/html/draft-foschiano-erspan-03
    24  type ERSPANII struct {
    25  	BaseLayer
    26  	IsTruncated                         bool
    27  	Version, CoS, TrunkEncap            uint8
    28  	VLANIdentifier, SessionID, Reserved uint16
    29  	Index                               uint32
    30  }
    31  
    32  func (erspan2 *ERSPANII) LayerType() gopacket.LayerType { return LayerTypeERSPANII }
    33  
    34  // DecodeFromBytes decodes the given bytes into this layer.
    35  func (erspan2 *ERSPANII) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
    36  	erspan2Length := 8
    37  	erspan2.Version = data[0] & 0xF0 >> 4
    38  	erspan2.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF
    39  	erspan2.CoS = data[2] & 0xE0 >> 5
    40  	erspan2.TrunkEncap = data[2] & 0x18 >> 3
    41  	erspan2.IsTruncated = data[2]&0x4>>2 != 0
    42  	erspan2.SessionID = binary.BigEndian.Uint16(data[2:4]) & 0x03FF
    43  	erspan2.Reserved = binary.BigEndian.Uint16(data[4:6]) & 0xFFF0 >> 4
    44  	erspan2.Index = binary.BigEndian.Uint32(data[4:8]) & 0x000FFFFF
    45  	erspan2.Contents = data[:erspan2Length]
    46  	erspan2.Payload = data[erspan2Length:]
    47  	return nil
    48  }
    49  
    50  // SerializeTo writes the serialized form of this layer into the
    51  // SerializationBuffer, implementing gopacket.SerializableLayer.
    52  // See the docs for gopacket.SerializableLayer for more info.
    53  func (erspan2 *ERSPANII) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
    54  	bytes, err := b.PrependBytes(8)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	twoByteInt := uint16(erspan2.Version&0xF)<<12 | erspan2.VLANIdentifier&0x0FFF
    60  	binary.BigEndian.PutUint16(bytes, twoByteInt)
    61  
    62  	twoByteInt = uint16(erspan2.CoS&0x7)<<13 | uint16(erspan2.TrunkEncap&0x3)<<11 | erspan2.SessionID&0x03FF
    63  	if erspan2.IsTruncated {
    64  		twoByteInt |= 0x400
    65  	}
    66  	binary.BigEndian.PutUint16(bytes[2:], twoByteInt)
    67  
    68  	fourByteInt := uint32(erspan2.Reserved&0x0FFF)<<20 | erspan2.Index&0x000FFFFF
    69  	binary.BigEndian.PutUint32(bytes[4:], fourByteInt)
    70  	return nil
    71  }
    72  
    73  // CanDecode returns the set of layer types that this DecodingLayer can decode.
    74  func (erspan2 *ERSPANII) CanDecode() gopacket.LayerClass {
    75  	return LayerTypeERSPANII
    76  }
    77  
    78  // NextLayerType returns the layer type contained by this DecodingLayer.
    79  func (erspan2 *ERSPANII) NextLayerType() gopacket.LayerType {
    80  	return LayerTypeEthernet
    81  }
    82  
    83  func decodeERSPANII(data []byte, p gopacket.PacketBuilder) error {
    84  	erspan2 := &ERSPANII{}
    85  	return decodingLayerDecoder(erspan2, data, p)
    86  }