1. 程式人生 > >【小菜學網路】MAC地址詳解

【小菜學網路】MAC地址詳解

上一小節介紹了乙太網幀的結構,以及幀中各個欄位的作用。參與乙太網通訊的實體,由乙太網地址唯一標識。乙太網地址也叫做 _MAC_ 地址,我們對它仍知之甚少。 > 乙太網地址在不同場景,稱謂也不一樣,常用叫法包括這些: > > - 乙太網地址 > - _MAC_ 地址 > - 硬體地址 > - 實體地址 > - 網絡卡地址 ## 網絡卡 在乙太網中,每臺主機都需要安裝一個物理裝置並通過網線連線到一起: ![1](https://cdn.fasionchan.com/p/18394ac97c9ef2e90596d62f6bc2f07b28796694.png#width=340px) 這個裝置就是 **網絡卡** ( _NIC_ ),**網路介面卡** ( _network interface card_ )的簡稱。有些文獻也將網絡卡稱為 **網路介面控制器** ( _network interface controller_ )。 從物理的層面看,網絡卡負責將位元流轉換成電訊號傳送出去; 反過來,也負責將檢測到的電訊號轉換成位元流並接收。 從軟體的層面看,傳送資料時,核心協議棧負責封裝乙太網幀(填充 **目的地址** , **源地址** , **型別** 和 **資料** 並計算 **校驗和**),並呼叫網絡卡驅動傳送; 接收資料時,負責驗證 **目的地址** 、 **校驗和** 並取出資料部分,交由上層協議棧處理。 ![2](https://cdn.fasionchan.com/p/d58604f365fbacb3a220d2379c0474605e64a3af.jpg#width=340px) 每塊網絡卡出廠時,都預先分配了一個全球唯一的 **MAC地址** ,並燒進硬體。 不管後來網絡卡身處何處,接入哪個網路,_MAC_ 地址均不變。 當然,某些作業系統也允許修改網絡卡的 _MAC_ 地址。 ## MAC地址 _MAC_ 地址由 _6_ 個位元組組成( _48_ 位),可以唯一標識 $2^{48}$ ,即 _281474976710656_ 個網路裝置(比如網絡卡)。 _MAC_ 地址 _6_ 個位元組可以劃分成兩部分,如下圖: ![3](https://cdn.fasionchan.com/p/18f17216ce3ec65b7b61c3a070c5d1d7e49dba4a.jpg#width=400px) - _3_ 位元組長的 **廠商程式碼** ( _OUI_ ),由國際組織分配給不同的網路裝置商; - _3_ 位元組長的 **序列號** ( _SN_ ),由廠商分配給它生產的網路裝置; 廠商程式碼和序列號都是唯一分配,因此 _MAC_ 地址是 **全球唯一** 的。 ## 冒分十六進位制表示法 _MAC_ 地址 _6_ 個位元組如何展示呢? 是否能夠作為 _ASCII_ 來解讀並顯示? 恐怕不能。一個位元組總共有 _8_ 個位,而 _ASCII_ 只定義了其中的 _7_ 位。況且 _ASCII_ 中定義了很多控制字元,能顯示的也只有字母、數字以及一些常用符號。以上述地址為例,只有 `0x5B` 這個位元組是可以顯示的,對應著字元 `[` 。 ![4](https://cdn.fasionchan.com/p/7d20b966b4622355560fd0d2ba54227a717c1662.png#width=619px) 好在,我們可以用多個可讀字元來表示一個原始位元組。我們將一個位元組分成兩部分,高 `4` 位以及低 `4` 位,每部分可以用一個十六進位制字元來表示。以 `0x00` 這個位元組為例,可以用兩個字元 `00` 表示: ![5](https://cdn.fasionchan.com/p/7a59527148a3b97626c41569cab75bf2fb41f2b2.png#width=366px) 這樣一來,整個地址可以用一個 _12_ 位元組長的字串表示: `0010A4BA875B` 。 為了進一步提高可讀性,可以在中間插入冒號 `:` : `00:10:A4:BA:87:5B` 。 ![6](https://cdn.fasionchan.com/p/67043e74cdcd09aaa861efe5393f1779a334b8ed.png) 這就是 **冒分十六進位制表示法** ( _colon hexadecimal notation_ )。 注意到,冒分十六進位制總共需要 `17` 個位元組。 如果算上字串結尾處的 `\0` ,將達到 _18_ 個位元組,原始 _MAC_ 地址的整整 _3_ 倍!順便提一下,十六進位制字母字元用大小寫都可以。 ## 網絡卡管理 _Linux_ 上有不少工具命令可以檢視系統當前接入的網絡卡以及每張網絡卡的詳細資訊。 首先是 _ifconfig_ 命令,他預設顯示已啟用的網絡卡,詳情中可以看到每張網絡卡的實體地址: ```txt fasion@u2004 [ ~ ] ➜ ifconfig enp0s3: fl