首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >原始套接字-以太型和接收算法-C

原始套接字-以太型和接收算法-C
EN

Stack Overflow用户
提问于 2012-03-12 16:18:35
回答 2查看 4K关注 0票数 3

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

MAC DST 0-5 - MAC SRC 6-11 - ETH TYPE12 12-13

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

MAC DST 0-5 - MAC SRC 6-11 - LENGTH12-13 -TRAILER14 14-58.

这是我的密码:

代码语言:javascript
运行
复制
...
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的“问题”吗?有什么想法吗?

我的第二个问题是关于接收原始消息。这个过程被卡住了。

这是我的密码:

代码语言:javascript
运行
复制
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));
    ...
}

你能帮我一下吗?

提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2012-03-13 10:16:34

我找到了关于我的第一个问题的回答:我使用以太型== 0x0001而不是Ethertype >= 0x0600。

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

第二个问题呢?我的密码怎么了?

票数 1
EN

Stack Overflow用户

发布于 2013-10-03 06:32:16

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

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9670775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档