ICMP RAW 套接字未完成接收
ICMP RAW Socket Incomplete Receive
我在 linux 中实现了一个 RAW 套接字来发送和接收 ICMP 数据包,
我已经使用 socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
创建了 RAW 套接字并使用 recvfrom
开始接收数据包。最初我在 recvfrom
中接收缓冲区 len 设置为 1000 的数据包,然后根据 ICMP 和 IP headers.
对数据包进行类型转换
但是当我开始单独接收数据包 header 和数据时(首先接收 IP Headers 的 20 个必要字节,然后从 header 中找到数据 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);
在第二种情况下,第二次接收没有收到任何东西。
原始套接字不提供 "stream" 范例。因此,您可以在初始 recvfrom
调用中收到尽可能多的数据包。但是你没有收到的任何部分都会被丢弃。所以你的第一个方法是要走的路:提供足够大的缓冲区来接收 IP header 及其 ICMP 有效负载。然后在你收到它之后解析它。
UDP数据包也是如此。参考this question and this one。 UDP 显然是一个不同的协议,但所有相同的注意事项都适用。
我在 linux 中实现了一个 RAW 套接字来发送和接收 ICMP 数据包,
我已经使用 socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
创建了 RAW 套接字并使用 recvfrom
开始接收数据包。最初我在 recvfrom
中接收缓冲区 len 设置为 1000 的数据包,然后根据 ICMP 和 IP headers.
但是当我开始单独接收数据包 header 和数据时(首先接收 IP Headers 的 20 个必要字节,然后从 header 中找到数据 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);
在第二种情况下,第二次接收没有收到任何东西。
原始套接字不提供 "stream" 范例。因此,您可以在初始 recvfrom
调用中收到尽可能多的数据包。但是你没有收到的任何部分都会被丢弃。所以你的第一个方法是要走的路:提供足够大的缓冲区来接收 IP header 及其 ICMP 有效负载。然后在你收到它之后解析它。
UDP数据包也是如此。参考this question and this one。 UDP 显然是一个不同的协议,但所有相同的注意事项都适用。