当我查看linux的源代码时,我偶然发现了下面关于IPv6头格式的定义,并且把“优先级”和“版本”字段的顺序搞混了。我认为这两个字段都是4位(半字节),它们与字节顺序无关。我不明白为什么linux内核要定义这样的ipv6头。
关于这个结构还有另一个问题。根据https://en.wikipedia.org/wiki/IPv6_packet,流量等级是8比特,流标签字段是20比特,但这种结构将它们分别定义为4比特和24比特。
struct ipv6hdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 priority:4,
version:4;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8 version:4,
priority:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 flow_lbl[3];
__be16 payload_len;
__u8 nexthdr;
__u8 hop_limit;
struct in6_addr saddr;
struct in6_addr daddr;
};发布于 2021-10-08 06:51:15
当我查看linux的源代码时,我偶然发现了下面关于IPv6头格式的定义,并且把“优先级”和“版本”字段的顺序搞混了。我认为这两个字段都是4位(半字节),它们与字节顺序无关。我不明白为什么linux内核要定义这样的ipv6头。
正如你所说,这些字段与字节顺序无关,但实际上你的平台(你的体系结构)如何将它们保存在内存中。没有人考虑线路上的/IP的字节顺序,这是定义良好的,统一的,明确的,但你的计算机的字节顺序和#if的控制是为了在两种机器上编译相同的源代码而不改变。为了使源代码在{big/low}endian体系结构中可编译,必须采取一些措施,使字段在数据包中完全相同的位置结束,独立于您在sun稀疏工作站或英特尔笔记本电脑中对它们进行编码。
通常进行编码的方式是逐个字节地制作一个确切的字节图像,说明数据包将如何在网络上序列化。这意味着如果你是一台低端的机器,32位整数的字节必须被交换,以便总是最重要的bye优先出现在网络中。有一些可移植的方法可以做到这一点,但它们通常需要在cpu中完成更多的工作,而不仅仅是两个字节地交换字节。
我不能说一个字中位字段的分配顺序是否取决于位字段本身的顺序,这在{big/low}endian机器上是不同的,但是正如你所说的,如果它是在linux内核中这样做的,那么答案将是它可能是这样的。(主要原因是很久以前工作正常,这样的问题会从一开始就中断tcp/ip通信)
https://stackoverflow.com/questions/69474402
复制相似问题