siddr5 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of siddr5 might be problematic. Click here for more details.
- package/LICENSE +20 -0
- package/README.md +1091 -0
- package/lib/audio.js +222 -0
- package/lib/battery.js +308 -0
- package/lib/bluetooth.js +229 -0
- package/lib/cli.js +31 -0
- package/lib/cpu.js +1704 -0
- package/lib/docker.js +757 -0
- package/lib/dockerSocket.js +327 -0
- package/lib/filesystem.js +1495 -0
- package/lib/graphics.js +1103 -0
- package/lib/index.d.ts +1028 -0
- package/lib/index.js +504 -0
- package/lib/internet.js +236 -0
- package/lib/memory.js +555 -0
- package/lib/network.js +1779 -0
- package/lib/osinfo.js +1167 -0
- package/lib/printer.js +210 -0
- package/lib/processes.js +1289 -0
- package/lib/system.js +720 -0
- package/lib/usb.js +274 -0
- package/lib/users.js +363 -0
- package/lib/util.js +1303 -0
- package/lib/virtualbox.js +107 -0
- package/lib/wifi.js +744 -0
- package/package.json +94 -0
package/lib/wifi.js
ADDED
@@ -0,0 +1,744 @@
|
|
1
|
+
'use strict';
|
2
|
+
// @ts-check
|
3
|
+
// ==================================================================================
|
4
|
+
// wifi.js
|
5
|
+
// ----------------------------------------------------------------------------------
|
6
|
+
// Description: System Information - library
|
7
|
+
// for Node.js
|
8
|
+
// Copyright: (c) 2014 - 2023
|
9
|
+
// Author: Sebastian Hildebrandt
|
10
|
+
// ----------------------------------------------------------------------------------
|
11
|
+
// License: MIT
|
12
|
+
// ==================================================================================
|
13
|
+
// 9. wifi
|
14
|
+
// ----------------------------------------------------------------------------------
|
15
|
+
|
16
|
+
const os = require('os');
|
17
|
+
const exec = require('child_process').exec;
|
18
|
+
const execSync = require('child_process').execSync;
|
19
|
+
const util = require('./util');
|
20
|
+
|
21
|
+
let _platform = process.platform;
|
22
|
+
|
23
|
+
const _linux = (_platform === 'linux' || _platform === 'android');
|
24
|
+
const _darwin = (_platform === 'darwin');
|
25
|
+
const _windows = (_platform === 'win32');
|
26
|
+
|
27
|
+
function wifiDBFromQuality(quality) {
|
28
|
+
return (parseFloat(quality) / 2 - 100);
|
29
|
+
}
|
30
|
+
|
31
|
+
function wifiQualityFromDB(db) {
|
32
|
+
const result = 2 * (parseFloat(db) + 100);
|
33
|
+
return result <= 100 ? result : 100;
|
34
|
+
}
|
35
|
+
|
36
|
+
const _wifi_frequencies = {
|
37
|
+
1: 2412,
|
38
|
+
2: 2417,
|
39
|
+
3: 2422,
|
40
|
+
4: 2427,
|
41
|
+
5: 2432,
|
42
|
+
6: 2437,
|
43
|
+
7: 2442,
|
44
|
+
8: 2447,
|
45
|
+
9: 2452,
|
46
|
+
10: 2457,
|
47
|
+
11: 2462,
|
48
|
+
12: 2467,
|
49
|
+
13: 2472,
|
50
|
+
14: 2484,
|
51
|
+
32: 5160,
|
52
|
+
34: 5170,
|
53
|
+
36: 5180,
|
54
|
+
38: 5190,
|
55
|
+
40: 5200,
|
56
|
+
42: 5210,
|
57
|
+
44: 5220,
|
58
|
+
46: 5230,
|
59
|
+
48: 5240,
|
60
|
+
50: 5250,
|
61
|
+
52: 5260,
|
62
|
+
54: 5270,
|
63
|
+
56: 5280,
|
64
|
+
58: 5290,
|
65
|
+
60: 5300,
|
66
|
+
62: 5310,
|
67
|
+
64: 5320,
|
68
|
+
68: 5340,
|
69
|
+
96: 5480,
|
70
|
+
100: 5500,
|
71
|
+
102: 5510,
|
72
|
+
104: 5520,
|
73
|
+
106: 5530,
|
74
|
+
108: 5540,
|
75
|
+
110: 5550,
|
76
|
+
112: 5560,
|
77
|
+
114: 5570,
|
78
|
+
116: 5580,
|
79
|
+
118: 5590,
|
80
|
+
120: 5600,
|
81
|
+
122: 5610,
|
82
|
+
124: 5620,
|
83
|
+
126: 5630,
|
84
|
+
128: 5640,
|
85
|
+
132: 5660,
|
86
|
+
134: 5670,
|
87
|
+
136: 5680,
|
88
|
+
138: 5690,
|
89
|
+
140: 5700,
|
90
|
+
142: 5710,
|
91
|
+
144: 5720,
|
92
|
+
149: 5745,
|
93
|
+
151: 5755,
|
94
|
+
153: 5765,
|
95
|
+
155: 5775,
|
96
|
+
157: 5785,
|
97
|
+
159: 5795,
|
98
|
+
161: 5805,
|
99
|
+
165: 5825,
|
100
|
+
169: 5845,
|
101
|
+
173: 5865,
|
102
|
+
183: 4915,
|
103
|
+
184: 4920,
|
104
|
+
185: 4925,
|
105
|
+
187: 4935,
|
106
|
+
188: 4940,
|
107
|
+
189: 4945,
|
108
|
+
192: 4960,
|
109
|
+
196: 4980
|
110
|
+
};
|
111
|
+
|
112
|
+
function wifiFrequencyFromChannel(channel) {
|
113
|
+
return {}.hasOwnProperty.call(_wifi_frequencies, channel) ? _wifi_frequencies[channel] : null;
|
114
|
+
}
|
115
|
+
|
116
|
+
function wifiChannelFromFrequencs(frequency) {
|
117
|
+
let channel = 0;
|
118
|
+
for (let key in _wifi_frequencies) {
|
119
|
+
if ({}.hasOwnProperty.call(_wifi_frequencies, key)) {
|
120
|
+
if (_wifi_frequencies[key] === frequency) { channel = util.toInt(key); }
|
121
|
+
}
|
122
|
+
}
|
123
|
+
return channel;
|
124
|
+
}
|
125
|
+
|
126
|
+
function ifaceListLinux() {
|
127
|
+
const result = [];
|
128
|
+
const cmd = 'iw dev 2>/dev/null';
|
129
|
+
try {
|
130
|
+
const all = execSync(cmd).toString().split('\n').map(line => line.trim()).join('\n');
|
131
|
+
const parts = all.split('\nInterface ');
|
132
|
+
parts.shift();
|
133
|
+
parts.forEach(ifaceDetails => {
|
134
|
+
const lines = ifaceDetails.split('\n');
|
135
|
+
const iface = lines[0];
|
136
|
+
const id = util.toInt(util.getValue(lines, 'ifindex', ' '));
|
137
|
+
const mac = util.getValue(lines, 'addr', ' ');
|
138
|
+
const channel = util.toInt(util.getValue(lines, 'channel', ' '));
|
139
|
+
result.push({
|
140
|
+
id,
|
141
|
+
iface,
|
142
|
+
mac,
|
143
|
+
channel
|
144
|
+
});
|
145
|
+
});
|
146
|
+
return result;
|
147
|
+
} catch (e) {
|
148
|
+
try {
|
149
|
+
const all = execSync('nmcli -t -f general,wifi-properties,wired-properties,interface-flags,capabilities,nsp device show 2>/dev/null').toString();
|
150
|
+
const parts = all.split('\nGENERAL.DEVICE:');
|
151
|
+
let i = 1;
|
152
|
+
parts.forEach(ifaceDetails => {
|
153
|
+
const lines = ifaceDetails.split('\n');
|
154
|
+
const iface = util.getValue(lines, 'GENERAL.DEVICE');
|
155
|
+
const type = util.getValue(lines, 'GENERAL.TYPE');
|
156
|
+
const id = i++; // // util.getValue(lines, 'GENERAL.PATH');
|
157
|
+
const mac = util.getValue(lines, 'GENERAL.HWADDR');
|
158
|
+
const channel = '';
|
159
|
+
if (type.toLowerCase() === 'wifi') {
|
160
|
+
result.push({
|
161
|
+
id,
|
162
|
+
iface,
|
163
|
+
mac,
|
164
|
+
channel
|
165
|
+
});
|
166
|
+
}
|
167
|
+
});
|
168
|
+
return result;
|
169
|
+
} catch (e) {
|
170
|
+
return [];
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
function nmiDeviceLinux(iface) {
|
176
|
+
const cmd = `nmcli -t -f general,wifi-properties,capabilities,ip4,ip6 device show ${iface} 2>/dev/null`;
|
177
|
+
try {
|
178
|
+
const lines = execSync(cmd).toString().split('\n');
|
179
|
+
const ssid = util.getValue(lines, 'GENERAL.CONNECTION');
|
180
|
+
return {
|
181
|
+
iface,
|
182
|
+
type: util.getValue(lines, 'GENERAL.TYPE'),
|
183
|
+
vendor: util.getValue(lines, 'GENERAL.VENDOR'),
|
184
|
+
product: util.getValue(lines, 'GENERAL.PRODUCT'),
|
185
|
+
mac: util.getValue(lines, 'GENERAL.HWADDR').toLowerCase(),
|
186
|
+
ssid: ssid !== '--' ? ssid : null
|
187
|
+
};
|
188
|
+
} catch (e) {
|
189
|
+
return {};
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
function nmiConnectionLinux(ssid) {
|
194
|
+
const cmd = `nmcli -t --show-secrets connection show ${ssid} 2>/dev/null`;
|
195
|
+
try {
|
196
|
+
const lines = execSync(cmd).toString().split('\n');
|
197
|
+
const bssid = util.getValue(lines, '802-11-wireless.seen-bssids').toLowerCase();
|
198
|
+
return {
|
199
|
+
ssid: ssid !== '--' ? ssid : null,
|
200
|
+
uuid: util.getValue(lines, 'connection.uuid'),
|
201
|
+
type: util.getValue(lines, 'connection.type'),
|
202
|
+
autoconnect: util.getValue(lines, 'connection.autoconnect') === 'yes',
|
203
|
+
security: util.getValue(lines, '802-11-wireless-security.key-mgmt'),
|
204
|
+
bssid: bssid !== '--' ? bssid : null
|
205
|
+
};
|
206
|
+
} catch (e) {
|
207
|
+
return {};
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
function wpaConnectionLinux(iface) {
|
212
|
+
const cmd = `wpa_cli -i ${iface} status 2>&1`;
|
213
|
+
try {
|
214
|
+
const lines = execSync(cmd).toString().split('\n');
|
215
|
+
const freq = util.toInt(util.getValue(lines, 'freq', '='));
|
216
|
+
return {
|
217
|
+
ssid: util.getValue(lines, 'ssid', '='),
|
218
|
+
uuid: util.getValue(lines, 'uuid', '='),
|
219
|
+
security: util.getValue(lines, 'key_mgmt', '='),
|
220
|
+
freq,
|
221
|
+
channel: wifiChannelFromFrequencs(freq),
|
222
|
+
bssid: util.getValue(lines, 'bssid', '=').toLowerCase()
|
223
|
+
};
|
224
|
+
} catch (e) {
|
225
|
+
return {};
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
function getWifiNetworkListNmi() {
|
230
|
+
const result = [];
|
231
|
+
const cmd = 'nmcli -t -m multiline --fields active,ssid,bssid,mode,chan,freq,signal,security,wpa-flags,rsn-flags device wifi list 2>/dev/null';
|
232
|
+
try {
|
233
|
+
const stdout = execSync(cmd, { maxBuffer: 1024 * 20000 });
|
234
|
+
const parts = stdout.toString().split('ACTIVE:');
|
235
|
+
parts.shift();
|
236
|
+
parts.forEach(part => {
|
237
|
+
part = 'ACTIVE:' + part;
|
238
|
+
const lines = part.split(os.EOL);
|
239
|
+
const channel = util.getValue(lines, 'CHAN');
|
240
|
+
const frequency = util.getValue(lines, 'FREQ').toLowerCase().replace('mhz', '').trim();
|
241
|
+
const security = util.getValue(lines, 'SECURITY').replace('(', '').replace(')', '');
|
242
|
+
const wpaFlags = util.getValue(lines, 'WPA-FLAGS').replace('(', '').replace(')', '');
|
243
|
+
const rsnFlags = util.getValue(lines, 'RSN-FLAGS').replace('(', '').replace(')', '');
|
244
|
+
result.push({
|
245
|
+
ssid: util.getValue(lines, 'SSID'),
|
246
|
+
bssid: util.getValue(lines, 'BSSID').toLowerCase(),
|
247
|
+
mode: util.getValue(lines, 'MODE'),
|
248
|
+
channel: channel ? parseInt(channel, 10) : null,
|
249
|
+
frequency: frequency ? parseInt(frequency, 10) : null,
|
250
|
+
signalLevel: wifiDBFromQuality(util.getValue(lines, 'SIGNAL')),
|
251
|
+
quality: parseFloat(util.getValue(lines, 'SIGNAL')),
|
252
|
+
security: security && security !== 'none' ? security.split(' ') : [],
|
253
|
+
wpaFlags: wpaFlags && wpaFlags !== 'none' ? wpaFlags.split(' ') : [],
|
254
|
+
rsnFlags: rsnFlags && rsnFlags !== 'none' ? rsnFlags.split(' ') : []
|
255
|
+
});
|
256
|
+
});
|
257
|
+
return result;
|
258
|
+
} catch (e) {
|
259
|
+
return [];
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
function getWifiNetworkListIw(iface) {
|
264
|
+
const result = [];
|
265
|
+
try {
|
266
|
+
let iwlistParts = execSync(`export LC_ALL=C; iwlist ${iface} scan 2>&1; unset LC_ALL`).toString().split(' Cell ');
|
267
|
+
if (iwlistParts[0].indexOf('resource busy') >= 0) { return -1; }
|
268
|
+
if (iwlistParts.length > 1) {
|
269
|
+
iwlistParts.shift();
|
270
|
+
iwlistParts.forEach(element => {
|
271
|
+
const lines = element.split('\n');
|
272
|
+
const channel = util.getValue(lines, 'channel', ':', true);
|
273
|
+
const address = (lines && lines.length && lines[0].indexOf('Address:') >= 0 ? lines[0].split('Address:')[1].trim().toLowerCase() : '');
|
274
|
+
const mode = util.getValue(lines, 'mode', ':', true);
|
275
|
+
const frequency = util.getValue(lines, 'frequency', ':', true);
|
276
|
+
const qualityString = util.getValue(lines, 'Quality', '=', true);
|
277
|
+
const dbParts = qualityString.toLowerCase().split('signal level=');
|
278
|
+
const db = dbParts.length > 1 ? util.toInt(dbParts[1]) : 0;
|
279
|
+
const quality = db ? wifiQualityFromDB(db) : 0;
|
280
|
+
const ssid = util.getValue(lines, 'essid', ':', true);
|
281
|
+
|
282
|
+
// security and wpa-flags
|
283
|
+
const isWpa = element.indexOf(' WPA ') >= 0;
|
284
|
+
const isWpa2 = element.indexOf('WPA2 ') >= 0;
|
285
|
+
const security = [];
|
286
|
+
if (isWpa) { security.push('WPA'); }
|
287
|
+
if (isWpa2) { security.push('WPA2'); }
|
288
|
+
const wpaFlags = [];
|
289
|
+
let wpaFlag = '';
|
290
|
+
lines.forEach(function (line) {
|
291
|
+
const l = line.trim().toLowerCase();
|
292
|
+
if (l.indexOf('group cipher') >= 0) {
|
293
|
+
if (wpaFlag) {
|
294
|
+
wpaFlags.push(wpaFlag);
|
295
|
+
}
|
296
|
+
const parts = l.split(':');
|
297
|
+
if (parts.length > 1) {
|
298
|
+
wpaFlag = parts[1].trim().toUpperCase();
|
299
|
+
}
|
300
|
+
}
|
301
|
+
if (l.indexOf('pairwise cipher') >= 0) {
|
302
|
+
const parts = l.split(':');
|
303
|
+
if (parts.length > 1) {
|
304
|
+
if (parts[1].indexOf('tkip')) { wpaFlag = (wpaFlag ? 'TKIP/' + wpaFlag : 'TKIP'); }
|
305
|
+
else if (parts[1].indexOf('ccmp')) { wpaFlag = (wpaFlag ? 'CCMP/' + wpaFlag : 'CCMP'); }
|
306
|
+
else if (parts[1].indexOf('proprietary')) { wpaFlag = (wpaFlag ? 'PROP/' + wpaFlag : 'PROP'); }
|
307
|
+
}
|
308
|
+
}
|
309
|
+
if (l.indexOf('authentication suites') >= 0) {
|
310
|
+
const parts = l.split(':');
|
311
|
+
if (parts.length > 1) {
|
312
|
+
if (parts[1].indexOf('802.1x')) { wpaFlag = (wpaFlag ? '802.1x/' + wpaFlag : '802.1x'); }
|
313
|
+
else if (parts[1].indexOf('psk')) { wpaFlag = (wpaFlag ? 'PSK/' + wpaFlag : 'PSK'); }
|
314
|
+
}
|
315
|
+
}
|
316
|
+
});
|
317
|
+
if (wpaFlag) {
|
318
|
+
wpaFlags.push(wpaFlag);
|
319
|
+
}
|
320
|
+
|
321
|
+
result.push({
|
322
|
+
ssid,
|
323
|
+
bssid: address,
|
324
|
+
mode,
|
325
|
+
channel: channel ? util.toInt(channel) : null,
|
326
|
+
frequency: frequency ? util.toInt(frequency.replace('.', '')) : null,
|
327
|
+
signalLevel: db,
|
328
|
+
quality,
|
329
|
+
security,
|
330
|
+
wpaFlags,
|
331
|
+
rsnFlags: []
|
332
|
+
});
|
333
|
+
});
|
334
|
+
}
|
335
|
+
return result;
|
336
|
+
} catch (e) {
|
337
|
+
return -1;
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
function parseWifiDarwin(wifiObj) {
|
342
|
+
const result = [];
|
343
|
+
if (wifiObj) {
|
344
|
+
wifiObj.forEach(function (wifiItem) {
|
345
|
+
const signalLevel = wifiItem.RSSI;
|
346
|
+
let security = [];
|
347
|
+
let wpaFlags = [];
|
348
|
+
if (wifiItem.WPA_IE) {
|
349
|
+
security.push('WPA');
|
350
|
+
if (wifiItem.WPA_IE.IE_KEY_WPA_UCIPHERS) {
|
351
|
+
wifiItem.WPA_IE.IE_KEY_WPA_UCIPHERS.forEach(function (ciphers) {
|
352
|
+
if (ciphers === 0 && wpaFlags.indexOf('unknown/TKIP') === -1) { wpaFlags.push('unknown/TKIP'); }
|
353
|
+
if (ciphers === 2 && wpaFlags.indexOf('PSK/TKIP') === -1) { wpaFlags.push('PSK/TKIP'); }
|
354
|
+
if (ciphers === 4 && wpaFlags.indexOf('PSK/AES') === -1) { wpaFlags.push('PSK/AES'); }
|
355
|
+
});
|
356
|
+
}
|
357
|
+
}
|
358
|
+
if (wifiItem.RSN_IE) {
|
359
|
+
security.push('WPA2');
|
360
|
+
if (wifiItem.RSN_IE.IE_KEY_RSN_UCIPHERS) {
|
361
|
+
wifiItem.RSN_IE.IE_KEY_RSN_UCIPHERS.forEach(function (ciphers) {
|
362
|
+
if (ciphers === 0 && wpaFlags.indexOf('unknown/TKIP') === -1) { wpaFlags.push('unknown/TKIP'); }
|
363
|
+
if (ciphers === 2 && wpaFlags.indexOf('TKIP/TKIP') === -1) { wpaFlags.push('TKIP/TKIP'); }
|
364
|
+
if (ciphers === 4 && wpaFlags.indexOf('PSK/AES') === -1) { wpaFlags.push('PSK/AES'); }
|
365
|
+
});
|
366
|
+
}
|
367
|
+
}
|
368
|
+
result.push({
|
369
|
+
ssid: wifiItem.SSID_STR,
|
370
|
+
bssid: wifiItem.BSSID,
|
371
|
+
mode: '',
|
372
|
+
channel: wifiItem.CHANNEL,
|
373
|
+
frequency: wifiFrequencyFromChannel(wifiItem.CHANNEL),
|
374
|
+
signalLevel: signalLevel ? parseInt(signalLevel, 10) : null,
|
375
|
+
quality: wifiQualityFromDB(signalLevel),
|
376
|
+
security,
|
377
|
+
wpaFlags,
|
378
|
+
rsnFlags: []
|
379
|
+
});
|
380
|
+
});
|
381
|
+
}
|
382
|
+
return result;
|
383
|
+
}
|
384
|
+
function wifiNetworks(callback) {
|
385
|
+
return new Promise((resolve) => {
|
386
|
+
process.nextTick(() => {
|
387
|
+
let result = [];
|
388
|
+
if (_linux) {
|
389
|
+
result = getWifiNetworkListNmi();
|
390
|
+
if (result.length === 0) {
|
391
|
+
try {
|
392
|
+
const iwconfigParts = execSync('export LC_ALL=C; iwconfig 2>/dev/null; unset LC_ALL').toString().split('\n\n');
|
393
|
+
let iface = '';
|
394
|
+
iwconfigParts.forEach(element => {
|
395
|
+
if (element.indexOf('no wireless') === -1 && element.trim() !== '') {
|
396
|
+
iface = element.split(' ')[0];
|
397
|
+
}
|
398
|
+
});
|
399
|
+
if (iface) {
|
400
|
+
const res = getWifiNetworkListIw(iface);
|
401
|
+
if (res === -1) {
|
402
|
+
// try again after 4 secs
|
403
|
+
setTimeout(function (iface) {
|
404
|
+
const res = getWifiNetworkListIw(iface);
|
405
|
+
if (res != -1) { result = res; }
|
406
|
+
if (callback) {
|
407
|
+
callback(result);
|
408
|
+
}
|
409
|
+
resolve(result);
|
410
|
+
}, 4000);
|
411
|
+
} else {
|
412
|
+
result = res;
|
413
|
+
if (callback) {
|
414
|
+
callback(result);
|
415
|
+
}
|
416
|
+
resolve(result);
|
417
|
+
}
|
418
|
+
} else {
|
419
|
+
if (callback) {
|
420
|
+
callback(result);
|
421
|
+
}
|
422
|
+
resolve(result);
|
423
|
+
}
|
424
|
+
} catch (e) {
|
425
|
+
if (callback) {
|
426
|
+
callback(result);
|
427
|
+
}
|
428
|
+
resolve(result);
|
429
|
+
}
|
430
|
+
} else {
|
431
|
+
if (callback) {
|
432
|
+
callback(result);
|
433
|
+
}
|
434
|
+
resolve(result);
|
435
|
+
}
|
436
|
+
} else if (_darwin) {
|
437
|
+
let cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s -x';
|
438
|
+
exec(cmd, { maxBuffer: 1024 * 40000 }, function (error, stdout) {
|
439
|
+
const output = stdout.toString();
|
440
|
+
result = parseWifiDarwin(util.plistParser(output));
|
441
|
+
if (callback) {
|
442
|
+
callback(result);
|
443
|
+
}
|
444
|
+
resolve(result);
|
445
|
+
});
|
446
|
+
} else if (_windows) {
|
447
|
+
let cmd = 'netsh wlan show networks mode=Bssid';
|
448
|
+
util.powerShell(cmd).then((stdout) => {
|
449
|
+
const ssidParts = stdout.toString('utf8').split(os.EOL + os.EOL + 'SSID ');
|
450
|
+
ssidParts.shift();
|
451
|
+
|
452
|
+
ssidParts.forEach(ssidPart => {
|
453
|
+
const ssidLines = ssidPart.split(os.EOL);
|
454
|
+
if (ssidLines && ssidLines.length >= 8 && ssidLines[0].indexOf(':') >= 0) {
|
455
|
+
const bssidsParts = ssidPart.split(' BSSID');
|
456
|
+
bssidsParts.shift();
|
457
|
+
|
458
|
+
bssidsParts.forEach((bssidPart) => {
|
459
|
+
const bssidLines = bssidPart.split(os.EOL);
|
460
|
+
const bssidLine = bssidLines[0].split(':');
|
461
|
+
bssidLine.shift();
|
462
|
+
const bssid = bssidLine.join(':').trim().toLowerCase();
|
463
|
+
const channel = bssidLines[3].split(':').pop().trim();
|
464
|
+
const quality = bssidLines[1].split(':').pop().trim();
|
465
|
+
|
466
|
+
result.push({
|
467
|
+
ssid: ssidLines[0].split(':').pop().trim(),
|
468
|
+
bssid,
|
469
|
+
mode: '',
|
470
|
+
channel: channel ? parseInt(channel, 10) : null,
|
471
|
+
frequency: wifiFrequencyFromChannel(channel),
|
472
|
+
signalLevel: wifiDBFromQuality(quality),
|
473
|
+
quality: quality ? parseInt(quality, 10) : null,
|
474
|
+
security: [ssidLines[2].split(':').pop().trim()],
|
475
|
+
wpaFlags: [ssidLines[3].split(':').pop().trim()],
|
476
|
+
rsnFlags: []
|
477
|
+
});
|
478
|
+
});
|
479
|
+
}
|
480
|
+
});
|
481
|
+
|
482
|
+
if (callback) {
|
483
|
+
callback(result);
|
484
|
+
}
|
485
|
+
resolve(result);
|
486
|
+
});
|
487
|
+
} else {
|
488
|
+
if (callback) {
|
489
|
+
callback(result);
|
490
|
+
}
|
491
|
+
resolve(result);
|
492
|
+
}
|
493
|
+
});
|
494
|
+
});
|
495
|
+
}
|
496
|
+
|
497
|
+
exports.wifiNetworks = wifiNetworks;
|
498
|
+
|
499
|
+
function getVendor(model) {
|
500
|
+
model = model.toLowerCase();
|
501
|
+
let result = '';
|
502
|
+
if (model.indexOf('intel') >= 0) { result = 'Intel'; }
|
503
|
+
else if (model.indexOf('realtek') >= 0) { result = 'Realtek'; }
|
504
|
+
else if (model.indexOf('qualcom') >= 0) { result = 'Qualcom'; }
|
505
|
+
else if (model.indexOf('broadcom') >= 0) { result = 'Broadcom'; }
|
506
|
+
else if (model.indexOf('cavium') >= 0) { result = 'Cavium'; }
|
507
|
+
else if (model.indexOf('cisco') >= 0) { result = 'Cisco'; }
|
508
|
+
else if (model.indexOf('marvel') >= 0) { result = 'Marvel'; }
|
509
|
+
else if (model.indexOf('zyxel') >= 0) { result = 'Zyxel'; }
|
510
|
+
else if (model.indexOf('melanox') >= 0) { result = 'Melanox'; }
|
511
|
+
else if (model.indexOf('d-link') >= 0) { result = 'D-Link'; }
|
512
|
+
else if (model.indexOf('tp-link') >= 0) { result = 'TP-Link'; }
|
513
|
+
else if (model.indexOf('asus') >= 0) { result = 'Asus'; }
|
514
|
+
else if (model.indexOf('linksys') >= 0) { result = 'Linksys'; }
|
515
|
+
return result;
|
516
|
+
}
|
517
|
+
|
518
|
+
function wifiConnections(callback) {
|
519
|
+
|
520
|
+
return new Promise((resolve) => {
|
521
|
+
process.nextTick(() => {
|
522
|
+
const result = [];
|
523
|
+
|
524
|
+
if (_linux) {
|
525
|
+
const ifaces = ifaceListLinux();
|
526
|
+
const networkList = getWifiNetworkListNmi();
|
527
|
+
ifaces.forEach(ifaceDetail => {
|
528
|
+
const nmiDetails = nmiDeviceLinux(ifaceDetail.iface);
|
529
|
+
const wpaDetails = wpaConnectionLinux(ifaceDetail.iface);
|
530
|
+
const ssid = nmiDetails.ssid || wpaDetails.ssid;
|
531
|
+
const network = networkList.filter(nw => nw.ssid === ssid);
|
532
|
+
const nmiConnection = nmiConnectionLinux(ssid);
|
533
|
+
const channel = network && network.length && network[0].channel ? network[0].channel : (wpaDetails.channel ? wpaDetails.channel : null);
|
534
|
+
const bssid = network && network.length && network[0].bssid ? network[0].bssid : (wpaDetails.bssid ? wpaDetails.bssid : null);
|
535
|
+
if (ssid && bssid) {
|
536
|
+
result.push({
|
537
|
+
id: ifaceDetail.id,
|
538
|
+
iface: ifaceDetail.iface,
|
539
|
+
model: nmiDetails.product,
|
540
|
+
ssid,
|
541
|
+
bssid: network && network.length && network[0].bssid ? network[0].bssid : (wpaDetails.bssid ? wpaDetails.bssid : null),
|
542
|
+
channel,
|
543
|
+
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
|
544
|
+
type: nmiConnection.type ? nmiConnection.type : '802.11',
|
545
|
+
security: nmiConnection.security ? nmiConnection.security : (wpaDetails.security ? wpaDetails.security : null),
|
546
|
+
signalLevel: network && network.length && network[0].signalLevel ? network[0].signalLevel : null,
|
547
|
+
txRate: null
|
548
|
+
});
|
549
|
+
}
|
550
|
+
});
|
551
|
+
if (callback) {
|
552
|
+
callback(result);
|
553
|
+
}
|
554
|
+
resolve(result);
|
555
|
+
} else if (_darwin) {
|
556
|
+
let cmd = 'system_profiler SPNetworkDataType';
|
557
|
+
exec(cmd, function (error, stdout) {
|
558
|
+
const parts1 = stdout.toString().split('\n\n Wi-Fi:\n\n');
|
559
|
+
if (parts1.length > 1) {
|
560
|
+
const lines = parts1[1].split('\n\n')[0].split('\n');
|
561
|
+
const iface = util.getValue(lines, 'BSD Device Name', ':', true);
|
562
|
+
const model = util.getValue(lines, 'hardware', ':', true);
|
563
|
+
cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I';
|
564
|
+
exec(cmd, function (error, stdout) {
|
565
|
+
const lines2 = stdout.toString().split('\n');
|
566
|
+
if (lines.length > 10) {
|
567
|
+
const ssid = util.getValue(lines2, 'ssid', ':', true);
|
568
|
+
const bssid = util.getValue(lines2, 'bssid', ':', true);
|
569
|
+
const security = util.getValue(lines2, 'link auth', ':', true);
|
570
|
+
const txRate = util.getValue(lines2, 'lastTxRate', ':', true);
|
571
|
+
const channel = util.getValue(lines2, 'channel', ':', true).split(',')[0];
|
572
|
+
const type = '802.11';
|
573
|
+
const rssi = util.toInt(util.getValue(lines2, 'agrCtlRSSI', ':', true));
|
574
|
+
const noise = util.toInt(util.getValue(lines2, 'agrCtlNoise', ':', true));
|
575
|
+
const signalLevel = rssi - noise;
|
576
|
+
if (ssid || bssid) {
|
577
|
+
result.push({
|
578
|
+
id: 'Wi-Fi',
|
579
|
+
iface,
|
580
|
+
model,
|
581
|
+
ssid,
|
582
|
+
bssid,
|
583
|
+
channel: util.toInt(channel),
|
584
|
+
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
|
585
|
+
type,
|
586
|
+
security,
|
587
|
+
signalLevel,
|
588
|
+
txRate
|
589
|
+
});
|
590
|
+
}
|
591
|
+
}
|
592
|
+
if (callback) {
|
593
|
+
callback(result);
|
594
|
+
}
|
595
|
+
resolve(result);
|
596
|
+
});
|
597
|
+
}
|
598
|
+
});
|
599
|
+
} else if (_windows) {
|
600
|
+
let cmd = 'netsh wlan show interfaces';
|
601
|
+
util.powerShell(cmd).then(function (stdout) {
|
602
|
+
const allLines = stdout.toString().split('\r\n');
|
603
|
+
for (let i = 0; i < allLines.length; i++) {
|
604
|
+
allLines[i] = allLines[i].trim();
|
605
|
+
}
|
606
|
+
const parts = allLines.join('\r\n').split(':\r\n\r\n');
|
607
|
+
parts.shift();
|
608
|
+
parts.forEach(part => {
|
609
|
+
const lines = part.split('\r\n');
|
610
|
+
if (lines.length >= 5) {
|
611
|
+
const iface = lines[0].indexOf(':') >= 0 ? lines[0].split(':')[1].trim() : '';
|
612
|
+
const model = lines[1].indexOf(':') >= 0 ? lines[1].split(':')[1].trim() : '';
|
613
|
+
const id = lines[2].indexOf(':') >= 0 ? lines[2].split(':')[1].trim() : '';
|
614
|
+
const ssid = util.getValue(lines, 'SSID', ':', true);
|
615
|
+
const bssid = util.getValue(lines, 'BSSID', ':', true);
|
616
|
+
const signalLevel = util.getValue(lines, 'Signal', ':', true);
|
617
|
+
const type = util.getValue(lines, 'Radio type', ':', true) || util.getValue(lines, 'Type de radio', ':', true) || util.getValue(lines, 'Funktyp', ':', true) || null;
|
618
|
+
const security = util.getValue(lines, 'authentication', ':', true) || util.getValue(lines, 'Authentification', ':', true) || util.getValue(lines, 'Authentifizierung', ':', true) || null;
|
619
|
+
const channel = util.getValue(lines, 'Channel', ':', true) || util.getValue(lines, 'Canal', ':', true) || util.getValue(lines, 'Kanal', ':', true) || null;
|
620
|
+
const txRate = util.getValue(lines, 'Transmit rate (mbps)', ':', true) || util.getValue(lines, 'Transmission (mbit/s)', ':', true) || util.getValue(lines, 'Empfangsrate (MBit/s)', ':', true) || null;
|
621
|
+
if (model && id && ssid && bssid) {
|
622
|
+
result.push({
|
623
|
+
id,
|
624
|
+
iface,
|
625
|
+
model,
|
626
|
+
ssid,
|
627
|
+
bssid,
|
628
|
+
channel: util.toInt(channel),
|
629
|
+
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
|
630
|
+
type,
|
631
|
+
security,
|
632
|
+
signalLevel,
|
633
|
+
txRate: util.toInt(txRate) || null
|
634
|
+
});
|
635
|
+
}
|
636
|
+
}
|
637
|
+
});
|
638
|
+
if (callback) {
|
639
|
+
callback(result);
|
640
|
+
}
|
641
|
+
resolve(result);
|
642
|
+
});
|
643
|
+
} else {
|
644
|
+
if (callback) {
|
645
|
+
callback(result);
|
646
|
+
}
|
647
|
+
resolve(result);
|
648
|
+
}
|
649
|
+
});
|
650
|
+
});
|
651
|
+
}
|
652
|
+
|
653
|
+
exports.wifiConnections = wifiConnections;
|
654
|
+
|
655
|
+
function wifiInterfaces(callback) {
|
656
|
+
|
657
|
+
return new Promise((resolve) => {
|
658
|
+
process.nextTick(() => {
|
659
|
+
const result = [];
|
660
|
+
|
661
|
+
if (_linux) {
|
662
|
+
const ifaces = ifaceListLinux();
|
663
|
+
ifaces.forEach(ifaceDetail => {
|
664
|
+
const nmiDetails = nmiDeviceLinux(ifaceDetail.iface);
|
665
|
+
result.push({
|
666
|
+
id: ifaceDetail.id,
|
667
|
+
iface: ifaceDetail.iface,
|
668
|
+
model: nmiDetails.product ? nmiDetails.product : null,
|
669
|
+
vendor: nmiDetails.vendor ? nmiDetails.vendor : null,
|
670
|
+
mac: ifaceDetail.mac,
|
671
|
+
});
|
672
|
+
});
|
673
|
+
if (callback) {
|
674
|
+
callback(result);
|
675
|
+
}
|
676
|
+
resolve(result);
|
677
|
+
} else if (_darwin) {
|
678
|
+
let cmd = 'system_profiler SPNetworkDataType';
|
679
|
+
exec(cmd, function (error, stdout) {
|
680
|
+
const parts1 = stdout.toString().split('\n\n Wi-Fi:\n\n');
|
681
|
+
if (parts1.length > 1) {
|
682
|
+
const lines = parts1[1].split('\n\n')[0].split('\n');
|
683
|
+
const iface = util.getValue(lines, 'BSD Device Name', ':', true);
|
684
|
+
const mac = util.getValue(lines, 'MAC Address', ':', true);
|
685
|
+
const model = util.getValue(lines, 'hardware', ':', true);
|
686
|
+
result.push({
|
687
|
+
id: 'Wi-Fi',
|
688
|
+
iface,
|
689
|
+
model,
|
690
|
+
vendor: '',
|
691
|
+
mac
|
692
|
+
});
|
693
|
+
}
|
694
|
+
if (callback) {
|
695
|
+
callback(result);
|
696
|
+
}
|
697
|
+
resolve(result);
|
698
|
+
});
|
699
|
+
} else if (_windows) {
|
700
|
+
let cmd = 'netsh wlan show interfaces';
|
701
|
+
util.powerShell(cmd).then(function (stdout) {
|
702
|
+
const allLines = stdout.toString().split('\r\n');
|
703
|
+
for (let i = 0; i < allLines.length; i++) {
|
704
|
+
allLines[i] = allLines[i].trim();
|
705
|
+
}
|
706
|
+
const parts = allLines.join('\r\n').split(':\r\n\r\n');
|
707
|
+
parts.shift();
|
708
|
+
parts.forEach(part => {
|
709
|
+
const lines = part.split('\r\n');
|
710
|
+
if (lines.length >= 5) {
|
711
|
+
const iface = lines[0].indexOf(':') >= 0 ? lines[0].split(':')[1].trim() : '';
|
712
|
+
const model = lines[1].indexOf(':') >= 0 ? lines[1].split(':')[1].trim() : '';
|
713
|
+
const id = lines[2].indexOf(':') >= 0 ? lines[2].split(':')[1].trim() : '';
|
714
|
+
const macParts = lines[3].indexOf(':') >= 0 ? lines[3].split(':') : [];
|
715
|
+
macParts.shift();
|
716
|
+
const mac = macParts.join(':').trim();
|
717
|
+
const vendor = getVendor(model);
|
718
|
+
if (iface && model && id && mac) {
|
719
|
+
result.push({
|
720
|
+
id,
|
721
|
+
iface,
|
722
|
+
model,
|
723
|
+
vendor,
|
724
|
+
mac,
|
725
|
+
});
|
726
|
+
}
|
727
|
+
}
|
728
|
+
});
|
729
|
+
if (callback) {
|
730
|
+
callback(result);
|
731
|
+
}
|
732
|
+
resolve(result);
|
733
|
+
});
|
734
|
+
} else {
|
735
|
+
if (callback) {
|
736
|
+
callback(result);
|
737
|
+
}
|
738
|
+
resolve(result);
|
739
|
+
}
|
740
|
+
});
|
741
|
+
});
|
742
|
+
}
|
743
|
+
|
744
|
+
exports.wifiInterfaces = wifiInterfaces;
|