• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stephendade / Rpanion-server / 15678546196

16 Jun 2025 10:38AM UTC coverage: 35.894% (+0.2%) from 35.71%
15678546196

Pull #288

github

web-flow
Merge 706cb0516 into c16840c55
Pull Request #288: Deb packaging

272 of 996 branches covered (27.31%)

Branch coverage included in aggregate %.

35 of 155 new or added lines in 12 files covered. (22.58%)

19 existing lines in 10 files now uncovered.

896 of 2258 relevant lines covered (39.68%)

2.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.02
/server/networkManager.js
1
const { exec, execSync, execFile } = require('child_process')
3✔
2

3
function getAdapters (callback) {
4
  // Get all network adapter name, type and states
5
  exec('nmcli -t -f device,type,state dev', (error, stdout, stderr) => {
3✔
6
    const netStatusList = []
3✔
7
    if (stderr) {
3!
8
      console.error(`exec error: ${error}`)
×
9
      return callback(stderr)
×
10
    } else {
11
      stdout.split('\n').forEach(function (item) {
3✔
12
        const device = item.split(':')
12✔
13
        if (device.length === 3 && device[1] !== 'loopback' && device[1] !== 'bridge' && device[1] !== 'wifi-p2p' && device[1] !== 'can0' && device[1] !== 'can1') {
12✔
14
          console.log('Adding Network device ' + device[0])
3✔
15
          // if wifi, check for avail channels
16
          const freqList = []
3✔
17
          freqList.push({ value: 0, freq: 0, text: 'auto', band: 0 })
3✔
18
          if (device[1] === 'wifi') {
3!
19
            try {
×
20
              const output = execSync('iwlist ' + device[0] + ' channel')
×
21
              const allFreqs = output.toString().split('\n')
×
22
              for (let i = 0, len = allFreqs.length; i < len; i++) {
×
23
                if (allFreqs[i].includes('Channel ') && !allFreqs[i].includes('Current')) {
×
24
                  const ln = allFreqs[i].split(' ').filter(i => i)
×
25
                  if (ln.length > 4) {
×
26
                    freqList.push({ value: parseInt(ln[1]), freq: ln[3], text: '' + ln[1] + ' (' + ln[3] + ' GHz)', band: ((parseFloat(ln[3]) < 3) ? 'bg' : 'a') })
×
27
                  }
28
                }
29
              }
30
            } catch (e) {
31
              console.error('exec error: ' + e)
×
32
              return callback(e)
×
33
            }
34
          }
35
          netStatusList.push({ value: device[0], label: device[0] + ' (' + device[1] + ')', type: device[1], state: device[2], channels: freqList, isDisabled: !!((device[2] === 'unavailable' && device[1] === 'wifi')) })
3!
36
        }
37
      })
38
    }
39
    return callback(null, netStatusList)
3✔
40
  })
41
}
42

43
function getWirelessStatus (callback) {
44
  // get the "flight mode" status of the wireless (wifi) adapters
45
  exec('nmcli -t radio wifi', (error, stdout, stderr) => {
×
46
    if (stderr) {
×
47
      console.error(`exec error: ${error}`)
×
48
      return callback(stderr)
×
49
    } else {
50
      console.log('Wifi is ' + stdout)
×
51
      if (stdout === 'enabled\n') {
×
52
        return callback(null, true)
×
53
      } else {
54
        return callback(null, false)
×
55
      }
56
    }
57
  })
58
}
59

60
function setWirelessStatus (status, callback) {
61
  exec('nmcli radio wifi ' + ((status === true) ? 'on' : 'off') + ' && nmcli -t radio wifi', (error, stdout, stderr) => {
×
62
    if (stderr) {
×
63
      console.error(`exec error: ${error}`)
×
64
      return callback(stderr)
×
65
    } else {
66
      if (stdout === 'enabled\n') {
×
67
        return callback(null, true)
×
68
      } else {
69
        return callback(null, false)
×
70
      }
71
    }
72
  })
73
}
74

75
function activateConnection (conName, callback) {
76
  // activate the connection (by id)
77
  // assumed that conName is a valid UUID
NEW
78
  execFile('nmcli', ['connection', 'mod', conName, 'connection.autoconnect', 'yes'], (error, stdout, stderr) => {
×
79
    if (stderr) {
×
80
      console.error(`exec error: ${error}`)
×
81
      return callback(stderr)
×
82
    } else {
NEW
83
      execFile('nmcli', ['connection', 'up', conName], (error, stdout, stderr) => {
×
84
        if (stderr) {
×
85
          console.error(`exec error: ${error}`)
×
86
          return callback(stderr)
×
87
        } else {
88
          console.log('Activated network: ' + conName)
×
89
          return callback(null, 'OK')
×
90
        }
91
      })
92
    }
93
  })
94
}
95

96
function deactivateConnection (conName, callback) {
97
  // deactivate the connection (by id)
98
  // assumed that conName is a valid UUID
99
  // need to disable auto-connect too
NEW
100
  execFile('nmcli', ['connection', 'mod', conName, 'connection.autoconnect', 'no'], (error, stdout, stderr) => {
×
101
    if (stderr) {
×
102
      console.error(`exec error: ${error}`)
×
103
      return callback(stderr)
×
104
    } else {
NEW
105
      execFile('nmcli', ['connection', 'down', conName], (error, stdout, stderr) => {
×
106
        if (stderr) {
×
107
          console.error(`exec error: ${error}`)
×
108
          return callback(stderr)
×
109
        } else {
110
          console.log('Dectivated network: ' + conName)
×
111
          return callback(null, 'OK')
×
112
        }
113
      })
114
    }
115
  })
116
}
117

118
function getPrimaryWifiDevice(callback) {
119
  exec('iw dev | grep Interface | awk \'{print $2}\'', (error, stdout, stderr) => {
×
120
      if (error) {
×
121
          console.error(`exec error: ${error}`)
×
122
          return callback(error)
×
123
      }
124
      if (stderr) {
×
125
          console.error(`stderr: ${stderr}`)
×
126
          return callback(new Error(stderr))
×
127
      }
128
      const device = stdout.trim().split('\n')[0]
×
129
      callback(null, device)
×
130
  });
131
}
132

133
function getWifiScan(callback) {
134
  getPrimaryWifiDevice((error, device) => {
×
135
      if (error) {
×
136
          return callback(error)
×
137
      }
138

NEW
139
      exec(`iwlist ${device} scan`, (error, stdout, stderr) => {
×
140
          if (error) {
×
141
              console.error(`exec error: ${error}`)
×
142
              return callback(error)
×
143
          }
144
          if (stderr) {
×
145
              console.error(`stderr: ${stderr}`)
×
146
              return callback(new Error(stderr))
×
147
          }
148

149
          const ssidRegex = /ESSID:"([^"]+)"/g
×
150
          const signalRegex = /Signal level=(-?\d+)/g
×
151
          const wpaRegex = /WPA[1-2]?/g
×
152

153
          let ssidMatch, signalMatch, wpaMatch
154
          const results = []
×
155

156
          while ((ssidMatch = ssidRegex.exec(stdout)) !== null) {
×
157
              signalMatch = signalRegex.exec(stdout)
×
158
              wpaMatch = wpaRegex.exec(stdout)
×
159

160
              results.push({
×
161
                  ssid: ssidMatch[1],
162
                  signal: signalMatch ? signalMatch[1] : 'N/A',
×
163
                  security: wpaMatch ? wpaMatch[0] : 'open'
×
164
              });
165
          }
166
          return callback(null, results)
×
167
      });
168
  });
169
}
170

