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