2

I try to send Request Identity EAPoL packet:

func eapol_requestIdentity(handle *pcap.Handle, iface *net.Interface, id uint8) error {
    
        len := uint16(5) // eap1 field length
    
        eap1 := layers.EAP{
            Code: layers.EAPCodeResponse,
            Id:   id,
            Type: layers.EAPTypeIdentity,
            TypeData: []byte{byte(layers.EAPTypeIdentity)}, // bugfix
            Length:   len,
        }
    
        eapol := layers.EAPOL{
            Version: 1,
            Type:    layers.EAPOLTypeEAP,
            Length:  eap1.Length,
        }
    
        eth := layers.Ethernet{
            SrcMAC:       iface.HardwareAddr,
            DstMAC:       net.HardwareAddr{0x01, 0x80, 0xc2, 0x00, 0x00, 0x03},
            EthernetType: layers.EthernetTypeEAPOL,
        }
    
        buf := gopacket.NewSerializeBuffer()
        opts := gopacket.SerializeOptions{
            //FixLengths:       true, // doesn't work
            FixLengths:       false,
            ComputeChecksums: true,
        }
    
        gopacket.SerializeLayers(buf, opts, &eth, &eapol, &eap1)
        log.Printf("send EOPoL : Request Identity %u...", id)
        if err := handle.WritePacketData(buf.Bytes()); err != nil {
            log.Printf("Send err ", err)
            return err
        }
        log.Printf("send packet [OK]")
    
        return nil
    }

I don't understand: if I delete line TypeData: [] byte{byte(layers.EAPTypeIdentity)} or line Type: layers.EAPTypeIdentity, my application sent a wrong packet. Is it normal?... why must I set data twice for de same byte in packet?

Also, I tried to set FixLengths to true, but length fields are bads in sent packet...

ipStack
  • 381
  • 1
  • 12

1 Answers1

0

I am not very familiar with EAP, but according to the RFC, Type and Type-Data are two different fields:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |  Type-Data ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

So it stands to reason that if you leave out a piece of the packet, that it is "wrong".

As for the length, it seems there is a bug in gopacket when calculating the length. According to the RFC

The Length field is two octets and indicates the length of the EAP packet including the Code, Identifier, Length, Type, and Type-Data fields

But when FixLengths is true, gopacket only counts Type and Type-Data.

if opts.FixLengths {
  e.Length = uint16(len(e.TypeData) + 1)
}

The +1 should be +5, so it seems like you discovered a bug.

Edit: Looks like you already filled a bug report: https://github.com/google/gopacket/issues/931

Dylan Reimerink
  • 5,874
  • 2
  • 15
  • 21
  • Yes, I created this ticket. After I don't know enough about golang to fix second problem : auto EAPOL layer length calculation. EAPOL layer encapsulate EAP field(s) : I don't know max EAP fields number in a EAPoL packet. EAPOL layer length field value is the sum of EAP field lengths. – ipStack Jan 19 '22 at 08:23