Длина заголовка 802.3 всегда 256 при использовании необработанных сокетов в Linux.

У меня есть следующий код, чтобы открыть необработанный сокет и отправить его. В функции отправки у меня есть оператор трассировки, показывающий, что длина моего пакета равна 21. Однако, когда я просматриваю пакеты на принимающей стороне с помощью анализатора пакетов, я вижу:

  1. Фактическая длина пакета составляет 60.
  2. Длина (как указано в заголовке 802.3) составляет 256.

Ни одно из этих чисел не равно 21, и я общаюсь со встроенным устройством, которому не нравится несоответствие. Я погуглил, но не могу понять, как заставить sendto() сообщать правильную длину.

bool EthernetSocket::_open(const char *ifname) {
  _sd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_802_2));
  _ifname = ifname;
  _ifidx = Ethernet::GetInterface(ifname);
  if(_sd < 0) {
    perror("Failed to open socket");
    _bOpened = false;
  }
  else {
    _bOpened = true;
  }
  return _bOpened;
}


bool EthernetSocket::_send(const Buffer& txbuff, Address& addr) {
  if(txbuff.Length() == 0)
    return false;

  if(_ifidx != -1)
    addr.SetInterface(_ifidx);

printf("SEND: Length: %d\n", txbuff.Length());
  if(sendto(_sd, txbuff.Data(), txbuff.Length(), 0, (struct sockaddr *) addr.Component(), (socklen_t) addr.Size()) == -1) {
    perror("Failed broadcast");
    return false;
  }
  return true;
}

Редактировать: я обнаружил, что это поле установлено в поле sll_protocol в моей структуре sockaddr_ll. Но почему? Установка на htons(ETH_P_802_2), как и должно быть, не помогает.


person Andrew Poelstra    schedule 05.08.2010    source источник


Ответы (1)


У меня есть частичный ответ.

Установка sll_protocol на htons(ETH_P_802_3) устраняет проблему. Я не уверен, почему это так, поскольку ETH_P_802_2 и ETH_P_802_3 должны вести себя почти одинаково - и все соответствующие исходные коды ядра, которые я смог найти, поддерживают меня в этом.

Я получаю пакеты через recvfrom() с протоколом ETH_P_802_2, и, следовательно, возвращаемый адрес имеет поле sll_protocol, установленное на ETH_P_802_2. Это означает, что для ответа я должен вручную установить в поле значение ETH_P_802_3 после получения данных. Это ужасный ляп.

В чем дело??

person Andrew Poelstra    schedule 05.08.2010