使用RAW套接字读取ICMP响应



我有以下工作函数,它接收一个为ICMP响应准备好的套接字,并将其读取到缓冲区中,但我很难理解代码流,希望有人纠正/确认我的理解。我的理解如下:

  1. 一个名为"buffer"的1024字符数组指针被定义为用作缓冲区
  2. 创建了两个名为"ip"one_answers"icmp"的指针来指向iphdr和icmphdr结构
  3. "ip"指针被设置为指向"buffer"指针,该指针现在被转换为iphdr结构指针
  4. "icmp"指针设置为指向"buffer"指针+结构体iphdr的大小,该结构体现已转换为icmphdr结构体指针

这是我不太明白的第四点。"icmp"指针地址是否堆叠在"ip"指针地址下方,并且"(buff+sizeof(struct iphdr(("正在引用"icmp’指针应指向的内存点?关于使用这种偏移类型的类型铸造,我有什么地方可以读到吗?`

int read_icmp_answer(int *sock){
char buff[1024];
struct iphdr *ip;   
struct icmphdr *icmp;   
ip = (struct iphdr *)buff;
icmp = (struct icmphdr *) (buff + sizeof(struct iphdr));
if(read(*sock, buff, sizeof(buff)) > 0) {
if(icmp->type == 0 && icmp->code == 0) return 1;
else return -1;
}
return 0;
}

`

没有什么可读的。

作者创建了1024个字节。然后,他们对编译器撒谎,说服它在该块的开头存在struct iphdr,然后立即存在struct icmphdr(使用一些非常基本的指针算术和几个强制转换(。

这不是真的,而且代码有未定义的行为。

可以使用char*检查类型为T的对象;不能将char[]当作T类型的对象来检查。这违反了严格的别名规则。不幸的是,由于较老和较简单的编译器在实践中更容易出现这种情况,因此围绕这样的代码存在一种常见的误解,并且这种误解继续出现在示例中。😿

相反,作者应该声明一个struct iphdr并向其中读取sizeof(iphdr)字节,然后声明一个struct icmphdr并向中读取sizeof(icmphdr)字节。

最新更新