blob: 250f857137203d7cca678ac29a57e32fc2ec86bf [file] [log] [blame]
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001// 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}