假设现在我需要在Beacon帧中添加一个字段,应该如何添加呢?我们首先来看一看Beacon帧的帧结构(我们需要在Frame Body的保留字段进行字段的添加):
Beacon帧是管理帧的一种,管理帧使用信息元素(informationelement,带有数字标签的数据块)来与其他系统交换信息。信息元素是管理帧的可变长组件。信息元素通常包含一个ElementID(元素标识符)字段、一个Length(长度)字段以及一个长度不定的字段,如图所示:
查阅802.11规定的信息元素表可以发现,编号为7-15(OpenWRT程序中是8-15)的信息元素是未使用的保留元素,因此可以在Beacon帧中加入该编号范围内的自定义信息元素。要修改Beacon帧,就是要在其中加入自定义的信息元素。
基于上述思想及前面对Beacon帧产生、发送和接收、提取信息过程的梳理,我们做一个修改Beacon帧的示例,假设我们需要添加一个元素标识符为8、长度为1、具体内容为0x63的字段,方法很简单,只需在tx.c文件的__ieee80211_beacon_add_tim()函数尾部加入如下代码即可:
skb_put(skb, 3); *pos++ = 8; /*元素标识符*/ *pos++ = 1; /*长度*/ *pos++ = 99; /*99也可以写作0x63*/ |
那么,写入的信息如何提取呢,我们在接收端rx.c文件的__ieee80211_rx_handle_packet()函数中对Beacon帧单独处理的部分加入如下代码,并使用printk函数将其通过串口打印出来即可:
u8* dest_addr,*src_addr; dest_addr = ((struct ieee80211_hdr *)skb->data)->addr1; src_addr = ((struct ieee80211_hdr *)skb->data)->addr2; if (src_addr[0] == 0xe0) /*由于周围有许多AP发来Beacon帧,因此加入MAC地址过滤,只对目标AP发过来的Beacon帧作新增信息的提取*/ { u8 *elements; size_t baselen; struct ieee80211_mgmt *mgmt = (void *)skb->data; baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); elements = mgmt->u.beacon.variable; size_t left = skb->len - baselen; const u8 *pos = elements; while (left >= 2) { u8 id, elen; bool elem_parse_failed; id = *pos++; elen = *pos++; left -= 2; switch (id) { case 8: printk(KERN_INFO "entered the target segment 8 !!!!!!!\n"); printk(KERN_INFO "%02x\n",*pos); break; default: break; } left -= elen; pos += elen; } } |
通过试验测试,在接收端成功的提取出了发送端写入的信息,Beacon帧修改成功。