【问题标题】:C libpcap API casting packet to struct(confusing)C libpcap API 将数据包转换为结构(令人困惑)
【发布时间】:2018-07-17 12:06:04
【问题描述】:

阅读本教程后

(https://www.tcpdump.org/pcap.html)

在最底部,作者将u_char *packet 指针转换为结构。

这样的铸造工作是这样的吗

假设我有这个结构

struct 16bits{ 
 int8_t a;
 int8_t b;
 }

和一个 16 位序列

0001 0011 0111 1111

如果我将它转换为 16bits 结构,它看起来像这样?

a = 0001 0011
b = 0111 1111

问题是我是否正确理解作者的投射。

我知道结构中的填充,但让我们认为编译器暂时不会添加它

【问题讨论】:

  • 是的-尽管您提到了填充,并且可能存在字节序问题。演员“假装”这个第一个字节是结构的开始。
  • 对链接代码的快速扫描发现在我看来有很多未定义的行为和严格的别名违规。

标签: c casting


【解决方案1】:

假设我有这个结构

struct 16bits{ 
 int8_t a;
 int8_t b;
 }

和一个 16 位序列

0001 0011 0111 1111

如果我将它转换为 16 位结构,它会是这个样子吗?

a = 0001 0011
b = 0111 1111

我假设你的意思是这样的:

// this points at your 16-bit sequence
unsigned char *input_data = ...

struct 16bits *output_data = ( struct 16bits * ) input_data;

uint8_t a_bits = output_data->a;
uint8_t b_bits = output_data->b;

一般来说,不,你不能假设你能做到这一点。一般来说,这将是a strict aliasing violation 和未定义的行为。 “严格别名”规则基本上说您不能将内存视为它不是的东西 - 但除了您始终可以一次访问任何一个 char 之外。 int 不是 float

此外,正如您提到的,结构中的字段之间可以有填充。

不过,在您的具体示例中,几乎可以肯定,它几乎可以在任何平台上“工作”,因为int8_t 几乎可以肯定是signed charstruct 16bits 中几乎肯定没有填充,并且任何内存始终可以作为char 值访问。

不过,将char 类型替换为doubleint64_t 等类型,您可能会遇到对齐和填充问题。在某些平台上,这种严格的别名违规可能会导致代码以SIGSEGVSIGBUS 失败。

假设 8 位 char 值,所以 int8_t 实际上是 char,作为两个 8 位值访问应用于 16 位序列的任何数据类型的完全符合标准的方法将是

// assume this points to your 16-bit sequence
unsigned char *input_data = ...

// create a structure that we can actually copy the bits into
struct 16bits output_data;

memcpy( &output_data, input_data, sizeof( output_data ) );

请注意,如果结构包含char 以外的类型的元素,则可能存在填充。如果你使用#pragma pack 之类的东西来消除填充,you can wind up with code that doesn't run on some platforms.

诸如您提供的链接中的代码很猖獗-实际上是未定义的行为。但它“有效”是因为编写最流行的已发布代码的 x86 平台非常、非常、非常容忍未对齐的访问(尽管仍然存在性能损失)。但是这种类型的代码在任何有对齐要求的平台上都不能很好地工作。只需Google pragma pack sigbus,您就会发现很多程序员的例子,例如,当在 x86 上运行良好的代码在 ARM 或 SPARC 平台上失败时,程序员会感到惊讶。

【讨论】:

    猜你喜欢
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多