以太网帧通过原始套接字传输

时间:2014-01-29 13:57:38

标签: c linux sockets

我的目的是编写一个函数,该函数将一个缓冲区作为参数,该缓冲区包含整个以太网帧并将其发送到原始套接字(因此仅需要传输)。

这里有明显的步骤:

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

但是写入功能因EXNIO错误代码而失败:"没有这样的设备或地址"。我从wireshark会话中获取数据包内容,因此它的格式应该很好。

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

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

感谢。

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

1 个答案:

答案 0 :(得分:0)

这是代码的一部分,对我有用。在我对事物的理解中,写不会起作用,因为它应该发送一串字符。它可以写入文件或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);