ICMP RAW套接字不完整接收

时间:2018-07-02 12:00:58

标签: sockets icmp raw-sockets recvfrom

我已经在Linux中实现了RAW套接字以接收ICMP响应数据包, 我已经使用socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)创建了RAW套接字,并开始使用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);

在第二种情况下,第二次接收不接收任何东西。

1 个答案:

答案 0 :(得分:1)

原始套接字不提供“流”范例。因此,您可以在初始recvfrom呼叫中接收任意数量的数据包。但是您没有收到的任何部分都将被丢弃。因此,您的第一种方法就是走:提供足够大的缓冲区来接收IP标头及其ICMP有效负载。然后在收到它后对其进行解析。

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