pppoe.go 1.6 KB

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