Port wiviz to -ng
authorFlorian Fainelli <florian@openwrt.org>
Sat, 26 Aug 2006 07:29:39 +0000 (07:29 +0000)
committerFlorian Fainelli <florian@openwrt.org>
Sat, 26 Aug 2006 07:29:39 +0000 (07:29 +0000)
SVN-Revision: 4675

33 files changed:
net/wiviz/Makefile [new file with mode: 0644]
net/wiviz/files/www/cgi-bin/wiviz/get.cgi [new file with mode: 0755]
net/wiviz/files/www/cgi-bin/wiviz/set.cgi [new file with mode: 0755]
net/wiviz/files/www/wiviz/adhoc-idle.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/adhoc-idle.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/adhoc.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/adhoc.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/ap-idle.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/ap-idle.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/ap-wep-idle.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/ap-wep-idle.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/ap-wep.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/ap-wep.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/ap.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/ap.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/pip-idle.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/pip-idle.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/pip.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/pip.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/station-idle.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/station-idle.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/station.gif [new file with mode: 0755]
net/wiviz/files/www/wiviz/station.png [new file with mode: 0755]
net/wiviz/files/www/wiviz/wiviz.css [new file with mode: 0755]
net/wiviz/files/www/wiviz/wiviz.html [new file with mode: 0755]
net/wiviz/files/www/wiviz/wiviz.js [new file with mode: 0755]
net/wiviz/src/Makefile [new file with mode: 0644]
net/wiviz/src/channelhopper.c [new file with mode: 0644]
net/wiviz/src/channelhopper.h [new file with mode: 0644]
net/wiviz/src/structs.h [new file with mode: 0644]
net/wiviz/src/wiviz.c [new file with mode: 0644]
net/wiviz/src/wl_access.c [new file with mode: 0644]
net/wiviz/src/wl_access.h [new file with mode: 0644]

