1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Cisco.php |
4
|
|
|
* |
5
|
|
|
* Base Cisco OS for Cisco based devices |
6
|
|
|
* |
7
|
|
|
* This program is free software: you can redistribute it and/or modify |
8
|
|
|
* it under the terms of the GNU General Public License as published by |
9
|
|
|
* the Free Software Foundation, either version 3 of the License, or |
10
|
|
|
* (at your option) any later version. |
11
|
|
|
* |
12
|
|
|
* This program is distributed in the hope that it will be useful, |
13
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the |
15
|
|
|
* GNU General Public License for more details. |
16
|
|
|
* |
17
|
|
|
* You should have received a copy of the GNU General Public License |
18
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
19
|
|
|
* |
20
|
|
|
* @link https://www.librenms.org |
21
|
|
|
* |
22
|
|
|
* @copyright 2018 Tony Murray |
23
|
|
|
* @author Tony Murray <[email protected]> |
24
|
|
|
* @copyright 2018 Jose Augusto Cardoso |
25
|
|
|
*/ |
26
|
|
|
|
27
|
|
|
namespace LibreNMS\OS\Shared; |
28
|
|
|
|
29
|
|
|
use App\Models\Device; |
30
|
|
|
use App\Models\Mempool; |
31
|
|
|
use App\Models\PortsNac; |
32
|
|
|
use App\Models\Sla; |
33
|
|
|
use Illuminate\Support\Arr; |
34
|
|
|
use LibreNMS\Device\Processor; |
35
|
|
|
use LibreNMS\Interfaces\Discovery\MempoolsDiscovery; |
36
|
|
|
use LibreNMS\Interfaces\Discovery\OSDiscovery; |
37
|
|
|
use LibreNMS\Interfaces\Discovery\ProcessorDiscovery; |
38
|
|
|
use LibreNMS\Interfaces\Discovery\SlaDiscovery; |
39
|
|
|
use LibreNMS\Interfaces\Polling\NacPolling; |
40
|
|
|
use LibreNMS\Interfaces\Polling\SlaPolling; |
41
|
|
|
use LibreNMS\OS; |
42
|
|
|
use LibreNMS\OS\Traits\YamlOSDiscovery; |
43
|
|
|
use LibreNMS\RRD\RrdDefinition; |
44
|
|
|
use LibreNMS\Util\IP; |
45
|
|
|
|
46
|
|
|
class Cisco extends OS implements OSDiscovery, SlaDiscovery, ProcessorDiscovery, MempoolsDiscovery, NacPolling, SlaPolling |
47
|
|
|
{ |
48
|
|
|
use YamlOSDiscovery { |
|
|
|
|
49
|
|
|
YamlOSDiscovery::discoverOS as discoverYamlOS; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
public function discoverOS(Device $device): void |
53
|
|
|
{ |
54
|
|
|
// yaml discovery overrides this |
55
|
|
|
if ($this->hasYamlDiscovery('os')) { |
56
|
|
|
$this->discoverYamlOS($device); |
57
|
|
|
|
58
|
|
|
return; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
$device->serial = $this->getMainSerial(); |
62
|
|
|
$hardware = null; |
63
|
|
|
|
64
|
|
|
if (preg_match('/^Cisco IOS Software, .+? Software \([^\-]+-([^\-]+)-\w\),.+?Version ([^, ]+)/', $device->sysDescr, $regexp_result)) { |
65
|
|
|
$device->features = $regexp_result[1]; |
66
|
|
|
$device->version = $regexp_result[2]; |
67
|
|
|
} elseif (preg_match('/Cisco Internetwork Operating System Software\s+IOS \(tm\) [^ ]+ Software \([^\-]+-([^\-]+)-\w\),.+?Version ([^, ]+)/', $device->sysDescr, $regexp_result)) { |
68
|
|
|
$device->features = $regexp_result[1]; |
69
|
|
|
$device->version = $regexp_result[2]; |
70
|
|
|
} elseif (preg_match('/^Cisco IOS Software \[([^\]]+)\],.+Software \(([^\)]+)\), Version ([^, ]+)/', $device->sysDescr, $regexp_result)) { |
71
|
|
|
$device->features = $regexp_result[1]; |
72
|
|
|
$device->version = $regexp_result[2] . ' ' . $regexp_result[3]; |
73
|
|
|
} elseif (preg_match('/^Cisco IOS Software.*?, .+? Software(\, )?([\s\w\d]+)? \([^\-]+-([\w\d]+)-\w\), Version ([^,]+)/', $device->sysDescr, $regexp_result)) { |
74
|
|
|
$device->features = $regexp_result[3]; |
75
|
|
|
$device->version = $regexp_result[4]; |
76
|
|
|
$hardware = $regexp_result[2]; |
77
|
|
|
$tmp = preg_split('/\\r\\n|\\r|\\n/', $device->version); |
78
|
|
|
if (! empty($tmp[0])) { |
79
|
|
|
$device->version = $tmp[0]; |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
$oids = [ |
84
|
|
|
'entPhysicalModelName.1', |
85
|
|
|
'entPhysicalContainedIn.1', |
86
|
|
|
'entPhysicalName.1', |
87
|
|
|
'entPhysicalSoftwareRev.1', |
88
|
|
|
'entPhysicalModelName.1000', |
89
|
|
|
'entPhysicalModelName.1001', |
90
|
|
|
'entPhysicalContainedIn.1000', |
91
|
|
|
'entPhysicalContainedIn.1001', |
92
|
|
|
]; |
93
|
|
|
|
94
|
|
|
$data = snmp_get_multi($this->getDeviceArray(), $oids, '-OQUs', 'ENTITY-MIB:OLD-CISCO-CHASSIS-MIB'); |
95
|
|
|
|
96
|
|
|
if (isset($data[1]['entPhysicalContainedIn']) && $data[1]['entPhysicalContainedIn'] == '0') { |
97
|
|
|
if (! empty($data[1]['entPhysicalSoftwareRev'])) { |
98
|
|
|
$device->version = $data[1]['entPhysicalSoftwareRev']; |
99
|
|
|
} |
100
|
|
|
if (! empty($data[1]['entPhysicalName'])) { |
101
|
|
|
$hardware = $data[1]['entPhysicalName']; |
102
|
|
|
} |
103
|
|
|
if (! empty($data[1]['entPhysicalModelName'])) { |
104
|
|
|
$hardware = $data[1]['entPhysicalModelName']; |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
if ((empty($hardware) || preg_match('/Switch System/', $hardware)) && ! empty($data[1000]['entPhysicalModelName'])) { |
109
|
|
|
$hardware = $data[1000]['entPhysicalModelName']; |
110
|
|
|
} elseif (empty($hardware) && ! empty($data[1000]['entPhysicalContainedIn'])) { |
111
|
|
|
$hardware = $data[$data[1000]['entPhysicalContainedIn']]['entPhysicalName']; |
112
|
|
|
} elseif ((preg_match('/stack/i', $hardware) || empty($hardware)) && ! empty($data[1001]['entPhysicalModelName'])) { |
113
|
|
|
$hardware = $data[1001]['entPhysicalModelName']; |
114
|
|
|
} elseif (empty($hardware) && ! empty($data[1001]['entPhysicalContainedIn'])) { |
115
|
|
|
$hardware = $data[$data[1001]['entPhysicalContainedIn']]['entPhysicalName']; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
$device->hardware = $hardware ?: snmp_translate($device->sysObjectID, 'SNMPv2-MIB:CISCO-PRODUCTS-MIB', 'cisco'); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
public function discoverMempools() |
122
|
|
|
{ |
123
|
|
|
if ($this->hasYamlDiscovery('mempools')) { |
124
|
|
|
return parent::discoverMempools(); // yaml |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
$mempools = collect(); |
128
|
|
|
$cemp = snmpwalk_cache_multi_oid($this->getDeviceArray(), 'cempMemPoolTable', [], 'CISCO-ENHANCED-MEMPOOL-MIB'); |
129
|
|
|
|
130
|
|
|
foreach (Arr::wrap($cemp) as $index => $entry) { |
131
|
|
|
if (is_numeric($entry['cempMemPoolUsed']) && $entry['cempMemPoolValid'] == 'true') { |
132
|
|
|
[$entPhysicalIndex] = explode('.', $index); |
133
|
|
|
$entPhysicalName = $this->getCacheByIndex('entPhysicalName', 'ENTITY-MIB')[$entPhysicalIndex]; |
134
|
|
|
$descr = ucwords($entPhysicalName . ' - ' . $entry['cempMemPoolName']); |
135
|
|
|
$descr = trim(str_replace(['Cisco ', 'Network Processing Engine'], '', $descr), ' -'); |
136
|
|
|
|
137
|
|
|
$mempools->push((new Mempool([ |
138
|
|
|
'mempool_index' => $index, |
139
|
|
|
'entPhysicalIndex' => $entPhysicalIndex, |
140
|
|
|
'mempool_type' => 'cemp', |
141
|
|
|
'mempool_class' => 'system', |
142
|
|
|
'mempool_precision' => 1, |
143
|
|
|
'mempool_descr' => $descr, |
144
|
|
|
'mempool_used_oid' => isset($entry['cempMemPoolHCUsed']) ? ".1.3.6.1.4.1.9.9.221.1.1.1.1.18.$index" : ".1.3.6.1.4.1.9.9.221.1.1.1.1.7.$index", |
145
|
|
|
'mempool_free_oid' => isset($entry['cempMemPoolHCFree']) ? ".1.3.6.1.4.1.9.9.221.1.1.1.1.20.$index" : ".1.3.6.1.4.1.9.9.221.1.1.1.1.8.$index", |
146
|
|
|
'mempool_perc_warn' => 90, |
147
|
|
|
'mempool_largestfree' => $entry['cempMemPoolHCLargestFree'] ?? $entry['cempMemPoolLargestFree'] ?? null, |
148
|
|
|
'mempool_lowestfree' => $entry['cempMemPoolHCLowestFree'] ?? $entry['cempMemPoolLowestFree'] ?? null, |
149
|
|
|
]))->fillUsage($entry['cempMemPoolHCUsed'] ?? $entry['cempMemPoolUsed'], null, $entry['cempMemPoolHCFree'] ?? $entry['cempMemPoolFree'])); |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
if ($mempools->isNotEmpty()) { |
154
|
|
|
return $mempools; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
$cmp = snmpwalk_cache_oid($this->getDeviceArray(), 'ciscoMemoryPool', [], 'CISCO-MEMORY-POOL-MIB'); |
158
|
|
|
foreach (Arr::wrap($cmp) as $index => $entry) { |
159
|
|
|
if (is_numeric($entry['ciscoMemoryPoolUsed']) && is_numeric($index)) { |
160
|
|
|
$mempools->push((new Mempool([ |
161
|
|
|
'mempool_index' => $index, |
162
|
|
|
'mempool_type' => 'cmp', |
163
|
|
|
'mempool_class' => 'system', |
164
|
|
|
'mempool_precision' => 1, |
165
|
|
|
'mempool_descr' => $entry['ciscoMemoryPoolName'], |
166
|
|
|
'mempool_used_oid' => ".1.3.6.1.4.1.9.9.48.1.1.1.5.$index", |
167
|
|
|
'mempool_free_oid' => ".1.3.6.1.4.1.9.9.48.1.1.1.6.$index", |
168
|
|
|
'mempool_perc_warn' => 90, |
169
|
|
|
'mempool_largestfree' => $entry['ciscoMemoryPoolLargestFree'] ?? null, |
170
|
|
|
]))->fillUsage($entry['ciscoMemoryPoolUsed'], null, $entry['ciscoMemoryPoolFree'])); |
171
|
|
|
} |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
if ($mempools->isNotEmpty()) { |
175
|
|
|
return $mempools; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
$cpm = $this->getCacheTable('cpmCPUTotalTable', 'CISCO-PROCESS-MIB'); |
179
|
|
|
|
180
|
|
|
$count = 0; |
181
|
|
|
foreach (Arr::wrap($cpm) as $index => $entry) { |
182
|
|
|
$count++; |
183
|
|
|
if (is_numeric($entry['cpmCPUMemoryFree']) && is_numeric($entry['cpmCPUMemoryFree'])) { |
184
|
|
|
$cpu = $this->getCacheByIndex('entPhysicalName', 'ENTITY-MIB')[$entry['cpmCPUTotalPhysicalIndex'] ?? 'none'] ?? "Processor $index"; |
185
|
|
|
|
186
|
|
|
$mempools->push((new Mempool([ |
187
|
|
|
'mempool_index' => $index, |
188
|
|
|
'mempool_type' => 'cpm', |
189
|
|
|
'mempool_class' => 'system', |
190
|
|
|
'mempool_precision' => 1024, |
191
|
|
|
'mempool_descr' => "$cpu Memory", |
192
|
|
|
'mempool_used_oid' => empty($entry['cpmCPUMemoryHCUsed']) ? ".1.3.6.1.4.1.9.9.109.1.1.1.1.12.$index" : ".1.3.6.1.4.1.9.9.109.1.1.1.1.17.$index", |
193
|
|
|
'mempool_free_oid' => empty($entry['cpmCPUMemoryHCFree']) ? ".1.3.6.1.4.1.9.9.109.1.1.1.1.13.$index" : ".1.3.6.1.4.1.9.9.109.1.1.1.1.19.$index", |
194
|
|
|
'mempool_perc_warn' => 90, |
195
|
|
|
'mempool_lowestfree' => $entry['cpmCPUMemoryHCLowest'] ?? $entry['cpmCPUMemoryLowest'] ?? null, |
196
|
|
|
]))->fillUsage( |
197
|
|
|
empty($entry['cpmCPUMemoryHCUsed']) ? $entry['cpmCPUMemoryUsed'] : $entry['cpmCPUMemoryHCUsed'], |
198
|
|
|
null, |
199
|
|
|
empty($entry['cpmCPUMemoryHCFree']) ? $entry['cpmCPUMemoryFree'] : $entry['cpmCPUMemoryHCFree'] |
200
|
|
|
)); |
201
|
|
|
} |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
return $mempools; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* Discover processors. |
209
|
|
|
* Returns an array of LibreNMS\Device\Processor objects that have been discovered |
210
|
|
|
* |
211
|
|
|
* @return array Processors |
212
|
|
|
*/ |
213
|
|
|
public function discoverProcessors() |
214
|
|
|
{ |
215
|
|
|
$processors_data = $this->getCacheTable('cpmCPUTotalTable', 'CISCO-PROCESS-MIB'); |
216
|
|
|
$processors_data = snmpwalk_group($this->getDeviceArray(), 'cpmCoreTable', 'CISCO-PROCESS-MIB', 1, $processors_data); |
217
|
|
|
$processors = []; |
218
|
|
|
|
219
|
|
|
foreach ($processors_data as $index => $entry) { |
220
|
|
|
if (is_numeric($entry['cpmCPUTotal5minRev'])) { |
221
|
|
|
$usage_oid = '.1.3.6.1.4.1.9.9.109.1.1.1.1.8.' . $index; |
222
|
|
|
$usage = $entry['cpmCPUTotal5minRev']; |
223
|
|
|
} elseif (is_numeric($entry['cpmCPUTotal5min'])) { |
224
|
|
|
$usage_oid = '.1.3.6.1.4.1.9.9.109.1.1.1.1.5.' . $index; |
225
|
|
|
$usage = $entry['cpmCPUTotal5min']; |
226
|
|
|
} else { |
227
|
|
|
continue; // skip bad data |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
if (isset($entry['cpmCPUTotalPhysicalIndex'])) { |
231
|
|
|
$descr = $this->getCacheByIndex('entPhysicalName', 'ENTITY-MIB')[$entry['cpmCPUTotalPhysicalIndex']]; |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
if (empty($descr)) { |
235
|
|
|
$descr = "Processor $index"; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
if (is_array($entry['cpmCore5min'])) { |
239
|
|
|
// This CPU has data per individual core |
240
|
|
|
foreach ($entry['cpmCore5min'] as $core_index => $core_usage) { |
241
|
|
|
$processors[] = Processor::discover( |
242
|
|
|
'cpm', |
243
|
|
|
$this->getDeviceId(), |
244
|
|
|
".1.3.6.1.4.1.9.9.109.1.1.2.1.5.$index.$core_index", |
245
|
|
|
"$index.$core_index", |
246
|
|
|
"$descr: Core $core_index", |
247
|
|
|
1, |
248
|
|
|
$core_usage, |
249
|
|
|
null, |
250
|
|
|
$entry['cpmCPUTotalPhysicalIndex'] |
251
|
|
|
); |
252
|
|
|
} |
253
|
|
|
} else { |
254
|
|
|
$processors[] = Processor::discover( |
255
|
|
|
'cpm', |
256
|
|
|
$this->getDeviceId(), |
257
|
|
|
$usage_oid, |
258
|
|
|
$index, |
259
|
|
|
$descr, |
260
|
|
|
1, |
261
|
|
|
$usage, |
262
|
|
|
null, |
263
|
|
|
$entry['cpmCPUTotalPhysicalIndex'] |
264
|
|
|
); |
265
|
|
|
} |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
if (empty($processors)) { |
269
|
|
|
// fallback to old pre-12.0 OID |
270
|
|
|
$processors[] = Processor::discover( |
271
|
|
|
'ios', |
272
|
|
|
$this->getDeviceId(), |
273
|
|
|
'.1.3.6.1.4.1.9.2.1.58.0', // OLD-CISCO-CPU-MIB::avgBusy5 |
274
|
|
|
0 |
275
|
|
|
); |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
// QFP processors (Forwarding Processors) |
279
|
|
|
$qfp_data = snmpwalk_group($this->getDeviceArray(), 'ceqfpUtilProcessingLoad', 'CISCO-ENTITY-QFP-MIB'); |
280
|
|
|
|
281
|
|
|
foreach ($qfp_data as $entQfpPhysicalIndex => $entry) { |
282
|
|
|
/* |
283
|
|
|
* .2 OID suffix is for 1 min SMA ('oneMinute') |
284
|
|
|
* .3 OID suffix is for 5 min SMA ('fiveMinute') |
285
|
|
|
* Could be dynamically changed to appropriate value if config had pol interval value |
286
|
|
|
*/ |
287
|
|
|
$qfp_usage_oid = '.1.3.6.1.4.1.9.9.715.1.1.6.1.14.' . $entQfpPhysicalIndex . '.3'; |
288
|
|
|
$qfp_usage = $entry['fiveMinute']; |
289
|
|
|
|
290
|
|
|
if ($entQfpPhysicalIndex) { |
291
|
|
|
$qfp_descr = $this->getCacheByIndex('entPhysicalName', 'ENTITY-MIB')[$entQfpPhysicalIndex]; |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
$processors[] = Processor::discover( |
295
|
|
|
'qfp', |
296
|
|
|
$this->getDeviceId(), |
297
|
|
|
$qfp_usage_oid, |
298
|
|
|
$entQfpPhysicalIndex . '.3', |
299
|
|
|
$qfp_descr ?? "QFP $entQfpPhysicalIndex", |
300
|
|
|
1, |
301
|
|
|
$qfp_usage, |
302
|
|
|
null, |
303
|
|
|
$entQfpPhysicalIndex |
304
|
|
|
); |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
return $processors; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
public function discoverSlas() |
311
|
|
|
{ |
312
|
|
|
$slas = collect(); |
313
|
|
|
|
314
|
|
|
$sla_data = snmpwalk_cache_oid($this->getDeviceArray(), 'rttMonCtrl', [], 'CISCO-RTTMON-MIB'); |
315
|
|
|
|
316
|
|
|
if (! empty($sla_data)) { |
317
|
|
|
$sla_data = snmpwalk_cache_oid($this->getDeviceArray(), 'rttMonLatestRttOperCompletionTime', $sla_data, 'CISCO-RTTMON-MIB'); |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
foreach ($sla_data as $index => $sla_config) { |
321
|
|
|
if (empty($sla_config['rttMonCtrlAdminRttType'])) { |
322
|
|
|
continue; // skip garbage entries |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
$slas->push(new Sla([ |
326
|
|
|
'sla_nr' => $index, |
327
|
|
|
'owner' => $sla_config['rttMonCtrlAdminOwner'] ?? '', |
328
|
|
|
'tag' => $this->getSlaTag($sla_config), |
329
|
|
|
'rtt_type' => $sla_config['rttMonCtrlAdminRttType'], |
330
|
|
|
'rtt' => $sla_config['rttMonLatestRttOperCompletionTime'] ?? null, |
331
|
|
|
'status' => ($sla_config['rttMonCtrlAdminStatus'] == 'active') ? 1 : 0, |
332
|
|
|
'opstatus' => ($sla_config['rttMonLatestRttOperSense'] == 'ok') ? 0 : 2, |
333
|
|
|
])); |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
return $slas; |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
private function getSlaTag($data) |
340
|
|
|
{ |
341
|
|
|
if (! empty($data['rttMonCtrlAdminTag'])) { |
342
|
|
|
return $data['rttMonCtrlAdminTag']; |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
switch ($data['rttMonCtrlAdminRttType']) { |
346
|
|
|
case 'http': |
347
|
|
|
return $data['rttMonEchoAdminURL']; |
348
|
|
|
case 'dns': |
349
|
|
|
return $data['rttMonEchoAdminTargetAddressString']; |
350
|
|
|
case 'echo': |
351
|
|
|
return IP::fromHexString($data['rttMonEchoAdminTargetAddress'], true); |
352
|
|
|
case 'jitter': |
353
|
|
|
$tag = IP::fromHexString($data['rttMonEchoAdminTargetAddress'], true) . ':' . $data['rttMonEchoAdminTargetPort']; |
354
|
|
|
if (isset($data['rttMonEchoAdminCodecType']) && $data['rttMonEchoAdminCodecType'] != 'notApplicable') { |
355
|
|
|
$tag .= ' (' . $data['rttMonEchoAdminCodecType'] . ' @ ' . $data['rttMonEchoAdminCodecInterval'] . 'ms)'; |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
return $tag; |
359
|
|
|
default: |
360
|
|
|
return ''; |
361
|
|
|
} |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
public function pollNac() |
365
|
|
|
{ |
366
|
|
|
$nac = collect(); |
367
|
|
|
|
368
|
|
|
$portAuthSessionEntry = snmpwalk_cache_oid($this->getDeviceArray(), 'cafSessionEntry', [], 'CISCO-AUTH-FRAMEWORK-MIB'); |
369
|
|
|
if (! empty($portAuthSessionEntry)) { |
370
|
|
|
$cafSessionMethodsInfoEntry = collect(snmpwalk_cache_oid($this->getDeviceArray(), 'cafSessionMethodsInfoEntry', [], 'CISCO-AUTH-FRAMEWORK-MIB'))->mapWithKeys(function ($item, $key) { |
371
|
|
|
$key_parts = explode('.', $key); |
372
|
|
|
$key = implode('.', array_slice($key_parts, 0, 2)); // remove the auth method |
373
|
|
|
|
374
|
|
|
return [$key => ['method' => $key_parts[2], 'authc_status' => $item['cafSessionMethodState']]]; |
375
|
|
|
}); |
376
|
|
|
|
377
|
|
|
// cache port ifIndex -> port_id map |
378
|
|
|
$ifIndex_map = $this->getDevice()->ports()->pluck('port_id', 'ifIndex'); |
379
|
|
|
|
380
|
|
|
// update the DB |
381
|
|
|
foreach ($portAuthSessionEntry as $index => $portAuthSessionEntryParameters) { |
382
|
|
|
[$ifIndex, $auth_id] = explode('.', str_replace("'", '', $index)); |
383
|
|
|
$session_info = $cafSessionMethodsInfoEntry->get($ifIndex . '.' . $auth_id); |
384
|
|
|
$mac_address = strtolower(implode(array_map('zeropad', explode(':', $portAuthSessionEntryParameters['cafSessionClientMacAddress'])))); |
385
|
|
|
|
386
|
|
|
$nac->put($mac_address, new PortsNac([ |
387
|
|
|
'port_id' => $ifIndex_map->get($ifIndex, 0), |
388
|
|
|
'mac_address' => $mac_address, |
389
|
|
|
'auth_id' => $auth_id, |
390
|
|
|
'domain' => $portAuthSessionEntryParameters['cafSessionDomain'], |
391
|
|
|
'username' => $portAuthSessionEntryParameters['cafSessionAuthUserName'], |
392
|
|
|
'ip_address' => (string) IP::fromHexString($portAuthSessionEntryParameters['cafSessionClientAddress'], true), |
393
|
|
|
'host_mode' => $portAuthSessionEntryParameters['cafSessionAuthHostMode'], |
394
|
|
|
'authz_status' => $portAuthSessionEntryParameters['cafSessionStatus'], |
395
|
|
|
'authz_by' => $portAuthSessionEntryParameters['cafSessionAuthorizedBy'], |
396
|
|
|
'timeout' => $portAuthSessionEntryParameters['cafSessionTimeout'], |
397
|
|
|
'time_left' => $portAuthSessionEntryParameters['cafSessionTimeLeft'], |
398
|
|
|
'vlan' => $portAuthSessionEntryParameters['cafSessionAuthVlan'], |
399
|
|
|
'authc_status' => $session_info['authc_status'], |
400
|
|
|
'method' => $session_info['method'], |
401
|
|
|
])); |
402
|
|
|
} |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
return $nac; |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
public function pollSlas($slas) |
409
|
|
|
{ |
410
|
|
|
$device = $this->getDeviceArray(); |
411
|
|
|
|
412
|
|
|
$data = snmpwalk_group($device, 'rttMonLatestRttOperTable', 'CISCO-RTTMON-MIB'); |
413
|
|
|
$data = snmpwalk_group($device, 'rttMonLatestOper', 'CISCO-RTTMON-MIB', 1, $data); |
414
|
|
|
|
415
|
|
|
$time_offset = time() - $this->getDevice()->uptime; |
416
|
|
|
|
417
|
|
|
foreach ($slas as $sla) { |
418
|
|
|
$sla_id = $sla->sla_id; |
|
|
|
|
419
|
|
|
$sla_nr = $sla->sla_nr; |
420
|
|
|
$rtt_type = $sla->rtt_type; |
421
|
|
|
|
422
|
|
|
// Lets process each SLA |
423
|
|
|
$unixtime = intval(($data[$sla_nr]['rttMonLatestRttOperTime'] / 100 + $time_offset)); |
424
|
|
|
$time = strftime('%Y-%m-%d %H:%M:%S', $unixtime); |
425
|
|
|
|
426
|
|
|
// Save data |
427
|
|
|
$sla->rtt = $data[$sla_nr]['rttMonLatestRttOperCompletionTime']; |
428
|
|
|
// Use Nagios Status codes. 0: Good, 2: Critical |
429
|
|
|
$sla->opstatus = $data[$sla_nr]['rttMonLatestRttOperSense'] == 1 ? 0 : 2; |
430
|
|
|
|
431
|
|
|
echo 'SLA ' . $sla_nr . ': ' . $rtt_type . ' ' . $sla['owner'] . ' ' . $sla['tag'] . '... ' . $sla->rtt . 'ms at ' . $time . "\n"; |
432
|
|
|
|
433
|
|
|
$fields = [ |
434
|
|
|
'rtt' => $sla->rtt, |
435
|
|
|
]; |
436
|
|
|
|
437
|
|
|
// The base RRD |
438
|
|
|
$rrd_name = ['sla', $sla['sla_nr']]; |
439
|
|
|
$rrd_def = RrdDefinition::make()->addDataset('rtt', 'GAUGE', 0, 300000); |
440
|
|
|
$tags = compact('sla_nr', 'rrd_name', 'rrd_def'); |
441
|
|
|
data_update($device, 'sla', $tags, $fields); |
442
|
|
|
|
443
|
|
|
// Let's gather some per-type fields. |
444
|
|
|
switch ($rtt_type) { |
445
|
|
|
case 'jitter': |
446
|
|
|
$jitter = [ |
447
|
|
|
'PacketLossSD' => $data[$sla_nr]['rttMonLatestJitterOperPacketLossSD'], |
448
|
|
|
'PacketLossDS' => $data[$sla_nr]['rttMonLatestJitterOperPacketLossDS'], |
449
|
|
|
'PacketOutOfSequence' => $data[$sla_nr]['rttMonLatestJitterOperPacketOutOfSequence'], |
450
|
|
|
'PacketMIA' => $data[$sla_nr]['rttMonLatestJitterOperPacketMIA'], |
451
|
|
|
'PacketLateArrival' => $data[$sla_nr]['rttMonLatestJitterOperPacketLateArrival'], |
452
|
|
|
'MOS' => isset($data[$sla_nr]['rttMonLatestJitterOperMOS']) ? intval($data[$sla_nr]['rttMonLatestJitterOperMOS']) / 100 : null, |
453
|
|
|
'ICPIF' => $data[$sla_nr]['rttMonLatestJitterOperICPIF'] ?? null, |
454
|
|
|
'OWAvgSD' => $data[$sla_nr]['rttMonLatestJitterOperOWAvgSD'] ?? null, |
455
|
|
|
'OWAvgDS' => $data[$sla_nr]['rttMonLatestJitterOperOWAvgDS'] ?? null, |
456
|
|
|
'AvgSDJ' => $data[$sla_nr]['rttMonLatestJitterOperAvgSDJ'] ?? null, |
457
|
|
|
'AvgDSJ' => $data[$sla_nr]['rttMonLatestJitterOperAvgDSJ'] ?? null, |
458
|
|
|
]; |
459
|
|
|
$rrd_name = ['sla', $sla_nr, $rtt_type]; |
460
|
|
|
$rrd_def = RrdDefinition::make() |
461
|
|
|
->addDataset('PacketLossSD', 'GAUGE', 0) |
462
|
|
|
->addDataset('PacketLossDS', 'GAUGE', 0) |
463
|
|
|
->addDataset('PacketOutOfSequence', 'GAUGE', 0) |
464
|
|
|
->addDataset('PacketMIA', 'GAUGE', 0) |
465
|
|
|
->addDataset('PacketLateArrival', 'GAUGE', 0) |
466
|
|
|
->addDataset('MOS', 'GAUGE', 0) |
467
|
|
|
->addDataset('ICPIF', 'GAUGE', 0) |
468
|
|
|
->addDataset('OWAvgSD', 'GAUGE', 0) |
469
|
|
|
->addDataset('OWAvgDS', 'GAUGE', 0) |
470
|
|
|
->addDataset('AvgSDJ', 'GAUGE', 0) |
471
|
|
|
->addDataset('AvgDSJ', 'GAUGE', 0); |
472
|
|
|
$tags = compact('rrd_name', 'rrd_def', 'sla_nr', 'rtt_type'); |
473
|
|
|
data_update($device, 'sla', $tags, $jitter); |
474
|
|
|
$fields = array_merge($fields, $jitter); |
475
|
|
|
break; |
476
|
|
|
case 'icmpjitter': |
477
|
|
|
$icmpjitter = [ |
478
|
|
|
'PacketLoss' => $data[$sla_nr]['rttMonLatestJitterOperPacketLossSD'], |
479
|
|
|
'PacketOosSD' => $data[$sla_nr]['rttMonLatestJitterOperPacketOutOfSequence'], |
480
|
|
|
'PacketOosDS' => $data[$sla_nr]['rttMonLatestJitterOperPacketMIA'], |
481
|
|
|
'PacketLateArrival' => $data[$sla_nr]['rttMonLatestJitterOperPacketLateArrival'], |
482
|
|
|
'JitterAvgSD' => $data[$sla_nr]['rttMonLatestJitterOperAvgSDJ'], |
483
|
|
|
'JitterAvgDS' => $data[$sla_nr]['rttMonLatestJitterOperAvgDSJ'], |
484
|
|
|
'LatencyOWAvgSD' => $data[$sla_nr]['rttMonLatestJitterOperOWAvgSD'], |
485
|
|
|
'LatencyOWAvgDS' => $data[$sla_nr]['rttMonLatestJitterOperOWAvgDS'], |
486
|
|
|
'JitterIAJOut' => $data[$sla_nr]['rttMonLatestJitterOperIAJOut'], |
487
|
|
|
'JitterIAJIn' => $data[$sla_nr]['rttMonLatestJitterOperIAJIn'], |
488
|
|
|
]; |
489
|
|
|
$rrd_name = ['sla', $sla_nr, $rtt_type]; |
490
|
|
|
$rrd_def = RrdDefinition::make() |
491
|
|
|
->addDataset('PacketLoss', 'GAUGE', 0) |
492
|
|
|
->addDataset('PacketOosSD', 'GAUGE', 0) |
493
|
|
|
->addDataset('PacketOosDS', 'GAUGE', 0) |
494
|
|
|
->addDataset('PacketLateArrival', 'GAUGE', 0) |
495
|
|
|
->addDataset('JitterAvgSD', 'GAUGE', 0) |
496
|
|
|
->addDataset('JitterAvgDS', 'GAUGE', 0) |
497
|
|
|
->addDataset('LatencyOWAvgSD', 'GAUGE', 0) |
498
|
|
|
->addDataset('LatencyOWAvgDS', 'GAUGE', 0) |
499
|
|
|
->addDataset('JitterIAJOut', 'GAUGE', 0) |
500
|
|
|
->addDataset('JitterIAJIn', 'GAUGE', 0); |
501
|
|
|
$tags = compact('rrd_name', 'rrd_def', 'sla_nr', 'rtt_type'); |
502
|
|
|
data_update($device, 'sla', $tags, $icmpjitter); |
503
|
|
|
$fields = array_merge($fields, $icmpjitter); |
504
|
|
|
break; |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
d_echo('The following datasources were collected for #' . $sla['sla_nr'] . ":\n"); |
508
|
|
|
d_echo($fields); |
509
|
|
|
} |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
protected function getMainSerial() |
513
|
|
|
{ |
514
|
|
|
$serial_output = snmp_get_multi($this->getDeviceArray(), ['entPhysicalSerialNum.1', 'entPhysicalSerialNum.1001'], '-OQUs', 'ENTITY-MIB:OLD-CISCO-CHASSIS-MIB'); |
515
|
|
|
// $serial_output = snmp_getnext($this->getDevice(), 'entPhysicalSerialNum', '-OQUs', 'ENTITY-MIB:OLD-CISCO-CHASSIS-MIB'); |
516
|
|
|
|
517
|
|
|
if (! empty($serial_output[1]['entPhysicalSerialNum'])) { |
518
|
|
|
return $serial_output[1]['entPhysicalSerialNum']; |
519
|
|
|
} elseif (! empty($serial_output[1000]['entPhysicalSerialNum'])) { |
520
|
|
|
return $serial_output[1000]['entPhysicalSerialNum']; |
521
|
|
|
} elseif (! empty($serial_output[1001]['entPhysicalSerialNum'])) { |
522
|
|
|
return $serial_output[1001]['entPhysicalSerialNum']; |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
return null; |
526
|
|
|
} |
527
|
|
|
} |
528
|
|
|
|