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