網絡字節序與字節內比特序

一、網絡字節序

(上圖來自網絡,侵刪)

本次討論以IP首部ip.h爲例。
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 */
};

已知網絡採用大端字節序。和實驗室的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之後。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章