0

我有以下代码来打开一个原始套接字并通过它发送。在发送函数中,我有一条跟踪语句,显示我的数据包长度为 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;
}

编辑:我发现该字段被设置为我的 sockaddr_ll 结构中的 sll_protocol 字段。但为什么?将其设置为 htons(ETH_P_802_2) 并没有帮助。

4

1 回答 1

0

我有一个部分答案。

将 sll_protocol 设置为 htons(ETH_P_802_3) 可以解决问题。我不确定为什么会这样,因为 ETH_P_802_2 和 ETH_P_802_3 的行为应该几乎相同 - 我能找到的所有相关内核源都支持我。

我使用协议 ETH_P_802_2 通过 recvfrom() 接收数据包,因此返回的地址的 sll_protocol 字段设置为 ETH_P_802_2。这意味着要回复,我必须在收到数据后手动将字段设置为 ETH_P_802_3。这是一个可怕的组合。

这是怎么回事??

于 2010-08-05T21:13:35.723 回答