github.com/gopacket/gopacket@v1.1.0/layers/eap.go (about)

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