1<?php
2
3/**
4 * Observium
5 *
6 *   This file is part of Observium.
7 *
8 * @package    observium
9 * @subpackage poller
10 * @copyright  (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited
11 *
12 */
13
14/// FIXME. Rewrite (clean), add discovery module with check ospf exist on device, clean stale entries (after disable)
15// Pre-polling checks
16if (!$config['enable_ospf'] || !is_device_mib($device, 'OSPF-MIB'))
17{
18  // OSPF not enabled or MIB excluded
19  return;
20}
21/*
22OSPF-MIB::ospfRouterId.0 = IpAddress: 1.185.1.113
23OSPF-MIB::ospfAdminStat.0 = INTEGER: enabled(1)
24OSPF-MIB::ospfVersionNumber.0 = INTEGER: version2(2)
25OSPF-MIB::ospfAreaBdrRtrStatus.0 = INTEGER: false(2)
26OSPF-MIB::ospfASBdrRtrStatus.0 = INTEGER: true(1)
27OSPF-MIB::ospfExternLsaCount.0 = Gauge32: 104
28OSPF-MIB::ospfExternLsaCksumSum.0 = INTEGER: 3322892
29OSPF-MIB::ospfTOSSupport.0 = INTEGER: false(2)
30OSPF-MIB::ospfOriginateNewLsas.0 = Counter32: 11993
31OSPF-MIB::ospfRxNewLsas.0 = Counter32: 553365
32OSPF-MIB::ospfExtLsdbLimit.0 = INTEGER: -1
33OSPF-MIB::ospfMulticastExtensions.0 = INTEGER: 0
34OSPF-MIB::ospfExitOverflowInterval.0 = INTEGER: 0
35OSPF-MIB::ospfDemandExtensions.0 = INTEGER: false(2)
36*/
37
38$ospf_instance_count = 0;
39$ospf_port_count     = 0;
40$ospf_area_count     = 0;
41$ospf_nbr_count      = 0;
42
43$set_ospf            = FALSE;
44
45$ospf_oids_db = array('ospfRouterId', 'ospfAdminStat', 'ospfVersionNumber', 'ospfAreaBdrRtrStatus', 'ospfASBdrRtrStatus',
46                      'ospfExternLsaCount', 'ospfExternLsaCksumSum', 'ospfTOSSupport', 'ospfOriginateNewLsas', 'ospfRxNewLsas',
47                      'ospfExtLsdbLimit', 'ospfMulticastExtensions', 'ospfExitOverflowInterval', 'ospfDemandExtensions');
48
49// Build array of existing entries
50$ospf_instance_db = dbFetchRow('SELECT * FROM `ospf_instances` WHERE `device_id` = ?', array($device['device_id']));
51
52// Pull data from device
53$ospf_instance_poll = snmpwalk_cache_oid($device, 'ospfGeneralGroup', array(), 'OSPF-MIB');
54if (is_array($ospf_instance_poll[0]))
55{
56  $ospf_instance_poll = $ospf_instance_poll[0];
57
58  // Don't bother polling everything if we have no enabled or non-defaulted router ids.
59  if ($ospf_instance_poll['ospfRouterId']  != '0.0.0.0' ||
60      $ospf_instance_poll['ospfAdminStat'] != 'disabled')
61  {
62    $set_ospf = TRUE;
63  }
64}
65
66
67$ospf_areas_poll = array();
68$ospf_ports_poll = array();
69$ospf_nbrs_poll = array();
70
71if ($set_ospf)
72{
73  $ospf_areas_poll = snmpwalk_cache_oid($device, 'ospfAreaEntry', $ospf_areas_poll, 'OSPF-MIB');
74  $ospf_ports_poll = snmpwalk_cache_oid($device, 'ospfIfEntry',   $ospf_ports_poll, 'OSPF-MIB');
75  $ospf_nbrs_poll  = snmpwalk_cache_oid($device, 'ospfNbrEntry',  $ospf_nbrs_poll,  'OSPF-MIB');
76}
77
78print_cli_data_field('Processes', 2);
79
80if (empty($ospf_instance_db) && !empty($ospf_instance_poll))
81{
82  dbInsert(array('device_id' => $device['device_id']), 'ospf_instances');
83  $ospf_instance_db = dbFetchRow('SELECT * FROM `ospf_instances` WHERE `device_id` = ?', array($device['device_id']));
84  echo('+');
85}
86else if (!empty($ospf_instance_db) && empty($ospf_instance_poll))
87{
88  dbDelete('ospf_instances', '`device_id` = ?', array($device['device_id']));
89  echo('-');
90}
91
92if (OBS_DEBUG && $set_ospf)
93{
94  echo("\nPolled: ");
95  print_vars($ospf_instance_poll);
96  echo('Database: ');
97  print_vars($ospf_instance_db);
98  echo("\n");
99}
100
101// Loop array of entries and update
102if (is_array($ospf_instance_db))
103{
104  $ospf_instance_id     = $ospf_instance_db['ospf_instance_id'];
105  $ospf_instance_update = array();
106  foreach ($ospf_oids_db as $oid)
107  { // Loop the OIDs
108    if ($ospf_instance_db[$oid] != $ospf_instance_poll[$oid])
109    { // If data has changed, build a query
110      $ospf_instance_update[$oid] = $ospf_instance_poll[$oid];
111      // log_event("$oid -> ".$this_port[$oid], $device, 'ospf', $port['port_id']); // FIXME
112    }
113  }
114
115  if ($ospf_instance_update)
116  {
117    dbUpdate($ospf_instance_update, 'ospf_instances', '`device_id` = ? AND `ospf_instance_id` = ?', array($device['device_id'], $ospf_instance_id));
118    echo('U');
119    unset($ospf_instance_update);
120  } else {
121    echo('.');
122  }
123
124  $ospf_instance_count++; // Really in OSPF-MIB always only 1 instance (process)
125}
126
127unset($ospf_instance_poll);
128unset($ospf_instance_db);
129
130echo(PHP_EOL);
131
132print_cli_data_field('Areas', 2);
133
134$ospf_area_oids = array('ospfAuthType', 'ospfImportAsExtern', 'ospfSpfRuns', 'ospfAreaBdrRtrCount', 'ospfAsBdrRtrCount',
135                        'ospfAreaLsaCount', 'ospfAreaLsaCksumSum', 'ospfAreaSummary', 'ospfAreaStatus');
136
137// Build array of existing entries
138foreach (dbFetchRows('SELECT * FROM `ospf_areas` WHERE `device_id` = ?', array($device['device_id'])) as $entry)
139{
140  $ospf_areas_db[$entry['ospfAreaId']] = $entry;
141}
142
143foreach ($ospf_areas_poll as $ospf_area_id => $ospf_area)
144{
145  // If the entry doesn't already exist in the prebuilt array, insert into the database and put into the array
146  if (!isset($ospf_areas_db[$ospf_area_id]))
147  {
148    $insert = array();
149    $insert['device_id']    = $device['device_id'];
150    $insert['ospfAreaId'] = $ospf_area_id;
151
152    foreach ($ospf_area_oids as $oid)
153    { // Loop the OIDs
154      $insert[$oid] = $ospf_area[$oid];
155    }
156
157    dbInsert($insert, 'ospf_areas');
158    echo('+');
159    $ospf_areas_db[$ospf_area_id] = dbFetchRow('SELECT * FROM `ospf_areas` WHERE `device_id` = ? AND `ospfAreaId` = ?', array($device['device_id'], $ospf_area_id));
160    unset($insert);
161  }
162}
163
164if (OBS_DEBUG && $set_ospf)
165{
166  echo("\nPolled: ");
167  print_vars($ospf_areas_poll);
168  echo('Database: ');
169  print_vars($ospf_areas_db);
170  echo("\n");
171}
172
173// Loop array of entries and update
174if (is_array($ospf_areas_db))
175{
176  foreach ($ospf_areas_db as $ospf_area_id => $ospf_area_db)
177  {
178
179    if (is_array($ospf_areas_poll[$ospf_area_id]))
180    {
181      $ospf_area_poll = $ospf_areas_poll[$ospf_area_db['ospfAreaId']];
182      foreach ($ospf_area_oids as $oid)
183      { // Loop the OIDs
184        if ($ospf_area_db[$oid] != $ospf_area_poll[$oid])
185        { // If data has changed, build a query
186          $ospf_area_update[$oid] = $ospf_area_poll[$oid];
187          // log_event("$oid -> ".$this_port[$oid], $device, 'port', $port['port_id']); // FIXME
188        } else {
189        // echo($ospf_area_db[$oid] . '=' . $ospf_area_poll[$oid]);
190        }
191      }
192      if ($ospf_area_update)
193      {
194        dbUpdate($ospf_area_update, 'ospf_areas', '`device_id` = ? AND `ospfAreaId` = ?', array($device['device_id'], $ospf_area_id));
195        echo('U');
196        unset($ospf_area_update);
197      } else {
198        echo('.');
199      }
200
201      $ospf_area_count++;
202    } else {
203      dbDelete('ospf_areas', '`device_id` = ? AND `ospfAreaId` = ?', array($device['device_id'], $ospf_area_db['ospfAreaId']));
204      echo '-';
205    }
206  }
207}
208
209unset($ospf_areas_db);
210unset($ospf_areas_poll);
211
212echo PHP_EOL;
213
214print_cli_data_field('Ports', 2);
215
216$ospf_port_oids = array('ospfIfIpAddress','port_id','ospfAddressLessIf','ospfIfAreaId','ospfIfType','ospfIfAdminStat','ospfIfRtrPriority','ospfIfTransitDelay','ospfIfRetransInterval','ospfIfHelloInterval','ospfIfRtrDeadInterval','ospfIfPollInterval','ospfIfState','ospfIfDesignatedRouter','ospfIfBackupDesignatedRouter','ospfIfEvents','ospfIfAuthKey','ospfIfStatus','ospfIfMulticastForwarding','ospfIfDemand','ospfIfAuthType');
217
218// Build array of existing entries
219foreach (dbFetchRows('SELECT * FROM `ospf_ports` WHERE `device_id` = ?', array($device['device_id'])) as $entry)
220{
221  $ospf_ports_db[$entry['ospf_port_id']] = $entry;
222}
223
224foreach ($ospf_ports_poll as $ospf_port_id => $ospf_port)
225{
226  // If the entry doesn't already exist in the prebuilt array, insert into the database and put into the array
227  if (!isset($ospf_ports_db[$ospf_port_id]))
228  {
229    dbInsert(array('device_id' => $device['device_id'], 'ospf_port_id' => $ospf_port_id), 'ospf_ports');
230    echo('+');
231    $ospf_ports_db[$entry['ospf_port_id']] = dbFetchRow('SELECT * FROM `ospf_ports` WHERE `device_id` = ? AND `ospf_port_id` = ?', array($device['device_id'], $ospf_port_id));
232  }
233}
234
235if (OBS_DEBUG && $set_ospf)
236{
237  echo("\nPolled: ");
238  print_vars($ospf_ports_poll);
239  echo('Database: ');
240  print_vars($ospf_ports_db);
241  echo("\n");
242}
243
244// Loop array of entries and update
245if (is_array($ospf_ports_db))
246{
247  foreach ($ospf_ports_db as $ospf_port_id => $ospf_port_db)
248  {
249    if (is_array($ospf_ports_poll[$ospf_port_db['ospf_port_id']]))
250    {
251      $ospf_port_poll = $ospf_ports_poll[$ospf_port_db['ospf_port_id']];
252
253      if ($ospf_port_poll['ospfAddressLessIf'])
254      {
255        $ospf_port_poll['port_id'] = @dbFetchCell('SELECT `port_id` FROM `ports` WHERE `device_id` = ? AND `ifIndex` = ?', array($device['device_id'], $ospf_port_poll['ospfAddressLessIf']));
256      } else {
257        //$ospf_port_poll['port_id'] = @dbFetchCell('SELECT A.`port_id` FROM ipv4_addresses AS A, ports AS I WHERE A.ipv4_address = ? AND I.port_id = A.port_id AND I.device_id = ?', array($ospf_port_poll['ospfIfIpAddress'], $device['device_id']));
258        $ospf_port_poll['port_id'] = current(get_entity_ids_ip_by_network('port', $ospf_port_poll['ospfIfIpAddress'], generate_query_values($device['device_id'], 'device_id')));
259      }
260
261      foreach ($ospf_port_oids as $oid)
262      { // Loop the OIDs
263        if ($ospf_port_db[$oid] != $ospf_port_poll[$oid])
264        { // If data has changed, build a query
265          $ospf_port_update[$oid] = $ospf_port_poll[$oid];
266          // log_event("$oid -> ".$this_port[$oid], $device, 'ospf', $port['port_id']); // FIXME
267        }
268      }
269      if ($ospf_port_update)
270      {
271        dbUpdate($ospf_port_update, 'ospf_ports', '`device_id` = ? AND `ospf_port_id` = ?', array($device['device_id'], $ospf_port_id));
272        echo('U');
273        unset($ospf_port_update);
274      } else {
275        echo('.');
276      }
277      unset($ospf_port_poll);
278      unset($ospf_port_db);
279      $ospf_port_count++;
280    } else {
281      dbDelete('ospf_ports', '`device_id` = ? AND `ospf_port_id` = ?', array($device['device_id'], $ospf_port_db['ospf_port_id']));
282      echo('-');
283    }
284  }
285}
286
287echo PHP_EOL;
288
289// OSPF-MIB::ospfNbrIpAddr.172.22.203.98.0 172.22.203.98
290// OSPF-MIB::ospfNbrAddressLessIndex.172.22.203.98.0 0
291// OSPF-MIB::ospfNbrRtrId.172.22.203.98.0 172.22.203.128
292// OSPF-MIB::ospfNbrOptions.172.22.203.98.0 2
293// OSPF-MIB::ospfNbrPriority.172.22.203.98.0 0
294// OSPF-MIB::ospfNbrState.172.22.203.98.0 full
295// OSPF-MIB::ospfNbrEvents.172.22.203.98.0 6
296// OSPF-MIB::ospfNbrLsRetransQLen.172.22.203.98.0 1
297// OSPF-MIB::ospfNbmaNbrStatus.172.22.203.98.0 active
298// OSPF-MIB::ospfNbmaNbrPermanence.172.22.203.98.0 dynamic
299// OSPF-MIB::ospfNbrHelloSuppressed.172.22.203.98.0 false
300
301print_cli_data_field('Neighbours',2);
302
303$ospf_nbr_oids_db  = array('ospfNbrIpAddr', 'ospfNbrAddressLessIndex', 'ospfNbrRtrId', 'ospfNbrOptions', 'ospfNbrPriority', 'ospfNbrState', 'ospfNbrEvents', 'ospfNbrLsRetransQLen', 'ospfNbmaNbrStatus', 'ospfNbmaNbrPermanence', 'ospfNbrHelloSuppressed');
304$ospf_nbr_oids_rrd = array();
305$ospf_nbr_oids = array_merge($ospf_nbr_oids_db, $ospf_nbr_oids_rrd);
306
307// Build array of existing entries
308foreach (dbFetchRows('SELECT * FROM `ospf_nbrs` WHERE `device_id` = ?', array($device['device_id'])) as $nbr_entry)
309{
310  $ospf_nbrs_db[$nbr_entry['ospf_nbr_id']] = $nbr_entry;
311}
312
313foreach ($ospf_nbrs_poll as $ospf_nbr_id => $ospf_nbr)
314{
315  // If the entry doesn't already exist in the prebuilt array, insert into the database and put into the array
316  if (!isset($ospf_nbrs_db[$ospf_nbr_id]))
317  {
318    dbInsert(array('device_id' => $device['device_id'], 'ospf_nbr_id' => $ospf_nbr_id), 'ospf_nbrs');
319    echo('+');
320    $entry = dbFetchRow('SELECT * FROM `ospf_nbrs` WHERE `device_id` = ? AND `ospf_nbr_id` = ?', array($device['device_id'], $ospf_nbr_id));
321    $ospf_nbrs_db[$entry['ospf_nbr_id']] = $entry;
322  }
323}
324
325if (OBS_DEBUG && $set_ospf)
326{
327  echo("\nPolled: ");
328  print_vars($ospf_nbrs_poll);
329  echo('Database: ');
330  print_vars($ospf_nbrs_db);
331  echo("\n");
332}
333
334// Loop array of entries and update
335if (is_array($ospf_nbrs_db))
336{
337  foreach ($ospf_nbrs_db as $ospf_nbr_id => $ospf_nbr_db)
338  {
339    if (is_array($ospf_nbrs_poll[$ospf_nbr_db['ospf_nbr_id']]))
340    {
341      $ospf_nbr_poll = $ospf_nbrs_poll[$ospf_nbr_db['ospf_nbr_id']];
342
343      //$ospf_nbr_poll['port_id'] = @dbFetchCell('SELECT A.`port_id` FROM `ipv4_addresses` AS A, `ospf_nbrs` AS I WHERE A.`ipv4_address` = ? AND I.`port_id` = A.`port_id` AND I.`device_id` = ?', array($ospf_nbr_poll['ospfNbrIpAddr'], $device['device_id']));
344      $ospf_nbr_poll['port_id'] = current(get_entity_ids_ip_by_network('port', $ospf_nbr_poll['ospfNbrIpAddr'], generate_query_values($device['device_id'], 'device_id')));
345
346      if ($ospf_nbr_db['port_id'] != $ospf_nbr_poll['port_id'])
347      {
348        if ($ospf_nbr_poll['port_id']) {
349          $ospf_nbr_update = array('port_id' => $ospf_nbr_poll['port_id']);
350        } else {
351          $ospf_nbr_update = array('port_id' => array('NULL'));
352        }
353      }
354
355      foreach ($ospf_nbr_oids as $oid)
356      { // Loop the OIDs
357        print_debug($ospf_nbr_db[$oid].'|'.$ospf_nbr_poll[$oid]);
358        if ($ospf_nbr_db[$oid] != $ospf_nbr_poll[$oid])
359        { // If data has changed, build a query
360          $ospf_nbr_update[$oid] = $ospf_nbr_poll[$oid];
361          // log_event("$oid -> ".$this_nbr[$oid], $device, 'ospf', $nbr['port_id']); // FIXME
362        }
363      }
364      if ($ospf_nbr_update)
365      {
366        dbUpdate($ospf_nbr_update, 'ospf_nbrs', '`device_id` = ? AND `ospf_nbr_id` = ?', array($device['device_id'], $ospf_nbr_id));
367        echo('U');
368        unset($ospf_nbr_update);
369      } else {
370        echo('.');
371      }
372
373      unset($ospf_nbr_poll);
374      unset($ospf_nbr_db);
375      $ospf_nbr_count++;
376    } else {
377      dbDelete('ospf_nbrs', '`device_id` = ? AND `ospf_nbr_id` = ?', array($device['device_id'], $ospf_nbr_db['ospf_nbr_id']));
378      echo('-');
379    }
380  }
381}
382
383echo PHP_EOL;
384
385if ($set_ospf)
386{
387  // Create device-wide statistics RRD
388  rrdtool_update_ng($device, 'ospf-statistics', array(
389    'instances'  => $ospf_instance_count,
390    'areas'      => $ospf_area_count,
391    'ports'      => $ospf_port_count,
392    'neighbours' => $ospf_nbr_count,
393  ));
394
395  $graphs['ospf_neighbours'] = TRUE;
396  $graphs['ospf_areas']      = TRUE;
397  $graphs['ospf_ports']      = TRUE;
398
399}
400
401unset($ospf_ports_db);
402unset($ospf_ports_poll);
403
404// EOF
405