【问题标题】:RAW Socket - Ethertype and receive's algorithm - CRAW Socket - Ethertype 和接收算法 - C
【发布时间】:2012-03-12 16:18:35
【问题描述】:

我正在使用 C 语言中的原始套接字。 我需要发送和接收原始以太网数据包。 数据包应以 IEEE 802.3 标头开头:

MAC DST [0-5] - MAC SRC [6-11] - ETH 类型[12-13]

使用wireshark捕获数据包我看到以下结构:

MAC DST [0-5] - MAC SRC [6-11] - LENGTH[12-13] - TRAILER[14-58]-....

这是我的代码:

...
sraw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_802_3));
...
retVal = setsockopt(sraw, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
...
val = 3;
retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof (val));
...
memcpy(ptr_eth_header->DstMac, dst_mac, 6);
memcpy(ptr_eth_header->SrcMac, src_mac, 6);
ptr_eth_header->Type = htons(ETH_P_802_3);
memcpy(buffer + ETHHDR_SIZE, data, 60);
...
sockaddr.sll_family = htons(PF_PACKET);
sockaddr.sll_protocol = htons(ETH_P_802_3);
sockaddr.sll_ifindex = ifr.ifr_ifru.ifru_ivalue;
sockaddr.sll_halen = 6;
memcpy(&(sockaddr.sll_addr), dst_mac, 6);
...
bytes = sendto(sraw, buffer, sizeof(buffer), 0, (struct sockaddr *) &(sockaddr), sizeof (struct sockaddr_ll));

这只是wireshark的“问题”吗?有什么想法吗?

我的第二个问题是关于原始消息的接收。 进程卡在 recvfrom 上。

这是我的代码:

sraw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_802_3));
...
retVal = setsockopt(sraw, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
...
val = 3;
retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof (val));
...
val = CLIENT_PACKET_SIZE;
retVal = setsockopt(sraw, SOL_SOCKET, SO_RCVBUF, &val, sizeof (val));

sockaddr.sll_family    = htons(PF_PACKET);
sockaddr.sll_ifindex   = ifr.ifr_ifindex;
sockaddr.sll_protocol  = htons(ETH_P_802_3);

buffer = malloc(CLIENT_PACKET_SIZE * sizeof(char));
while (count < PACKET_COUNT) {
    bytes = recvfrom(sraw, buffer, CLIENT_PACKET_SIZE, 0, (struct sockaddr *)&sockaddr, (socklen_t*)sizeof(sockaddr));
    ...
}

你能帮帮我吗?

提前致谢!

【问题讨论】:

  • 你的标头结构打包了吗? sizeof(buffer) 是什么?
  • 是的。 typedef struct { char DstMac[6]; char SrcMac[6]; short int Type; } HEADER;sizeof(buffer) 是 64。
  • 您是否能够独立于您的程序使用 Wireshark 验证 NIC 发送/接收数据包?
  • 是的。我经常使用wireshark。它只是无法识别(在这种情况下)数据包的正确格式,或者我发送了错误的类型。
  • 我用wireshark看到了正确的位序列。 (ETH_P_802_3 = 0x0001)

标签: c sockets network-programming raw-sockets


【解决方案1】:

我找到了关于我的第一个问题的回复:我使用 Ethertype == 0x0001 而不是 EtherType >= 0x0600

http://www.cavebear.com/archive/cavebear/Ethernet/type.html

第二个问题呢? 我的代码有什么问题?

【讨论】:

    【解决方案2】:

    很难用一个词回答您的问题。但是,如果您问我为什么 recvfrom 可能会卡住,使用您的代码,我会说您可能没有得到任何满足您的过滤条件的数据包。您确定要以预期格式传递 ifindex 值吗?我看到你通过 ifindex sockaddr.sll_ifindex = ifr.ifr_ifru.ifru_ivalue;像这样在sendto。

    其他原因可能是,您在套接字上设置的缓冲区大小不受内核支持或内核缓冲区不足等许多其他原因。但其中任何一个的机会都是最小的。

    另外,对于您的情况,我建议使用非阻塞套接字而不是阻塞。仅当您知道有数据包等待读取时才调用 recvfrom。

    【讨论】:

      猜你喜欢
      • 2018-12-10
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多