В ядре есть такая замечательная функция:
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);
}
То есть skb_header_pointer() позволяет получить указатель на буфер длиной len на любую часть сетевого пакета в skb.
Вопрос — всегда ли гарантируется, что любые 16- или 32-битные фрагенты пакета будут в big-endian формате?
Например, можно ли делать так:
__be32 *ptr, data;
ptr = skb_header_pointer(skb, offset, sizeof(u32), &data);