【问题标题】:Ethernet frame transmission via raw socket通过原始套接字传输以太网帧
【发布时间】:2014-02-21 09:09:13
【问题描述】:

我的意图是编写一个函数,该函数将保存整个以太网帧的缓冲区作为参数,并将其发送到原始套接字(仅用于传输)。

这里有明显的步骤:

sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
// ...
write(sockfd, buffer, buffer_len);
// ...
close(sockfd);

但是写入函数失败并出现 EXNIO 错误代码:“没有这样的设备或地址”。我从 Wireshark 会话中获取数据包内容,因此它的格式应该很好。

互联网上有几个关于发送原始 eth 数据包的示例,但我没有找到任何使用 write() 而不是 sendto() 的示例,这需要填充 sockaddr_ll 结构。

有人遇到过同样的问题吗?使用 sendto() 是完成任务的唯一方法吗?

谢谢。

注意:程序以 root 身份运行。

【问题讨论】:

    标签: c linux sockets


    【解决方案1】:

    这是对我有用的部分代码。在我对事物的理解中,写入将不起作用,因为它应该发送一个字符流。它可以写入文件或 TCP 连接或类似内容。我认为原始数据包非常不同。

    int sock;
    sock = socket(PF_INET, SOCK_RAW, 0);
    if (sock < 0) {
      printf("Can't get socket\n");
      exit(1);
    }
    /* Insist that we have header included */
    int one = 1;
    if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof (one)) < 0) {
      printf ("Cannot set IP_HDRINCL!\n");
      exit(1);
    }
    ...
    struct sockaddr_in sockin;
    sockin.sin_family = AF_INET;
    sockin.sin_port = dest_port;
    sockin.sin_addr.s_addr = dest_ip;
    ...
    sendto (sock, buffer, bufferlen, 0, (struct sockaddr *) &sockin, sizeof (sockin));
    ...
    close(sock);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-16
      • 1970-01-01
      • 2018-09-14
      • 2023-03-13
      • 2010-10-20
      • 2017-12-26
      • 2018-12-13
      相关资源
      最近更新 更多