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 }