ppp.go 2.4 KB

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