本帖最后由 karma303 于 2016-07-06 17:19 编辑
本来想更新到这篇旧帖子里的,但觉得这部分有点儿“地理大发现”的感觉,就专门贴出来,跟各位交流。
我说的“地理大发现”,是说wiki上的ip header的布局图,它们用0,1,2,3,4,5,6,7细分出每个字节的bit,但wiki上的0,1,2,3,4,5,6,7,分别对应常规思维的7,6,5,4,3,2,1,0。
到这里我才发现,原来wiki上给出的布局图,是彻彻底底的按照“大端思维“来走的。
其实wiki就从RFC里摘的图,1981年的文档,那时的程序员为什么会反着看bit?(是没经过x86的洗礼吗?)
题外话:
在上一篇帖子里,我贴了一点关于bitfield跨字节的测试。
其实今天意识到这个问题,也是从ip header里的offset成员开始的,我发现没办法用bitfield来表示这个成员。
如果编译目标是小端机器,gcc是没有办法用bitfield来表示offset这个成员的。
所以linux内核里,很粗暴的定义成:
__be16 frag_off;
__be16就是unsigned short。
然后在代码里再分解它:
offset = ntohs(ip_hdr(skb)->frag_off);
flags = offset & ~IP_OFFSET;
offset &= IP_OFFSET;
offset <<= 3; /* offset is in 8-byte chunks */ |