diff --git a/net/wiviz/Makefile b/net/wiviz/Makefile
new file mode 100644 (file)
index 0000000..e767d0f
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id$
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=wiviz
+PKG_VERSION:=1.0
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/wiviz
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+libpcap
+  TITLE:=Wireless Network Visualization
+  DESCRIPTION:=Wireless Network Visualization
+  URL:=http://students.washington.edu/natetrue/wiviz/
+endef
+       
+define Build/Prepare
+       mkdir -p $(PKG_BUILD_DIR)
+       $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+$(call Build/Compile/Default,CC="$(TARGET_CC)" \
+               CCOPTS="$(TARGET_CFLAGS)" \
+               INCLUDE="-I$(STAGING_DIR)/include -I$(STAGING_DIR)/usr/include" \
+               LDFLAGS="-L$(STAGING_DIR)/lib -L$(STAGING_DIR)/usr/lib")
+endef
+
+define Package/wiviz/install   
+       mkdir -p $(1)/usr/sbin
+       $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin/
+       $(RSTRIP) $(1)
+       $(CP) ./files/* $(1)
+       find $(1) -name CVS | xargs rm -rf
+       find $(1) -name .svn | xargs rm -rf
+endef
+
+$(eval $(call BuildPackage,wiviz))
diff --git a/net/wiviz/files/www/cgi-bin/wiviz/get.cgi b/net/wiviz/files/www/cgi-bin/wiviz/get.cgi
new file mode 100755 (executable)
index 0000000..161fc75
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+WIVIZ_PATH=wiviz
+
+echo Content-type: text/html
+echo 
+killall -USR1 wiviz >/dev/null 2>&1
+if [ 0 -ne $? ]
+ then #### Wi-Viz daemon not running, start it
+  $WIVIZ_PATH >/dev/null </dev/null 2>&1 &
+  killall -USR1 wiviz > /dev/null
+ fi
+echo "<html><head><script language='JavaScript1.2'>"
+cat /tmp/wiviz-pipe
+echo "</script></head><body></body></html>"
diff --git a/net/wiviz/files/www/cgi-bin/wiviz/set.cgi b/net/wiviz/files/www/cgi-bin/wiviz/set.cgi
new file mode 100755 (executable)
index 0000000..17b4787
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+httpd -d $QUERY_STRING > /tmp/wiviz-cfg
+killall -USR2 wiviz
diff --git a/net/wiviz/files/www/wiviz/adhoc-idle.gif b/net/wiviz/files/www/wiviz/adhoc-idle.gif
new file mode 100755 (executable)
index 0000000..05e479f
Binary files /dev/null and b/net/wiviz/files/www/wiviz/adhoc-idle.gif differ
diff --git a/net/wiviz/files/www/wiviz/adhoc-idle.png b/net/wiviz/files/www/wiviz/adhoc-idle.png
new file mode 100755 (executable)
index 0000000..b10b102
Binary files /dev/null and b/net/wiviz/files/www/wiviz/adhoc-idle.png differ
diff --git a/net/wiviz/files/www/wiviz/adhoc.gif b/net/wiviz/files/www/wiviz/adhoc.gif
new file mode 100755 (executable)
index 0000000..d07c80c
Binary files /dev/null and b/net/wiviz/files/www/wiviz/adhoc.gif differ
diff --git a/net/wiviz/files/www/wiviz/adhoc.png b/net/wiviz/files/www/wiviz/adhoc.png
new file mode 100755 (executable)
index 0000000..57db25c
Binary files /dev/null and b/net/wiviz/files/www/wiviz/adhoc.png differ
diff --git a/net/wiviz/files/www/wiviz/ap-idle.gif b/net/wiviz/files/www/wiviz/ap-idle.gif
new file mode 100755 (executable)
index 0000000..a929696
Binary files /dev/null and b/net/wiviz/files/www/wiviz/ap-idle.gif differ
diff --git a/net/wiviz/files/www/wiviz/ap-idle.png b/net/wiviz/files/www/wiviz/ap-idle.png
new file mode 100755 (executable)
index 0000000..a6e6fb3
Binary files /dev/null and b/net/wiviz/files/www/wiviz/ap-idle.png differ
diff --git a/net/wiviz/files/www/wiviz/ap-wep-idle.gif b/net/wiviz/files/www/wiviz/ap-wep-idle.gif
new file mode 100755 (executable)
index 0000000..a929696
Binary files /dev/null and b/net/wiviz/files/www/wiviz/ap-wep-idle.gif differ
diff --git a/net/wiviz/files/www/wiviz/ap-wep-idle.png b/net/wiviz/files/www/wiviz/ap-wep-idle.png
new file mode 100755 (executable)
index 0000000..a6e6fb3
Binary files /dev/null and b/net/wiviz/files/www/wiviz/ap-wep-idle.png differ
diff --git a/net/wiviz/files/www/wiviz/ap-wep.gif b/net/wiviz/files/www/wiviz/ap-wep.gif
new file mode 100755 (executable)
index 0000000..2901520
Binary files /dev/null and b/net/wiviz/files/www/wiviz/ap-wep.gif differ
diff --git a/net/wiviz/files/www/wiviz/ap-wep.png b/net/wiviz/files/www/wiviz/ap-wep.png
new file mode 100755 (executable)
index 0000000..3436183
Binary files /dev/null and b/net/wiviz/files/www/wiviz/ap-wep.png differ
diff --git a/net/wiviz/files/www/wiviz/ap.gif b/net/wiviz/files/www/wiviz/ap.gif
new file mode 100755 (executable)
index 0000000..7eb5b3a
Binary files /dev/null and b/net/wiviz/files/www/wiviz/ap.gif differ
diff --git a/net/wiviz/files/www/wiviz/ap.png b/net/wiviz/files/www/wiviz/ap.png
new file mode 100755 (executable)
index 0000000..ccfc864
Binary files /dev/null and b/net/wiviz/files/www/wiviz/ap.png differ
diff --git a/net/wiviz/files/www/wiviz/pip-idle.gif b/net/wiviz/files/www/wiviz/pip-idle.gif
new file mode 100755 (executable)
index 0000000..fa923bd
Binary files /dev/null and b/net/wiviz/files/www/wiviz/pip-idle.gif differ
diff --git a/net/wiviz/files/www/wiviz/pip-idle.png b/net/wiviz/files/www/wiviz/pip-idle.png
new file mode 100755 (executable)
index 0000000..3fe25fe
Binary files /dev/null and b/net/wiviz/files/www/wiviz/pip-idle.png differ
diff --git a/net/wiviz/files/www/wiviz/pip.gif b/net/wiviz/files/www/wiviz/pip.gif
new file mode 100755 (executable)
index 0000000..1c566e9
Binary files /dev/null and b/net/wiviz/files/www/wiviz/pip.gif differ
diff --git a/net/wiviz/files/www/wiviz/pip.png b/net/wiviz/files/www/wiviz/pip.png
new file mode 100755 (executable)
index 0000000..5c05a73
Binary files /dev/null and b/net/wiviz/files/www/wiviz/pip.png differ
diff --git a/net/wiviz/files/www/wiviz/station-idle.gif b/net/wiviz/files/www/wiviz/station-idle.gif
new file mode 100755 (executable)
index 0000000..155f022
Binary files /dev/null and b/net/wiviz/files/www/wiviz/station-idle.gif differ
diff --git a/net/wiviz/files/www/wiviz/station-idle.png b/net/wiviz/files/www/wiviz/station-idle.png
new file mode 100755 (executable)
index 0000000..eb1621e
Binary files /dev/null and b/net/wiviz/files/www/wiviz/station-idle.png differ
diff --git a/net/wiviz/files/www/wiviz/station.gif b/net/wiviz/files/www/wiviz/station.gif
new file mode 100755 (executable)
index 0000000..c8a075f
Binary files /dev/null and b/net/wiviz/files/www/wiviz/station.gif differ
diff --git a/net/wiviz/files/www/wiviz/station.png b/net/wiviz/files/www/wiviz/station.png
new file mode 100755 (executable)
index 0000000..8daf8df
Binary files /dev/null and b/net/wiviz/files/www/wiviz/station.png differ
diff --git a/net/wiviz/files/www/wiviz/wiviz.css b/net/wiviz/files/www/wiviz/wiviz.css
new file mode 100755 (executable)
index 0000000..7b5afa7
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+body {
+       background-color: #D0D0D0;
+       vertical-align: center;
+       text-align: center;
+}
+div.main {
+       background-color: #D0F0D0;
+       width: 500px;
+       height: 500px;
+       border: 1px solid #555599;
+       vertical-align: center;
+       text-align: center;
+}
+div.floater {
+       background-color: #D0F0D0;
+       width: 125px;
+       height: 300px;
+       border: 1px solid #555599;
+       float: right;
+       z-index: 3;
+}
+span.status {
+       color: #FF0000;
+}
+img.icon {
+       width: 50px;
+       height: 50px;
+}
+img.pip {
+       width: 12px;
+       height: 12px;
+       position: absolute;
+       z-index: 1;
+}
+td {
+       vertical-align: center;
+  text-align: center;
+}
+span.hostdesc {
+       font-size: 10pt;
+}
+span.extrafo {
+       font-size: 10pt;
+       visibility: hidden;
+}
+div.hostdiv {
+       position: absolute;
+       background-color: transparent;
+       text-align: center;
+       width: 150px;
+       z-index: 2;
+}
+div.hostdiv_hov {
+       position: absolute;
+       background-color: #C0E0C0;
+       text-align: center;
+       width: 150px;
+       z-index: 3;
+       border: 1px solid #000000;
+}
diff --git a/net/wiviz/files/www/wiviz/wiviz.html b/net/wiviz/files/www/wiviz/wiviz.html
new file mode 100755 (executable)
index 0000000..f1356fd
--- /dev/null
@@ -0,0 +1,81 @@
+<html>
+<head>
+<!--
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+-->
+<title>Wi-viz wireless network environment visualization</title>
+<link rel='stylesheet' type='text/css' href='wiviz.css'>
+<script language='JavaScript1.2' src='wiviz.js'>
+</script>
+</head>
+<body>
+<h2>OpenWRT Wi-viz network visualization</h2>
+<div class='floater'>
+Status: <span id='status' class='status'>Monitoring</span><br>
+<input type='button' id='togglelisten' value='Stop monitoring' onclick='toggleListen()'>
+<p><form name='channelform' action='/cgi-bin/wiviz/set.cgi' method='get' target='wivizGetFrame'>
+Channel setting:
+<select id='channelsel' name='channelsel' onchange='channelSet()'>
+<option value='nochange' selected>No change</option>
+<option value='hop'>Hopping</option>
+<option>1</option>
+<option>2</option>
+<option>3</option>
+<option>4</option>
+<option>5</option>
+<option>6</option>
+<option>7</option>
+<option>8</option>
+<option>9</option>
+<option>10</option>
+<option>11</option>
+<option>12</option>
+<option>13</option>
+<option>14</option>
+</select><br>
+<span id='hopoptions' style='display: none'>
+Time/channel: <select name='hopdwell'>
+<option value='500'>0.5 sec</option>
+<option selected value='1000'>1 sec</option>
+<option value='2000'>2 sec</option>
+<option value='5000'>5 sec</option>
+</select><br>
+Hop sequence: <select name='hopseq'>
+<option selected>1,3,6,8,11</option>
+<option>1,3,6,8,11,14</option>
+<option>1,6,11</option>
+<option value='1,2,3,4,5,6,7,8,9,10,11'>1 to 11</option>
+<option value='1,2,3,4,5,6,7,8,9,10,11,12,13,14'>1 to 14</option>
+</select><br>
+<input type='submit' value='Set'>
+</form>
+</span>
+</div>
+<center>
+<div id='infodiv' class='main'>
+<table height=100% width=100%><tr><td>
+<span id='pips' style='position: relative'></span>
+<span id='content' style='position: relative'></span>
+</td></tr></table>
+</div>
+</center>
+<span id='debug' style='display: none'></span>
+<iframe style='display:none' id='wivizGetFrame' name='wivizGetFrame' src='about:blank'></iframe>
+<script language='JavaScript1.2'>
+ scan_thread();
+</script>
+</body>
+</html>
diff --git a/net/wiviz/files/www/wiviz/wiviz.js b/net/wiviz/files/www/wiviz/wiviz.js
new file mode 100755 (executable)
index 0000000..dc67d8f
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+var mv = 353;
+var stupid = eval('window.attachEvent') ? 1 : 0;
+var hosts;
+var idle_timeout = 20;
+var erase_timeout = 35;
+var skew_x = 0; skew_y = 0;
+var listening = 1;
+var wiviz_cgi_url = "/cgi-bin/wiviz/get.cgi";
+
+//What? You mean the POSIX thread API hasn't been ported to Javascript?  Bugger.
+function scan_thread() {
+       var loc = document.getElementById('wivizGetFrame').contentWindow.location;
+       if (!listening) return;
+       if (loc.href != wiviz_cgi_url) {
+               loc.replace(wiviz_cgi_url);
+       }
+       else {
+               loc.reload(true);
+       }
+       setTimeout("scan_thread()", 5000);
+}
+
+function toggleListen() {
+       statusel = document.getElementById('status');
+       statusbutton = document.getElementById('togglelisten');
+       listening = 1 - listening;
+       if (listening) {
+           statusel.innerHTML = "Monitoring";
+           statusbutton.value = "Stop monitoring";
+           document.getElementById('content').innerHTML = '';
+           scan_thread();
+       }
+       else {
+           statusel.innerHTML = "Stopped";
+           statusbutton.value = "Start monitoring";
+       }
+}
+
+function channelSet() {
+       channelset = document.getElementById('channelsel').value;
+       if (channelset == 'hop') {
+           document.getElementById('hopoptions').style.display = 'inline';
+       }
+       else {
+           document.getElementById('hopoptions').style.display = 'none';
+           if (channelset != 'nochange') document.forms[0].submit();
+       }
+}
+
+function mousenter(e) {
+       if (stupid) e = event;
+       el = stupid ? e.srcElement : e.currentTarget;
+       el.parentNode.parentNode.className = 'hostdiv_hov';
+       el.nextSibling.nextSibling.nextSibling.style.visibility = 'visible';
+}
+
+function mouseout(e) {
+       if (stupid) e = event;
+       el = stupid ? e.srcElement : e.currentTarget;
+       el.parentNode.parentNode.className = 'hostdiv';
+       el.nextSibling.nextSibling.nextSibling.style.visibility = 'hidden';
+}
+
+function generate_mnemonic(hash) {
+       c = new Array('b','c','d','f','g','h','j','k','l','m','n','p','qu','r','s',
+               't','v','w','y','z','th','ch','sh','cc','rr');
+       v = new Array('a','e','i','o','u','ae','ai','ao','au','eo','ei','eu','iu','oa','oe');
+       var i, a;
+       var p = hash & 1;
+       var n = '';
+       for (i = 0; i < 4; i++) {
+               a = p ? c : v;
+               n += a[hash % a.length];
+               hash += a.length << 3 + a.length / 2;
+               hash *= hash;
+         p = 1 - p;
+       }
+       return n;
+}
+
+function mkhash(mac) {
+       var     macarr = mac.split(/:/);
+  var hash = 0;
+               for (j = 0; j < 6; j++) {
+                       hash += parseInt(macarr[j]) * j << j;
+                       hash += 11;
+               }
+       if (hash < 0) hash = -hash;
+       return hash;
+}
+
+function wiviz_callback(mhosts, cfgstring) {
+       var nh = '';
+       hosts = mhosts;
+       for (i = 0; i < hosts.length; i++) {
+         hs = hosts[i];
+         if (hs.length == 0) break;
+    hs.mac = hs[0];
+    hs.rssi = hs[1];
+    hs.desc = hs[2];
+    hs.descarr = hs.desc.split(/-/)
+    hs.age = hs[3];
+               hs.hash = mkhash(hs.mac);
+    hs.mnem = generate_mnemonic(hs.hash)
+    hs.name = hs.mnem;
+    el = document.getElementById(hs.mnem);
+    if (el) {
+      if (hs.age > erase_timeout) {
+        el.parentNode.removeChild(el);
+        continue;
+      }
+       el.innerHTML = genHTML(hs);
+    }
+    else {
+      if (hs.age > erase_timeout) continue;
+                       hs.x = Math.sin(hs.hash / mv) * hs.rssi * 2 - 67;
+                       hs.y = Math.cos(hs.hash / mv) * hs.rssi * 2;
+                       nh += "<div class='hostdiv' id='" + hs.mnem + "' style='top: ";
+                       nh += parseInt(hs.y) + "px; left: " + parseInt(hs.x) + "px'>";
+                 nh += genHTML(hs) + "</div>";
+    }
+       }
+       document.getElementById('content').innerHTML += nh;
+       
+       cfgarr = cfgstring.split(/-/);
+       if (cfgarr[1]) {
+           if (cfgarr[1] == 'hopping') cfgarr[1] = 'hop';
+           document.getElementById('channelsel').value = cfgarr[1];
+           if (cfgarr[1] == 'hop') channelSet();
+       }
+       
+       //repip();
+       setTimeout("declump(); repip();", 250);
+}
+
+function repip() {
+  var nh = "";
+  if (!hosts) return;
+       for (i = 0; i < hosts.length; i++) {
+         hs = hosts[i];
+         if (hs.length == 0) break;
+    mac = hs[0];
+    rssi = hs[1];
+    desc = hs[2].split(/-/);
+               if (desc[0] == 'sta' && desc[1] == 'assoc') {
+                       bss = desc[2];
+                       hs.apmnem = generate_mnemonic(mkhash(bss));
+                       ap = document.getElementById(hs.apmnem);
+                       sta = document.getElementById(hs.mnem);
+                       if (ap && sta) {
+                         x = parseInt(sta.style.left);
+                         y = parseInt(sta.style.top);
+                         dx = parseInt(ap.style.left) - x;
+                         dy = parseInt(ap.style.top) - y;
+                         x += 67;
+                         y += 10;
+                         d = Math.sqrt(dx*dx+dy*dy);
+                         for (j = 0; j < d; j += 15) {
+                           nh += "<img src='"
+                                         + ((hs.age < idle_timeout) ? "pip" : "pip-idle")
+                                         + (stupid ? ".gif" : ".png")
+                                               + "' class='pip' style='top:"
+                             + parseInt(y+dy * j / d) + "; left:"
+                             + parseInt(x+dx * j / d) + "'>";
+                         }
+                       }
+               }
+       }
+       document.getElementById('pips').innerHTML = nh;
+}
+
+function declump() {
+       var c = 0;
+       var top = 30000,left = 30000,right = -30000,bottom = -30000;
+       for (i = 0; i < hosts.length; i++) {
+         for (j = 0; j < hosts.length; j++) {
+           if (i == j) continue;
+                       e1 = document.getElementById(hosts[i].mnem);
+                       e2 = document.getElementById(hosts[j].mnem);
+                       if (!e1 || !e2) continue;
+                       x1 = parseInt(e1.style.left);
+                       x2 = parseInt(e2.style.left);
+                       y1 = parseInt(e1.style.top);
+                       y2 = parseInt(e2.style.top);
+                       if (x1 < left) left = x1;
+                       if (y1 < top) top = y1;
+                       if (x1 > right) right = x1;
+                       if (y1 > bottom) bottom = y1;
+                       ox = x2;
+                       oy = y2;
+                       dist = Math.sqrt(Math.pow((x1-x2), 2) + Math.pow((y1-y2), 2));
+                       if (dist == 0) {
+                           x2 += Math.random() * 5;
+                               y2 += Math.random() * 5;
+                               dist = 10;
+                       }
+                       if (dist < 100) {
+                               cx = (x1-x2) * 5 / (dist / 3);
+                               cy = (y1-y2) * 5 / (dist / 3);
+                               x2 -= cx;
+                               y2 -= cy;
+                               }
+                       if (hosts[j].apmnem == hosts[i].mnem
+                                       || hosts[i].apmnem == hosts[j].mnem) {
+                         cx = (x1-x2) * 5 / (dist / 3);
+                         cy = (y1-y2) * 5 / (dist / 3);
+                               if (dist > 150) {
+                                 x2 += cx;
+                                 y2 += cy;
+                               }
+                       }
+                       if (Math.abs(ox-x2) > 2 || Math.abs(oy-y2) > 2) {
+                               e2.style.left = parseInt(x2);
+                               e2.style.top = parseInt(y2);
+                               c++;
+                       }
+         }
+       }
+       if (top < bottom && left < right) {
+         document.getElementById('debug').innerHTML = left + "," + right + "," + top + "," +bottom;
+         document.getElementById('content').style.left =
+               document.getElementById('pips').style.left =
+                        -(right - left) / 2 - left - 67;
+         document.getElementById('content').style.top =
+         document.getElementById('pips').style.top =
+                        -(bottom - top) / 2 - top - 25;
+       }
+       repip();
+       if (c) setTimeout("declump()", 100);
+}
+
+function genHTML(hs) {
+       var nh = '';
+  nh += "<center><img class='icon' src='"
+       a = hs.descarr;
+       if (a[0] == 'ap' || a[0] == 'adhoc') {
+         if (a[0] == 'ap') {
+                       nh += "ap";
+                       if (a[5] == 'enc') nh += "-wep";
+         }
+         else {
+           nh += "adhoc";
+         }
+               hs.channel = a[2];
+               hs.name = a[4];
+       }
+       else if (a[0] == 'sta') {
+               nh += "station";
+               hs.channel = 0;
+       }
+       nh += (hs.age < idle_timeout) ? "": "-idle";
+       nh += stupid ? ".gif" : ".png";
+       nh += "' onmouseover='mousenter(event)' onmouseout='mouseout(event)'"
+               + "><br><span class='hostdesc'>" + hs.mac + "<br><i>'" + hs.name;
+       nh += "'</i>";
+       if (hs.channel) {
+         nh += " ch" + hs.channel;
+       }
+       nh += "</span><span class='extrafo'><br>";
+       if (a[0] == 'ap') nh += "Access point";
+       if (a[0] == 'sta') nh += "Station";
+       if (a[0] == 'adhoc') nh += "Logical ad-hoc entity";
+       if (a[0] == 'ap' || a[0] == 'adhoc') {
+               nh += "<br>";
+               if (a[5] == '?enc') nh += "Encryption unknown";
+               if (a[5] == 'enc') nh += "Encrypted";
+               if (a[5] == 'unenc') nh += "Unencrypted";
+               if (a[6] == 'wep') nh += "-WEP";
+               if (a[6] == 'wpa') nh += "-WPA";
+       }
+       nh += "<br>RSSI: " + hs.rssi + " dBm<br>"
+               + "Seen " + hs.age + " seconds ago<br>";
+       nh += "</span></center>";
+       return nh;
+}
diff --git a/net/wiviz/src/Makefile b/net/wiviz/src/Makefile
new file mode 100644 (file)
index 0000000..6f23035
--- /dev/null
@@ -0,0 +1,25 @@
+## Wi-viz makefile
+# Supply your own C cross-compiler; I recommend the one from the OpenWRT buildroot
+# Also requires a libpcap to link with, use libpcap.a for static, .so for shared
+CC=~/buildroot/staging_dir_mipsel/bin/mipsel-linux-gcc
+LDFLAGS=-L~/buildroot/staging_dir_mipsel/lib
+LIBS=-lpcap
+
+CCOPTS=-O2 -Os -pipe -mips32 -mtune=mips32
+INCLUDE=-I~/buildroot/staging_dir_mipsel/include
+SOURCES=wiviz.c wl_access.c channelhopper.c
+OBJS=wiviz.o wl_access.o channelhopper.o
+TARGET=wiviz
+
+wiviz: ${OBJS}
+       ${CC} ${CCOPTS} ${INCLUDE} -o ${TARGET} ${OBJS} ${LDFLAGS} ${LIBS}
+
+wiviz.o: wiviz.c
+       ${CC} ${CCOPTS} ${INCLUDE} -c ${SOURCES}
+wl_access.o: wl_access.c
+       ${CC} ${CCOPTS} ${INCLUDE} -c ${SOURCES}
+channelhopper.o: channelhopper.c
+       ${CC} ${CCOPTS} ${INCLUDE} -c ${SOURCES}
+
+remake:
+       touch wiviz.c wl_access.c channelhopper.c
diff --git a/net/wiviz/src/channelhopper.c b/net/wiviz/src/channelhopper.c
new file mode 100644 (file)
index 0000000..0a3e6fe
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <stdio.h>
+#include <pcap.h>
+#include <signal.h>
+#include <sys/time.h>
+#include "wl_access.h"
+#include "channelhopper.h"
+#include "structs.h"
+
+void ch_sig_handler(int i) {
+
+  }
+
+void channelHopper(wiviz_cfg * cfg) {
+  int hopPos;
+  int nc;
+
+  //Turn off signal handling from parent process
+  signal(SIGUSR1, &ch_sig_handler);
+  signal(SIGUSR2, &ch_sig_handler);
+
+  //Start hoppin'!
+  hopPos = 0;
+  while (1) {
+    nc = cfg->channelHopSeq[hopPos];
+    hopPos = (hopPos + 1) % cfg->channelHopSeqLen;
+    //Set the channel
+    fprintf(stderr, "It sets the channel to %i\n", nc);
+    wl_ioctl(WL_DEVICE, WLC_SET_CHANNEL, &nc, 4);
+    //Sleep
+    usleep(cfg->channelDwellTime * 1000);
+    }
+  }
diff --git a/net/wiviz/src/channelhopper.h b/net/wiviz/src/channelhopper.h
new file mode 100644 (file)
index 0000000..6ab63af
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+// Channel hopper definition
+
+void channelHopper();
diff --git a/net/wiviz/src/structs.h b/net/wiviz/src/structs.h
new file mode 100644 (file)
index 0000000..10f80f3
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+//Structure definitions for wireless packets
+
+#define MAX_HOSTS 257
+
+#ifdef DEFINE_TYPES
+typedef unsigned short u_short;
+typedef unsigned char u_char;
+typedef unsigned int u_int;
+#endif
+
+typedef enum {
+  mgt_assocRequest = 0,
+  mgt_assocResponse = 1,
+  mgt_reassocRequest = 2,
+  mgt_reassocResponse = 3,
+  mgt_probeRequest = 4,
+  mgt_probeResponse = 5,
+  mgt_beacon = 8,
+  mgt_disassoc = 10,
+  mgt_auth = 11,
+  mgt_deauth = 12
+  } wifi_frametype;
+
+typedef struct ieee802_11_hdr {
+  u_char frame_control;
+  u_char flags;
+#define IEEE80211_TO_DS 0x01
+#define IEEE80211_FROM_DS 0x02
+#define IEEE80211_MORE_FRAG 0x04
+#define IEEE80211_RETRY 0x08
+#define IEEE80211_PWR_MGT 0x10
+#define IEEE80211_MORE_DATA 0x20
+#define IEEE80211_WEP_FLAG 0x40
+#define IEEE80211_ORDER_FLAG 0x80
+  u_short duration;
+  u_char addr1[6];
+  u_char addr2[6];
+  u_char addr3[6];
+  u_short frag_and_seq;
+  } ieee802_11_hdr;
+
+typedef struct {
+  u_char timestamp[8];
+  u_short bcn_interval;
+  u_short caps;
+#define MGT_CAPS_AP 0x1
+#define MGT_CAPS_IBSS 0x2
+#define MGT_CAPS_WEP 0x10
+  } ieee_802_11_mgt_frame;
+
+typedef struct {
+  u_char tag;
+  u_char length;
+  } ieee_802_11_tag;
+
+typedef enum {
+  tagSSID = 0,
+  tagRates = 1,
+  tagChannel = 3,
+  tagVendorSpecific = 0xDD
+  } i81tag;
+
+typedef struct prism_hdr {
+  u_int msg_code;
+  u_int msg_length;
+  char cap_device[16];
+  //char dids[0];
+  } prism_hdr;
+
+typedef struct prism_did {
+  u_short did;
+  u_short status1;
+  u_short status2;
+  u_short length;
+  //int value[0];
+  } prism_did;
+
+typedef enum prism_did_num {
+  pdn_host_time = 0x1041,
+  pdn_mac_time = 0x2041,
+  pdn_rssi = 0x4041,
+  pdn_sq = 0x5041,
+  pdn_datarate = 0x8041,
+  pdn_framelen = 0xa041
+  } prism_did_num;
+
+
+
+//Structure definitions for data collection
+
+typedef enum {
+  typeUnknown,
+  typeAP,
+  typeSta,
+  typeAdhocHub
+  } host_type;
+
+typedef enum {
+  ssUnknown,
+  ssUnassociated,
+  ssAssociated
+  } sta_state;
+
+typedef enum {
+  aetUnknown,
+  aetUnencrypted,
+  aetEncUnknown,
+  aetEncWEP,
+  aetEncWPA
+  } ap_enc_type;
+
+typedef struct {
+  u_char bssid[6];
+  char * ssid[32];
+  u_char ssidlen;
+  u_char channel;
+  u_short flags;
+  ap_enc_type encryption;
+  } ap_info;
+
+typedef struct {
+  sta_state state;
+  u_char connectedBSSID[6];
+  } sta_info;
+
+typedef struct {
+  u_char occupied;
+  u_char mac[6];
+  host_type type;
+  time_t lastSeen;
+  int RSSI;
+  ap_info * apInfo;
+  sta_info * staInfo;
+  } wiviz_host;
+
+//Primary config struct
+typedef struct {
+  wiviz_host hosts[MAX_HOSTS];
+  int numHosts;
+  int readFromWl;
+  time_t lastKeepAlive;
+  int channelHopping;
+  int channelDwellTime;
+  int channelHopSeq[14];
+  int channelHopSeqLen;
+  int curChannel;
+  int channelHopperPID;
+  } wiviz_cfg;
+
+
+
+
+
diff --git a/net/wiviz/src/wiviz.c b/net/wiviz/src/wiviz.c
new file mode 100644 (file)
index 0000000..d2ad9f2
--- /dev/null
@@ -0,0 +1,572 @@
+/*
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <stdio.h>
+#include <pcap.h>
+#include <signal.h>
+
+#define HOST_TIMEOUT 300
+
+#include "wl_access.h"
+#include "structs.h"
+#include "channelhopper.h"
+
+#ifdef WIN32
+#define OFFLINE
+#endif
+#ifndef __cplusplus
+#define __cdecl
+#endif
+
+#define nonzeromac(x) memcmp(x, "\0\0\0\0\0\0", 6)
+
+void dealWithPacket(wiviz_cfg * cfg, struct pcap_pkthdr * header, const u_char * packet);
+wiviz_host * gotHost(wiviz_cfg * cfg, u_char * mac, host_type type);
+void fprint_mac(FILE * outf, u_char * mac, char * extra);
+void print_mac(u_char * mac, char * extra);
+void print_host(FILE * outf, wiviz_host * host);
+void __cdecl signal_handler(int);
+void readWL(wiviz_cfg * cfg);
+void reloadConfig();
+
+wiviz_cfg * global_cfg;
+
+////////////////////////////////////////////////////////////////////////////////
+int main(int argc, char * * argv) {
+  pcap_t *handle;                        
+  char *dev;                                
+  char errbuf[PCAP_ERRBUF_SIZE]; 
+  int stop = 0;
+  int oldMonitor, newMonitor;
+  struct pcap_pkthdr header;          
+  const u_char *packet;                 
+  wiviz_cfg cfg;
+  int i;
+  int defaultHopSeq[] = { 1, 3, 6, 8, 11 };
+  
+  global_cfg = &cfg;
+  signal(SIGUSR1, &signal_handler);
+  signal(SIGUSR2, &signal_handler);
+
+  fprintf(stderr, "Wi-Viz infogathering daemon by Nathan True\n");
+  
+  memset(&cfg, 0, sizeof(wiviz_cfg));
+  cfg.numHosts = 0;
+  cfg.lastKeepAlive = time(NULL);
+  cfg.channelHopping = 0;
+  cfg.channelDwellTime = 1000;
+  cfg.channelHopSeqLen = 5;
+  memcpy(cfg.channelHopSeq, defaultHopSeq, sizeof(defaultHopSeq));
+
+  wl_ioctl(WL_DEVICE, WLC_GET_MAGIC, &i, 4);
+       if (i != WLC_IOCTL_MAGIC) {
+               fprintf(stderr, "Wireless magic not correct, not querying wl for info\n");
+               cfg.readFromWl = 0;
+       }
+       else {
+         cfg.readFromWl = 1;
+         wl_ioctl(WL_DEVICE, WLC_GET_MONITOR, &oldMonitor, 4);
+         newMonitor = 1;
+         wl_ioctl(WL_DEVICE, WLC_SET_MONITOR, &newMonitor, 4);
+       }
+
+  reloadConfig();
+
+#ifndef OFFLINE
+  dev = "prism0";
+  handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
+#else
+  dev = "c:\\cifsroot\\wdump2.pcap";
+  handle = pcap_open_offline(dev, errbuf);
+#endif
+
+       if (cfg.readFromWl) {
+         readWL(&cfg);
+       }
+
+  if (!handle) {
+    fprintf(stderr, "Failure to open pcap!\nErr=%s\n", errbuf);
+    return -1;
+    }
+  while (!stop) {
+    packet = pcap_next(handle, &header);
+    if (!packet) break;
+    dealWithPacket(&cfg, &header, packet);
+    if (time(NULL) - cfg.lastKeepAlive > 30) stop = 1;
+    }
+
+  signal_handler(SIGUSR1);
+
+  if (cfg.channelHopperPID) kill(cfg.channelHopperPID, SIGKILL);
+
+  for (i = 0; i < MAX_HOSTS; i++) {
+    print_host(stderr, cfg.hosts + i);
+    if (cfg.hosts[i].occupied) printf("\n");
+    if (cfg.hosts[i].apInfo) free(cfg.hosts[i].apInfo);
+    if (cfg.hosts[i].staInfo) free(cfg.hosts[i].staInfo);
+    }
+
+  wl_ioctl(WL_DEVICE, WLC_SET_MONITOR, &oldMonitor, 4);
+
+  pcap_close(handle);
+  return 0;
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+void writeJavascript() { 
+  int i;
+  FILE * outf;
+  wiviz_host * h;
+
+  outf = fopen("/tmp/wiviz-pipe", "w");
+  if (!outf) {
+    fprintf(stderr, "Failure to open output file\n");
+    return;
+    }
+
+  global_cfg->lastKeepAlive = time(NULL);
+  
+  if(global_cfg->readFromWl) readWL(global_cfg);
+  
+  fprintf(outf, "top.hosts = new Array(\n");
+  for (i = 0; i < MAX_HOSTS; i++) {
+    h = global_cfg->hosts + i;
+    if (h->occupied == 0) continue;
+    if (time(NULL) - h->lastSeen > HOST_TIMEOUT) {
+      h->occupied = 0;
+      }
+    fprintf(outf, "  new Array(");
+    print_host(outf, h);
+    fprintf(outf, "),\n");
+    }
+  fprintf(outf, "new Array());\n");
+  fprintf(outf, "var cfg_string = 'channel-");
+  if (global_cfg->channelHopping) {
+    fprintf(outf, "hopping");
+    }
+  else {
+    fprintf(outf, "%i", global_cfg->curChannel);
+    }
+  fprintf(outf, "';\ntop.wiviz_callback(top.hosts, cfg_string);\n");
+  fclose(outf);
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+void reloadConfig() {
+  FILE * cnf;
+  wiviz_cfg * cfg = global_cfg;
+  char filebuffer[512];
+  char * fbptr, * p, * v, * vv;
+  int fblen, val;
+  int hopCfgChanged = 0;
+  int newHopSeq[12];
+  int newHopSeqLen = 0;
+
+  fprintf(stderr, "Loading config file\n");
+
+  cnf = fopen("/tmp/wiviz-cfg", "r");
+  if (!cnf) {
+    fprintf(stderr, "Wiviz: No config file (/tmp/wiviz-cfg) present, using defaults\n");
+    return;
+    }
+
+  fblen = fread(filebuffer, 1, 512, cnf);
+  fclose(cnf);
+  if (fblen >= 512) {
+    fprintf(stderr, "Error reading config file\n");
+    return;
+    }
+  filebuffer[fblen] = 0;
+  fprintf(stderr, "Read %i bytes from config file\n", fblen);
+
+  fbptr = filebuffer;
+
+  while (fbptr < filebuffer + fblen && *fbptr != 0) {
+    p = fbptr;
+    //Find end of parameter
+    for (; *fbptr != '=' && *fbptr != 0; fbptr++);
+    *fbptr = 0;
+    v = ++fbptr;
+    //Find end of value
+    for (; *fbptr != '&' && *fbptr != 0; fbptr++);
+    *(fbptr++) = 0;
+    fprintf(stderr, "Config: %s=%s\n", p, v);
+    //Apply configuration
+    if (!strcmp(p, "channelsel")) {
+      //Channel selector
+      cfg->channelHopping = 0;
+      if (!strcmp(v, "hop")) {
+        //Set channel hopping
+        cfg->channelHopping = 1;
+        hopCfgChanged = 1;
+        }
+      else if (!strcmp(v, "nochange")) {
+        //Don't change anything, read channel from wireless card
+        readWL(cfg);
+        }
+      else {
+        val = atoi(v);
+        if (val < 1 || val > 14) {
+          fprintf(stderr, "Channel setting in config file invalid (%i)\n", cfg->curChannel);
+        }
+        else {
+          cfg->curChannel = val;
+          if (cfg->readFromWl) {
+            if (wl_ioctl(WL_DEVICE, WLC_SET_CHANNEL, &cfg->curChannel, 4) < 0) {
+              fprintf(stderr, "Channel set to %i failed\n", cfg->curChannel);
+              }
+            }
+          else {
+            fprintf(stderr, "Can't set channel, no Broadcom wireless device present\n");
+            }
+          }
+        }
+      }
+    if (!strcmp(p, "hopdwell")) {
+      val = atoi(v);
+      if (val < 100) val = 100;
+      if (val > 30000) val = 30000;
+      if (cfg->channelDwellTime != val) hopCfgChanged = 1;
+      cfg->channelDwellTime = val;
+      }
+    if (!strcmp(p, "hopseq")) {
+      cfg->channelHopSeqLen = 0;
+      while (v < fbptr) {
+        for (vv = v; *vv != ',' && *vv != 0; vv++);
+        if (*vv == 0) {
+          cfg->channelHopSeq[cfg->channelHopSeqLen++] = atoi(v);
+          break;          
+          }
+        *vv = 0;
+        cfg->channelHopSeq[cfg->channelHopSeqLen++] = atoi(v);
+        v = vv + 1;
+        }
+      }
+    /*
+    if (!strcmp(p, "")) {
+      }
+    */
+    }
+  //Apply channel hopper settings
+  if (cfg->channelHopping == 0 && cfg->channelHopperPID) {
+    kill(cfg->channelHopperPID, SIGKILL);
+    cfg->channelHopperPID = 0;
+    }
+  if (cfg->channelHopping == 1 && hopCfgChanged) {
+    if (cfg->channelHopperPID) kill(cfg->channelHopperPID, SIGKILL);
+    if ((cfg->channelHopperPID = fork()) == 0) {
+      channelHopper(cfg);
+      }
+    }
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+void __cdecl signal_handler(int signum) {
+  if (signum == SIGUSR1) writeJavascript();
+  if (signum == SIGUSR2) reloadConfig();
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+void dealWithPacket(wiviz_cfg * cfg, struct pcap_pkthdr * header, const u_char * packet) {
+  ieee802_11_hdr * hWifi;
+  prism_hdr * hPrism;
+  wiviz_host * host;
+  wiviz_host * emergebss;
+  host_type type = typeUnknown;
+  int wfType;
+  int rssi = 0;
+  int to_ds, from_ds;
+  prism_did * i;
+  ieee_802_11_tag * e;
+  ieee_802_11_mgt_frame * m;
+  char * src = "\0\0\0\0\0\0";
+  char * dst = "\0\0\0\0\0\0";
+  char * bss = "\0\0\0\0\0\0";
+  char * ssid = "";
+  int channel = 0;
+  int adhocbeacon = 0;
+  u_char ssidlen = 0;
+  ap_enc_type encType = aetUnknown;
+
+  if (!packet) return;
+  if (header->len < sizeof(prism_hdr) + sizeof(ieee802_11_hdr)) return;
+  hPrism = (prism_hdr *) packet;
+  hWifi = (ieee802_11_hdr *) (packet + (hPrism->msg_length));
+
+  //Parse the prism DIDs
+  i = (prism_did *)((char *)hPrism + sizeof(prism_hdr));
+  while ((int)i < (int)hWifi) {
+    if (i->did == pdn_rssi) rssi = *(int *)(i+1);
+    i = (prism_did *) ((int)(i+1) + i->length);
+    }
+
+  //Establish the frame type
+  wfType = ((hWifi->frame_control & 0xF0) >> 4) + ((hWifi->frame_control & 0xC) << 2);
+  switch (wfType) {
+    case mgt_assocRequest:
+    case mgt_reassocRequest:
+    case mgt_probeRequest:
+      type = typeSta;
+      src=hWifi->addr2;
+      dst=hWifi->addr1;
+      break;
+    case mgt_assocResponse:
+    case mgt_reassocResponse:
+    case mgt_probeResponse:
+    case mgt_beacon:
+      src=hWifi->addr2;
+      dst=hWifi->addr1;
+      bss=hWifi->addr3;
+      type = typeAP;
+      break;
+    }
+  to_ds = hWifi->flags & IEEE80211_TO_DS;
+  from_ds = hWifi->flags & IEEE80211_FROM_DS;
+  if ((wfType & 0xF0) == 0x20 && (wfType & 0xF) < 4) {
+    //Data frame
+    src=hWifi->addr2;
+    dst=hWifi->addr1;
+    if (!from_ds) type = typeSta;
+      else type = typeAP;
+    if (!to_ds && !from_ds) bss = hWifi->addr3;
+    if (to_ds && !from_ds) bss = hWifi->addr1;
+    if (!to_ds && from_ds) bss = hWifi->addr2;
+    }
+  if (type == typeUnknown) return;
+
+  //Parse the 802.11 tags
+  if (wfType == mgt_probeResponse || wfType == mgt_beacon) {
+    m = (ieee_802_11_mgt_frame *) (hWifi + 1);
+    if (m->caps & MGT_CAPS_IBSS) {
+      type = typeSta;
+      adhocbeacon = 1;
+      }
+    if (m->caps & MGT_CAPS_WEP) encType = aetEncWEP;
+    else encType = aetUnencrypted;
+    e = (ieee_802_11_tag *) ((int) m + sizeof(ieee_802_11_mgt_frame));
+    while ((u_int)e < (u_int)packet + header->len) {
+      if (e->tag == tagSSID) {
+        ssidlen = e->length;
+        ssid = (char *)(e + 1);
+        }
+      if (e->tag == tagChannel) {
+        channel = *(char *)(e + 1);
+        }
+      if (e->tag == tagVendorSpecific) {
+        if (e->length >= 4 && memcmp(e + 1, "\x00\x50\xf2\x01", 4) == 0) {
+          //WPA encryption
+          encType = aetEncWPA;
+          }
+        }
+      e = (ieee_802_11_tag *) ((int)(e + 1) + e->length);
+      }
+    }
+  
+  //Look up the host in the hash table
+  host = gotHost(cfg, src, type);
+
+  //Add any info we received
+  if (host->RSSI) {
+    host->RSSI = host->RSSI * 9 / 10 + (-rssi * 10);
+    }
+  else {
+    host->RSSI = -rssi * 100;
+    }
+  if (type == typeSta) {
+    if (nonzeromac(bss)) {
+      memcpy(host->staInfo->connectedBSSID, bss, 6);
+      host->staInfo->state = ssAssociated;
+      emergebss = gotHost(cfg, bss, typeAP);
+      if (emergebss->RSSI == 0) emergebss->RSSI = 10000;
+      memcpy(emergebss->apInfo->bssid, bss, 6);
+      if (adhocbeacon) {
+        emergebss->type = typeAdhocHub;
+        if (ssidlen > 0 && ssidlen <= 32) {
+          memcpy(emergebss->apInfo->ssid, ssid, ssidlen);
+          emergebss->apInfo->ssidlen = ssidlen;
+          }
+        if (channel) emergebss->apInfo->channel = channel;
+        emergebss->apInfo->flags = hWifi->flags;
+        emergebss->RSSI = host->RSSI;
+        if (encType != aetUnknown) emergebss->apInfo->encryption = encType;
+        }
+      }
+    if (wfType == mgt_probeRequest && host->staInfo->state == ssUnknown) host->staInfo->state = ssUnassociated;
+    }
+  if (type == typeAP) {
+    if (nonzeromac(bss)) {
+      memcpy(host->apInfo->bssid, bss, 6);
+      }
+    if (ssidlen > 0 && ssidlen <= 32) {
+      memcpy(host->apInfo->ssid, ssid, ssidlen);
+      host->apInfo->ssidlen = ssidlen;
+      }
+    if (channel) host->apInfo->channel = channel;
+    host->apInfo->flags = hWifi->flags;
+    if (encType != aetUnknown) host->apInfo->encryption = encType;
+    }
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+void print_mac(u_char * mac, char * extra) {
+  fprint_mac(stdout, mac, extra);
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+void fprint_mac(FILE * outf, u_char * mac, char * extra) {
+  fprintf(outf, "%02X:%02X:%02X:%02X:%02X:%02X%s",
+      mac[0] & 0xFF,
+      mac[1] & 0xFF,
+      mac[2] & 0xFF,
+      mac[3] & 0xFF,
+      mac[4] & 0xFF,
+      mac[5] & 0xFF,
+      extra);
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+#define MAX_PROBES MAX_HOSTS/2
+wiviz_host * gotHost(wiviz_cfg * cfg, u_char * mac, host_type type) {
+  int i = (mac[5] + (mac[4] << 8)) % MAX_HOSTS;
+  int c = 0;
+  wiviz_host * h = cfg->hosts + i;
+  while (h->occupied && memcmp(h->mac, mac, 6)) {
+    i++; h++; c++;
+    if (i >= MAX_HOSTS) {
+      i = 0;
+      h = cfg->hosts;
+      }
+    if (c > MAX_PROBES) break;
+    } 
+  if (!h->occupied) {
+    fprintf(stderr, "New host, ");
+    fprint_mac(stderr, mac, ", type=");
+    fprintf(stderr, "%s\n", (type==typeAP) ? "AP" : ((type==typeSta) ? "Sta" : "Unk"));
+    }
+  h->occupied = 1;
+  h->lastSeen = time(NULL);
+  h->type = type;
+  memcpy(h->mac, mac, 6);
+  if (h->type == typeAP && !h->apInfo) {
+    h->apInfo = (ap_info *) malloc(sizeof(ap_info));
+    memset(h->apInfo, 0, sizeof(ap_info));
+    }
+  if (h->type == typeSta && !h->staInfo) {
+    h->staInfo = (sta_info *) malloc(sizeof(sta_info));
+    memset(h->staInfo, 0, sizeof(sta_info));
+    }
+  return h;
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+void print_host(FILE * outf, wiviz_host * host) {
+  int i;
+
+  if (!host->occupied) return;
+  fprintf(outf, "'");
+  fprint_mac(outf, host->mac, "'");
+  fprintf(outf, ", -%i, '", host->RSSI / 100);
+  switch (host->type) {
+    case typeAP:  fprintf(outf, "ap"); break;
+    case typeSta: fprintf(outf, "sta"); break;
+    case typeAdhocHub: fprintf(outf, "adhoc"); break;
+    }
+  if (host->type == typeSta) {
+    switch(host->staInfo->state) {
+      case ssAssociated:
+        fprintf(outf, "-assoc-");
+        fprint_mac(outf, host->staInfo->connectedBSSID, "");
+        break;
+      case ssUnassociated:
+        fprintf(outf, "-unassoc");
+      }
+    }
+  if (host->type == typeAP || host->type == typeAdhocHub) {
+    fprintf(outf, "-channel-%i-ssid-", host->apInfo->channel & 0xFF);
+    for (i = 0; i < host->apInfo->ssidlen; i++) {
+      fprintf(outf, "\\x%02X", *((char *)host->apInfo->ssid + i) & 0xFF);
+       }
+    switch (host->apInfo->encryption) {
+      case aetUnknown: fprintf(outf, "-?enc-?alg"); break;
+      case aetUnencrypted: fprintf(outf, "-unenc-na"); break;
+      case aetEncUnknown: fprintf(outf, "-enc-unknown"); break;
+      case aetEncWEP: fprintf(outf, "-enc-wep"); break;
+      case aetEncWPA: fprintf(outf, "-enc-wpa"); break;
+      }
+    }
+  fprintf(outf, "', %i", time(0) - host->lastSeen);
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+#define MAX_STA_COUNT 64
+void readWL(wiviz_cfg * cfg) {
+       int ap, i;
+       wiviz_host * host, * sta;
+       uchar mac[6];
+       wlc_ssid_t ssid; 
+       channel_info_t channel;
+       maclist_t * macs;
+  sta_rssi_t starssi;
+       
+       get_mac(WL_DEVICE, mac);
+       printf("AP mac: ");
+       print_mac(mac, "\n");
+       if (!nonzeromac(mac)) return;
+       wl_ioctl(WL_DEVICE, WLC_GET_AP, &ap, 4);
+       if (ap) {
+               host = gotHost(cfg, mac, typeAP);
+               wl_ioctl(WL_DEVICE, WLC_GET_BSSID, host->apInfo->bssid, 6);
+               wl_ioctl(WL_DEVICE, WLC_GET_SSID, &ssid, sizeof(wlc_ssid_t));
+               memcpy(host->apInfo->ssid, ssid.SSID, 32);
+               host->apInfo->ssidlen = ssid.SSID_len;
+               host->RSSI = 0;
+               wl_ioctl(WL_DEVICE, WLC_GET_CHANNEL, &channel, sizeof(channel_info_t));
+               host->apInfo->channel = channel.hw_channel;
+               macs = (maclist_t *) malloc(4 + MAX_STA_COUNT * sizeof(ether_addr_t));
+               macs->count = MAX_STA_COUNT;
+               if (wl_ioctl(WL_DEVICE, WLC_GET_ASSOCLIST, macs, 4 + MAX_STA_COUNT * sizeof(ether_addr_t)) > -1) {
+                       for (i = 0; i < macs->count; i++) {
+                         sta = gotHost(cfg, (char *)&macs->ea[i], typeSta);
+        memcpy(starssi.mac, &macs->ea[i], 6);
+        starssi.RSSI = 3000;
+        starssi.zero_ex_forty_one = 0x41;
+                               if (wl_ioctl(WL_DEVICE, WLC_GET_RSSI, &starssi, 12) < 0) printf("rssifail\n");
+                               sta->RSSI = -starssi.RSSI * 100;
+                               sta->staInfo->state = ssAssociated;
+                               memcpy(sta->staInfo->connectedBSSID, host->apInfo->bssid, 6);
+                       }
+               }
+       }
+       else {
+               host = gotHost(cfg, mac, typeSta);
+               host->RSSI = 0;
+               if (wl_ioctl(WL_DEVICE, WLC_GET_BSSID, &host->staInfo->connectedBSSID, 6) < 0) {
+                 host->staInfo->state = ssUnassociated;
+               }
+               else {
+                 host->staInfo->state = ssAssociated;
+               }
+       }
+  if (wl_ioctl(WL_DEVICE, WLC_GET_CHANNEL, &channel, sizeof(channel_info_t)) >= 0) {
+    cfg->curChannel = channel.hw_channel;
+    fprintf(stderr, "Current channel is %i\n", cfg->curChannel);
+    }
+}
+
+
+
+
+
diff --git a/net/wiviz/src/wl_access.c b/net/wiviz/src/wl_access.c
new file mode 100644 (file)
index 0000000..a5172c3
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#include "wl_access.h"
+
+int wl_ioctl(char *name, int cmd, void *buf, int len)
+{
+       struct ifreq ifr;
+       wl_ioctl_t ioc;
+       int ret = 0;
+       int s;
+
+       /* open socket to kernel */
+       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               perror("socket");
+               return errno;
+       }
+
+       /* do it */
+       ioc.cmd = cmd;
+       ioc.buf = buf;
+       ioc.len = len;
+       strncpy(ifr.ifr_name, name, IFNAMSIZ);
+       ifr.ifr_data = (caddr_t) &ioc;
+       ret = ioctl(s, SIOCDEVPRIVATE, &ifr);
+
+       /* cleanup */
+       close(s);
+       return ret;
+}
+
+int get_mac(char *name, void *buf)
+{
+       struct ifreq ifr;
+       int ret = 0;
+       int s;
+
+       /* open socket to kernel */
+       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               perror("socket");
+               return errno;
+       }
+
+       strncpy(ifr.ifr_name, name, IFNAMSIZ);
+       //ifr.ifr_data = (caddr_t) buf;
+       if ((ret = ioctl(s, SIOCGIFHWADDR, &ifr)) < 0)
+                       perror(ifr.ifr_name);
+
+       /* cleanup */
+       close(s);
+       memcpy(buf, &ifr.ifr_hwaddr.sa_data, 6);
+       return ret;
+}
diff --git a/net/wiviz/src/wl_access.h b/net/wiviz/src/wl_access.h
new file mode 100644 (file)
index 0000000..96f239d
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+This file is part of Wi-viz (http://wiviz.natetrue.com).
+
+Wi-viz is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License v2 as published by
+the Free Software Foundation.
+
+Wi-viz 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.
+
+You should have received a copy of the GNU General Public License
+along with Wi-viz; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+//wl_access.h - functions for accessing broadcom crap
+
+#define WL_DEVICE "eth1"
+
+typedef unsigned int uint32;
+typedef unsigned char uchar;
+typedef int bool;
+
+typedef struct ether_addr {
+       uchar addr[6];
+} ether_addr_t;
+
+typedef struct wlc_ssid {
+       uint32          SSID_len;
+       uchar           SSID[32];
+} wlc_ssid_t;
+/* For ioctls that take a list of MAC addresses */
+typedef struct maclist {
+       uint count;                     /* number of MAC addresses */
+       struct ether_addr ea[1];        /* variable length array of MAC addresses */
+} maclist_t;
+/* Linux network driver ioctl encoding */
+typedef struct wl_ioctl {
+       uint cmd;       /* common ioctl definition */
+       void *buf;      /* pointer to user buffer */
+       uint len;       /* length of user buffer */
+       bool set;       /* get or set request (optional) */
+       uint used;      /* bytes read or written (optional) */
+       uint needed;    /* bytes needed (optional) */
+} wl_ioctl_t;
+/* channel encoding */
+typedef struct channel_info {
+       int hw_channel;
+       int target_channel;
+       int scan_channel;
+} channel_info_t;
+/* RSSI info for sta */
+typedef struct sta_rssi {
+  int RSSI;
+  char mac[6];
+  u_short zero_ex_forty_one;
+  } sta_rssi_t;
+/* check this magic number */
+#define WLC_IOCTL_MAGIC                0x14e46c77
+
+#define WLC_GET_MAGIC                          0
+#define WLC_GET_BSSID                          23
+#define WLC_SET_BSSID                          24
+#define WLC_GET_SSID                           25
+#define WLC_SET_SSID                           26
+#define WLC_GET_CHANNEL                                29
+#define WLC_SET_CHANNEL                                30
+#define WLC_GET_MONITOR                                107     /* discovered by nbd */
+#define WLC_SET_MONITOR                                108     /* discovered by nbd */
+#define WLC_GET_AP                             117
+#define WLC_SET_AP                             118
+#define WLC_GET_RSSI                           127
+#define WLC_GET_ASSOCLIST                      159
+
+
+int wl_ioctl(char *name, int cmd, void *buf, int len);