【问题标题】:sendto function does not use MAC address provided in struct sockaddr_ll when sending raw packetssendto 函数在发送原始数据包时不使用 struct sockaddr_ll 中提供的 MAC 地址
【发布时间】:2013-04-20 14:00:37
【问题描述】:

我正在尝试使用原始套接字发送 OAM 以太网帧。我成功地这样做了。

我写的发送函数是:

    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));
    }

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

我的问题是,那么struct sockaddr_ll 中的sll_addr 字段需要什么?手册上说是目的MAC地址。

【问题讨论】:

    标签: c linux sockets network-programming


    【解决方案1】:

    在我看来,它就像手册页描述的那样工作(man 7 packet):

    SOCK_RAW 数据包传入和传出设备驱动程序,没有任何 包数据的变化。接收数据包时,地址为 仍然在标准的 sockaddr_ll 地址结构中解析和传递。 传输数据包时,用户提供的缓冲区应包含 物理层头。然后,该数据包在未修改的情况下排队到 目标地址定义的接口的网络驱动程序。 某些设备驱动程序总是添加其他标头。 SOCK_RAW 类似于 但不兼容Linux 2.0过时的PF_INET/SOCK_PACKET。

    这里的缓冲区指的是sendto()的第二个参数。因此,stuct sockaddr_ll 仅用于向调用者返回数据,而不是格式化 RAW 数据包。也许您想改用 SOCK_DGRAMlibpcap

    【讨论】:

      猜你喜欢
      • 2014-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-20
      • 2021-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多