eap.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. "fmt"
  10. "github.com/google/gopacket"
  11. )
  12. type EAPCode uint8
  13. type EAPType uint8
  14. const (
  15. EAPCodeRequest EAPCode = 1
  16. EAPCodeResponse EAPCode = 2
  17. EAPCodeSuccess EAPCode = 3
  18. EAPCodeFailure EAPCode = 4
  19. // EAPTypeNone means that this EAP layer has no Type or TypeData.
  20. // Success and Failure EAPs will have this set.
  21. EAPTypeNone EAPType = 0
  22. EAPTypeIdentity EAPType = 1
  23. EAPTypeNotification EAPType = 2
  24. EAPTypeNACK EAPType = 3
  25. EAPTypeOTP EAPType = 4
  26. EAPTypeTokenCard EAPType = 5
  27. )
  28. // EAP defines an Extensible Authentication Protocol (rfc 3748) layer.
  29. type EAP struct {
  30. BaseLayer
  31. Code EAPCode
  32. Id uint8
  33. Length uint16
  34. Type EAPType
  35. TypeData []byte
  36. }
  37. // LayerType returns LayerTypeEAP.
  38. func (e *EAP) LayerType() gopacket.LayerType { return LayerTypeEAP }
  39. // DecodeFromBytes decodes the given bytes into this layer.
  40. func (e *EAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  41. if len(data) < 4 {
  42. df.SetTruncated()
  43. return fmt.Errorf("EAP length %d too short", len(data))
  44. }
  45. e.Code = EAPCode(data[0])
  46. e.Id = data[1]
  47. e.Length = binary.BigEndian.Uint16(data[2:4])
  48. if len(data) < int(e.Length) {
  49. df.SetTruncated()
  50. return fmt.Errorf("EAP length %d too short, %d expected", len(data), e.Length)
  51. }
  52. switch {
  53. case e.Length > 4:
  54. e.Type = EAPType(data[4])
  55. e.TypeData = data[5:]
  56. case e.Length == 4:
  57. e.Type = 0
  58. e.TypeData = nil
  59. default:
  60. return fmt.Errorf("invalid EAP length %d", e.Length)
  61. }
  62. e.BaseLayer.Contents = data[:e.Length]
  63. e.BaseLayer.Payload = data[e.Length:] // Should be 0 bytes
  64. return nil
  65. }
  66. // SerializeTo writes the serialized form of this layer into the
  67. // SerializationBuffer, implementing gopacket.SerializableLayer.
  68. // See the docs for gopacket.SerializableLayer for more info.
  69. func (e *EAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  70. if opts.FixLengths {
  71. e.Length = uint16(len(e.TypeData) + 1)
  72. }
  73. size := len(e.TypeData) + 4
  74. if size > 4 {
  75. size++
  76. }
  77. bytes, err := b.PrependBytes(size)
  78. if err != nil {
  79. return err
  80. }
  81. bytes[0] = byte(e.Code)
  82. bytes[1] = e.Id
  83. binary.BigEndian.PutUint16(bytes[2:], e.Length)
  84. if size > 4 {
  85. bytes[4] = byte(e.Type)
  86. copy(bytes[5:], e.TypeData)
  87. }
  88. return nil
  89. }
  90. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  91. func (e *EAP) CanDecode() gopacket.LayerClass {
  92. return LayerTypeEAP
  93. }
  94. // NextLayerType returns the layer type contained by this DecodingLayer.
  95. func (e *EAP) NextLayerType() gopacket.LayerType {
  96. return gopacket.LayerTypeZero
  97. }
  98. func decodeEAP(data []byte, p gopacket.PacketBuilder) error {
  99. e := &EAP{}
  100. return decodingLayerDecoder(e, data, p)
  101. }