wifi探针只需设备开启无线网卡,并不需要连接wifi即可探测出设备的mac地址和信号强度。 最近公司要做一款wifi探针产品用于扩充无线覆盖的应用。
wifi探针本身并不复杂,之前我在树莓派2代的板子上插usb无线网卡实现过, 新入手的树莓派3代板子集成了wifi,同时也预留了焊盘可焊接天线底座。
在树莓派上做wifi探针是为了产品开发和演示方便,最终产品会移植到OpenWRT平台的板子上。
树莓派3代的板载无线网卡默认是不支持monitor模式的,首先得打补丁支持monitor模式。
开机自动挂载驱动
修改 /etc/rc.local
exit 0 前增加
insmod /root/brcmfmac.ko
wifi探针实现的功能:获取周边手机等设备的mac地址和信号强度上报到云端, 首先复制粘贴网上的N行实现wifi探针的python脚本看看效果,文章使用的是scapy来做的, 实际测试信号强度是不对的,时间关系没去研究具体原因,使用了pcap的版本可以获取到需要的数据。
修改带上报功能后python代码:
#coding:utf-8 # by zhangdi <h4ck@163.com> import os import random import pcapy import time import json import zlib import socket import binascii from multiprocessing import Process from impacket import ImpactDecoder, dot11 MYMAC = open('/sys/class/net/eth0/address').read().strip().lower() INTERFACE = 'wlan0' MAX_LEN = 1514 # max size of packet to capture PROMISCUOUS = 1 # promiscuous mode? READ_TIMEOUT = 300 # in milliseconds RTD = ImpactDecoder.RadioTapDecoder() UDP_IP = '192.168.88.234' UDP_PORT = 12345 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP clients = {'mac': MYMAC, 'clients':[]} latest = time.time() # Channel hopper def channel_hopper(): while True: channel = random.randrange(1,14) cmd = "iw dev wlan0 set channel %d" % channel #print cmd try: os.system(cmd) time.sleep(1) except KeyboardInterrupt: break def getBssid(arr): #Get Binary array to MAC addr format out = [] s = binascii.hexlify(arr) t = iter(s) st = ':'.join(a+b for a,b in zip(t,t)) return st def pcapy_packet(header, data): global clients, latest radio_packet = RTD.decode(data) _signal = radio_packet.get_dBm_ant_signal() channel = radio_packet.get_channel()[0] if _signal: signal = _signal and -(256-_signal) or -120 pkt = radio_packet.child() if pkt.get_type() == dot11.Dot11Types.DOT11_TYPE_MANAGEMENT: base = pkt.child().child() if base.__class__ != dot11.Dot11ManagementProbeRequest: return bssid_base = pkt.child() #try: ssid = str(base.get_ssid()) #except: ssid = '' bssid = getBssid(bssid_base.get_source_address()) clients['clients'].append({'mac':bssid, 'channel': channel, 'signal':signal}) if (time.time() - latest) > 3: latest = time.time() print clients sock.sendto(zlib.compress(json.dumps(clients)), (UDP_IP, UDP_PORT)) clients['clients'] = [] #if __name__ == "__main__": p = Process(target = channel_hopper) p.start() c = pcapy.open_live('wlan0', MAX_LEN, PROMISCUOUS, READ_TIMEOUT) try: c.loop(-1, pcapy_packet) except SystemError: print clients
测试期间发现偶尔无线网卡死掉,后换了2A的电源后解决,部署了3台在几个办公区用于计算区域人流。
补充:我在这里做了网卡自动切换信道,在后来形成产品的C语言版本时发现变信道不需要,本身就是广播啊。
本站的文章和资源来自互联网或者站长的原创,按照 CC BY -NC -SA 3.0 CN协议发布和共享,转载或引用本站文章应遵循相同协议。如果有侵犯版权的资 源请尽快联系站长,我们会在24h内删除有争议的资源。欢迎大家多多交流,期待共同学习进步。