【问题标题】:When using a raw socket, why do I need to give out MAC address twice?使用原始套接字时,为什么我需要给出两次 MAC 地址?
【发布时间】:2015-07-11 06:42:27
【问题描述】:

我想在 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));

【问题讨论】:

    标签: c linux macos raw-sockets


    【解决方案1】:

    如果你输入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

    【讨论】:

      【解决方案2】:

      sendto function does not use MAC address provided in struct sockaddr_ll when sending raw packets 的类似主题。

      似乎在其他情况下,目标地址结构将提供额外的数据,例如接口索引。

      【讨论】:

        【解决方案3】:

        当您使用 AF_PACKET 原始套接字时,您不应该使用 sendto。您甚至可以使用写入或发送。数据包套接字正好放置在您绑定的网络设备上方。因此,输出数据包将完全按照您在缓冲区中指定的方式通过线路发送(仅 FCS/CRC32 将自动添加以控制数据包完整性)。

        【讨论】:

          猜你喜欢
          • 2021-05-23
          • 1970-01-01
          • 2011-11-25
          • 2017-05-05
          • 1970-01-01
          • 2020-02-20
          • 1970-01-01
          • 2022-07-12
          • 2015-06-17
          相关资源
          最近更新 更多