add Wi-viz
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@1785 3c298f89-4303-0410-b956-a3cf2f4a3e73
@ -108,6 +108,7 @@ source "package/wpa_supplicant/Config.in"
|
|||||||
source "package/wput/Config.in"
|
source "package/wput/Config.in"
|
||||||
source "package/xinetd/Config.in"
|
source "package/xinetd/Config.in"
|
||||||
source "package/wificonf/Config.in"
|
source "package/wificonf/Config.in"
|
||||||
|
source "package/wiviz/Config.in"
|
||||||
|
|
||||||
comment "Libraries"
|
comment "Libraries"
|
||||||
source "package/cgilib/Config.in"
|
source "package/cgilib/Config.in"
|
||||||
|
@ -157,6 +157,7 @@ package-$(BR2_PACKAGE_USBUTILS) += usbutils
|
|||||||
package-$(BR2_PACKAGE_VTUN) += vtun
|
package-$(BR2_PACKAGE_VTUN) += vtun
|
||||||
package-$(BR2_PACKAGE_VSFTPD) += vsftpd
|
package-$(BR2_PACKAGE_VSFTPD) += vsftpd
|
||||||
package-$(BR2_PACKAGE_WIFICONF) += wificonf
|
package-$(BR2_PACKAGE_WIFICONF) += wificonf
|
||||||
|
package-$(BR2_PACKAGE_WIVIZ) += wiviz
|
||||||
package-$(BR2_PACKAGE_WIRELESS_TOOLS) += wireless-tools
|
package-$(BR2_PACKAGE_WIRELESS_TOOLS) += wireless-tools
|
||||||
package-$(BR2_PACKAGE_WOL) += wol
|
package-$(BR2_PACKAGE_WOL) += wol
|
||||||
package-$(BR2_PACKAGE_WPA_SUPPLICANT) += wpa_supplicant
|
package-$(BR2_PACKAGE_WPA_SUPPLICANT) += wpa_supplicant
|
||||||
|
7
package/wiviz/Config.in
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
config BR2_PACKAGE_WIVIZ
|
||||||
|
tristate "wiviz - Wireless Network Visualization"
|
||||||
|
default m if CONFIG_DEVEL
|
||||||
|
help
|
||||||
|
Wireless Network Visualization
|
||||||
|
|
||||||
|
http://students.washington.edu/natetrue/wiviz/
|
42
package/wiviz/Makefile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# $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 $(TOPDIR)/package/rules.mk
|
||||||
|
|
||||||
|
$(eval $(call PKG_template,WIVIZ,wiviz,$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
|
||||||
|
|
||||||
|
$(PKG_BUILD_DIR)/.prepared:
|
||||||
|
mkdir -p $(PKG_BUILD_DIR)
|
||||||
|
cp -fpR ./src/* $(PKG_BUILD_DIR)/
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(PKG_BUILD_DIR)/.configured:
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(PKG_BUILD_DIR)/.built:
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||||
|
CC="$(TARGET_CC)" \
|
||||||
|
COPTS="$(TARGET_CFLAGS)" \
|
||||||
|
INCLUDE="-I$(STAGING_DIR)/include -I$(STAGING_DIR)/usr/include" \
|
||||||
|
LDFLAGS="-L$(STAGING_DIR)/lib -L$(STAGING_DIR)/usr/lib"
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
$(IPKG_WIVIZ):
|
||||||
|
mkdir -p $(IDIR_WIVIZ)/usr/sbin
|
||||||
|
cp $(PKG_BUILD_DIR)/$(PKG_NAME) $(IDIR_WIVIZ)/usr/sbin/
|
||||||
|
$(RSTRIP) $(IDIR_WIVIZ)
|
||||||
|
cp -fpR ./files/* $(IDIR_WIVIZ)
|
||||||
|
find $(IDIR_WIVIZ) -name CVS | xargs rm -rf
|
||||||
|
find $(IDIR_WIVIZ) -name .svn | xargs rm -rf
|
||||||
|
$(IPKG_BUILD) $(IDIR_WIVIZ) $(PACKAGE_DIR)
|
||||||
|
|
||||||
|
mostlyclean:
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) clean
|
||||||
|
rm -f $(PKG_BUILD_DIR)/.built
|
15
package/wiviz/files/www/cgi-bin/wiviz/get.cgi
Executable file
@ -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>"
|
3
package/wiviz/files/www/cgi-bin/wiviz/set.cgi
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
httpd -d $QUERY_STRING > /tmp/wiviz-cfg
|
||||||
|
killall -USR2 wiviz
|
BIN
package/wiviz/files/www/wiviz/adhoc-idle.gif
Executable file
After Width: | Height: | Size: 332 B |
BIN
package/wiviz/files/www/wiviz/adhoc-idle.png
Executable file
BIN
package/wiviz/files/www/wiviz/adhoc.gif
Executable file
After Width: | Height: | Size: 451 B |
BIN
package/wiviz/files/www/wiviz/adhoc.png
Executable file
BIN
package/wiviz/files/www/wiviz/ap-idle.gif
Executable file
After Width: | Height: | Size: 812 B |
BIN
package/wiviz/files/www/wiviz/ap-idle.png
Executable file
BIN
package/wiviz/files/www/wiviz/ap-wep-idle.gif
Executable file
After Width: | Height: | Size: 812 B |
BIN
package/wiviz/files/www/wiviz/ap-wep-idle.png
Executable file
BIN
package/wiviz/files/www/wiviz/ap-wep.gif
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
package/wiviz/files/www/wiviz/ap-wep.png
Executable file
BIN
package/wiviz/files/www/wiviz/ap.gif
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
package/wiviz/files/www/wiviz/ap.png
Executable file
BIN
package/wiviz/files/www/wiviz/pip-idle.gif
Executable file
After Width: | Height: | Size: 190 B |
BIN
package/wiviz/files/www/wiviz/pip-idle.png
Executable file
BIN
package/wiviz/files/www/wiviz/pip.gif
Executable file
After Width: | Height: | Size: 190 B |
BIN
package/wiviz/files/www/wiviz/pip.png
Executable file
BIN
package/wiviz/files/www/wiviz/station-idle.gif
Executable file
After Width: | Height: | Size: 754 B |
BIN
package/wiviz/files/www/wiviz/station-idle.png
Executable file
BIN
package/wiviz/files/www/wiviz/station.gif
Executable file
After Width: | Height: | Size: 929 B |
BIN
package/wiviz/files/www/wiviz/station.png
Executable file
76
package/wiviz/files/www/wiviz/wiviz.css
Executable file
@ -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;
|
||||||
|
}
|
81
package/wiviz/files/www/wiviz/wiviz.html
Executable file
@ -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>
|
291
package/wiviz/files/www/wiviz/wiviz.js
Executable file
@ -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;
|
||||||
|
}
|
7
package/wiviz/ipkg/wiviz.control
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Package: wiviz
|
||||||
|
Priority: optional
|
||||||
|
Section: net
|
||||||
|
Maintainer: Felix Fietkau <openwrt@nbd.name>
|
||||||
|
Source: buildroot internal
|
||||||
|
Depends: libpcap
|
||||||
|
Description: Wireless Network Visualization
|
25
package/wiviz/src/Makefile
Normal file
@ -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
|
48
package/wiviz/src/channelhopper.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
19
package/wiviz/src/channelhopper.h
Normal file
@ -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();
|
169
package/wiviz/src/structs.h
Normal file
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
572
package/wiviz/src/wiviz.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
73
package/wiviz/src/wl_access.c
Normal file
@ -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;
|
||||||
|
}
|
77
package/wiviz/src/wl_access.h
Normal file
@ -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);
|