Ядро 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 используется для извлечения полей пакета в формате с прямым порядком байтов, поскольку это сеть skb
.Поэтому я понимаю, когда этот API применяется к заголовкам пакетов, которые, как мы знаем, имеют некоторые поля с прямым порядком байтов, например struct iphdr
, где 16/32-битные поля явно объявлены как __be16/__be32
.
поля https://en.wikipedia.org/wiki/Endianness
в протоколах набора протоколов Интернета, таких как IPv4, IPv6, TCP и UDP, передаются в порядке с прямым порядком байтов.
Однако всегда ли гарантируется, что любая 16- или 32-битная часть пакета, хранящегося в skb
, будет иметь сетевой порядок байтов?
Так что в другомслова, следующий вызов:
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 / и т. Д.) Должны быть в байтовом порядке с прямым порядком байтов, порядок байтов полезной нагрузки определяется отправляющим компьютером.