github.com/gopacket/gopacket@v1.1.0/layers/dot1q.go (about) 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 8 package layers 9 10 import ( 11 "encoding/binary" 12 "fmt" 13 14 "github.com/gopacket/gopacket" 15 ) 16 17 // Dot1Q is the packet layer for 802.1Q VLAN headers. 18 type Dot1Q struct { 19 BaseLayer 20 Priority uint8 21 DropEligible bool 22 VLANIdentifier uint16 23 Type EthernetType 24 } 25 26 // LayerType returns gopacket.LayerTypeDot1Q 27 func (d *Dot1Q) LayerType() gopacket.LayerType { return LayerTypeDot1Q } 28 29 // DecodeFromBytes decodes the given bytes into this layer. 30 func (d *Dot1Q) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 31 if len(data) < 4 { 32 df.SetTruncated() 33 return fmt.Errorf("802.1Q tag length %d too short", len(data)) 34 } 35 d.Priority = (data[0] & 0xE0) >> 5 36 d.DropEligible = data[0]&0x10 != 0 37 d.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF 38 d.Type = EthernetType(binary.BigEndian.Uint16(data[2:4])) 39 d.BaseLayer = BaseLayer{Contents: data[:4], Payload: data[4:]} 40 return nil 41 } 42 43 // CanDecode returns the set of layer types that this DecodingLayer can decode. 44 func (d *Dot1Q) CanDecode() gopacket.LayerClass { 45 return LayerTypeDot1Q 46 } 47 48 // NextLayerType returns the layer type contained by this DecodingLayer. 49 func (d *Dot1Q) NextLayerType() gopacket.LayerType { 50 return d.Type.LayerType() 51 } 52 53 func decodeDot1Q(data []byte, p gopacket.PacketBuilder) error { 54 d := &Dot1Q{} 55 return decodingLayerDecoder(d, data, p) 56 } 57 58 // SerializeTo writes the serialized form of this layer into the 59 // SerializationBuffer, implementing gopacket.SerializableLayer. 60 // See the docs for gopacket.SerializableLayer for more info. 61 func (d *Dot1Q) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 62 bytes, err := b.PrependBytes(4) 63 if err != nil { 64 return err 65 } 66 if d.VLANIdentifier > 0xFFF { 67 return fmt.Errorf("vlan identifier %v is too high", d.VLANIdentifier) 68 } 69 firstBytes := uint16(d.Priority)<<13 | d.VLANIdentifier 70 if d.DropEligible { 71 firstBytes |= 0x1000 72 } 73 binary.BigEndian.PutUint16(bytes, firstBytes) 74 binary.BigEndian.PutUint16(bytes[2:], uint16(d.Type)) 75 return nil 76 }