# 802.11 - Frame Format [TOC] ## 課程影片 ### 第 3F 講 IEEE 802.11 無線區域網路 (Wireless LAN) L03 {%youtube 8xvPiPVcW90 %} ## Frame Format 完整的格式如下: ![](https://i.imgur.com/fuqNLfk.jpg) 而 Linux 核心相關的巨集定義在 [`include/linux/ieee80211.h`](https://elixir.bootlin.com/linux/latest/source/include/linux/ieee80211.h) 中,實際上就是經由適當對齊之後的一個結構體: ```c struct ieee80211_hdr { __le16 frame_control; __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; __le16 seq_ctrl; u8 addr4[ETH_ALEN]; } __packed __aligned(2); ``` ### Addr1 ~ Addr4 (6 X 4 位元組) 第一眼看過去,最明顯的地方是他居然包含了 4 個 *address*。這是因為 802.11 使用的是分散式系統,假定 $A_1$ 與 $E_1$ 基地台連接,而 $A_2$ 與 $E_2$ 基地台連接,則若 $A_1$ 需要與 $A_2$ 通訊,需要先傳送給 $E_1$ 基地台,由 $E_1$ 基地台傳給另外一個 $E_2$ 基地台,再由該 $E_2$ 基地台傳送給其底下的 $A_2$。因此,最多需要 $A_1, E_2, A_2, E_2$ 四者的位址。也就是: $$ A_1 \to E_1 \leadsto E_2 \to A_2 $$ ### Frame Control 相關的常數同樣是定義在 [`include/linux/ieee80211.h`](https://elixir.bootlin.com/linux/latest/source/include/linux/ieee80211.h#L32) 中: ```c #define IEEE80211_FCTL_VERS 0x0003 #define IEEE80211_FCTL_FTYPE 0x000c #define IEEE80211_FCTL_STYPE 0x00f0 #define IEEE80211_FCTL_TODS 0x0100 #define IEEE80211_FCTL_FROMDS 0x0200 #define IEEE80211_FCTL_MOREFRAGS 0x0400 #define IEEE80211_FCTL_RETRY 0x0800 #define IEEE80211_FCTL_PM 0x1000 #define IEEE80211_FCTL_MOREDATA 0x2000 #define IEEE80211_FCTL_PROTECTED 0x4000 #define IEEE80211_FCTL_ORDER 0x8000 #define IEEE80211_FCTL_CTL_EXT 0x0f00 ``` 當中一個重要的位元是 `From DS/To DS`,除了課程影片內容之外, [`include/linux/ieee80211.h`](https://elixir.bootlin.com/linux/latest/source/include/linux/ieee80211.h#L32) 的註解中也有提到他的功能: ```c /* * DS bit usage * * TA = transmitter address * RA = receiver address * DA = destination address * SA = source address * * ToDS FromDS A1(RA) A2(TA) A3 A4 Use * ----------------------------------------------------------------- * 0 0 DA SA BSSID - IBSS/DLS * 0 1 DA BSSID SA - AP -> STA * 1 0 BSSID SA DA - AP <- STA * 1 1 RA TA DA SA unspecified (WDS) */ ``` 這兩個位元決定傳輸的起點與終點是否為基地台。 ### Data (0 ~ 2312 位元組) ## Inter-Frame Space 封包並不是連續地收發,而是傳輸完一個封包之後,必須間隔一段時間,才可以進行下一次的收發。 不同種類的封包的收發之間有規定的間隔,這個時間間隔稱為 *IFS* (*inter-frame space*) 的常數時間之後,才可以繼續下一個動作。所以一種可能的傳輸是像下面這樣: ![](https://i.imgur.com/4zjjfc1.png) 在這個傳輸當中,目的地(Dst)收到 *RTS* 之後,不會立刻傳 *CTS*,而是要等待長度為 *SIFS* 的時間,才可以回傳 *CTS*; 而收到 *CTS* 的一方,也不能立即傳輸,要等另外一段長度為 *SIFS* 的時間之後,才能傳輸封包。 而這樣的時間間隔不只有一種。實際上,這樣的長度間隔共有三種值,由短到長分別是 *SIFS*, *PIFS*, *DIFS*。 > 這個在 DCF 才會提到,但覺得可以放在這邊。