【问题标题】:Is it safe to write an unsigned byte array in network order directly to ip.ip_dest?将网络顺序中的无符号字节数组直接写入ip.ip_dest是否安全?
【发布时间】:2019-06-17 15:03:37
【问题描述】:

在 netinet/ip.h 中有一个结构“ip”,用于传输 IP 数据包。地址字段是“ip_src”和“ip_dest”。

如果我的 IPv4 地址按网络顺序排列在一个无符号字节数组中,我是否可以安全地将这个数组直接复制到 ip_src 和 ip_dest?

例如,如果我向 23.45.167.92 发送数据包,并且我有以下 unsigned char[4]:

destination_ip[0] = 23;
destination_ip[1] = 45;
destination_ip[2] = 167;
destination_ip[3] = 92;

然后我可以安全地这样做吗:

struct ip my_packet_header;
my_packet_header.ip_dest = *((ip_addr*)destination_ip);

“安全”是指它可以在大端和小端机器上运行。

【问题讨论】:

  • 什么是ip_addr
  • memcpy() 会更合适,恕我直言(避免演员阵容和对齐问题)
  • 它将是destination_ip的地址,而不是其中的字节。

标签: c networking ip


【解决方案1】:

来自man ip

struct in_addr 的成员 s_addr 包含网络字节顺序的主机接口地址。

所以你可以复制字节,但最好使用 memcpy 而不是强制转换。

memcpy(&my_packet_header.ip_dest.s_addr, destination_ip);

【讨论】:

    【解决方案2】:

    除了字节序,至少存在一个问题:对齐。

    struct ip my_packet_header 的对齐要求可能比unsigned char destination_ip[] 更严格

    指向对象类型的指针可以转换为指向不同对象类型的指针。如果结果指针未正确对齐引用类型,则 行为为 未定义。 C11 §6.3.2.3 7


    memcpy() 处理该问题并消除问题@wildplasser

    assert(sizeof my_packet_header >= sizeof destination_ip);
    memcpy(&my_packet_header, destination_ip, sizeof destination_ip);
    

    可以期望优化编译器分析此memcpy() 调用并发出高效代码 - 可能无需真正的函数调用。

    【讨论】:

      猜你喜欢
      • 2011-12-11
      • 2015-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2014-05-18
      • 1970-01-01
      相关资源
      最近更新 更多