// 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" "fmt" "github.com/google/gopacket" ) type EAPCode uint8 type EAPType uint8 const ( EAPCodeRequest EAPCode = 1 EAPCodeResponse EAPCode = 2 EAPCodeSuccess EAPCode = 3 EAPCodeFailure EAPCode = 4 // EAPTypeNone means that this EAP layer has no Type or TypeData. // Success and Failure EAPs will have this set. EAPTypeNone EAPType = 0 EAPTypeIdentity EAPType = 1 EAPTypeNotification EAPType = 2 EAPTypeNACK EAPType = 3 EAPTypeOTP EAPType = 4 EAPTypeTokenCard EAPType = 5 ) // EAP defines an Extensible Authentication Protocol (rfc 3748) layer. type EAP struct { BaseLayer Code EAPCode Id uint8 Length uint16 Type EAPType TypeData []byte } // LayerType returns LayerTypeEAP. func (e *EAP) LayerType() gopacket.LayerType { return LayerTypeEAP } // DecodeFromBytes decodes the given bytes into this layer. func (e *EAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { e.Code = EAPCode(data[0]) e.Id = data[1] e.Length = binary.BigEndian.Uint16(data[2:4]) switch { case e.Length > 4: e.Type = EAPType(data[4]) e.TypeData = data[5:] case e.Length == 4: e.Type = 0 e.TypeData = nil default: return fmt.Errorf("invalid EAP length %d", e.Length) } e.BaseLayer.Contents = data[:e.Length] e.BaseLayer.Payload = data[e.Length:] // Should be 0 bytes return nil } // SerializeTo writes the serialized form of this layer into the // SerializationBuffer, implementing gopacket.SerializableLayer. // See the docs for gopacket.SerializableLayer for more info. func (e *EAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { if opts.FixLengths { e.Length = uint16(len(e.TypeData) + 1) } size := len(e.TypeData) + 4 if size > 4 { size++ } bytes, err := b.PrependBytes(size) if err != nil { return err } bytes[0] = byte(e.Code) bytes[1] = e.Id binary.BigEndian.PutUint16(bytes[2:], e.Length) if size > 4 { bytes[4] = byte(e.Type) copy(bytes[5:], e.TypeData) } return nil } // CanDecode returns the set of layer types that this DecodingLayer can decode. func (e *EAP) CanDecode() gopacket.LayerClass { return LayerTypeEAP } // NextLayerType returns the layer type contained by this DecodingLayer. func (e *EAP) NextLayerType() gopacket.LayerType { return gopacket.LayerTypeZero } func decodeEAP(data []byte, p gopacket.PacketBuilder) error { e := &EAP{} return decodingLayerDecoder(e, data, p) }