#!/usr/bin/env python # # IBSS Merge version 0.40 # (C) 2008-09-23 Georg Lukas # licensed under the GPL v2 Open Source license # # The most current version of this script can be found at: # http://ivs.cs.uni-magdeburg.de/EuK/mitarbeiter/glukas/ibss-merge.scapy # # You will need Scapy v2 (http://www.secdev.org/projects/scapy/) to run this! # # This script runs on a MadWifi NG monitor device and displays # IBSS merging related information about the Ad-Hoc cell given as # command line argument. # # WARNING: your terminal should be at least 150 characters wide! import sys from scapy.all import * try: import psyco except ImportError: pass class Bunch(dict): def __init__(self,**kw): dict.__init__(self,kw) self.__dict__.update(kw) essid = "" if len(sys.argv) > 1: essid = sys.argv[1] device = "ath0" if len(sys.argv) > 2: device = sys.argv[2] try: devtype = open("/proc/sys/net/" + device + "/dev_type", "w") devtype.write("802\n") devtype.close() except: pass nodes = {} time = 0 # width of the beacon history memory = 10 # put together that many 1us slots unify = 20 # ! = illegal, WPA without Privacy. # + = WEP # # = WPA FLAGS = " !+#" def flags(n): return FLAGS[n.privacy*2 + n.wpa*1] def paint(): global time, memory, nodes FMT="%-17s %-17s %c %2s %17s %-10s %-20s" #print "\x1b\x5b\x48", "Node BSSID", \ # "%-22s" % ("("+essid+")"), " TSF History", \ # " "*(memory-7), "Signal" if essid == "": ssid_title="BSSID" else: ssid_title="'%s'" % essid[:17] print "\x1b\x5b\x48" + FMT % ("Node", ssid_title, "W", "Ch", "TSF", "History", "Signal") #list = nodes.keys() #list.sort() for l, n in nodes.iteritems(): #n = nodes[l] hist = n.levels while hist and hist[0] + memory < time: hist.pop(0) histline = "" for x in range((time-memory), time): if x in hist: histline += "X" else: histline += "-" sigline = "=" * n.sig if n.bssid == l: ssid = "'%s'" % n.essid[:15] else: ssid = n.bssid print FMT % (l, ssid, flags(n), n.channel, n.tsf, histline, sigline) def update(pkt): global time, memory, nodes #if not PrismHeader in pkt: # pkt.show() # sys.exit(1) if not PrismHeader in pkt: redraw = True elif pkt.hosttime/unify != time: time = pkt.hosttime/unify redraw = True else: redraw = False #if Dot11Beacon in pkt: # print "\x1b\x5b\x48", time, pkt.hosttime, pkt[Dot11Elt].info #if Dot11Beacon in pkt: # print "beacon", pkt.__repr__() #else: # print "packet", pkt.__repr__() if (Dot11Beacon in pkt or Dot11ProbeResp in pkt) and (essid == "" or pkt[Dot11Elt].info == essid): if Dot11Beacon in pkt: beacon = pkt[Dot11Beacon] else: beacon = pkt[Dot11ProbeResp] mac = pkt[Dot11].addr2 if mac not in nodes: nodes[mac] = Bunch(levels = []) n = nodes[mac] hist = n.levels hist.append(pkt.hosttime/unify) n.tsf = beacon.timestamp n.bssid = pkt[Dot11].addr3 n.essid = pkt[Dot11Elt].info n.privacy = (beacon.cap & 0x1000) == 0x1000 n.wme = False n.wpa = False n.channel = "?" elt11 = pkt[Dot11Elt] #print #print elt11.__repr__() while type(elt11) == Dot11Elt: if elt11.ID == 221 and elt11.info.startswith("\x00P\xf2\x02"): n.wme = True if elt11.ID == 221 and elt11.info.startswith("\x00P\xf2\x01"): n.wpa = True if elt11.ID == 3: n.channel = struct.unpack("!B", elt11.info)[0] elt11 = elt11.payload if PrismHeader in pkt: #n.sig = -(-97-pkt.signal)/3 n.sig = min(pkt.rssi/3, 20) else: n.sig = 0 if redraw: paint() # clear screen hack print "\x1b\x5b\x32\x4a" paint() try: sniff(iface=device, prn=update, store=0) except Exception, e: print "Error sniffing:", e