171
function addConnection (conNameStr, conType, conAdapter, conSettings, callback) {
172
  // add a new connection with name conNameStr and settings
173
  // conSettings
174
  // nmcli connection add type wifi ifname $IFNAME con-name $APNAME ssid $SSID
175
  // due to the multiple edits, we need to set autoconnect to "no"
176
  if (conType === 'wifi') {
×
NEW
177
    exec('nmcli connection add type ' + conType + ' ifname ' + conAdapter +
×
178
             ' con-name ' + conNameStr + ' ssid \'' + conSettings.ssid.value + '\' 802-11-wireless.mode ' +
179
             conSettings.mode.value + (Object.keys(conSettings.band).length ? (' 802-11-wireless.band ' + conSettings.band.value) : '') +
×
180
             (Object.keys(conSettings.channel).length ? (' 802-11-wireless.channel ' + (conSettings.channel.value === '0' ? '\'\'' : conSettings.channel.value)) : '') +
×
181
             ' ipv4.method ' + conSettings.ipaddresstype.value + ' connection.autoconnect no ' + ' && ' +
182
             'nmcli -g connection.uuid con show ' + conNameStr, (error, stdout, stderr) => {
183
      if (stderr) {
×
184
        console.error(`exec error: ${error}`)
×
185
        return callback(stderr)
×
186
      } else {
187
        // once the network is created, add in the settings
188
        const conUUID = stdout.split('\n')[stdout.split('\n').length - 2]
×
189
        console.log('Added network Wifi: ' + conNameStr + ' - ' + conAdapter + ' - ' + conUUID)
×
190
        this.editConnection(conUUID, conSettings, (err) => {
×
191
          // set autoconnect back to "yes"
NEW
192
          exec('nmcli connection mod ' + conUUID + ' connection.autoconnect yes', (error, stdout, stderr) => {
×
193
            if (!err && !stderr) {
×
NEW
194
              console.log('addConnection() wifi OK')
×
195
              return callback(null, 'AddOK')
×
196
            } else {
NEW
197
              console.log('Error in editConnection() wifi addcon ', { message: err })
×
NEW
198
              console.log('Error in editConnection() wifi addcon ', { message: stderr })
×
UNCOV
199
              return callback(err)
×
200
            }
201
          })
202
        })
203
      }
204
    })
205
  } else {
NEW
206
    exec('nmcli connection add type ' + conType + ' ifname ' + conAdapter +
×
207
             ' con-name ' + conNameStr + ' connection.autoconnect no ' + '&&' +
208
             'nmcli -g connection.uuid con show ' + conNameStr, (error, stdout, stderr) => {
209
      if (stderr) {
×
210
        console.error(`exec error: ${error}`)
×
211
        return callback(stderr)
×
212
      } else {
213
        // once the network is created, add in the settings
214
        const conUUID = stdout.split('\n')[stdout.split('\n').length - 2]
×
215
        console.log('Added network Wired: ' + conNameStr + ' - ' + conAdapter + ' - ' + conUUID)
×
216
        this.editConnection(conUUID, conSettings, (err) => {
×
217
          // set autoconnect back to "yes"
NEW
218
          exec('nmcli connection mod ' + conUUID + ' connection.autoconnect yes', (error, stdout, stderr) => {
×
219
            if (!err && !stderr) {
×
NEW
220
              console.log('addConnection() wired OK')
×
221
              return callback(null, 'AddOK')
×
222
            } else {
NEW
223
              console.log('Error in editConnection() wired addcon ', { message: err })
×
NEW
224
              console.log('Error in editConnection() wired addcon ', { message: stderr })
×
UNCOV
225
              return callback(err)
×
226
            }
227
          })
228
        })
229
      }
230
    })
231
  }
232
}
233

234
function editConnection (conName, conSettings, callback) {
235
  // edit an existing connection
236
  // assumed that conName is a valid UUID
237
  // there are 4 types of edits - AttachedInterface, IP, Wifi security, Wifi AP
238
  // small amount of callback hell here :(
239
  console.log(conSettings)
×
240
  editConnectionAttached(conName, conSettings, (errAttach) => {
×
241
    console.log('Attach')
×
242
    if (!errAttach) {
×
243
      editConnectionIP(conName, conSettings, (errIP) => {
×
244
        console.log('IP')
×
245
        if (!errIP) {
×
246
          editConnectionPSK(conName, conSettings, (errPSK) => {
×
247
            console.log('PSK')
×
248
            if (!errPSK) {
×
249
              editConnectionAPClient(conName, conSettings, (errAP) => {
×
250
                console.log('AP')
×
251
                if (!errAP) {
×
252
                  return callback(null, 'EditOK')
×
253
                } else {
254
                  return callback(errAP)
×
255
                }
256
              })
257
            } else {
NEW
258
              console.log('Error in editConnection() errPSK ', { message: errPSK })
×
259
              return callback(errPSK)
×
260
            }
261
          })
262
        } else {
NEW
263
          console.log('Error in editConnection() errIP ', { message: errIP })
×
264
          return callback(errIP)
×
265
        }
266
      })
267
    } else {
NEW
268
      console.log('Error in editConnection() errAttach ', { message: errAttach })
×
269
      return callback(errAttach)
×
270
    }
271
  })
272
}
273

274
function editConnectionAttached (conName, conSettings, callback) {
275
  // edit the attached interface for a connection
276
  if (conSettings.attachedIface.value === '&quot;&quot;' || conSettings.attachedIface.value === 'undefined') {
×
277
    conSettings.attachedIface.value = '""'
×
278
  }
279

NEW
280
  execFile('nmcli', ['connection', 'mod', conName, 'connection.interface-name', conSettings.attachedIface.value], (error, stdout, stderr) => {
×
281
    if (stderr) {
×
282
      console.error(`exec error: ${error}`)
×
283
      return callback(stderr)
×
284
    } else {
285
      console.log('Edited network Attachment: ' + conName + ' to ' + conSettings.attachedIface.value)
×
286
      return callback(null, 'EditAttachOK')
×
287
    }
288
  })
289
}
290

291
function editConnectionIP (conName, conSettings, callback) {
292
  // first sort out the IP Addressing (DHCP/static) for LAN and Wifi Client
293
  if (Object.keys(conSettings.ssid).length === 0 || conSettings.mode.value === 'infrastructure') {
×
294
    if (conSettings.ipaddresstype.value === 'auto') {
×
NEW
295
      execFile('nmcli', ['connection', 'mod', conName, 'ipv4.method', 'auto', 'ipv4.addresses', ''], (error, stdout, stderr) => {
×
296
        if (stderr) {
×
297
          console.error(`exec error: ${error}`)
×
298
          return callback(stderr)
×
299
        } else {
300
          console.log('Edited network IP Auto: ' + conName)
×
301
          return callback(null, 'EditOK')
×
302
        }
303
      })
304
    } else if (Object.keys(conSettings.ipaddress).length !== 0 && Object.keys(conSettings.subnet).length !== 0) {
×
NEW
305
      execFile('nmcli', ['connection', 'mod', conName, 'ipv4.addresses', conSettings.ipaddress.value + '/' +
×
306
        netmask2CIDR(conSettings.subnet.value), 'ipv4.method', conSettings.ipaddresstype.value], (error, stdout, stderr) => {
307
        if (stderr) {
×
308
          console.error(`exec error: ${error}`)
×
309
          return callback(stderr)
×
310
        } else {
311
          console.log('Edited network IP manual: ' + conName)
×
312
          return callback(null, 'EditOK')
×
313
        }
314
      })
315
    }
316
  } else {
NEW
317
    console.log('editConnectionIP() not required')
×
318
    return callback(null, 'EditNotRequired')
×
319
  }
320
}
321

322
function editConnectionPSK (conName, conSettings, callback) {
323
  // now sort out Wifi client/ap settings - password and security type
324
  if (Object.keys(conSettings.mode).length === 0) {
×
325
    return callback(null, 'EditNotRequired')
×
326
  }
327
  if (conSettings.mode.value === 'infrastructure' || conSettings.mode.value === 'ap') {
×
328
    // psk network
329
    if (conSettings.wpaType.value !== 'none' &&
×
330
            Object.keys(conSettings.ssid).length !== 0 &&
331
            Object.keys(conSettings.password).length !== 0) {
NEW
332
            execFile('nmcli', ['connection', 'mod', conName, '802-11-wireless-security.key-mgmt', conSettings.wpaType.value], (error, stdout, stderr) => {
×
333
        if (stderr) {
×
334
          console.error(`exec error: ${error}`)
×
335
          return callback(stderr)
×
336
        } else {
NEW
337
          execFile('nmcli', ['-s', 'connection', 'mod', conName, '802-11-wireless-security.pairwise', 'ccmp', '802-11-wireless-security.psk', conSettings.password.value], (error, stdout, stderr) => {
×
338
            if (stderr) {
×
339
              console.error(`exec error: ${error}`)
×
340
              return callback(stderr)
×
341
            } else {
342
              console.log('Edited Wifi psk: ' + conName)
×
343
              return callback(null, 'OK')
×
344
            }
345
          })
346
        }
347
      })
348
    }
349
    else if (conSettings.wpaType.value === 'none' &&
×
350
                 Object.keys(conSettings.ssid).length !== 0) {
NEW
351
      execFile('nmcli', ['connection', 'mod', conName, 'remove', '802-11-wireless-security'], (error, stdout, stderr) => {
×
352
        if (stderr) {
×
353
          console.error(`exec error: ${error}`)
×
354
          return callback(stderr)
×
355
        } else {
356
          console.log('Edited Wifi no-psk: ' + conName)
×
357
          return callback(null, 'OK')
×
358
        }
359
      })
360
    }
361
  } else {
NEW
362
    console.log('editConnectionPSK() not required')
×
363
    return callback(null, 'EditNotRequired')
×
364
  }
365
}
366

367
function editConnectionAPClient (conName, conSettings, callback) {
368
  // now sort out Wifi ap or client settings - ssid, band, starting ip
369
  if (Object.keys(conSettings.mode).length === 0) {
×
370
    return callback(null, 'EditNotRequired')
×
371
  }
372
  if (conSettings.mode.value === 'ap') {
×
373
    if (Object.keys(conSettings.ssid).length !== 0 &&
×
374
            Object.keys(conSettings.band).length !== 0 &&
375
            Object.keys(conSettings.channel).length !== 0 &&
376
            Object.keys(conSettings.ipaddress).length !== 0) {
NEW
377
      const cmds = ['connection', 'mod', conName, '802-11-wireless.ssid', conSettings.ssid.value,
×
378
        '802-11-wireless.band', conSettings.band.value, 'ipv4.addresses', conSettings.ipaddress.value + '/24']
379
      if (conSettings.channel.value !== '0') {
×
380
        cmds.push('802-11-wireless.channel', conSettings.channel.value)
×
381
      }
382
      if (conSettings.wpaType.value !== 'none') {
×
383
        cmds.push('802-11-wireless-security.group', 'ccmp', '802-11-wireless-security.wps-method', '1')
×
384
      }
NEW
385
      execFile('nmcli', cmds, (error, stdout, stderr) => {
×
386
        if (stderr) {
×
387
          console.error(`exec error: ${error}`)
×
388
          return callback(stderr)
×
389
        } else {
390
          console.log('Edited Wifi ap ssid/band: ' + conName)
×
391
          return callback(null, 'OK')
×
392
        }
393
      })
394
    } else {
395
      console.log('Badsettings in editConnectionAPClient')
×
396
      console.log(conSettings)
×
397
      return callback(null, 'BADARGS')
×
398
    }
399
  } else {
400
    // client connection - edit ssid if required
401
    if (Object.keys(conSettings.ssid).length !== 0) {
×
NEW
402
      execFile('nmcli', ['connection', 'mod', conName, '802-11-wireless.ssid', conSettings.ssid.value], (error, stdout, stderr) => {
×
403
        if (stderr) {
×
404
          console.error(`exec error: ${error}`)
×
405
          return callback(stderr)
×
406
        } else {
407
          console.log('Edited Wifi client ssid: ' + conName)
×
408
          return callback(null, 'OK')
×
409
        }
410
      })
411
    } else {
412
      console.log('Badsettings in editConnectionAPClient')
×
413
      console.log(conSettings)
×
414
      return callback(null, 'BADARGS')
×
415
    }
416
  }
417
}
418

419
function deleteConnection (conName, callback) {
420
  // delete the connection (by id)
421
  // assumed that conName is a valid UUID
NEW
422
  execFile('nmcli', ['connection', 'delete', conName], (error, stdout, stderr) => {
×
423
    if (stderr) {
×
424
      console.error(`exec error: ${error}`)
×
425
      return callback(stderr)
×
426
    } else {
427
      console.log('Deleted network: ' + conName)
×
428
      return callback(null, 'OK')
×
429
    }
430
  })
431
}
432

433
function getConnections (callback) {
434
  let output = ''
3✔
435
  const conStatusList = []
3✔
436
  try {
3✔
437
    output = execSync('nmcli -t -f NAME,UUID,TYPE,DEVICE connection show')
3✔
438
  } catch (e) {
439
    console.error('exec error: ' + e)
×
440
    return callback(e)
×
441
  }
442

443
  const allConns = output.toString().split('\n')
3✔
444
  for (let i = 0, len = allConns.length; i < len; i++) {
3✔
445
    const item = allConns[i]
3✔
446
    const connection = item.split(':')
3✔
447
    let curConn = {}
3✔
448
    let subout = ''
3✔
449
    if (connection.length == 4 || connection.length == 3) {
3!
450
      try {
×
451
        subout = execSync('nmcli -s -t -f connection.interface-name connection show ' + connection[1])
×
452
        subout = subout.toString().split(':')[1].trim()
×
453
      } catch (e) {
454
        console.error('exec error: ' + e)
×
455
        // return callback("");
456
      }
457
    }
458
    if (connection[3] === '' || connection[3] === '--') {
3!
459
      curConn = { value: connection[1], label: '', labelPre: connection[0], type: connection[2], state: '', attachedIface: subout }
×
460
      conStatusList.push(curConn)
×
461
    } else if (connection.length === 4) {
3!
462
      // active connection
463
      curConn = { value: connection[1], label: '', labelPre: connection[0], type: connection[2], state: connection[3], attachedIface: subout }
×
464
      conStatusList.push(curConn)
×
465
    }
466
    // if we're at the end, return callback
467
    if (i === allConns.length - 1) {
3!
468
      console.log('getConnections() got: ' + allConns.length)
3✔
469
      return callback(null, conStatusList)
3✔
470
    }
471
  }
472
}
473

474
function getConnectionDetails (conName, callback) {
475
  execFile('nmcli', ['-s', '-t', '-f', 'ipv4.addresses,802-11-wireless.band,ipv4.method,IP4.ADDRESS,802-11-wireless.ssid,802-11-wireless.mode,802-11-wireless-security.key-mgmt,802-11-wireless-security.psk,connection.interface-name,802-11-wireless.channel', 'connection', 'show', conName], (error, stdout, stderr) => {
×
476
    if (stderr) {
×
477
      // no connection with that name
478
      console.error(`exec error: ${error}`)
×
479
      return callback(stderr)
×
480
    } else {
481
      const ret = { DHCP: 'auto', IP: '', subnet: '', mode: '', wpaType: 'none', password: '' }
×
482
      stdout.split('\n').forEach(function (item) {
×
483
        if (item.split(':')[0] === '802-11-wireless.ssid') {
×
484
          ret.ssid = item.split(':')[1]
×
485
        } else if (item.split(':')[0] === '802-11-wireless.band') {
×
486
          if (item.split(':')[1] === '') {
×
487
            ret.band = 'bg'
×
488
          } else {
489
            ret.band = item.split(':')[1]
×
490
          }
491
        } else if (item.split(':')[0] === 'ipv4.method') {
×
492
          ret.DHCP = item.split(':')[1]
×
493
        }
494
        // DHCP IP, if using DHCP
495
        else if (item.split(':')[0] === 'IP4.ADDRESS[1]' && item.split(':').length > 1 && item.split(':')[1] !== '') {
×
496
          ret.IP = item.split(':')[1].split('/')[0]
×
497
          ret.subnet = CIDR2netmask(item.split(':')[1].split('/')[1])
×
498
        }
499
        // static IP
500
        else if (item.split(':')[0] === 'ipv4.addresses' && item.split(':').length > 1 && item.split(':')[1] !== '') {
×
501
          ret.IP = item.split(':')[1].split('/')[0]
×
502
          ret.subnet = CIDR2netmask(item.split(':')[1].split('/')[1])
×
503
        } else if (item.split(':')[0] === '802-11-wireless.mode') {
×
504
          ret.mode = item.split(':')[1]
×
505
        } else if (item.split(':')[0] === '802-11-wireless-security.key-mgmt') {
×
506
          ret.wpaType = item.split(':')[1]
×
507
        } else if (item.split(':')[0] === '802-11-wireless-security.psk') {
×
508
          ret.password = item.split(':')[1]
×
509
        } else if (item.split(':')[0] === 'connection.interface-name') {
×
510
          ret.attachedIface = item.split(':')[1]
×
511
        } else if (item.split(':')[0] === '802-11-wireless.channel') {
×
512
          ret.channel = item.split(':')[1]
×
513
        }
514
      })
515
      return callback(null, ret)
×
516
    }
517
  })
518
}
519

520
function CIDR2netmask (bitCountstr) {
521
  const mask = []
×
522
  let bitCount = parseInt(bitCountstr)
×
523
  // console.log(bitCountstr);
524
  for (let i = 0; i < 4; i++) {
×
525
    const n = Math.min(bitCount, 8)
×
526
    // console.log(bitCount);
527
    mask.push(256 - Math.pow(2, 8 - n))
×
528
    bitCount -= n
×
529
  }
530
  return mask.join('.')
×
531
}
532

533
function netmask2CIDR (mask) {
534
  let cidr = ''
×
535
  for (const m of mask.split('.')) {
×
536
    if (parseInt(m) > 255) { throw 'ERROR: Invalid Netmask' } // Check each group is 0-255
×
537
    if (parseInt(m) > 0 && parseInt(m) < 128) { throw 'ERROR: Invalid Netmask' }
×
538

539
    cidr += (m >>> 0).toString(2)
×
540
  }
541
  // Condition to check for validity of the netmask
542
  if (cidr.substring(cidr.search('0'), 32).search('1') !== -1) {
×
NEW
543
    console.log('Error in netmask2CIDR() ', { message: mask })
×
544
    throw 'ERROR: Invalid Netmask ' + mask
×
545
  }
546
  return cidr.split('1').length - 1
×
547
}
548

549
module.exports = {
3✔
550
  getAdapters,
551
  getConnections,
552
  getConnectionDetails,
553
  activateConnection,
554
  deleteConnection,
555
  editConnection,
556
  addConnection,
557
  deactivateConnection,
558
  getWirelessStatus,
559
  setWirelessStatus,
560
  getWifiScan
561
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc