sysiddr5 1.0.1-beta-3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sysiddr5 might be problematic. Click here for more details.

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;