// Copyright 2012 Google, Inc. All rights reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source // tree. package layers import ( "encoding/binary" "github.com/google/gopacket" ) // PPPoE is the layer for PPPoE encapsulation headers. type PPPoE struct { BaseLayer Version uint8 Type uint8 Code PPPoECode SessionId uint16 Length uint16 } // LayerType returns gopacket.LayerTypePPPoE. func (p *PPPoE) LayerType() gopacket.LayerType { return LayerTypePPPoE } // decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516). func decodePPPoE(data []byte, p gopacket.PacketBuilder) error { pppoe := &PPPoE{ Version: data[0] >> 4, Type: data[0] & 0x0F, Code: PPPoECode(data[1]), SessionId: binary.BigEndian.Uint16(data[2:4]), Length: binary.BigEndian.Uint16(data[4:6]), } pppoe.BaseLayer = BaseLayer{data[:6], data[6 : 6+pppoe.Length]} p.AddLayer(pppoe) return p.NextDecoder(pppoe.Code) } // SerializeTo writes the serialized form of this layer into the // SerializationBuffer, implementing gopacket.SerializableLayer. // See the docs for gopacket.SerializableLayer for more info. func (p *PPPoE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { payload := b.Bytes() bytes, err := b.PrependBytes(6) if err != nil { return err } bytes[0] = (p.Version << 4) | p.Type bytes[1] = byte(p.Code) binary.BigEndian.PutUint16(bytes[2:], p.SessionId) if opts.FixLengths { p.Length = uint16(len(payload)) } binary.BigEndian.PutUint16(bytes[4:], p.Length) return nil }