struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN
u_char ip_hl:4, /* header length */
ip_v:4; /* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN
u_char ip_v:4, /* version */
ip_hl:4; /* header length */
#endif
u_char ip_tos; /* type of service */
short ip_len; /* total length */
u_short ip_id; /* identification */
short ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
網絡字節序與字節內比特序
一、網絡字節序
(上圖來自網絡,侵刪)
本次討論以IP首部ip.h爲例。
已知網絡採用大端字節序。和實驗室的JackYang討論,我們得出結論,上圖各個字段是從低地址向高地址排布的。比如源地址字段比目的地址字段的地址低,這樣和struct ip中各個字段順序是匹配的。所謂字節序是針對某個字段的各個字節來說的。考慮下圖的Flag與Fragment offset字段,它們合起來是ip.h中的16位ip_id字段:
JackYang認爲wireshark看到的大端順序。如果是小端機,真實順序是Fragment offset字段13個bit0在低地址,Flag010(0x2)在高地址。
另一個證據是內核網絡源碼,如下:
注意到佔2個字節的IP校驗和(iph->check)在重新計算時需要先ntohs再htons。這樣在x86小端機可以正確運行。
二、字節內比特序
看到ip.h源碼中ip_hl和ip_v的位置關係(header
length與version的位置關係),一個困擾我很久的歷史遺留問題浮現腦海:字節內的比特順序應該也和大小端有關!
答案的確如此。x86爲小端序,它採用LSB 0 bit numbering,故ip_v在ip_hl之後。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.