skb_header_pointer()总是以big-endian返回?

时间:2018-06-08 14:47:07

标签: networking linux-kernel endianness

Linux内核定义了这个API:

static inline void * __must_check
__skb_header_pointer(const struct sk_buff *skb, int offset,
             int len, void *data, int hlen, void *buffer)
{
    if (hlen - offset >= len)
        return data + offset;

    if (!skb ||
        skb_copy_bits(skb, offset, buffer, len) < 0)
        return NULL;

    return buffer;
}

static inline void * __must_check
skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer)
{
    return __skb_header_pointer(skb, offset, len, skb->data,
                    skb_headlen(skb), buffer);
}

在内核的某些部分,此API用于检索big-endian中的数据包字段,因为它是一个网络skb。所以我理解这个API何时应用于数据包标头,我们知道这些数据包在big-endian中有一些字段,例如struct iphdr其中16/32位字段显式声明为__be16/__be32

所以根据https://en.wikipedia.org/wiki/Endianness

  Internet协议套件协议中的

字段,如IPv4,IPv6,TCP和UDP,以big-endian顺序传输。

但是,始终保证{em> 存储在skb中的数据包的16位或32位部分将按网络字节顺序排列吗?

换句话说,接下来的电话:

u32 *ptr, data;
ptr = skb_header_pointer(skb, offset, 4, &data);

可以更改为:

__be32 *ptr, data;
ptr = skb_header_pointer(skb, offset, 4, &data);

这是正确的假设吗?

更新我认为不是。只有协议(IP / TCP / UDP / ICMP / etc。)标头需要采用big-endian字节顺序,有效负载字节顺序由发送机器确定。

0 个答案:

没有答案