#! /usr/bin/env python ############################################################################# ## ## ## locator.py --- Wi-Fi locator using signal strength ## ## see http://www.secdev.org/projects/locator/ ## ## for more informations ## ## ## ## Copyright (C) 2004 Philippe Biondi ## ## ## ## This program is free software; you can redistribute it and/or modify it ## ## under the terms of the GNU General Public License version 2 as ## ## published by the Free Software Foundation; version 2. ## ## ## ## This program is distributed in the hope that it will be useful, but ## ## WITHOUT ANY WARRANTY; without even the implied warranty of ## ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## ## General Public License for more details. ## ## ## ############################################################################# import sys,os,re import socket,struct import random,time,select ETH_P_ALL = 3 IFACE="wlan0" CHANNEL=11 MANUF="/usr/share/ethereal/manuf" SCALE=6 TIMESCALE=2 def parse_manuf(file): s = {} re_manuf = re.compile(r'^\s*(..:..:..)\s+([^\s]+).*') for l in open(file).readlines(): m = re_manuf.match(l) if m: mac,manuf = m.groups() s["".join(map(lambda x:chr(int(x,16)), mac.split(":")))] = manuf return s manuf = parse_manuf(MANUF) chars = "#@O0o. " def mac2txt(x): return "%02x:%02x:%02x:%02x:%02x:%02x" % tuple(map(ord,x)) os.system("ifconfig %s up" % IFACE) os.system("iwconfig %s channel %i" % (IFACE,CHANNEL)) os.system("iwconfig %s mode monitor" % IFACE) os.system("iwpriv %s monitor 3" % IFACE) s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL)) s.bind((IFACE, ETH_P_ALL)) emitlist = [] emit = {} seen = [] print "" try: while 1: print "" for i in emitlist: tm,sig,osig = emit[i] cn = (time.time()-tm)*TIMESCALE if cn+1 >= len(chars): c = " " c2 = " " else: c = chars[int(cn)] c2 = chars[int(cn)+1] print "%s %-11s %3i: %s%s%s" % (mac2txt(i), manuf.get(i[:3],"?"),sig, c2*(osig/SCALE), "\b"*(osig/SCALE), c*(sig/SCALE)) r,w,e = select.select([s],[],[],1) if r: pkt = s.recv(1200) if len(pkt) < 160: # print "short frame:",repr(pkt) continue signal = struct.unpack("I",pkt[92:96])[0] if signal < 60: signal += 255 signal -= 60 ptype = ord(pkt[144]) if ptype & 0xc == 0x4: if (ptype >> 4) not in [ 0xb, 0xa, 0xe, 0xf]: continue mac = pkt[154:160] if mac not in emit: emitlist.append(mac) emit[mac] = (time.time(), signal, emit.get(mac,(0,0,0))[1]) except ValueError: pass