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