Длина заголовка 802.3 всегда 256 при использовании сырых сокетов в Linux - PullRequest
0 голосов
/ 05 августа 2010

У меня есть следующий код для открытия необработанного сокета и отправки по нему. В функции отправки у меня есть оператор трассировки, показывающий, что длина моего пакета равна 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), как и должно быть, не помогает.

1 Ответ

0 голосов
/ 06 августа 2010

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

Установка 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 после получения данных. Это ужасный клудж.

Что происходит ??

...