Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
8eeb0a9827 | |||
d140e224c9 | |||
ef25a7fb7c | |||
32b516e302 | |||
d1eac84058 | |||
50090aecda | |||
bc61dc2f02 | |||
5030d9f693 | |||
e874b44200 | |||
f1c0c014da | |||
29e715897e | |||
d302473da7 | |||
77da84a261 | |||
9669064662 |
@ -4,5 +4,5 @@ branches:
|
||||
- master
|
||||
- develop
|
||||
node_js:
|
||||
- "4"
|
||||
- "5"
|
||||
- "10"
|
||||
- "11"
|
||||
|
25
README.md
25
README.md
@ -27,6 +27,12 @@ It was tested with the following operating systems:
|
||||
|
||||
## Usage
|
||||
|
||||
### Command Line
|
||||
|
||||
Run the script ```scan``` in the bin folder.
|
||||
|
||||
### Code
|
||||
|
||||
const scanner = require('node-wifi-scanner');
|
||||
|
||||
scanner.scan((err, networks) => {
|
||||
@ -53,12 +59,29 @@ The module uses command line tools for gathering the network information:
|
||||
|
||||
* airport on Mac OS-X: `airport -s`
|
||||
* netsh on Windows: `netsh wlan show networks mode=Bssid`
|
||||
* iwlist (1st choice) on Linux: `iwlist scan`
|
||||
* iwlist on Linux: `iwlist scan`
|
||||
|
||||
|
||||
Unfortunately, Mac OS-X and Windows use the system language for the output which requires a quite
|
||||
generic way of parsing the data. If you experience any troubles, please create a GitHub issue and supply
|
||||
the output of the tool.
|
||||
|
||||
## Limits of the tool
|
||||
|
||||
There is no such thing as perfect software and this is all the more true when the tools used require different
|
||||
access rights depending on
|
||||
the operating system. Please note the following restrictions
|
||||
before using this tool in a productive system.
|
||||
|
||||
**Linux**: iwlist does only return all found networks if run as sudo! Otherwise you'll
|
||||
get only the network you're connected to.
|
||||
|
||||
**Windows**: there are some network cards which do not
|
||||
return the MAC address and other parameters of the found networks. In this case
|
||||
the "found" networks are ignored as there is no valuable data. If you have this effect
|
||||
on your system, please provide as many information about your system (PC manufacturer, network
|
||||
card, OS,...) as available. Thanks
|
||||
|
||||
## Licence
|
||||
|
||||
The MIT License (MIT)
|
||||
|
2
bin/scan
2
bin/scan
@ -5,7 +5,7 @@
|
||||
* Created by kc on 04.04.16.
|
||||
*/
|
||||
|
||||
var scanner = require('../index');
|
||||
const scanner = require('../index');
|
||||
|
||||
scanner.scan((err, output) => {
|
||||
if (err) {
|
||||
|
5
index.js
5
index.js
@ -3,7 +3,6 @@
|
||||
* Created by kc on 04.04.16.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const exec = require('child_process').exec;
|
||||
const async = require('async');
|
||||
const _ = require('lodash');
|
||||
@ -12,7 +11,7 @@ const airport = require('./lib/airport');
|
||||
const iwlist = require('./lib/iwlist');
|
||||
const netsh = require('./lib/netsh');
|
||||
|
||||
var scanner;
|
||||
let scanner;
|
||||
|
||||
// Initializing the tools
|
||||
function initTools(callback) {
|
||||
@ -43,7 +42,7 @@ function initTools(callback) {
|
||||
}
|
||||
],
|
||||
function (err, results) {
|
||||
var res = _.find(results,
|
||||
let res = _.find(results,
|
||||
function (f) {
|
||||
return !f.err
|
||||
});
|
||||
|
@ -3,43 +3,45 @@
|
||||
* Created by kc on 04.04.16.
|
||||
*/
|
||||
|
||||
const tool = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport';
|
||||
const cmdLine = tool + ' -s';
|
||||
const tool = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport';
|
||||
const cmdLine = tool + ' -s';
|
||||
const detector = tool + ' -getInfo';
|
||||
|
||||
const macRegex = /([0-9a-zA-Z]{1}[0-9a-zA-Z]{1}[:]{1}){5}[0-9a-zA-Z]{1}[0-9a-zA-Z]{1}/;
|
||||
|
||||
/**
|
||||
* Parsing the output of airport (Mac OS X)
|
||||
* @param str output of the tool
|
||||
* @param callback
|
||||
*/
|
||||
function parseOutput(str, callback) {
|
||||
var err = null;
|
||||
let err = null;
|
||||
let wifis = [];
|
||||
|
||||
try {
|
||||
var lines = str.split('\n');
|
||||
var wifis = [];
|
||||
let lines = str.split('\n');
|
||||
|
||||
for (var i = 1, l = lines.length; i < l; i++) {
|
||||
var mac = lines[i].match(macRegex);
|
||||
for (let i = 1, l = lines.length; i < l; i++) {
|
||||
let mac = lines[i].match(macRegex);
|
||||
if (!mac) {
|
||||
continue;
|
||||
}
|
||||
var macStart = lines[i].indexOf(mac[0]);
|
||||
var elements = lines[i].substr(macStart).split(/[ ]+/);
|
||||
let macStart = lines[i].indexOf(mac[0]);
|
||||
let elements = lines[i].substr(macStart).split(/[ ]+/);
|
||||
wifis.push({
|
||||
'ssid' : lines[i].substr(0, macStart).trim(),
|
||||
'mac' : elements[0].trim(),
|
||||
'channel' : parseInt(elements[2].trim(), 10),
|
||||
'rssi' : parseInt(elements[1].trim(), 10)
|
||||
'ssid' : lines[i].substr(0, macStart).trim(),
|
||||
'mac' : elements[0].trim(),
|
||||
'channel': parseInt(elements[2].trim(), 10),
|
||||
'rssi' : parseInt(elements[1].trim(), 10)
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
err = ex;
|
||||
}
|
||||
|
||||
callback(err, wifis);
|
||||
finally {
|
||||
callback(err, wifis);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,31 +3,32 @@
|
||||
* Created by kc on 04.04.16.
|
||||
*/
|
||||
|
||||
const _ = require('lodash');
|
||||
const _ = require('lodash');
|
||||
// usually located in /usr/bin/ but as it could be at another location, allow all found in PATH (but we're in trouble
|
||||
// when the default location, /usr/bin/ is not in the PATH!). GitHub issue #1
|
||||
const tool = 'iwlist';
|
||||
const cmdLine = tool + ' scan';
|
||||
const tool = 'iwlist';
|
||||
const cmdLine = tool + ' scan';
|
||||
const detector = tool + ' --help';
|
||||
|
||||
|
||||
const macRegex = /([0-9a-zA-Z]{1}[0-9a-zA-Z]{1}[:]{1}){5}[0-9a-zA-Z]{1}[0-9a-zA-Z]{1}/;
|
||||
const cellRegex = /Cell [0-9]{2,} - Address:/;
|
||||
|
||||
/**
|
||||
* Parsing the output of iwlist, tool having a lot of different faces :-(
|
||||
* @param str output of the tool
|
||||
* @param callback
|
||||
*/
|
||||
function parseOutput(str, callback) {
|
||||
var err = null;
|
||||
var wifis = [];
|
||||
let err = null;
|
||||
let wifis = [];
|
||||
|
||||
try {
|
||||
var blocks = str.split(cellRegex);
|
||||
let blocks = str.split(cellRegex);
|
||||
|
||||
blocks.forEach(block => {
|
||||
var network = {};
|
||||
var lines = block.split('\n');
|
||||
let network = {};
|
||||
let lines = block.split('\n');
|
||||
if (macRegex.exec(lines[0])) {
|
||||
// First line is the mac address (always! (?))
|
||||
network.mac = lines[0].trim();
|
||||
@ -43,8 +44,8 @@ function parseOutput(str, callback) {
|
||||
}
|
||||
|
||||
// Channel, an ugly thing to get it
|
||||
else if (_.startsWith(line.trim(), 'Frequency:')) {
|
||||
network.channel = parseInt(_.trim(line, ' )').split(/Channel/)[1], 10);
|
||||
else if (_.startsWith(line.trim(), 'Channel:')) {
|
||||
network.channel = parseInt(_.trim(line, ' )').split(/:/)[1]);
|
||||
}
|
||||
|
||||
// Another ugly thing, the signal which can have different formats, even worse als
|
||||
@ -53,15 +54,14 @@ function parseOutput(str, callback) {
|
||||
if (line.indexOf('Quality') > -1) {
|
||||
// This is a "Quality=40/70 Signal level=-70 dBm" line
|
||||
network.rssi = parseInt(line.substr(line.indexOf('Signal level') + 13), 10);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// This is a "Signal level=60/100" line
|
||||
var elements = line.split('=');
|
||||
let elements = line.split('=');
|
||||
elements.forEach(e => {
|
||||
if (e.indexOf('/') > 0) {
|
||||
// that's our part
|
||||
var parts = e.split('/');
|
||||
var level = Math.floor(100 * parseInt(parts[0], 10) / parseInt(parts[1], 10));
|
||||
let parts = e.split('/');
|
||||
let level = Math.floor(100 * parseInt(parts[0], 10) / parseInt(parts[1], 10));
|
||||
network.rssi = level / 2 - 100;
|
||||
}
|
||||
})
|
||||
|
26
lib/netsh.js
26
lib/netsh.js
@ -15,9 +15,9 @@ const detector = tool + ' show alias';
|
||||
* an approach of analyzing the structure of the output
|
||||
*/
|
||||
function parseOutput(str, callback) {
|
||||
var blocks = str.split('\n\n');
|
||||
var wifis = [];
|
||||
var err = null;
|
||||
let blocks = str.split('\n\n');
|
||||
let wifis = [];
|
||||
let err = null;
|
||||
try {
|
||||
if (blocks.length < 2) {
|
||||
// 2nd try, with \r\n
|
||||
@ -40,18 +40,18 @@ function parseOutput(str, callback) {
|
||||
// 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;
|
||||
for (let i = 1, l = blocks.length; i < l; i++) {
|
||||
let network = {};
|
||||
let lines = blocks[i].split('\n');
|
||||
let 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();
|
||||
let ssid = lines[0].substring(lines[0].indexOf(':') + 1).trim();
|
||||
|
||||
for (var t = 1, n = lines.length; t < n; t++) {
|
||||
for (let 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) {
|
||||
@ -61,14 +61,12 @@ function parseOutput(str, callback) {
|
||||
ssid: ssid,
|
||||
mac : lines[t].substring(lines[t].indexOf(':') + 1).trim()
|
||||
};
|
||||
}
|
||||
else if (lines[t].indexOf('%') > 0) {
|
||||
} else if (lines[t].indexOf('%') > 0) {
|
||||
// Network signal strength, identified by '%'
|
||||
var level = parseInt(lines[t].split(':')[1].split('%')[0].trim(), 10);
|
||||
let level = parseInt(lines[t].split(':')[1].split('%')[0].trim(), 10);
|
||||
|
||||
network.rssi = (level / 2) - 100;
|
||||
}
|
||||
else if (!network.channel) {
|
||||
} 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].trim())) {
|
||||
|
1666
package-lock.json
generated
Normal file
1666
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-wifi-scanner",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.2",
|
||||
"description": "node.js module for WiFi network detection",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@ -35,12 +35,12 @@
|
||||
"test": "mocha test"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "2.1.4",
|
||||
"lodash": "4.17.2"
|
||||
"async": "3.1.0",
|
||||
"lodash": "4.17.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "0.4.5",
|
||||
"grunt-bump": "0.7.0",
|
||||
"mocha": "2.2.5"
|
||||
"grunt": "^1.0.3",
|
||||
"grunt-bump": "0.8.0",
|
||||
"mocha": "6.2.0"
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ describe('airport', () => {
|
||||
assert.ok(info);
|
||||
assert.equal(info.length, 36);
|
||||
|
||||
var ap = info[0];
|
||||
let ap = info[0];
|
||||
assert.equal(ap.mac, '00:35:1a:90:56:03');
|
||||
assert.equal(ap.ssid, 'OurTest');
|
||||
assert.equal(ap.rssi, -70);
|
||||
@ -49,7 +49,7 @@ describe('airport', () => {
|
||||
assert.ok(info);
|
||||
assert.equal(info.length, 4);
|
||||
|
||||
var ap = info[0];
|
||||
let ap = info[0];
|
||||
assert.equal(ap.mac, '7c:b7:33:ae:3b:06');
|
||||
assert.equal(ap.ssid, 'Raupo');
|
||||
assert.equal(ap.rssi, -80);
|
||||
|
@ -22,7 +22,7 @@ describe('iwlist', () => {
|
||||
|
||||
assert.ok(info);
|
||||
|
||||
var ap = info[0];
|
||||
let ap = info[0];
|
||||
assert.equal(ap.mac, 'D4:D1:84:50:76:45');
|
||||
assert.equal(ap.ssid, 'gsy-97796');
|
||||
assert.equal(ap.rssi, -76);
|
||||
@ -40,7 +40,7 @@ describe('iwlist', () => {
|
||||
iwlist.parseOutput(fs.readFileSync(path.join(__dirname, 'fixtures','iwlist','iwlist03_raspi.txt'), { encoding: 'utf8' }), (err, info) => {
|
||||
assert.ok(info);
|
||||
|
||||
var ap = info[0];
|
||||
let ap = info[0];
|
||||
assert.equal(ap.mac, '00:35:1A:90:56:00');
|
||||
assert.equal(ap.ssid, 'LORA-Wifi');
|
||||
assert.equal(ap.rssi, -71);
|
||||
|
@ -16,7 +16,7 @@ describe('netsh', function () {
|
||||
assert.ok(info);
|
||||
assert.equal(info.length, 86);
|
||||
|
||||
var ap = info[0];
|
||||
let ap = info[0];
|
||||
assert.equal(ap.mac, '00:f2:8b:8c:a6:88');
|
||||
assert.equal(ap.ssid, '');
|
||||
assert.equal(ap.rssi, -88.5);
|
||||
@ -55,7 +55,7 @@ describe('netsh', function () {
|
||||
assert.ok(info);
|
||||
assert.equal(info.length, 86);
|
||||
|
||||
var ap = info[0];
|
||||
let ap = info[0];
|
||||
assert.equal(ap.mac, '00:f2:8b:8c:a6:88');
|
||||
assert.equal(ap.ssid, '');
|
||||
assert.equal(ap.rssi, -88.5);
|
||||
@ -94,7 +94,7 @@ describe('netsh', function () {
|
||||
assert.ok(info);
|
||||
assert.equal(info.length, 8);
|
||||
|
||||
var ap = info[0];
|
||||
let ap = info[0];
|
||||
assert.equal(ap.mac, '98:fc:11:b6:88:9e');
|
||||
assert.equal(ap.ssid, 'CARAMANZANAS_BAJA');
|
||||
assert.equal(ap.rssi, -86);
|
||||
|
Reference in New Issue
Block a user