-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Why not add Packet Body Length field to EAPOL frame? #249
Copy link
Copy link
Closed
Description
I am learning IEEE 802.1X protocol with gopacket. Currently, there are only three fields in EAPOL interface.
I know that when no further information is needed and the packet body length is set to 0 (and the body is omitted). However, if there is a packet body, such as an EAP message, its length and data are added on as appropriate.
- So why there is no Length field in
EAPOLtype? since sometimes it decodes EAPOL packet with errors
example:
- packet (Get from wireshark)
----
# Packet 0 from /tmp/wireshark_eth0_20161108163321_MDBpM6.pcapng
- 154
- 6.941372676
- Hangzhou_91:eb:ec
- Nearest
- EAP
- 64
- Request, Identity
0000 01 80 c2 00 00 03 50 da 00 91 eb ec 88 8e 01 00 ......P.........
0010 00 05 01 01 00 05 01 00 00 00 00 00 00 00 00 00 ................
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030 00 00 00 00 00 00 00 00 00 00 00 00 29 70 35 65 ............)p5e
- Code:
import (
"fmt"
"log"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
var (
device string = "eth0"
snapshotLen int32 = 1024
promiscuous bool = false
err error
timeout time.Duration = -1 * time.Second
handle *pcap.Handle
)
func main() {
// Open device
handle, err = pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
var filter string = "ether proto 0x888e || udp port 61440"
err = handle.SetBPFFilter(filter)
if err != nil {
log.Fatal(err)
}
defer handle.Close()
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
printPacketInfo(packet)
}
}
func printPacketInfo(packet gopacket.Packet) {
eapolP := gopacket.NewPacket(packet.Data(), layers.LayerTypeEthernet, gopacket.Default)
fmt.Println(eapolP)
}- Running log
PACKET: 64 bytes
- Layer 1 (14 bytes) = Ethernet {Contents=[..14..] Payload=[..50..] SrcMAC=50:da:00:91:eb:ec DstMAC=01:80:c2:00:00:03 EthernetType=EAPOL Length=0}
- Layer 2 (02 bytes) = EAPOL {Contents=[1, 0] Payload=[..48..] Version=1 Type=EAP}
- Layer 3 (48 bytes) = DecodeFailure Packet decoding error: runtime error: slice bounds out of range
PACKET: 64 bytes
- Layer 1 (14 bytes) = Ethernet {Contents=[..14..] Payload=[..50..] SrcMAC=50:da:00:91:eb:ec DstMAC=01:80:c2:00:00:03 EthernetType=EAPOL Length=0}
- Layer 2 (02 bytes) = EAPOL {Contents=[1, 0] Payload=[..48..] Version=1 Type=EAP}
- Layer 3 (48 bytes) = DecodeFailure Packet decoding error: runtime error: slice bounds out of range
But it supposed to be like this (with following modified codeseapol.go):
- Layer 1 (14 bytes) = Ethernet {Contents=[..14..] Payload=[..50..] SrcMAC=50:da:00:91:eb:ec DstMAC=01:80:c2:00:00:03 EthernetType=EAPOL Length=0}
- Layer 2 (04 bytes) = EAPOL {Contents=[1, 0, 0, 5] Payload=[..46..] Version=1 Type=EAP Length=5}
- Layer 3 (05 bytes) = EAP {Contents=[..5..] Payload=[..41..] Code=1 Id=1 Length=5 Type=1 TypeData=[..41..]}
- By the way, why there is not SerializeTo method associated with EAPOL type?
Provided with the customized code I have been tested:
// 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"
"github.com/google/gopacket"
)
// EAPOL defines an EAP over LAN (802.1x) layer.
type EAPOL struct {
BaseLayer
Version uint8
Type EAPOLType
Length uint16
}
// LayerType returns LayerTypeEAPOL.
func (e *EAPOL) LayerType() gopacket.LayerType { return LayerTypeEAPOL }
// DecodeFromBytes decodes the given bytes into this layer.
func (e *EAPOL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
e.Version = data[0]
e.Type = EAPOLType(data[1])
e.Length = binary.BigEndian.Uint16(data[2:4])
e.BaseLayer = BaseLayer{data[:4], data[4:]}
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 *EAPOL) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
bytes, _ := b.PrependBytes(4)
bytes[0] = e.Version
bytes[1] = byte(e.Type)
binary.BigEndian.PutUint16(bytes[2:], e.Length)
return nil
}
// CanDecode returns the set of layer types that this DecodingLayer can decode.
func (e *EAPOL) CanDecode() gopacket.LayerClass {
return LayerTypeEAPOL
}
// NextLayerType returns the layer type contained by this DecodingLayer.
func (e *EAPOL) NextLayerType() gopacket.LayerType {
return e.Type.LayerType()
}
func decodeEAPOL(data []byte, p gopacket.PacketBuilder) error {
e := &EAPOL{}
return decodingLayerDecoder(e, data, p)
}Thank you in advance.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels