]> code.delx.au - monosys/blob - wifi-scan
wifi-scan rewrite
[monosys] / wifi-scan
1 #!/usr/bin/env node
2
3 const {exec} = require('child_process');
4
5 function execAsync(command, opts) {
6 return new Promise((resolve, reject) => {
7 exec(command, opts, (error, stdout, stderr) => {
8 if (error) {
9 reject(error);
10 } else {
11 resolve({stdout, stderr});
12 }
13 });
14 });
15 }
16
17 function sleep(n) {
18 return new Promise((resolve) => setTimeout(resolve, n));
19 }
20
21 async function findInterface() {
22 const {stdout} = await execAsync('iw dev');
23 const lines = stdout.split('\n')
24 .map((line) => line.trim())
25 .filter((line) => line.startsWith('Interface '))
26 .map((line) => line.split(' ')[1]);
27 return lines[0];
28 }
29
30 async function scanInterface(interface) {
31 const {stdout} = await execAsync(`sudo iw dev ${interface} scan`);
32
33 const results = [];
34 let partial = null;
35
36 for (let line of stdout.split('\n')) {
37 if (line.startsWith('BSS ')) {
38 finishPartial();
39 partial = {};
40 partial.bssid = line.match(/[a-z0-9:]+/)[0];
41 }
42
43 line = line.trim()
44 if (line.startsWith('SSID: ')) {
45 partial.ssid = line.split(':')[1].trim();
46 }
47 if (line.startsWith('signal: ')) {
48 partial.signal = line.split(':')[1].trim();
49 }
50 if (line.startsWith('DS Parameter set: channel')) {
51 partial.channel = line.split(':')[1].trim();
52 }
53 }
54
55 function finishPartial() {
56 if (!partial) {
57 return;
58 }
59
60 partial.ssid = partial.ssid || '';
61 partial.channel = partial.channel || '';
62
63 const sortKey = [
64 parseFloat(partial.signal),
65 parseInt(partial.channel.split(' ')[1])
66 ];
67
68 results.push([sortKey, partial]);
69 }
70
71 return results
72 .sort()
73 .map(([_, {bssid, ssid, signal, channel}]) => {
74 ssid = ssid.padStart(40, ' ');
75 channel = channel.padEnd(10, ' ');
76 return `${signal} ${channel} ${ssid} ${bssid}`;
77 })
78 .join('\n') + '\n';
79 }
80
81 async function main() {
82 const interface = await findInterface();
83
84 for (;;) {
85 const scanResult = await scanInterface(interface).catch((err) => err.toString());
86 process.stdout.write('\033[2J\033[0f');
87 process.stdout.write(scanResult);
88 await sleep(3000);
89 }
90 }
91
92 main().catch((err) => {
93 console.log('Unhandled error!', err);
94 process.exit(1);
95 });