【问题标题】:Reading an ICMP response using RAW sockets使用 RAW 套接字读取 ICMP 响应
【发布时间】:2020-02-22 15:50:52
【问题描述】:

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

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

这是我不太明白的第四点。 '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;

}

`

【问题讨论】:

  • 缓冲区布局:[ iphdr [ icmphdr ] ] 以上代码是标准 C++ 中的未定义行为;编译器扩展可能没问题。我不知道C的合法性
  • @RichardCritten 我想是[ [ iphdr ] [ icmphdr ] ],不是吗?

标签: c++ c sockets pointers casting


【解决方案1】:

没有什么可读的。

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

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

您可以使用char* 来检查T 类型的对象;您不能检查 char[],就好像它是 T 类型的对象一样。这违反了严格的别名规则。不幸的是,由于旧的和更简单的编译器在实践中更有可能让这种滑动,围绕这样的代码存在一个常见的误解,并且它继续出现在示例中。 ?

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

【讨论】:

    猜你喜欢
    • 2013-01-28
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 2014-05-11
    相关资源
    最近更新 更多