【问题标题】:ICMP RAW Socket Incomplete ReceiveICMP RAW Socket 接收不完整
【发布时间】:2018-12-10 15:45:58
【问题描述】:

我在 linux 中实现了一个 RAW Socket 来发送和接收 ICMP 数据包, 我已经使用socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) 创建了RAW Socket,并开始使用recvfrom 接收数据包。最初,我在recvfrom 中接收缓冲区 len 设置为 1000 的数据包,然后根据 ICMP 和 IP 标头对数据包进行类型转换。

但是当我开始单独接收数据包标头和数据时(首先接收 IP 标头的 20 个必要字节,然后从该标头中找到数据 len 并使用 recvfrom 接收那么多字节的数据)。 我无法接收数据部分,因为我无法接收第二个数据部分。

第一种方法:

n=recvfrom(sockfd,buf,1000,0,(struct sockaddr *)&cliaddr,&clilen);
struct iphdr *ip_hdr = (struct iphdr *)buf;
struct icmphdr *icmp_hdr = (struct icmphdr *)((char *)ip_hdr + (4 * ip_hdr->ihl));

第二种方法:

struct iphdr ip_hdr;
struct icmphdr icmp_hdr;
n=recvfrom(sockfd, &ip_hdr, 20 ,0,(struct sockaddr *)&cliaddr,&clilen);
len = ip_hdr->tot_len - ip_hdr.ihl*4 ;
n=recvfrom(sockfd, &icmp_hdr, len ,0,(struct sockaddr *)&cliaddr,&clilen);

在第二种情况下,第二次接收不接收任何内容。

【问题讨论】:

    标签: sockets icmp raw-sockets recvfrom


    【解决方案1】:

    原始套接字不提供“流”范式。因此,您可以在最初的recvfrom 呼叫中接收尽可能多的数据包。但是,您没有收到的任何部分都将被丢弃。所以你的第一个方法是要走的路:提供足够大的缓冲区来接收 IP 标头及其 ICMP 有效负载。收到后再解析。

    UDP 数据包也是如此。参考this questionthis one。 UDP 显然是一个不同的协议,但所有相同的考虑因素都适用。

    【讨论】:

      猜你喜欢
      • 2012-11-29
      • 1970-01-01
      • 1970-01-01
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 1970-01-01
      相关资源
      最近更新 更多