简体   繁体   English

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

[英]sendto function does not use MAC address provided in struct sockaddr_ll when sending raw packets

I am trying to send an OAM ethernet frame using raw socket. 我正在尝试使用原始套接字发送OAM以太网帧。 I was successful in doing so. 我成功了。

The send function I have written is: 我写的发送功能是:

    int send_frame(sock_info *info,char *buf,int length)
    {
       struct sockaddr_ll dest_addr;
       memset(&dest_addr,0,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,0,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, 0, (struct sockaddr*) &dest_addr, sizeof(struct sockaddr_ll));
    }

I was unable to capture the packet using wireshark. 我无法使用wireshark捕获数据包。 After tryiing too many things, I found out that buffer used to send should have all ethernet frame fields (starting from destination address). 在尝试了太多的东西之后,我发现用于发送的缓冲区应该具有所有以太网帧字段(从目标地址开始)。 When I added the destination and source address and other ethernet fields into the buffer, I was able to capture the packet using wireshark. 当我将目标和源地址以及其他以太网字段添加到缓冲区时,我能够使用wireshark捕获数据包。 So the send function doesn't use the MAC address stored in dest_addr.sll_addr . 因此send函数不使用存储在dest_addr.sll_addr的MAC地址。

My question is, Then what's the need of sll_addr field in the struct sockaddr_ll ? 我的问题是,那么struct sockaddr_llsll_addr字段的需求是什么? Manuals say that it is the destination MAC address. 手册说它是目标MAC地址。

To me it sounds like it works as the manual page describes it ( man 7 packet ): 对我来说,它听起来像手册页描述它( man 7数据包 ):

SOCK_RAW packets are passed to and from the device driver without any changes in the packet data. SOCK_RAW数据包传递到设备驱动程序和从设备驱动程序传递,而不会对数据包数据进行任何更改。 When receiving a packet, the address is still parsed and passed in a standard sockaddr_ll address structure. 接收数据包时,仍会解析地址并将其传递到标准的sockaddr_ll地址结构中。 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. SOCK_RAW与Linux 2.0的过时PF_INET / SOCK_PACKET类似但不兼容。

The buffer here refers to the 2nd parameter of sendto() . 这里的缓冲区是指sendto()的第二个参数。 So, the stuct sockaddr_ll is only used to return data to the caller, not to format the RAW packet. 因此,stuct sockaddr_ll仅用于将数据返回给调用者,而不是用于格式化RAW数据包。 Maybe you want to user SOCK_DGRAM or libpcap instead? 也许您想要使用SOCK_DGRAMlibpcap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用sendto通过原始以太网套接字发送数据而不使用sockaddr_ll? - How to send data over a raw ethernet socket using sendto without using sockaddr_ll? 原始以太网套接字填充sockaddr_ll - raw ethernet sockets filling sockaddr_ll 数据包sockets中sockaddr_ll的含义和用途 - Meaning and purpose of sockaddr_ll in packet sockets 在FreeBSD中创建和发送原始IP数据包-sendto()错误无效参数 - Creating and sending raw IP packets in FreeBSD - sendto() error Invalid Argument 为什么`struct sockaddr`包含一个地址族字段? - Why does `struct sockaddr` contain a address family field? 错误:在原始 sockets 中使用 sendto() 时地址错误 - Error: Bad address when using sendto() in raw sockets getaddrinfo什么时候在列表中返回多个sockaddr结构? - When does getaddrinfo return more than one sockaddr struct in the list? 在使用之前将结构如sockaddr_in,sockaddr_in6和addrinfo归零时,这是正确的:memset,初始化器还是其中之一? - When zeroing a struct such as sockaddr_in, sockaddr_in6 and addrinfo before use, which is correct: memset, an initializer or either? C 原始套接字的发送地址的目的? - Purpose of sendto address for C raw socket? connect(2)调用是否使用完整的结构sockaddr_in还是可以满足in_addr结构? - Does the connect(2) call make use of a full struct sockaddr_in or could it just suffice with a struct in_addr?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM