網絡傳輸中的位域
緣起

解包的時候發現數據包里面多了一層mpls,有時會有兩層,一層是4字節,如果是多層,每一層里面會有一位,指示當前這層是不是mpls棧的最底層,那就好辦了,與(&)一下獲得這個位的信息就好了嘛,然后腦袋就短路了,出現了疑問三連
- 我該咋與(&)呢?
- 這個位是在這個字節的哪個位置呢?
- 看著不是在頭就是在尾,
& 0x80還是& 0x01呢?
上面這些問題還真是讓我懵逼了一下下,讓我意識到,可能需要去了解一下網絡數據傳輸中的位域問題。這個問題其實之前就遇到過,想必也已經去了解過,這次遇到居然又卡住了,真是不應該啊,這次就記錄一下吧
研習
在之前對大小端的學習中的兩個東西估計你早忘了,那就是MSB(most significant bit,最高有效位)和LSB(least significant bit,最低有效位),一個字節,從bit0到bit7,對于大端來說,bit0是MSB,bit7是LSB,對于小端來說,bit7是MSB,bit0是LSB
ip首部的第一個字節包含了ip版本信息和ip首部長度信息,所以這里也涉及到了位域,那么就以此為例
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
這是ip首部的一部分,根據RFC791 Page 38的描述,每個字節的最左邊,即,標記為0的,是最高有效位,傳輸時,也是先傳輸最高有效位,就以最常見的情況,ip版本為4,ip首部長度為20字節,那么對應到首部結構,就應該是這個樣子
| MSB | LSB | ||||||
|---|---|---|---|---|---|---|---|
| bit0 | bit1 | bit2 | bit3 | bit4 | bit5 | bit6 | bit7 |
| 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
既然先傳輸的是MSB,那計算機先接收的肯定也是MSB嘛,肯定也要存儲在本地的MSB上,所以,小端的計算機接收下來存儲后就是這樣的格式
| MSB | LSB | ||||||
|---|---|---|---|---|---|---|---|
| bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
| 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
用十六進制表示那就是0x45,所以說ip版本其實是在高4位,而ip首部長度則是在低4位,這也對應了頭文件中ip的結構體里面,如果是小端,則長度信息在前,版本信息在后
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ip_hl:4; /* header length */
unsigned int ip_v:4; /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int ip_v:4; /* version */
unsigned int ip_hl:4; /* header length */
#endif
結論
定位到那個字節之后,& 0x01

浙公網安備 33010602011771號