github.com/gopacket/gopacket@v1.1.0/layers/pppoe.go (about)

     1  // Copyright 2012 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  
     7  package layers
     8  
     9  import (
    10  	"encoding/binary"
    11  
    12  	"github.com/gopacket/gopacket"
    13  )
    14  
    15  // PPPoE is the layer for PPPoE encapsulation headers.
    16  type PPPoE struct {
    17  	BaseLayer
    18  	Version   uint8
    19  	Type      uint8
    20  	Code      PPPoECode
    21  	SessionId uint16
    22  	Length    uint16
    23  }
    24  
    25  // LayerType returns gopacket.LayerTypePPPoE.
    26  func (p *PPPoE) LayerType() gopacket.LayerType {
    27  	return LayerTypePPPoE
    28  }
    29  
    30  // decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516).
    31  func decodePPPoE(data []byte, p gopacket.PacketBuilder) error {
    32  	pppoe := &PPPoE{
    33  		Version:   data[0] >> 4,
    34  		Type:      data[0] & 0x0F,
    35  		Code:      PPPoECode(data[1]),
    36  		SessionId: binary.BigEndian.Uint16(data[2:4]),
    37  		Length:    binary.BigEndian.Uint16(data[4:6]),
    38  	}
    39  	pppoe.BaseLayer = BaseLayer{data[:6], data[6 : 6+pppoe.Length]}
    40  	p.AddLayer(pppoe)
    41  	return p.NextDecoder(pppoe.Code)
    42  }
    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 (p *PPPoE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
    48  	payload := b.Bytes()
    49  	bytes, err := b.PrependBytes(6)
    50  	if err != nil {
    51  		return err
    52  	}
    53  	bytes[0] = (p.Version << 4) | p.Type
    54  	bytes[1] = byte(p.Code)
    55  	binary.BigEndian.PutUint16(bytes[2:], p.SessionId)
    56  	if opts.FixLengths {
    57  		p.Length = uint16(len(payload))
    58  	}
    59  	binary.BigEndian.PutUint16(bytes[4:], p.Length)
    60  	return nil
    61  }