dot1q.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright 2012 Google, Inc. All rights reserved.
  2. // Copyright 2009-2011 Andreas Krennmair. All rights reserved.
  3. //
  4. // Use of this source code is governed by a BSD-style license
  5. // that can be found in the LICENSE file in the root of the source
  6. // tree.
  7. package layers
  8. import (
  9. "encoding/binary"
  10. "fmt"
  11. "github.com/google/gopacket"
  12. )
  13. // Dot1Q is the packet layer for 802.1Q VLAN headers.
  14. type Dot1Q struct {
  15. BaseLayer
  16. Priority uint8
  17. DropEligible bool
  18. VLANIdentifier uint16
  19. Type EthernetType
  20. }
  21. // LayerType returns gopacket.LayerTypeDot1Q
  22. func (d *Dot1Q) LayerType() gopacket.LayerType { return LayerTypeDot1Q }
  23. // DecodeFromBytes decodes the given bytes into this layer.
  24. func (d *Dot1Q) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  25. d.Priority = (data[0] & 0xE0) >> 5
  26. d.DropEligible = data[0]&0x10 != 0
  27. d.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF
  28. d.Type = EthernetType(binary.BigEndian.Uint16(data[2:4]))
  29. d.BaseLayer = BaseLayer{Contents: data[:4], Payload: data[4:]}
  30. return nil
  31. }
  32. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  33. func (d *Dot1Q) CanDecode() gopacket.LayerClass {
  34. return LayerTypeDot1Q
  35. }
  36. // NextLayerType returns the layer type contained by this DecodingLayer.
  37. func (d *Dot1Q) NextLayerType() gopacket.LayerType {
  38. return d.Type.LayerType()
  39. }
  40. func decodeDot1Q(data []byte, p gopacket.PacketBuilder) error {
  41. d := &Dot1Q{}
  42. return decodingLayerDecoder(d, data, p)
  43. }
  44. // SerializeTo writes the serialized form of this layer into the
  45. // SerializationBuffer, implementing gopacket.SerializableLayer.
  46. // See the docs for gopacket.SerializableLayer for more info.
  47. func (d *Dot1Q) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  48. bytes, err := b.PrependBytes(4)
  49. if err != nil {
  50. return err
  51. }
  52. if d.VLANIdentifier > 0xFFF {
  53. return fmt.Errorf("vlan identifier %v is too high", d.VLANIdentifier)
  54. }
  55. firstBytes := uint16(d.Priority)<<13 | d.VLANIdentifier
  56. if d.DropEligible {
  57. firstBytes |= 0x1000
  58. }
  59. binary.BigEndian.PutUint16(bytes, firstBytes)
  60. binary.BigEndian.PutUint16(bytes[2:], uint16(d.Type))
  61. return nil
  62. }