我想在Linux中使用raw_socket发送以太网帧,我使用下面的代码。它有效,但我无法理解,因为我已经在帧(缓冲区)中发出了MAC地址,为什么我必须在struct sockaddr_ll
中再次给它?
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
/*socket_address*/
struct sockaddr_ll socket_address;
socket_address.sll_addr[0] = 0x00;
socket_address.sll_addr[1] = 0x04;
socket_address.sll_addr[2] = 0x75;
socket_address.sll_addr[3] = 0xC8;
socket_address.sll_addr[4] = 0x28;
socket_address.sll_addr[5] = 0xE5;
/*frame*/
unsigned char src_mac[6] = {0x00, 0x01, 0x02, 0xFA, 0x70, 0xAA};
unsigned char dest_mac[6] = {0x00, 0x04, 0x75, 0xC8, 0x28, 0xE5};
memcpy((void*)buffer, (void*)dest_mac, ETH_ALEN);
memcpy((void*)(buffer+ETH_ALEN), (void*)src_mac, ETH_ALEN);
send_result = sendto(s, buffer, ETH_FRAME_LEN, 0,
(struct sockaddr*)&socket_address, sizeof(socket_address));
答案 0 :(得分:3)
如果您输入man 2 sendto
,则会收到以下信息:
ssize_t
send(int socket, const void *buffer, size_t length, int flags);
ssize_t
sendmsg(int socket, const struct msghdr *buffer, int flags);
ssize_t
sendto(int socket, const void *buffer, size_t length, int flags,
const struct sockaddr *dest_addr, socklen_t dest_len);
也许你应该使用send
或sendmsg
答案 1 :(得分:0)
sendto function does not use MAC address provided in struct sockaddr_ll when sending raw packets处的类似帖子。
似乎在其他情况下,目标地址结构将提供额外的数据,例如接口索引。
答案 2 :(得分:0)
使用AF_PACKET原始套接字时,不应使用sendto。您甚至可以使用写入或发送。数据包套接字正好位于您绑定的网络设备上方。因此,输出数据包将完全按照您在缓冲区中指定的方式通过线路发送(仅自动添加FCS / CRC32以控制数据包完整性)。