c - 将数据包转换到结构的 Endian 问题

标签 c networking packet endianness

我正在使用 libtrace 来解析网络数据包,但我认为这是一个字节序问题。

这是 Radiotap 数据包的 libtrace 定义:

typedef struct libtrace_radiotap_t {
    uint8_t     it_version; /**< Radiotap version */
    uint8_t     it_pad; /**< Padding for natural alignment */
    uint16_t    it_len; /**< Length in bytes of the entire Radiotap header */
    uint32_t    it_present; /**< Which Radiotap fields are present */
} PACKED libtrace_radiotap_t;

所以我将我的 libtrace_packet_t 转换到这个 Radiotap 结构并检查结果:

link = (char *) trace_get_packet_buffer(packet, &linktype, NULL);

if (linktype != TRACE_TYPE_80211_RADIO)
    return;

rtap = (libtrace_radiotap_t *) link;

printf("%d %d %d %d\n", rtap->it_present, rtap->it_pad, rtap->it_len,
       rtap->it_present);

在我的小端开发机器上,我的 pcap 文件中数据包中的 Radiotap 数据是:

806959 0 72 806959

这是正确的。我的开发机器成功解析了我希望从 pcap 文件中看到的数据。

在我的大端生产机器上运行时,我看到了不同的值:

793775104 0 18432 793775104

同一 pcap 文件中的同一数据包。不同的 Radiotap 值。我怀疑问题出在两台机器的不同字节序上。但是,rtap.it_version 是一个 uint8_t,它是单字节,不应受到端序问题的影响,不是吗?

最佳答案

那应该是字节顺序问题。 对于 72,十六进制是 0x48,它是一个 uint16_t,所以在不同的字节序中是 0x4800 = 18432。没错。 对于 806959 = 0xC502F,在不同的字节序中是 0x2F50C000 = 793775104。

这可能有帮助:

#define T(x) (((x&0xff)<<24)|((x&0xff00)<<8)|((x&0xff0000)>>8)|((x&0xff000000)>>24))

关于c - 将数据包转换到结构的 Endian 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18501516/

相关文章:

c - Varnish 4 + Pounds - 绕过特定 IP 地址的缓存

linux - 如果 dhcp 失败,设置保存的静态 IP 地址

c# - 在 C# 中获取 Windows VPN 接口(interface)

firewall - 从 netfilter 接受用户空间中的数据包

java - 如何访问 JpCap 数据包中的数据包信息

c - qsort() 问题 - 排序不正确 (C)

c++ - LLVM 无法识别 unnamed_addr

c - 在函数中返回字符串

http - http协议(protocol)在linux中的实现在哪里

tcp - 我应该如何标记 TCP 数据包的结尾?