生のソケットを開いて送信する次のコードがあります。send 関数には、パケットの長さが 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;
}
編集:そのフィールドが sockaddr_ll 構造の sll_protocol フィールドに設定されていることを発見しました。しかし、なぜ?htons(ETH_P_802_2) に設定しても、本来は役に立ちません。