简体   繁体   English

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

[英]RAW Socket - Ethertype and receive's algorithm - C

I'm working with raw socket in C language. 我正在使用C语言的原始套接字。 I need to send and to receive a raw ethernet packet. 我需要发送和接收原始以太网数据包。 The packet should start with an IEEE 802.3 header: 数据包应以IEEE 802.3标头开头:

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

Catching the packets with wireshark I see the following structure: 使用wireshark捕获数据包我看到以下结构:

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

This is my code: 这是我的代码:

...
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));

Is it just a wireshark's "problem"? 这只是一个wirehark的“问题”吗? Any ideas? 有任何想法吗?

My second problem is about the receipt of the raw messages. 我的第二个问题是收到原始邮件。 The process is stuck on the recvfrom. 这个过程停留在recvfrom上。

This is my code: 这是我的代码:

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));
    ...
}

Could you help me? 你可以帮帮我吗?

Thanks in advance! 提前致谢!

I found the response about my first question: I use Ethertype == 0x0001 instead EtherType >= 0x0600 我找到了关于我的第一个问题的回答:我使用Ethertype == 0x0001而不是EtherType> = 0x0600

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

What about the second question? 那第二个问题呢? What's wrong with my code? 我的代码出了什么问题?

A one word answer for your question is difficult. 对你的问题一个单词的答案很难。 But if you ask me why the recvfrom could be stuck, with your code, i would say you may not be getting any packet satisfying your filter condition. 但是,如果你问我为什么recvfrom可能卡住,你的代码,我会说你可能没有得到满足你的过滤条件的任何数据包。 Are you sure you are passing the ifindex value in the expected format? 您确定要以预期格式传递ifindex值吗? I see you pass the ifindex sockaddr.sll_ifindex = ifr.ifr_ifru.ifru_ivalue; 我看到你传递了ifindex sockaddr.sll_ifindex = ifr.ifr_ifru.ifru_ivalue; like this in sendto. 像sendto这样的。

Other reasons could be, the buffer size you set on the socket is unsupported by kernel or the kernel is running out of buffers and so many other reasons. 其他原因可能是,您在套接字上设置的缓冲区大小不受内核支持,或者内核用尽缓冲区以及其他许多原因。 but the chances of any of these are minimum. 但这些中的任何一个的可能性都是最小的。

Also, for your scenario, i would suggest using a non-blocking socket instead of blocking. 另外,对于您的场景,我建议使用非阻塞套接字而不是阻塞。 Call the recvfrom only when you know there are packets waiting to be read. 仅当您知道有等待读取的数据包时才调用recvfrom。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM