Проблемы с получением кадров Ethernet с помощью Go

Я работаю со старым протоколом, основанным на Ethernet (в частности, BACnet/Ethernet), поэтому я пишу приложение для отправки и получения кадров Ethernet с помощью Go. Я использую пакет с github, который до сих пор довольно хорош, и следую руководству, расположенному здесь

Я работаю на платформе Linux, в частности, на дистрибутиве Debian. 4.14 Кернал.

Я могу отлично отправлять кадры и проверять с помощью Wireshark, что они отправляются. Я также делаю так, чтобы удаленные устройства отвечали на мой кадр на Wireshark. Однако моя функция прослушивания никак не обрабатывает ответ. Нет никаких выходных данных или ошибок.

Я следовал примеру в связанной статье, но я включу источник ниже. Этот код не мой, я не беру на себя ответственность за него. Он принадлежит Мэтту Лейеру.

Почему моя заявка не получает ответа?

package main

import (
    "log"
    "github.com/mdlayher/ethernet"
    "github.com/mdlayher/raw"
    "net"
)

func main {
// Select the eth0 interface to use for Ethernet traffic.
ifi, err := net.InterfaceByName("eth0")
if err != nil {
    log.Fatalf("failed to open interface: %v", err)
}

// Open a raw socket using same EtherType as our frame.
c, err := raw.ListenPacket(ifi, 0xcccc)
if err != nil {
    log.Fatalf("failed to listen: %v", err)
}
defer c.Close()

// Accept frames up to interface's MTU in size.
b := make([]byte, ifi.MTU)
var f ethernet.Frame

// Keep reading frames.
for {
    n, addr, err := c.ReadFrom(b)
    if err != nil {
        log.Fatalf("failed to receive message: %v", err)
    }

    // Unpack Ethernet frame into Go representation.
    if err := (&f).UnmarshalBinary(b[:n]); err != nil {
        log.Fatalf("failed to unmarshal ethernet frame: %v", err)
    }

    // Display source of message and message itself.
    log.Printf("[%s] %s", addr.String(), string(f.Payload))
}

person Michael Anonymous    schedule 23.12.2019    source источник


Ответы (1)


Нашел мою проблему.

Когда вы настраиваете сокет для прослушивания, вы должны указать тип кадра Ethernet. В C это будет связано с типами фреймов в linux/if_ether.h.

Если я укажу тип фрейма 0x0003, он будет работать для фрейма BACnet/Ethernet, и я смогу видеть поступающие фреймы.

person Michael Anonymous    schedule 24.12.2019