blob: 154436205ef7a86be2e3fe4f43a76301c7b88f90 [file] [log] [blame]
Naveen Sampath04696f72022-06-13 15:19:14 +05301// 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
7package layers
8
9import (
10 "encoding/binary"
11
12 "github.com/google/gopacket"
13)
14
15const (
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
24type ERSPANII struct {
25 BaseLayer
26 IsTruncated bool
27 Version, CoS, TrunkEncap uint8
28 VLANIdentifier, SessionID, Reserved uint16
29 Index uint32
30}
31
32func (erspan2 *ERSPANII) LayerType() gopacket.LayerType { return LayerTypeERSPANII }
33
34// DecodeFromBytes decodes the given bytes into this layer.
35func (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.
53func (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.
74func (erspan2 *ERSPANII) CanDecode() gopacket.LayerClass {
75 return LayerTypeERSPANII
76}
77
78// NextLayerType returns the layer type contained by this DecodingLayer.
79func (erspan2 *ERSPANII) NextLayerType() gopacket.LayerType {
80 return LayerTypeEthernet
81}
82
83func decodeERSPANII(data []byte, p gopacket.PacketBuilder) error {
84 erspan2 := &ERSPANII{}
85 return decodingLayerDecoder(erspan2, data, p)
86}