netsh added

This commit is contained in:
Christian Kuster 2016-04-04 20:16:11 +02:00
parent 1fa96c3ed7
commit 7153b41460
3 changed files with 200 additions and 4 deletions

View File

@ -1,3 +1,90 @@
/**
* Scanning WiFis on Windows
* Created by kc on 04.04.16.
*/
const systemRoot = process.env.SystemRoot || 'C:\\Windows';
const tool = systemRoot + '\\System32\\netsh.exe';
const cmdLine = tool + ' wlan show networks mode=Bssid';
/**
* Parsing netnsh output. Unfortunately netsh supplies the network information
* in the language of the operating system. Translating the terms into every
* language supplied is not possible, therefore this implementation follows
* an approach of analyzing the structure of the output
*/
function parseOutput(str, callback) {
var blocks = str.split('\n\n');
var wifis = [];
var err = null;
try {
if (!blocks || blocks.length === 1) {
// No WiFis found
return [];
}
// Each block has the same structure, while some parts might be available and others
// not. A sample structure:
// SSID 1 : AP-Test1
// Network type : Infrastructure
// Authentication : WPA2-Personal
// Encryption : CCMP
// BSSID 1 : 00:aa:f2:77:a5:53
// Signal : 46%
// Radio type : 802.11n
// Channel : 6
// Basic rates (MBit/s) : 1 2 5.5 11
// Other rates (MBit/s) : 6 9 12 18 24 36 48 54
for (var i = 1, l = blocks.length; i < l; i++) {
var network = {};
var lines = blocks[i].split('\n');
var regexChannel = /[a-zA-Z0-9()\s]+:[\s]*[0-9]+$/g;
if (!lines || lines.length < 2) {
continue;
}
// First line is always the SSID (which can be empty)
var ssid = lines[0].substring(lines[0].indexOf(':') + 1).trim();
for (var t = 1, n = lines.length; t < n; t++) {
if (lines[t].split(':').length === 7) {
// This is the mac address, use this one as trigger for a new network
if (network.mac) {
wifis.push(network);
}
network = {
ssid: ssid,
mac : lines[t].substring(lines[t].indexOf(':') + 1).trim()
};
}
else if (lines[t].indexOf('%') > 0) {
// Network signal strength, identified by '%'
var level = parseInt(lines[t].split(':')[1].split('%')[0].trim(), 10);
network.signal_level = (level / 2) - 100;
}
else if (!network.channel) {
// A tricky one: the channel is the first one having just ONE number. Set only
// if the channel is not already set ("Basic Rates" can be a single number also)
if (regexChannel.exec(lines[t])) {
network.channel = parseInt(lines[t].split(':')[1].trim());
}
}
}
if (network) {
wifis.push(network);
}
}
}
catch (ex) {
err = ex;
}
callback(err, wifis);
}
module.exports = {
parseOutput: parseOutput,
cmdLine : cmdLine,
tool : tool
};

View File

@ -1,7 +1,25 @@
{
"name": "",node-wifi-scanner
"name": "node-wifi-scanner",
"version": "0.0.1",
"description": "detects WiFi networks",
"author": "Christian Kuster <christian@kusti.ch>",
"main": "index.js"
"description": "node.js module for WiFi network detection",
"main": "index.js",
"keywords": [
"WiFi",
"Node.js",
"scanner"
],
"author": {
"name": "Christian Kuster, CH-8342 Wernetshausen",
"email": "christian@kusti.ch",
"url": "http://www.kusti.ch/"
},
"homepage": "http://www.ferropoly.ch/",
"repository": {
"type": "git",
"url": "https://github.com/ancasicolica/node-wifi-scanner.git"
},
"engines": {
"node": ">= 4.4.0",
"npm": ">= 2.14.0"
}
}

91
tests/netsh.js Normal file
View File

@ -0,0 +1,91 @@
/**
* Created by kc on 04.04.16.
*/
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const netsh = require('../lib/netsh');
describe('netsh', function () {
it('parses de locale output', function (done) {
netsh.parseOutput(fs.readFileSync(path.join(__dirname, 'fixtures', 'netsh', 'netsh_de_complex01.txt'), {encoding: 'utf8'}), (err, info) => {
assert.ok(info);
assert.equal(info.length, 86);
var ap = info[0];
assert.equal(ap.mac, '00:f2:8b:8c:a6:88');
assert.equal(ap.ssid, '');
assert.equal(ap.signal_level, -88.5);
assert.strictEqual(ap.channel, 1);
ap = info[22];
assert.equal(ap.mac, '00:35:1a:5b:46:7b');
assert.equal(ap.ssid, '');
assert.equal(ap.signal_level, -90);
assert.strictEqual(ap.channel, 116);
ap = info[23];
assert.equal(ap.mac, '10:bd:18:ab:4d:8f');
assert.equal(ap.ssid, 'Network-1');
assert.equal(ap.signal_level, -81);
assert.strictEqual(ap.channel, 6);
ap = info[74];
assert.equal(ap.mac, '00:f2:8b:8c:a6:8d');
assert.equal(ap.ssid, 'Network-6');
assert.equal(ap.signal_level, -87.5);
assert.strictEqual(ap.channel, 1);
ap = info[85];
assert.equal(ap.mac, '00:f2:8b:8c:a6:85');
assert.equal(ap.ssid, 'Network-7');
assert.equal(ap.signal_level, -89.5);
assert.strictEqual(ap.channel, 1);
done(err);
});
});
it('parses en locale output', function (done) {
netsh.parseOutput(fs.readFileSync(path.join(__dirname, 'fixtures', 'netsh', 'netsh_en_complex01.txt'), {encoding: 'utf8'}), (err, info) => {
assert.ok(info);
assert.equal(info.length, 86);
var ap = info[0];
assert.equal(ap.mac, '00:f2:8b:8c:a6:88');
assert.equal(ap.ssid, '');
assert.equal(ap.signal_level, -88.5);
assert.strictEqual(ap.channel, 1);
ap = info[22];
assert.equal(ap.mac, '00:35:1a:5b:46:7b');
assert.equal(ap.ssid, '');
assert.equal(ap.signal_level, -90);
assert.strictEqual(ap.channel, 116);
ap = info[23];
assert.equal(ap.mac, '10:bd:18:ab:4d:8f');
assert.equal(ap.ssid, 'Network-1');
assert.equal(ap.signal_level, -81);
assert.strictEqual(ap.channel, 6);
ap = info[74];
assert.equal(ap.mac, '00:f2:8b:8c:a6:8d');
assert.equal(ap.ssid, 'Network-6');
assert.equal(ap.signal_level, -87.5);
assert.strictEqual(ap.channel, 1);
ap = info[85];
assert.equal(ap.mac, '00:f2:8b:8c:a6:85');
assert.equal(ap.ssid, 'Network-7');
assert.equal(ap.signal_level, -89.5);
assert.strictEqual(ap.channel, 1);
done(err);
});
});
});