上一章说到了Linux内核网络子系统中beacon帧是如何产生与发送的。下面我们来看一看beacon帧是如何接收并提取信息的。
void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
Linux内核是通过中断来对接收到的数据进行响应的。当硬件检测到有接收数据的时候,产生一个中断,中断触发下半部的tasklet机制,在802.11协议栈这里会调用ieee80211_tasklet_handler()函数。我们来看一看函数体:
static void ieee80211_tasklet_handler(unsigned long data)
{
struct ieee80211_local *local = (struct ieee80211_local *) data;
struct sk_buff *skb;
while ((skb = skb_dequeue(&local->skb_queue)) ||
(skb = skb_dequeue(&local->skb_queue_unreliable))) {
switch (skb->pkt_type) {
case IEEE80211_RX_MSG:
/* Clear skb->pkt_type in order to not confuse kernel
* netstack. */
skb->pkt_type = 0;
ieee80211_rx(&local->hw, skb);
break;
case IEEE80211_TX_STATUS_MSG:
...
default:
...
}
}
}
系统收到数据时会开辟一个sk_buff缓存空间进行数据的存储,ieee80211_tasklet_handler()触发后对sk_buff中存储的数据帧进行判断,如果是接收来的数据(MPDU),则进入ieee80211_rx()函数:
void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_rate *rate = NULL;
struct ieee80211_supported_band *sband;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
...
__ieee80211_rx_handle_packet(hw, skb);
rcu_read_unlock();
return;
drop:
kfree_skb(skb);
}
EXPORT_SYMBOL(ieee8021

Linux内核通过中断响应接收数据,中断触发tasklet机制,调用ieee80211_tasklet_handler()。beacon帧通过ieee80211_rx()和__ieee80211_rx_handle_packet()处理,进入ieee80211_scan_rx()进行帧信息扫描。beacon帧信息存储在sk_buff的data中,通过ieee80211_mgmt结构体提取MAC头、固有字段和可选字段。信息读取有两种方法:结构体直接取数据和指针偏移法,后者用于处理可选字段的灵活性需求。
最低0.47元/天 解锁文章
1973

被折叠的 条评论
为什么被折叠?



