erspan2.go 2.8 KB

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