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