2 This file is part of Wi-viz (http://wiviz.natetrue.com).
4 Wi-viz is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License v2 as published by
6 the Free Software Foundation.
8 Wi-viz is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with Wi-viz; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 var stupid = eval('window.attachEvent') ? 1 : 0;
20 var idle_timeout = 20;
21 var erase_timeout = 35;
22 var skew_x = 0; skew_y = 0;
24 var wiviz_cgi_url = "/cgi-bin/wiviz/get.cgi";
26 //What? You mean the POSIX thread API hasn't been ported to Javascript? Bugger.
27 function scan_thread() {
28 var loc = document.getElementById('wivizGetFrame').contentWindow.location;
29 if (!listening) return;
30 if (loc.href != wiviz_cgi_url) {
31 loc.replace(wiviz_cgi_url);
36 setTimeout("scan_thread()", 5000);
39 function toggleListen() {
40 statusel = document.getElementById('status');
41 statusbutton = document.getElementById('togglelisten');
42 listening = 1 - listening;
44 statusel.innerHTML = "Monitoring";
45 statusbutton.value = "Stop monitoring";
46 document.getElementById('content').innerHTML = '';
50 statusel.innerHTML = "Stopped";
51 statusbutton.value = "Start monitoring";
55 function channelSet() {
56 channelset = document.getElementById('channelsel').value;
57 if (channelset == 'hop') {
58 document.getElementById('hopoptions').style.display = 'inline';
61 document.getElementById('hopoptions').style.display = 'none';
62 if (channelset != 'nochange') document.forms[0].submit();
66 function mousenter(e) {
67 if (stupid) e = event;
68 el = stupid ? e.srcElement : e.currentTarget;
69 el.parentNode.parentNode.className = 'hostdiv_hov';
70 el.nextSibling.nextSibling.nextSibling.style.visibility = 'visible';
73 function mouseout(e) {
74 if (stupid) e = event;
75 el = stupid ? e.srcElement : e.currentTarget;
76 el.parentNode.parentNode.className = 'hostdiv';
77 el.nextSibling.nextSibling.nextSibling.style.visibility = 'hidden';
80 function generate_mnemonic(hash) {
81 c = new Array('b','c','d','f','g','h','j','k','l','m','n','p','qu','r','s',
82 't','v','w','y','z','th','ch','sh','cc','rr');
83 v = new Array('a','e','i','o','u','ae','ai','ao','au','eo','ei','eu','iu','oa','oe');
87 for (i = 0; i < 4; i++) {
89 n += a[hash % a.length];
90 hash += a.length << 3 + a.length / 2;
97 function mkhash(mac) {
98 var macarr = mac.split(/:/);
100 for (j = 0; j < 6; j++) {
101 hash += parseInt(macarr[j]) * j << j;
104 if (hash < 0) hash = -hash;
108 function wiviz_callback(mhosts, cfgstring) {
111 for (i = 0; i < hosts.length; i++) {
113 if (hs.length == 0) break;
117 hs.descarr = hs.desc.split(/-/)
119 hs.hash = mkhash(hs.mac);
120 hs.mnem = generate_mnemonic(hs.hash)
122 el = document.getElementById(hs.mnem);
124 if (hs.age > erase_timeout) {
125 el.parentNode.removeChild(el);
128 el.innerHTML = genHTML(hs);
131 if (hs.age > erase_timeout) continue;
132 hs.x = Math.sin(hs.hash / mv) * hs.rssi * 2 - 67;
133 hs.y = Math.cos(hs.hash / mv) * hs.rssi * 2;
134 nh += "<div class='hostdiv' id='" + hs.mnem + "' style='top: ";
135 nh += parseInt(hs.y) + "px; left: " + parseInt(hs.x) + "px'>";
136 nh += genHTML(hs) + "</div>";
139 document.getElementById('content').innerHTML += nh;
141 cfgarr = cfgstring.split(/-/);
143 if (cfgarr[1] == 'hopping') cfgarr[1] = 'hop';
144 document.getElementById('channelsel').value = cfgarr[1];
145 if (cfgarr[1] == 'hop') channelSet();
149 setTimeout("declump(); repip();", 250);
155 for (i = 0; i < hosts.length; i++) {
157 if (hs.length == 0) break;
160 desc = hs[2].split(/-/);
161 if (desc[0] == 'sta' && desc[1] == 'assoc') {
163 hs.apmnem = generate_mnemonic(mkhash(bss));
164 ap = document.getElementById(hs.apmnem);
165 sta = document.getElementById(hs.mnem);
167 x = parseInt(sta.style.left);
168 y = parseInt(sta.style.top);
169 dx = parseInt(ap.style.left) - x;
170 dy = parseInt(ap.style.top) - y;
173 d = Math.sqrt(dx*dx+dy*dy);
174 for (j = 0; j < d; j += 15) {
176 + ((hs.age < idle_timeout) ? "pip" : "pip-idle")
177 + (stupid ? ".gif" : ".png")
178 + "' class='pip' style='top:"
179 + parseInt(y+dy * j / d) + "; left:"
180 + parseInt(x+dx * j / d) + "'>";
185 document.getElementById('pips').innerHTML = nh;
190 var top = 30000,left = 30000,right = -30000,bottom = -30000;
191 for (i = 0; i < hosts.length; i++) {
192 for (j = 0; j < hosts.length; j++) {
193 if (i == j) continue;
194 e1 = document.getElementById(hosts[i].mnem);
195 e2 = document.getElementById(hosts[j].mnem);
196 if (!e1 || !e2) continue;
197 x1 = parseInt(e1.style.left);
198 x2 = parseInt(e2.style.left);
199 y1 = parseInt(e1.style.top);
200 y2 = parseInt(e2.style.top);
201 if (x1 < left) left = x1;
202 if (y1 < top) top = y1;
203 if (x1 > right) right = x1;
204 if (y1 > bottom) bottom = y1;
207 dist = Math.sqrt(Math.pow((x1-x2), 2) + Math.pow((y1-y2), 2));
209 x2 += Math.random() * 5;
210 y2 += Math.random() * 5;
214 cx = (x1-x2) * 5 / (dist / 3);
215 cy = (y1-y2) * 5 / (dist / 3);
219 if (hosts[j].apmnem == hosts[i].mnem
220 || hosts[i].apmnem == hosts[j].mnem) {
221 cx = (x1-x2) * 5 / (dist / 3);
222 cy = (y1-y2) * 5 / (dist / 3);
228 if (Math.abs(ox-x2) > 2 || Math.abs(oy-y2) > 2) {
229 e2.style.left = parseInt(x2);
230 e2.style.top = parseInt(y2);
235 if (top < bottom && left < right) {
236 document.getElementById('debug').innerHTML = left + "," + right + "," + top + "," +bottom;
237 document.getElementById('content').style.left =
238 document.getElementById('pips').style.left =
239 -(right - left) / 2 - left - 67;
240 document.getElementById('content').style.top =
241 document.getElementById('pips').style.top =
242 -(bottom - top) / 2 - top - 25;
245 if (c) setTimeout("declump()", 100);
248 function genHTML(hs) {
250 nh += "<center><img class='icon' src='"
252 if (a[0] == 'ap' || a[0] == 'adhoc') {
255 if (a[5] == 'enc') nh += "-wep";
263 else if (a[0] == 'sta') {
267 nh += (hs.age < idle_timeout) ? "": "-idle";
268 nh += stupid ? ".gif" : ".png";
269 nh += "' onmouseover='mousenter(event)' onmouseout='mouseout(event)'"
270 + "><br><span class='hostdesc'>" + hs.mac + "<br><i>'" + hs.name;
273 nh += " ch" + hs.channel;
275 nh += "</span><span class='extrafo'><br>";
276 if (a[0] == 'ap') nh += "Access point";
277 if (a[0] == 'sta') nh += "Station";
278 if (a[0] == 'adhoc') nh += "Logical ad-hoc entity";
279 if (a[0] == 'ap' || a[0] == 'adhoc') {
281 if (a[5] == '?enc') nh += "Encryption unknown";
282 if (a[5] == 'enc') nh += "Encrypted";
283 if (a[5] == 'unenc') nh += "Unencrypted";
284 if (a[6] == 'wep') nh += "-WEP";
285 if (a[6] == 'wpa') nh += "-WPA";
287 nh += "<br>RSSI: " + hs.rssi + " dBm<br>"
288 + "Seen " + hs.age + " seconds ago<br>";
289 nh += "</span></center>";