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 }