dot1q.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. if len(data) < 4 {
  26. df.SetTruncated()
  27. return fmt.Errorf("802.1Q tag length %d too short", len(data))
  28. }
  29. d.Priority = (data[0] & 0xE0) >> 5
  30. d.DropEligible = data[0]&0x10 != 0
  31. d.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF
  32. d.Type = EthernetType(binary.BigEndian.Uint16(data[2:4]))
  33. d.BaseLayer = BaseLayer{Contents: data[:4], Payload: data[4:]}
  34. return nil
  35. }
  36. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  37. func (d *Dot1Q) CanDecode() gopacket.LayerClass {
  38. return LayerTypeDot1Q
  39. }
  40. // NextLayerType returns the layer type contained by this DecodingLayer.
  41. func (d *Dot1Q) NextLayerType() gopacket.LayerType {
  42. return d.Type.LayerType()
  43. }
  44. func decodeDot1Q(data []byte, p gopacket.PacketBuilder) error {
  45. d := &Dot1Q{}
  46. return decodingLayerDecoder(d, data, p)
  47. }
  48. // SerializeTo writes the serialized form of this layer into the
  49. // SerializationBuffer, implementing gopacket.SerializableLayer.
  50. // See the docs for gopacket.SerializableLayer for more info.
  51. func (d *Dot1Q) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  52. bytes, err := b.PrependBytes(4)
  53. if err != nil {
  54. return err
  55. }
  56. if d.VLANIdentifier > 0xFFF {
  57. return fmt.Errorf("vlan identifier %v is too high", d.VLANIdentifier)
  58. }
  59. firstBytes := uint16(d.Priority)<<13 | d.VLANIdentifier
  60. if d.DropEligible {
  61. firstBytes |= 0x1000
  62. }
  63. binary.BigEndian.PutUint16(bytes, firstBytes)
  64. binary.BigEndian.PutUint16(bytes[2:], uint16(d.Type))
  65. return nil
  66. }