I have the following code to open a raw socket and send over it. In the send function I have a trace statement showing me that the length of my packet is 21. However, when I view the packets on the receiving end using a packet sniffer, I see:
- The actual packet length is 60.
- The length (as given in the 802.3 header) is 256.
Neither of those numbers is 21, and I'm communicating with an embedded device that does not like the discrepancy. I've Googled around but I can't figure out how to make sendto() report the correct length.
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;
}
Edit: I've discovered that that field is being set to the sll_protocol field in my sockaddr_ll structure. But why? Setting it to htons(ETH_P_802_2), as it should be, does not help.