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  }