【发布时间】:2010-10-03 03:04:41
【问题描述】:
我对数据对齐有点困惑。在 x86 上,我们通常认为对齐是理所当然的。但是,我在一个非常严格的系统上编程,如果我尝试访问未对齐的数据会出错。
这是我的问题:
首先,我将向您展示我拥有的一些结构:
struct sniff_ethernet {
u_char ether_dhost[6]; /* Destination host address */
u_char ether_shost[6]; /* Source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
};
struct sniff_ip {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
我正在处理 pcap。 pcap会返回一个指向数据包的指针给我:
u_char *packet;
让我们假设数据包是几百字节。我通常会将该数据包转换为几个结构指针,这样我就可以直接访问数据。
struct sniff_ethernet *seth = (struct sniff_ethernet *) packet;
struct sniff_ip *sip = (struct sniff_ip *) (packet + 14); // 14 is the size of an ethernet header
好的。所以一切看起来都很棒,对吧?在 x86 上,一切似乎都正常。在具有严格对齐的任何其他架构上,我在访问某些值时遇到问题,通常会导致 sigbus。例如:
sip->ip_len = 0x32AA;
或
u_short val = sip->ip_len;
导致错误。我猜是因为它在演员的记忆中没有对齐。在进行此类强制转换时,通常最好的处理方法是什么?
【问题讨论】:
-
在 gcc 中,你有 __attribute__((packed)) 告诉编译器紧密对齐结构,没有任何填充。
-
__attribute__((packed))在这种情况下没有任何区别,因为这些结构没有填充。
标签: c networking alignment