我正在尝试使用原始套接字发送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地址.
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?