blob: 14cd63a1899e3a18e1514e17e695013f7c9ce97b [file] [log] [blame]
Takahiro Suzukid7bf8202020-12-17 20:21:59 +09001// 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 "github.com/google/gopacket"
12)
13
14// PPPoE is the layer for PPPoE encapsulation headers.
15type PPPoE struct {
16 BaseLayer
17 Version uint8
18 Type uint8
19 Code PPPoECode
20 SessionId uint16
21 Length uint16
22}
23
24// LayerType returns gopacket.LayerTypePPPoE.
25func (p *PPPoE) LayerType() gopacket.LayerType {
26 return LayerTypePPPoE
27}
28
29// decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516).
30func decodePPPoE(data []byte, p gopacket.PacketBuilder) error {
31 pppoe := &PPPoE{
32 Version: data[0] >> 4,
33 Type: data[0] & 0x0F,
34 Code: PPPoECode(data[1]),
35 SessionId: binary.BigEndian.Uint16(data[2:4]),
36 Length: binary.BigEndian.Uint16(data[4:6]),
37 }
38 pppoe.BaseLayer = BaseLayer{data[:6], data[6 : 6+pppoe.Length]}
39 p.AddLayer(pppoe)
40 return p.NextDecoder(pppoe.Code)
41}
42
43// SerializeTo writes the serialized form of this layer into the
44// SerializationBuffer, implementing gopacket.SerializableLayer.
45// See the docs for gopacket.SerializableLayer for more info.
46func (p *PPPoE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
47 payload := b.Bytes()
48 bytes, err := b.PrependBytes(6)
49 if err != nil {
50 return err
51 }
52 bytes[0] = (p.Version << 4) | p.Type
53 bytes[1] = byte(p.Code)
54 binary.BigEndian.PutUint16(bytes[2:], p.SessionId)
55 if opts.FixLengths {
56 p.Length = uint16(len(payload))
57 }
58 binary.BigEndian.PutUint16(bytes[4:], p.Length)
59 return nil
60}