github.com/gopacket/gopacket@v1.1.0/layers/ppp.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  	"errors"
    12  
    13  	"github.com/gopacket/gopacket"
    14  )
    15  
    16  // PPP is the layer for PPP encapsulation headers.
    17  type PPP struct {
    18  	BaseLayer
    19  	PPPType       PPPType
    20  	HasPPTPHeader bool
    21  }
    22  
    23  // PPPEndpoint is a singleton endpoint for PPP.  Since there is no actual
    24  // addressing for the two ends of a PPP connection, we use a singleton value
    25  // named 'point' for each endpoint.
    26  var PPPEndpoint = gopacket.NewEndpoint(EndpointPPP, nil)
    27  
    28  // PPPFlow is a singleton flow for PPP.  Since there is no actual addressing for
    29  // the two ends of a PPP connection, we use a singleton value to represent the
    30  // flow for all PPP connections.
    31  var PPPFlow = gopacket.NewFlow(EndpointPPP, nil, nil)
    32  
    33  // LayerType returns LayerTypePPP
    34  func (p *PPP) LayerType() gopacket.LayerType { return LayerTypePPP }
    35  
    36  // LinkFlow returns PPPFlow.
    37  func (p *PPP) LinkFlow() gopacket.Flow { return PPPFlow }
    38  
    39  func decodePPP(data []byte, p gopacket.PacketBuilder) error {
    40  	ppp := &PPP{}
    41  	offset := 0
    42  	if data[0] == 0xff && data[1] == 0x03 {
    43  		offset = 2
    44  		ppp.HasPPTPHeader = true
    45  	}
    46  	if data[offset]&0x1 == 0 {
    47  		if data[offset+1]&0x1 == 0 {
    48  			return errors.New("PPP has invalid type")
    49  		}
    50  		ppp.PPPType = PPPType(binary.BigEndian.Uint16(data[offset : offset+2]))
    51  		ppp.Contents = data[offset : offset+2]
    52  		ppp.Payload = data[offset+2:]
    53  	} else {
    54  		ppp.PPPType = PPPType(data[offset])
    55  		ppp.Contents = data[offset : offset+1]
    56  		ppp.Payload = data[offset+1:]
    57  	}
    58  	p.AddLayer(ppp)
    59  	p.SetLinkLayer(ppp)
    60  	return p.NextDecoder(ppp.PPPType)
    61  }
    62  
    63  // SerializeTo writes the serialized form of this layer into the
    64  // SerializationBuffer, implementing gopacket.SerializableLayer.
    65  // See the docs for gopacket.SerializableLayer for more info.
    66  func (p *PPP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
    67  	if p.PPPType&0x100 == 0 {
    68  		bytes, err := b.PrependBytes(2)
    69  		if err != nil {
    70  			return err
    71  		}
    72  		binary.BigEndian.PutUint16(bytes, uint16(p.PPPType))
    73  	} else {
    74  		bytes, err := b.PrependBytes(1)
    75  		if err != nil {
    76  			return err
    77  		}
    78  		bytes[0] = uint8(p.PPPType)
    79  	}
    80  	if p.HasPPTPHeader {
    81  		bytes, err := b.PrependBytes(2)
    82  		if err != nil {
    83  			return err
    84  		}
    85  		bytes[0] = 0xff
    86  		bytes[1] = 0x03
    87  	}
    88  	return nil
    89  }