blob: 54238e8c73bbf2deb6038f3d7eced2bb48f5b665 [file] [log] [blame]
Naveen Sampath04696f72022-06-13 15:19:14 +05301// 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 if len(data) < 4 {
51 df.SetTruncated()
52 return fmt.Errorf("EAP length %d too short", len(data))
53 }
54 e.Code = EAPCode(data[0])
55 e.Id = data[1]
56 e.Length = binary.BigEndian.Uint16(data[2:4])
57 if len(data) < int(e.Length) {
58 df.SetTruncated()
59 return fmt.Errorf("EAP length %d too short, %d expected", len(data), e.Length)
60 }
61 switch {
62 case e.Length > 4:
63 e.Type = EAPType(data[4])
64 e.TypeData = data[5:]
65 case e.Length == 4:
66 e.Type = 0
67 e.TypeData = nil
68 default:
69 return fmt.Errorf("invalid EAP length %d", e.Length)
70 }
71 e.BaseLayer.Contents = data[:e.Length]
72 e.BaseLayer.Payload = data[e.Length:] // Should be 0 bytes
73 return nil
74}
75
76// SerializeTo writes the serialized form of this layer into the
77// SerializationBuffer, implementing gopacket.SerializableLayer.
78// See the docs for gopacket.SerializableLayer for more info.
79func (e *EAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
80 if opts.FixLengths {
81 e.Length = uint16(len(e.TypeData) + 1)
82 }
83 size := len(e.TypeData) + 4
84 if size > 4 {
85 size++
86 }
87 bytes, err := b.PrependBytes(size)
88 if err != nil {
89 return err
90 }
91 bytes[0] = byte(e.Code)
92 bytes[1] = e.Id
93 binary.BigEndian.PutUint16(bytes[2:], e.Length)
94 if size > 4 {
95 bytes[4] = byte(e.Type)
96 copy(bytes[5:], e.TypeData)
97 }
98 return nil
99}
100
101// CanDecode returns the set of layer types that this DecodingLayer can decode.
102func (e *EAP) CanDecode() gopacket.LayerClass {
103 return LayerTypeEAP
104}
105
106// NextLayerType returns the layer type contained by this DecodingLayer.
107func (e *EAP) NextLayerType() gopacket.LayerType {
108 return gopacket.LayerTypeZero
109}
110
111func decodeEAP(data []byte, p gopacket.PacketBuilder) error {
112 e := &EAP{}
113 return decodingLayerDecoder(e, data, p)
114}