首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >原始以太网套接字填充sockaddr_ll

原始以太网套接字填充sockaddr_ll
EN

Stack Overflow用户
提问于 2013-11-06 23:29:15
回答 1查看 13.2K关注 0票数 2

我正在使用PF_PACKET和SOCK_RAW构建服务器/客户端软件,并在调用socket()时使用自定义协议。

在客户端软件中,我以同样的方式创建套接字,并从该套接字执行get,然后获取数据

我的问题是,我是否必须像填写服务器一样填写sockaddr_ll结构,因为当我从客户端回复时,我获得的源MAC地址是一个奇怪的地址,例如11:11:00:00:00:00,当然这不是我客户端的MAC

有人知道这是怎么回事吗?打开插座

代码语言:javascript
运行
复制
if ( (sckfd=socket(PF_PACKET, SOCK_RAW, htons(proto)))<0)
{
    myError("socket");

}

这就是我接收数据的方式

代码语言:javascript
运行
复制
n = recvfrom(sckfd, buffer, 2048, 0, NULL, NULL);
printf("%d bytes read\n",n);

这基本上就是我在不填充结构sockaddr_ll的情况下在客户端接收数据的方式

对于server Program,我必须填充结构

代码语言:javascript
运行
复制
struct sockaddr_ll saddrll;
memset((void*)&saddrll, 0, sizeof(saddrll));
saddrll.sll_family = PF_PACKET;   
saddrll.sll_ifindex = ifindex;
saddrll.sll_halen = ETH_ALEN;
memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);

我的问题是,我如图所示接收并如图所示发送,当我回复服务器调用服务器中用于发送的相同函数时,当我接收客户端回复时,我会得到什么: 11:11:00:00:00:00

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-07 07:05:23

您可能应该使用

socket(AF_PACKET, SOCK_DGRAM, htons(proto)))

而不是SOCK_RAW套接字。通过SOCK_RAW,您可以发送/接收整个以太网帧,包括源和目的MAC地址。使用SOCK_DGRAM,内核将填充以太网头。

您可能希望将回复发送到与请求来自相同的地址,recvfrom()可以填充源地址;

代码语言:javascript
运行
复制
struct sockaddr_ll src_addr;
socklen_t addr_len = sizeof src_addr;
n = recvfrom(sckfd, buffer, 2048, 0, 
            (struct sockaddr*)&src_addr, &addr_len);

现在你已经知道了源地址,所以把包发回给它:

代码语言:javascript
运行
复制
...
sendto(sckfd, data, data_len, src_addr, addr_len);

如果你更需要使用SOCK_RAW,你也会收到以太网报头,所以只需从接收到的数据中复制出MAC地址,并在构建回复帧时交换它们。

对于一个SOCK_RAW套接字,你可以手工制作整个以太网帧,你不需要填写以太网地址,所以不需要下面的内容;

代码语言:javascript
运行
复制
 memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19816071

复制
相关文章

相似问题

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