netsh added
This commit is contained in:
parent
1fa96c3ed7
commit
7153b41460
87
lib/netsh.js
87
lib/netsh.js
@ -1,3 +1,90 @@
|
|||||||
/**
|
/**
|
||||||
|
* Scanning WiFis on Windows
|
||||||
* Created by kc on 04.04.16.
|
* 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
|
||||||
|
};
|
||||||
|
26
package.json
26
package.json
@ -1,7 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "",node-wifi-scanner
|
"name": "node-wifi-scanner",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "detects WiFi networks",
|
"description": "node.js module for WiFi network detection",
|
||||||
"author": "Christian Kuster <christian@kusti.ch>",
|
"main": "index.js",
|
||||||
"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
91
tests/netsh.js
Normal 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user