Matteo Scandolo | a6a3aee | 2019-11-26 13:30:14 -0700 | [diff] [blame] | 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 | "github.com/google/gopacket" |
| 12 | ) |
| 13 | |
| 14 | // PPPoE is the layer for PPPoE encapsulation headers. |
| 15 | type 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. |
| 25 | func (p *PPPoE) LayerType() gopacket.LayerType { |
| 26 | return LayerTypePPPoE |
| 27 | } |
| 28 | |
| 29 | // decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516). |
| 30 | func 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. |
| 46 | func (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 | } |