1 | <?php |
||||
2 | /** |
||||
3 | * ArubaInstant.php |
||||
4 | * |
||||
5 | * HPE Aruba Instant |
||||
6 | * |
||||
7 | * |
||||
8 | * This program is free software: you can redistribute it and/or modify |
||||
9 | * it under the terms of the GNU General Public License as published by |
||||
10 | * the Free Software Foundation, either version 3 of the License, or |
||||
11 | * (at your option) any later version. |
||||
12 | * |
||||
13 | * This program is distributed in the hope that it will be useful, |
||||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the |
||||
16 | * GNU General Public License for more details. |
||||
17 | * |
||||
18 | * You should have received a copy of the GNU General Public License |
||||
19 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
20 | * |
||||
21 | * @link https://www.librenms.org |
||||
22 | * |
||||
23 | * @copyright 2019 Timothy Willey |
||||
24 | * @author Timothy Willey <[email protected]> |
||||
25 | */ |
||||
26 | |||||
27 | namespace LibreNMS\OS; |
||||
28 | |||||
29 | use App\Models\Device; |
||||
30 | use LibreNMS\Device\Processor; |
||||
31 | use LibreNMS\Device\WirelessSensor; |
||||
32 | use LibreNMS\Interfaces\Discovery\OSDiscovery; |
||||
33 | use LibreNMS\Interfaces\Discovery\ProcessorDiscovery; |
||||
34 | use LibreNMS\Interfaces\Discovery\Sensors\WirelessApCountDiscovery; |
||||
35 | use LibreNMS\Interfaces\Discovery\Sensors\WirelessClientsDiscovery; |
||||
36 | use LibreNMS\Interfaces\Discovery\Sensors\WirelessFrequencyDiscovery; |
||||
37 | use LibreNMS\Interfaces\Discovery\Sensors\WirelessNoiseFloorDiscovery; |
||||
38 | use LibreNMS\Interfaces\Discovery\Sensors\WirelessPowerDiscovery; |
||||
39 | use LibreNMS\Interfaces\Discovery\Sensors\WirelessUtilizationDiscovery; |
||||
40 | use LibreNMS\Interfaces\Polling\Sensors\WirelessApCountPolling; |
||||
41 | use LibreNMS\Interfaces\Polling\Sensors\WirelessClientsPolling; |
||||
42 | use LibreNMS\Interfaces\Polling\Sensors\WirelessFrequencyPolling; |
||||
43 | use LibreNMS\OS; |
||||
44 | use LibreNMS\Util\Rewrite; |
||||
45 | |||||
46 | class ArubaInstant extends OS implements |
||||
47 | OSDiscovery, |
||||
48 | ProcessorDiscovery, |
||||
49 | WirelessApCountDiscovery, |
||||
50 | WirelessApCountPolling, |
||||
51 | WirelessClientsDiscovery, |
||||
52 | WirelessClientsPolling, |
||||
53 | WirelessFrequencyDiscovery, |
||||
54 | WirelessFrequencyPolling, |
||||
55 | WirelessNoiseFloorDiscovery, |
||||
56 | WirelessPowerDiscovery, |
||||
57 | WirelessUtilizationDiscovery |
||||
58 | { |
||||
59 | public function discoverOS(Device $device): void |
||||
60 | { |
||||
61 | parent::discoverOS($device); // yaml |
||||
62 | $device->serial = snmp_getnext($this->getDeviceArray(), 'aiAPSerialNum', '-Oqv', 'AI-AP-MIB'); |
||||
63 | } |
||||
64 | |||||
65 | /** |
||||
66 | * Discover processors. |
||||
67 | * Returns an array of LibreNMS\Device\Processor objects that have been discovered |
||||
68 | * |
||||
69 | * @return array Processors |
||||
70 | */ |
||||
71 | public function discoverProcessors() |
||||
72 | { |
||||
73 | $processors = []; |
||||
74 | $ai_mib = 'AI-AP-MIB'; |
||||
75 | $ai_ap_data = $this->getCacheTable('aiAccessPointEntry', $ai_mib); |
||||
76 | |||||
77 | foreach ($ai_ap_data as $ai_ap => $ai_ap_oid) { |
||||
78 | $value = $ai_ap_oid['aiAPCPUUtilization']; |
||||
79 | $combined_oid = sprintf('%s::%s.%s', $ai_mib, 'aiAPCPUUtilization', Rewrite::oidMac($ai_ap)); |
||||
80 | $oid = snmp_translate($combined_oid, 'ALL', 'arubaos', '-On'); |
||||
81 | $description = $ai_ap_data[$ai_ap]['aiAPSerialNum']; |
||||
82 | $processors[] = Processor::discover('aruba-instant', $this->getDeviceId(), $oid, Rewrite::macToHex($ai_ap), $description, 1, $value); |
||||
83 | } // end foreach |
||||
84 | |||||
85 | return $processors; |
||||
86 | } |
||||
87 | |||||
88 | /** |
||||
89 | * Discover wireless client counts. Type is clients. |
||||
90 | * Returns an array of LibreNMS\Device\Sensor objects that have been discovered |
||||
91 | * |
||||
92 | * @return array Sensors |
||||
93 | */ |
||||
94 | public function discoverWirelessClients() |
||||
95 | { |
||||
96 | $sensors = []; |
||||
97 | $device = $this->getDeviceArray(); |
||||
98 | $ai_mib = 'AI-AP-MIB'; |
||||
99 | |||||
100 | if (intval(explode('.', $device['version'])[0]) >= 8 && intval(explode('.', $device['version'])[1]) >= 4) { |
||||
101 | // version is at least 8.4.0.0 |
||||
102 | $ssid_data = $this->getCacheTable('aiWlanSSIDEntry', $ai_mib); |
||||
103 | |||||
104 | $ap_data = array_merge_recursive( |
||||
105 | $this->getCacheTable('aiAccessPointEntry', $ai_mib), |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
106 | $this->getCacheTable('aiRadioClientNum', $ai_mib) |
||||
107 | ); |
||||
108 | |||||
109 | $oids = []; |
||||
110 | $total_clients = 0; |
||||
111 | |||||
112 | // Clients Per SSID |
||||
113 | foreach ($ssid_data as $index => $entry) { |
||||
114 | $combined_oid = sprintf('%s::%s.%s', $ai_mib, 'aiSSIDClientNum', $index); |
||||
115 | $oid = snmp_translate($combined_oid, 'ALL', 'arubaos', '-On'); |
||||
116 | $description = sprintf('SSID %s Clients', $entry['aiSSID']); |
||||
117 | $oids[] = $oid; |
||||
118 | $total_clients += $entry['aiSSIDClientNum']; |
||||
119 | $sensors[] = new WirelessSensor('clients', $this->getDeviceId(), $oid, 'aruba-instant', $index, $description, $entry['aiSSIDClientNum']); |
||||
120 | } |
||||
121 | |||||
122 | // Total Clients across all SSIDs |
||||
123 | $sensors[] = new WirelessSensor('clients', $this->getDeviceId(), $oids, 'aruba-instant', 'total-clients', 'Total Clients', $total_clients); |
||||
124 | |||||
125 | // Clients Per Radio |
||||
126 | foreach ($ap_data as $index => $entry) { |
||||
127 | foreach ($entry['aiRadioClientNum'] as $radio => $value) { |
||||
128 | $combined_oid = sprintf('%s::%s.%s.%s', $ai_mib, 'aiRadioClientNum', Rewrite::oidMac($index), $radio); |
||||
129 | $oid = snmp_translate($combined_oid, 'ALL', 'arubaos', '-On'); |
||||
130 | $description = sprintf('%s Radio %s', $entry['aiAPSerialNum'], $radio); |
||||
131 | $sensor_index = sprintf('%s.%s', Rewrite::macToHex($index), $radio); |
||||
132 | $sensors[] = new WirelessSensor('clients', $this->getDeviceId(), $oid, 'aruba-instant', $sensor_index, $description, $value); |
||||
133 | } |
||||
134 | } |
||||
135 | } else { |
||||
136 | // version is lower than 8.4.0.0 |
||||
137 | // fetch the MAC addresses of currently connected clients, then count them to get an overall total |
||||
138 | $client_data = $this->getCacheTable('aiClientMACAddress', $ai_mib); |
||||
139 | |||||
140 | $total_clients = sizeof($client_data); |
||||
0 ignored issues
–
show
It seems like
$client_data can also be of type null ; however, parameter $value of sizeof() does only seem to accept Countable|array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
141 | |||||
142 | $combined_oid = sprintf('%s::%s', $ai_mib, 'aiClientMACAddress'); |
||||
143 | $oid = snmp_translate($combined_oid, 'ALL', 'arubaos', '-On'); |
||||
144 | |||||
145 | $sensors[] = new WirelessSensor('clients', $this->getDeviceId(), $oid, 'aruba-instant', 'total-clients', 'Total Clients', $total_clients); |
||||
146 | } |
||||
147 | |||||
148 | return $sensors; |
||||
149 | } |
||||
150 | |||||
151 | /** |
||||
152 | * Discover wireless AP counts. Type is ap-count. |
||||
153 | * Returns an array of LibreNMS\Device\Sensor objects that have been discovered |
||||
154 | * |
||||
155 | * @return array Sensors |
||||
156 | */ |
||||
157 | public function discoverWirelessApCount() |
||||
158 | { |
||||
159 | $sensors = []; |
||||
160 | $ai_mib = 'AI-AP-MIB'; |
||||
161 | $ap_data = $this->getCacheTable('aiAPSerialNum', $ai_mib); |
||||
162 | |||||
163 | $total_aps = sizeof($ap_data); |
||||
0 ignored issues
–
show
It seems like
$ap_data can also be of type null ; however, parameter $value of sizeof() does only seem to accept Countable|array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
164 | |||||
165 | $combined_oid = sprintf('%s::%s', $ai_mib, 'aiAPSerialNum'); |
||||
166 | $oid = snmp_translate($combined_oid, 'ALL', 'arubaos', '-On'); |
||||
167 | |||||
168 | $sensors[] = new WirelessSensor('ap-count', $this->getDeviceId(), $oid, 'aruba-instant', 'total-aps', 'Total APs', $total_aps); |
||||
169 | |||||
170 | return $sensors; |
||||
171 | } |
||||
172 | |||||
173 | /** |
||||
174 | * Discover wireless frequency. This is in MHz. Type is frequency. |
||||
175 | * Returns an array of LibreNMS\Device\Sensor objects that have been discovered |
||||
176 | * |
||||
177 | * @return array Sensors |
||||
178 | */ |
||||
179 | public function discoverWirelessFrequency() |
||||
180 | { |
||||
181 | // instant |
||||
182 | return $this->discoverInstantRadio('frequency', 'aiRadioChannel'); |
||||
183 | } |
||||
184 | |||||
185 | /** |
||||
186 | * Discover wireless noise floor. This is in dBm/Hz. Type is noise-floor. |
||||
187 | * Returns an array of LibreNMS\Device\Sensor objects that have been discovered |
||||
188 | * |
||||
189 | * @return array |
||||
190 | */ |
||||
191 | public function discoverWirelessNoiseFloor() |
||||
192 | { |
||||
193 | // instant |
||||
194 | return $this->discoverInstantRadio('noise-floor', 'aiRadioNoiseFloor'); |
||||
195 | } |
||||
196 | |||||
197 | /** |
||||
198 | * Discover wireless tx or rx power. This is in dBm. Type is power. |
||||
199 | * Returns an array of LibreNMS\Device\Sensor objects that have been discovered |
||||
200 | * |
||||
201 | * @return array |
||||
202 | */ |
||||
203 | public function discoverWirelessPower() |
||||
204 | { |
||||
205 | // instant |
||||
206 | return $this->discoverInstantRadio('power', 'aiRadioTransmitPower', '%s Radio %s: Tx Power'); |
||||
207 | } |
||||
208 | |||||
209 | /** |
||||
210 | * Discover wireless utilization. This is in %. Type is utilization. |
||||
211 | * Returns an array of LibreNMS\Device\Sensor objects that have been discovered |
||||
212 | * |
||||
213 | * @return array Sensors |
||||
214 | */ |
||||
215 | public function discoverWirelessUtilization() |
||||
216 | { |
||||
217 | // instant |
||||
218 | return $this->discoverInstantRadio('utilization', 'aiRadioUtilization64'); |
||||
219 | } |
||||
220 | |||||
221 | /** |
||||
222 | * Aruba Instant Radio Discovery |
||||
223 | * |
||||
224 | * @return array Sensors |
||||
225 | */ |
||||
226 | private function discoverInstantRadio($type, $mib, $desc = '%s Radio %s') |
||||
227 | { |
||||
228 | $ai_mib = 'AI-AP-MIB'; |
||||
229 | $ai_sg_data = array_merge_recursive( |
||||
230 | $this->getCacheTable('aiAPSerialNum', $ai_mib), |
||||
0 ignored issues
–
show
It seems like
$this->getCacheTable('aiAPSerialNum', $ai_mib) can also be of type null ; however, parameter $arrays of array_merge_recursive() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
231 | $this->getCacheTable('aiRadioChannel', $ai_mib), |
||||
232 | $this->getCacheTable('aiRadioNoiseFloor', $ai_mib), |
||||
233 | $this->getCacheTable('aiRadioTransmitPower', $ai_mib), |
||||
234 | $this->getCacheTable('aiRadioUtilization64', $ai_mib) |
||||
235 | ); |
||||
236 | |||||
237 | $sensors = []; |
||||
238 | |||||
239 | foreach ($ai_sg_data as $ai_ap => $ai_ap_oid) { |
||||
240 | if (isset($ai_ap_oid[$mib])) { |
||||
241 | foreach ($ai_ap_oid[$mib] as $ai_ap_radio => $value) { |
||||
242 | $multiplier = 1; |
||||
243 | if ($type == 'frequency') { |
||||
244 | $value = WirelessSensor::channelToFrequency($this->decodeChannel($value)); |
||||
245 | } |
||||
246 | |||||
247 | if ($type == 'noise-floor') { |
||||
248 | $multiplier = -1; |
||||
249 | $value = $value * $multiplier; |
||||
250 | } |
||||
251 | |||||
252 | $combined_oid = sprintf('%s::%s.%s.%s', $ai_mib, $mib, Rewrite::oidMac($ai_ap), $ai_ap_radio); |
||||
253 | $oid = snmp_translate($combined_oid, 'ALL', 'arubaos', '-On'); |
||||
254 | $description = sprintf($desc, $ai_sg_data[$ai_ap]['aiAPSerialNum'], $ai_ap_radio); |
||||
255 | $index = sprintf('%s.%s', Rewrite::macToHex($ai_ap), $ai_ap_radio); |
||||
256 | |||||
257 | $sensors[] = new WirelessSensor($type, $this->getDeviceId(), $oid, 'aruba-instant', $index, $description, $value, $multiplier); |
||||
258 | } // end foreach |
||||
259 | } // end if |
||||
260 | } // end foreach |
||||
261 | |||||
262 | return $sensors; |
||||
263 | } |
||||
264 | |||||
265 | protected function decodeChannel($channel) |
||||
266 | { |
||||
267 | return $channel & 255; // mask off the channel width information |
||||
268 | } |
||||
269 | |||||
270 | /** |
||||
271 | * Poll wireless frequency as MHz |
||||
272 | * The returned array should be sensor_id => value pairs |
||||
273 | * |
||||
274 | * @param array $sensors Array of sensors needed to be polled |
||||
275 | * @return array of polled data |
||||
276 | */ |
||||
277 | public function pollWirelessFrequency(array $sensors) |
||||
278 | { |
||||
279 | return $this->pollWirelessChannelAsFrequency($sensors, [$this, 'decodeChannel']); |
||||
280 | } |
||||
281 | |||||
282 | /** |
||||
283 | * Poll wireless clients |
||||
284 | * The returned array should be sensor_id => value pairs |
||||
285 | * |
||||
286 | * @param array $sensors Array of sensors needed to be polled |
||||
287 | * @return array of polled data |
||||
288 | */ |
||||
289 | public function pollWirelessClients(array $sensors) |
||||
290 | { |
||||
291 | $data = []; |
||||
292 | if (! empty($sensors)) { |
||||
293 | $device = $this->getDeviceArray(); |
||||
294 | |||||
295 | if (intval(explode('.', $device['version'])[0]) >= 8 && intval(explode('.', $device['version'])[1]) >= 4) { |
||||
296 | // version is at least 8.4.0.0 |
||||
297 | $oids = []; |
||||
298 | |||||
299 | foreach ($sensors as $sensor) { |
||||
300 | $oids[$sensor['sensor_id']] = current($sensor['sensor_oids']); |
||||
301 | } |
||||
302 | |||||
303 | $snmp_data = snmp_get_multi_oid($this->getDeviceArray(), $oids); |
||||
304 | |||||
305 | foreach ($oids as $id => $oid) { |
||||
306 | $data[$id] = $snmp_data[$oid]; |
||||
307 | } |
||||
308 | } else { |
||||
309 | // version is lower than 8.4.0.0 |
||||
310 | if (! empty($sensors) && sizeof($sensors) == 1) { |
||||
311 | $ai_mib = 'AI-AP-MIB'; |
||||
312 | $client_data = $this->getCacheTable('aiClientMACAddress', $ai_mib); |
||||
313 | |||||
314 | if (empty($client_data)) { |
||||
315 | $total_clients = 0; |
||||
316 | } else { |
||||
317 | $total_clients = sizeof($client_data); |
||||
318 | } |
||||
319 | |||||
320 | $data[$sensors[0]['sensor_id']] = $total_clients; |
||||
321 | } |
||||
322 | } |
||||
323 | } |
||||
324 | |||||
325 | return $data; |
||||
326 | } |
||||
327 | |||||
328 | /** |
||||
329 | * Poll AP Count |
||||
330 | * The returned array should be sensor_id => value pairs |
||||
331 | * |
||||
332 | * @param array $sensors Array of sensors needed to be polled |
||||
333 | * @return array of polled data |
||||
334 | */ |
||||
335 | public function pollWirelessApCount(array $sensors) |
||||
336 | { |
||||
337 | $data = []; |
||||
338 | if (! empty($sensors) && sizeof($sensors) == 1) { |
||||
339 | $ai_mib = 'AI-AP-MIB'; |
||||
340 | $ap_data = $this->getCacheTable('aiAPSerialNum', $ai_mib); |
||||
341 | |||||
342 | $total_aps = 0; |
||||
343 | |||||
344 | if (! empty($ap_data)) { |
||||
345 | $total_aps = sizeof($ap_data); |
||||
346 | } |
||||
347 | |||||
348 | $data[$sensors[0]['sensor_id']] = $total_aps; |
||||
349 | } |
||||
350 | |||||
351 | return $data; |
||||
352 | } |
||||
353 | } |
||||
354 |