RAW Socket - Ethertype和接收算法 - C.

时间:2012-03-12 16:18:36

标签: c sockets network-programming raw-sockets

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

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

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

MAC DST [0-5] - MAC SRC [6-11] - 长度[12-13] - 拖车[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));

这只是一个wirehark的“问题”吗?有什么想法吗?

我的第二个问题是收到原始邮件。 这个过程停留在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));
    ...
}

你能帮帮我吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

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

其他原因可能是,您在套接字上设置的缓冲区大小不受内核支持,或者内核用尽缓冲区以及其他许多原因。但这些中的任何一个的可能性都是最小的。

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