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