发送原始数据包时,sendto函数不使用struct sockaddr_ll中提供的MAC地址

前端之家收集整理的这篇文章主要介绍了发送原始数据包时,sendto函数不使用struct sockaddr_ll中提供的MAC地址前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我正在尝试使用原始套接字发送OAM以太网帧.我成功了.

我写的发送功能是:

    int send_frame(sock_info *info,char *buf,int length)
    {
       struct sockaddr_ll dest_addr;
       memset(&dest_addr,sizeof(struct sockaddr_ll));
       dest_addr.sll_family = PF_PACKET;
       dest_addr.sll_protocol = htons(8902);
       dest_addr.sll_ifindex = info->if_index;
       dest_addr.sll_halen = ETH_MAC_ADDR_LEN;
       dest_addr.sll_pkttype = PACKET_OTHERHOST;
       dest_addr.sll_hatype   = ARPHRD_ETHER;
       memset(dest_addr.sll_addr,8);

       dest_addr.sll_addr[0] = 0x00;
       dest_addr.sll_addr[1] = 0xE0;
       dest_addr.sll_addr[2] = 0x0C;
       dest_addr.sll_addr[3] = 0x00;
       dest_addr.sll_addr[4] = 0x95;
       dest_addr.sll_addr[5] = 0x02;

       return sendto(info->sock_fd,buf,length,(struct sockaddr*) &dest_addr,sizeof(struct sockaddr_ll));
    }

我无法使用wireshark捕获数据包.在尝试了太多的东西之后,我发现用于发送的缓冲区应该具有所有以太网帧字段(从目标地址开始).当我将目标和源地址以及其他以太网字段添加到缓冲区时,我能够使用wireshark捕获数据包.因此send函数不使用存储在dest_addr.sll_addr中的MAC地址.

我的问题是,那么struct sockaddr_ll中sll_addr字段的需求是什么?手册说它是目标MAC地址.

最佳答案
对我来说,它听起来像手册页描述它(man 7数据包):

SOCK_RAW packets are passed to and from the device driver without any
changes in the packet data. When receiving a packet,the address is
still parsed and passed in a standard sockaddr_ll address structure.
When transmitting a packet,the user supplied buffer should contain the
physical layer header
. That packet is then queued unmodified to the
network driver
of the interface defined by the destination address.
Some device drivers always add other headers. SOCK_RAW is similar to
but not compatible with the obsolete PF_INET/SOCK_PACKET of Linux 2.0.

这里的缓冲区是指sendto()的第二个参数.因此,stuct sockaddr_ll仅用于将数据返回给调用者,而不是用于格式化RAW数据包.也许您想要使用SOCK_DGRAM或libpcap?

猜你在找的Linux相关文章