数据对齐网络编程

数据对齐网络编程

本文介绍了数据对齐网络编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点糊涂了关于数据对齐。在x86上,我们通常采取调整是理所当然的。不过,我编写系统,这是非常严格的,并将错误,如果我试图访问未对齐的数据。

I'm a little confused regarding data alignment. On x86, we typically take alignment for granted. However, I'm programming on a system that is very strict and will error out if I try to access unaligned data.

这是我的问题:

首先,我要告诉你一些结构,我有:

First, I'm going to show you some structs I have:

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将返回一个指向一个数据包对我说:

I'm dealing with pcap. Pcap will return a pointer to a data packet to me:

u_char *packet;

允许pretend分组是几百字节。我通常做的是施放该数据包到多个结构的指针,这样我就可以直接访问数据。

Lets pretend the packet is a couple hundred bytes. What I typically do is cast that packet to several struct pointers, so I can access the data directly.

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上,一切似乎工作的权利。在具有严格对齐的任何其他archetecture,我在访问一些值时的问题,它通常会导致一个SIGBUS。例如:

Ok. So everything looks great right? On x86, everything appears to work right. On any other archetecture that has strict alignment, I have issues when accessing some values and it will typically result in a sigbus. For example:

sip->ip_len = 0x32AA;

u_short val = sip->ip_len;

将导致错误。我猜它,因为它是从投错位在内存中。请告诉我通常处理这种做这些类型的强制转换的时候,最好的方法是什么?

results in an error. I'm guessing its because it's misaligned in memory from the cast. Whats typically the best way to handle this when doing these kind of casts?

推荐答案

最简单的方法是使用的memcpy

struct sniff_ip sip;
memcpy(&sip, packet + 14, sizeof(sip));

这假定您的两台机器使用相同的字节顺序,并谨慎地考虑结构的填充。

This assumes that your two machines use the same byte order, and have been careful to take account of structure padding.

的更硬,更普遍的方式来处理,这是从单个字节构造值:

The harder and more general way to handle this is to construct the values from the individual bytes:

u_short val;
int offset = 14 + offsetof(sniff_ip, ip_len);
val = packet[offset] + (packet[offset+1] << 8); // assuming little endian packet

当然,你可能会使用一个函数或宏摘要。

Of course, you'd probably use a function or macro to abstract this.

这篇关于数据对齐网络编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 00:19