openwrt上wifi探針的實現
看到探針,感覺很高大上的樣子,其實就是通過wifi搜集經過這個AP范圍的手機的mac地址,沒有什么深刻的東西,知乎上關于這個東西討論的很多,有人覺得很有用,可以做很多增值的應用,有人覺得沒啥用,不過這并不妨礙我們從技術上去實現它。
802.11協議
協議里面要求每個AP每隔一定時間(幾十毫秒到幾秒不等)向周圍的sta和AP廣播beacon幀,就是告訴周圍的sta和其他的AP:我是xxxx(bssid),快來連我!我是xxxx(bssid),快來連我!瞬間感覺每個AP都有一顆放蕩的心,有木有!有木有!
每 個sta(可以理解為手機、筆記本)除了默默監聽周邊AP發送的beacon幀以外,還會偷偷發送probe幀:我是xxxx(mac地址),我能連你 嗎?我是xxxx(mac地址)我能連你嗎?十足一個悶騷的小婊砸,所以我每次出門都默默關掉手機的wifi,現在的無線環境實在是太不安全了,參看連接
在7620a上的實現
基本思路是在AP受到探測幀后,將mac地址記錄下來,通過proc文件系統上報給應用層。下面是代碼:
mac地址獲取部分:
在函數VOID APPeerProbeReqAction(IN PRTMP_ADAPTER pAd,IN MLME_QUEUE_ELEM *Elem);中添加
extern UCHAR GLOBAL_AddrLocalNum;
extern UCHAR GLOBAL_AddrLocal[ADDR_LOCAL_NUMBER][MAC_ADDR_LEN];
PFRAME_802_11 pFramelxd = (PFRAME_802_11)Elem->Msg;
if(GLOBAL_AddrLocalNum >ADDR_LOCAL_NUMBER || GLOBAL_AddrLocalNum == ADDR_LOCAL_NUMBER)
{
//GLOBAL_AddrLocalNum = 0;
}
else
{
int index = 0;
BOOLEAN flag = 1;
for(index=0; index<GLOBAL_AddrLocalNum; index++)
{
if(NdisCmpMemory(GLOBAL_AddrLocal[index],pFramelxd->Hdr.Addr2,MAC_ADDR_LEN)==0)
{
flag = 0;
break;
}
}
//COPY_MAC_ADDR(GLOBAL_AddrLocal[GLOBAL_AddrLocalNum], pFramelxd->Hdr.Addr1);
//GLOBAL_AddrLocalNum++;
//COPY_MAC_ADDR(GLOBAL_AddrLocal[GLOBAL_AddrLocalNum], pFramelxd->Hdr.Addr2);
//GLOBAL_AddrLocalNum++;
if(flag)
{
COPY_MAC_ADDR(GLOBAL_AddrLocal[GLOBAL_AddrLocalNum], pFramelxd->Hdr.Addr2);
GLOBAL_AddrLocalNum++;
}
}
proc部分:
應用層向proc的節點中寫入“s”,告知驅動需要獲取sta相關的數據,驅動給出采集到的maclist。
static struct proc_dir_entry *entry_wl_beacon_mac;
UCHAR GLOBAL_AddrLocalNum = 0;
UCHAR GLOBAL_AddrLocal[MAX_MCAST_LIST_SIZE][6];
static char *maclistbuffer;
static int maclist_proc_show(struct seq_file *m, void *v)
{
if(maclistbuffer[0] == 's')
{
maclistbuffer[0] = '0';
int index=0;
for(index=0;index<GLOBAL_AddrLocalNum;index++)
{
seq_printf(m,"%02x:%02x:%02x:%02x:%02x:%02x\n", GLOBAL_AddrLocal[index][0],GLOBAL_AddrLocal[index][1],GLOBAL_AddrLocal[index][2],GLOBAL_AddrLocal[index][3],GLOBAL_AddrLocal[index][4],GLOBAL_AddrLocal[index][5]);
}
GLOBAL_AddrLocalNum = 0;
}
else
{
//seq_printf(m,"sta number is %d, proc!\n", GLOBAL_AddrLocalNum);
//seq_printf(m,"ap number is %d, proc!\n", GLOBAL_AddrLocalNum1);
}
return 0;
}
static int maclist_proc_open(struct inode *inode, struct file *file)
{
return single_open(file,maclist_proc_show,inode->i_private);
}
static ssize_t maclist_proc_write(struct file *file, const char *buffer, size_t len, loff_t *off)
{
int user_len = 0;
if (len > MAX_MACLIST_LENGTH)
{
user_len = MAX_MACLIST_LENGTH;
}
else
{
user_len = len;
}
if(copy_from_user(maclistbuffer, buffer, user_len))
{
return -EFAULT;
}
return user_len;
}