2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2016 Victor Kirhenshtein
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 BOOL g_bModificationsLocked
= FALSE
;
30 Network NXCORE_EXPORTABLE
*g_pEntireNet
= NULL
;
31 ServiceRoot NXCORE_EXPORTABLE
*g_pServiceRoot
= NULL
;
32 TemplateRoot NXCORE_EXPORTABLE
*g_pTemplateRoot
= NULL
;
33 PolicyRoot NXCORE_EXPORTABLE
*g_pPolicyRoot
= NULL
;
34 NetworkMapRoot NXCORE_EXPORTABLE
*g_pMapRoot
= NULL
;
35 DashboardRoot NXCORE_EXPORTABLE
*g_pDashboardRoot
= NULL
;
36 BusinessServiceRoot NXCORE_EXPORTABLE
*g_pBusinessServiceRoot
= NULL
;
38 UINT32 NXCORE_EXPORTABLE g_dwMgmtNode
= 0;
40 Queue
*g_pTemplateUpdateQueue
= NULL
;
42 ObjectIndex g_idxObjectById
;
43 InetAddressIndex g_idxSubnetByAddr
;
44 InetAddressIndex g_idxInterfaceByAddr
;
45 ObjectIndex g_idxZoneByGUID
;
46 ObjectIndex g_idxNodeById
;
47 InetAddressIndex g_idxNodeByAddr
;
48 ObjectIndex g_idxClusterById
;
49 ObjectIndex g_idxMobileDeviceById
;
50 ObjectIndex g_idxAccessPointById
;
51 ObjectIndex g_idxConditionById
;
52 ObjectIndex g_idxServiceCheckById
;
53 ObjectIndex g_idxNetMapById
;
54 ObjectIndex g_idxChassisById
;
59 static int m_iStatusCalcAlg
= SA_CALCULATE_MOST_CRITICAL
;
60 static int m_iStatusPropAlg
= SA_PROPAGATE_UNCHANGED
;
61 static int m_iFixedStatus
; // Status if propagation is "Fixed"
62 static int m_iStatusShift
; // Shift value for "shifted" status propagation
63 static int m_iStatusTranslation
[4];
64 static int m_iStatusSingleThreshold
;
65 static int m_iStatusThresholds
[4];
66 static CONDITION s_condUpdateMaps
= INVALID_CONDITION_HANDLE
;
69 * Thread which apply template updates
71 static THREAD_RESULT THREAD_CALL
ApplyTemplateThread(void *pArg
)
73 DbgPrintf(1, _T("Apply template thread started"));
76 TEMPLATE_UPDATE_INFO
*pInfo
= (TEMPLATE_UPDATE_INFO
*)g_pTemplateUpdateQueue
->getOrBlock();
77 if (pInfo
== INVALID_POINTER_VALUE
)
80 DbgPrintf(5, _T("ApplyTemplateThread: template=%d(%s) updateType=%d target=%d removeDci=%s"),
81 pInfo
->pTemplate
->getId(), pInfo
->pTemplate
->getName(), pInfo
->updateType
, pInfo
->targetId
, pInfo
->removeDCI
? _T("true") : _T("false"));
82 BOOL bSuccess
= FALSE
;
83 NetObj
*dcTarget
= FindObjectById(pInfo
->targetId
);
86 if (dcTarget
->isDataCollectionTarget())
90 switch(pInfo
->updateType
)
93 lock1
= pInfo
->pTemplate
->lockDCIList(0x7FFFFFFF, _T("SYSTEM"), NULL
);
94 lock2
= ((DataCollectionTarget
*)dcTarget
)->lockDCIList(0x7FFFFFFF, _T("SYSTEM"), NULL
);
97 pInfo
->pTemplate
->applyToTarget((DataCollectionTarget
*)dcTarget
);
101 pInfo
->pTemplate
->unlockDCIList(0x7FFFFFFF);
103 ((DataCollectionTarget
*)dcTarget
)->unlockDCIList(0x7FFFFFFF);
105 case REMOVE_TEMPLATE
:
106 if (((DataCollectionTarget
*)dcTarget
)->lockDCIList(0x7FFFFFFF, _T("SYSTEM"), NULL
))
108 ((DataCollectionTarget
*)dcTarget
)->unbindFromTemplate(pInfo
->pTemplate
->getId(), pInfo
->removeDCI
);
109 ((DataCollectionTarget
*)dcTarget
)->unlockDCIList(0x7FFFFFFF);
122 DbgPrintf(8, _T("ApplyTemplateThread: success"));
123 pInfo
->pTemplate
->decRefCount();
128 DbgPrintf(8, _T("ApplyTemplateThread: failed"));
129 g_pTemplateUpdateQueue
->put(pInfo
); // Requeue
134 DbgPrintf(1, _T("Apply template thread stopped"));
139 * Update DCI cache for all data collection targets referenced by given index
141 static void UpdateDataCollectionCache(ObjectIndex
*idx
)
143 ObjectArray
<NetObj
> *objects
= idx
->getObjects(true);
144 for(int i
= 0; i
< objects
->size(); i
++)
146 DataCollectionTarget
*t
= (DataCollectionTarget
*)objects
->get(i
);
154 * DCI cache loading thread
156 static THREAD_RESULT THREAD_CALL
CacheLoadingThread(void *pArg
)
158 DbgPrintf(1, _T("Started caching of DCI values"));
160 UpdateDataCollectionCache(&g_idxNodeById
);
161 UpdateDataCollectionCache(&g_idxClusterById
);
162 UpdateDataCollectionCache(&g_idxMobileDeviceById
);
163 UpdateDataCollectionCache(&g_idxAccessPointById
);
164 UpdateDataCollectionCache(&g_idxChassisById
);
166 DbgPrintf(1, _T("Finished caching of DCI values"));
171 * Callback for map update thread
173 static void UpdateMapCallback(NetObj
*object
, void *data
)
175 ((NetworkMap
*)object
)->updateContent();
176 ((NetworkMap
*)object
)->calculateCompoundStatus();
182 static THREAD_RESULT THREAD_CALL
MapUpdateThread(void *pArg
)
184 DbgPrintf(2, _T("Map update thread started"));
185 while(!SleepAndCheckForShutdown(60))
187 DbgPrintf(5, _T("Updating maps..."));
188 g_idxNetMapById
.forEach(UpdateMapCallback
, NULL
);
189 DbgPrintf(5, _T("Map update completed"));
191 DbgPrintf(2, _T("Map update thread stopped"));
196 * Initialize objects infrastructure
200 // Load default status calculation info
201 m_iStatusCalcAlg
= ConfigReadInt(_T("StatusCalculationAlgorithm"), SA_CALCULATE_MOST_CRITICAL
);
202 m_iStatusPropAlg
= ConfigReadInt(_T("StatusPropagationAlgorithm"), SA_PROPAGATE_UNCHANGED
);
203 m_iFixedStatus
= ConfigReadInt(_T("FixedStatusValue"), STATUS_NORMAL
);
204 m_iStatusShift
= ConfigReadInt(_T("StatusShift"), 0);
205 ConfigReadByteArray(_T("StatusTranslation"), m_iStatusTranslation
, 4, STATUS_WARNING
);
206 m_iStatusSingleThreshold
= ConfigReadInt(_T("StatusSingleThreshold"), 75);
207 ConfigReadByteArray(_T("StatusThresholds"), m_iStatusThresholds
, 4, 50);
209 g_pTemplateUpdateQueue
= new Queue
;
211 s_condUpdateMaps
= ConditionCreate(FALSE
);
213 // Create "Entire Network" object
214 g_pEntireNet
= new Network
;
215 NetObjInsert(g_pEntireNet
, false, false);
217 // Create "Service Root" object
218 g_pServiceRoot
= new ServiceRoot
;
219 NetObjInsert(g_pServiceRoot
, false, false);
221 // Create "Template Root" object
222 g_pTemplateRoot
= new TemplateRoot
;
223 NetObjInsert(g_pTemplateRoot
, false, false);
225 // Create "Policy Root" object
226 g_pPolicyRoot
= new PolicyRoot
;
227 NetObjInsert(g_pPolicyRoot
, false, false);
229 // Create "Network Maps Root" object
230 g_pMapRoot
= new NetworkMapRoot
;
231 NetObjInsert(g_pMapRoot
, false, false);
233 // Create "Dashboard Root" object
234 g_pDashboardRoot
= new DashboardRoot
;
235 NetObjInsert(g_pDashboardRoot
, false, false);
237 // Create "Business Service Root" object
238 g_pBusinessServiceRoot
= new BusinessServiceRoot
;
239 NetObjInsert(g_pBusinessServiceRoot
, false, false);
241 DbgPrintf(1, _T("Built-in objects created"));
243 // Initialize service checks
248 * Insert new object into network
250 void NetObjInsert(NetObj
*pObject
, bool newObject
, bool importedObject
)
254 // Assign unique ID to new object
255 pObject
->setId(CreateUniqueId(IDG_NETWORK_OBJECT
));
256 if (!importedObject
) // imported objects already have valid GUID
257 pObject
->generateGuid();
259 // Create tables for storing data collection values
260 if (pObject
->isDataCollectionTarget())
262 TCHAR szQuery
[256], szQueryTemplate
[256];
265 DB_HANDLE hdb
= DBConnectionPoolAcquireConnection();
267 MetaDataReadStr(_T("IDataTableCreationCommand"), szQueryTemplate
, 255, _T(""));
268 _sntprintf(szQuery
, sizeof(szQuery
) / sizeof(TCHAR
), szQueryTemplate
, pObject
->getId());
269 DBQuery(hdb
, szQuery
);
271 for(i
= 0; i
< 10; i
++)
273 _sntprintf(szQuery
, sizeof(szQuery
) / sizeof(TCHAR
), _T("IDataIndexCreationCommand_%d"), i
);
274 MetaDataReadStr(szQuery
, szQueryTemplate
, 255, _T(""));
275 if (szQueryTemplate
[0] != 0)
277 _sntprintf(szQuery
, sizeof(szQuery
) / sizeof(TCHAR
), szQueryTemplate
, pObject
->getId(), pObject
->getId());
278 DBQuery(hdb
, szQuery
);
282 for(i
= 0; i
< 10; i
++)
284 _sntprintf(szQuery
, sizeof(szQuery
) / sizeof(TCHAR
), _T("TDataTableCreationCommand_%d"), i
);
285 MetaDataReadStr(szQuery
, szQueryTemplate
, 255, _T(""));
286 if (szQueryTemplate
[0] != 0)
288 _sntprintf(szQuery
, sizeof(szQuery
) / sizeof(TCHAR
), szQueryTemplate
, pObject
->getId(), pObject
->getId());
289 DBQuery(hdb
, szQuery
);
293 for(i
= 0; i
< 10; i
++)
295 _sntprintf(szQuery
, sizeof(szQuery
) / sizeof(TCHAR
), _T("TDataIndexCreationCommand_%d"), i
);
296 MetaDataReadStr(szQuery
, szQueryTemplate
, 255, _T(""));
297 if (szQueryTemplate
[0] != 0)
299 _sntprintf(szQuery
, sizeof(szQuery
) / sizeof(TCHAR
), szQueryTemplate
, pObject
->getId(), pObject
->getId());
300 DBQuery(hdb
, szQuery
);
304 DBConnectionPoolReleaseConnection(hdb
);
307 g_idxObjectById
.put(pObject
->getId(), pObject
);
308 if (!pObject
->isDeleted())
310 switch(pObject
->getObjectClass())
314 case OBJECT_CONTAINER
:
315 case OBJECT_SERVICEROOT
:
316 case OBJECT_NETWORKSERVICE
:
317 case OBJECT_TEMPLATE
:
318 case OBJECT_TEMPLATEGROUP
:
319 case OBJECT_TEMPLATEROOT
:
320 case OBJECT_VPNCONNECTOR
:
321 case OBJECT_POLICYGROUP
:
322 case OBJECT_POLICYROOT
:
323 case OBJECT_AGENTPOLICY
:
324 case OBJECT_AGENTPOLICY_CONFIG
:
325 case OBJECT_AGENTPOLICY_LOGPARSER
:
326 case OBJECT_NETWORKMAPROOT
:
327 case OBJECT_NETWORKMAPGROUP
:
328 case OBJECT_DASHBOARDROOT
:
329 case OBJECT_DASHBOARD
:
330 case OBJECT_BUSINESSSERVICEROOT
:
331 case OBJECT_BUSINESSSERVICE
:
332 case OBJECT_NODELINK
:
336 g_idxNodeById
.put(pObject
->getId(), pObject
);
337 if (!(((Node
*)pObject
)->getFlags() & NF_REMOTE_AGENT
))
339 if (IsZoningEnabled())
341 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(((Node
*)pObject
)->getZoneId());
344 zone
->addToIndex((Node
*)pObject
);
348 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for node object %s [%d]"),
349 (int)((Node
*)pObject
)->getZoneId(), pObject
->getName(), (int)pObject
->getId());
354 if (((Node
*)pObject
)->getIpAddress().isValidUnicast())
355 g_idxNodeByAddr
.put(((Node
*)pObject
)->getIpAddress(), pObject
);
360 g_idxClusterById
.put(pObject
->getId(), pObject
);
362 case OBJECT_MOBILEDEVICE
:
363 g_idxMobileDeviceById
.put(pObject
->getId(), pObject
);
365 case OBJECT_ACCESSPOINT
:
366 g_idxAccessPointById
.put(pObject
->getId(), pObject
);
367 MacDbAddAccessPoint((AccessPoint
*)pObject
);
370 g_idxChassisById
.put(pObject
->getId(), pObject
);
373 if (((Subnet
*)pObject
)->getIpAddress().isValidUnicast())
375 if (IsZoningEnabled())
377 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(((Subnet
*)pObject
)->getZoneId());
380 zone
->addToIndex((Subnet
*)pObject
);
384 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for subnet object %s [%d]"),
385 (int)((Subnet
*)pObject
)->getZoneId(), pObject
->getName(), (int)pObject
->getId());
390 g_idxSubnetByAddr
.put(((Subnet
*)pObject
)->getIpAddress(), pObject
);
394 PostEvent(EVENT_SUBNET_ADDED
, g_dwMgmtNode
, "isAd", pObject
->getId(), pObject
->getName(),
395 &((Subnet
*)pObject
)->getIpAddress(), ((Subnet
*)pObject
)->getIpAddress().getMaskBits());
399 case OBJECT_INTERFACE
:
400 if (!((Interface
*)pObject
)->isExcludedFromTopology())
402 if (IsZoningEnabled())
404 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(((Interface
*)pObject
)->getZoneId());
407 zone
->addToIndex((Interface
*)pObject
);
411 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for interface object %s [%d]"),
412 (int)((Interface
*)pObject
)->getZoneId(), pObject
->getName(), (int)pObject
->getId());
417 g_idxInterfaceByAddr
.put(((Interface
*)pObject
)->getIpAddressList(), pObject
);
420 MacDbAddInterface((Interface
*)pObject
);
423 g_idxZoneByGUID
.put(((Zone
*)pObject
)->getZoneId(), pObject
);
425 case OBJECT_CONDITION
:
426 g_idxConditionById
.put(pObject
->getId(), pObject
);
428 case OBJECT_SLMCHECK
:
429 g_idxServiceCheckById
.put(pObject
->getId(), pObject
);
431 case OBJECT_NETWORKMAP
:
432 g_idxNetMapById
.put(pObject
->getId(), pObject
);
436 bool processed
= false;
437 for(UINT32 i
= 0; i
< g_dwNumModules
; i
++)
439 if (g_pModuleList
[i
].pfNetObjInsert
!= NULL
)
441 if (g_pModuleList
[i
].pfNetObjInsert(pObject
))
446 nxlog_write(MSG_BAD_NETOBJ_TYPE
, EVENTLOG_ERROR_TYPE
, "d", pObject
->getObjectClass());
452 // Notify modules about object creation
455 CALL_ALL_MODULES(pfPostObjectCreate
, (pObject
));
459 CALL_ALL_MODULES(pfPostObjectLoad
, (pObject
));
464 * Delete object from indexes
465 * If object has an IP address, this function will delete it from
466 * appropriate index. Normally this function should be called from
467 * NetObj::deleteObject() method.
469 void NetObjDeleteFromIndexes(NetObj
*pObject
)
471 switch(pObject
->getObjectClass())
475 case OBJECT_CONTAINER
:
476 case OBJECT_SERVICEROOT
:
477 case OBJECT_NETWORKSERVICE
:
478 case OBJECT_TEMPLATE
:
479 case OBJECT_TEMPLATEGROUP
:
480 case OBJECT_TEMPLATEROOT
:
481 case OBJECT_VPNCONNECTOR
:
482 case OBJECT_POLICYGROUP
:
483 case OBJECT_POLICYROOT
:
484 case OBJECT_AGENTPOLICY
:
485 case OBJECT_AGENTPOLICY_CONFIG
:
486 case OBJECT_NETWORKMAPROOT
:
487 case OBJECT_NETWORKMAPGROUP
:
488 case OBJECT_DASHBOARDROOT
:
489 case OBJECT_DASHBOARD
:
490 case OBJECT_BUSINESSSERVICEROOT
:
491 case OBJECT_BUSINESSSERVICE
:
492 case OBJECT_NODELINK
:
496 g_idxNodeById
.remove(pObject
->getId());
497 if (!(((Node
*)pObject
)->getFlags() & NF_REMOTE_AGENT
))
499 if (IsZoningEnabled())
501 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(((Node
*)pObject
)->getZoneId());
504 zone
->removeFromIndex((Node
*)pObject
);
508 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for node object %s [%d]"),
509 (int)((Node
*)pObject
)->getZoneId(), pObject
->getName(), (int)pObject
->getId());
514 if (((Node
*)pObject
)->getIpAddress().isValidUnicast())
515 g_idxNodeByAddr
.remove(((Node
*)pObject
)->getIpAddress());
520 g_idxClusterById
.remove(pObject
->getId());
522 case OBJECT_MOBILEDEVICE
:
523 g_idxMobileDeviceById
.remove(pObject
->getId());
525 case OBJECT_ACCESSPOINT
:
526 g_idxAccessPointById
.remove(pObject
->getId());
527 MacDbRemove(((AccessPoint
*)pObject
)->getMacAddr());
530 g_idxChassisById
.remove(pObject
->getId());
533 if (((Subnet
*)pObject
)->getIpAddress().isValidUnicast())
535 if (IsZoningEnabled())
537 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(((Subnet
*)pObject
)->getZoneId());
540 zone
->removeFromIndex((Subnet
*)pObject
);
544 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for subnet object %s [%d]"),
545 (int)((Subnet
*)pObject
)->getZoneId(), pObject
->getName(), (int)pObject
->getId());
550 g_idxSubnetByAddr
.remove(((Subnet
*)pObject
)->getIpAddress());
554 case OBJECT_INTERFACE
:
555 if (IsZoningEnabled())
557 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(((Interface
*)pObject
)->getZoneId());
560 zone
->removeFromIndex((Interface
*)pObject
);
564 DbgPrintf(2, _T("Cannot find zone object with GUID=%d for interface object %s [%d]"),
565 (int)((Interface
*)pObject
)->getZoneId(), pObject
->getName(), (int)pObject
->getId());
570 const ObjectArray
<InetAddress
> *list
= ((Interface
*)pObject
)->getIpAddressList()->getList();
571 for(int i
= 0; i
< list
->size(); i
++)
573 InetAddress
*addr
= list
->get(i
);
574 if (addr
->isValidUnicast())
576 NetObj
*o
= g_idxInterfaceByAddr
.get(*addr
);
577 if ((o
!= NULL
) && (o
->getId() == pObject
->getId()))
579 g_idxInterfaceByAddr
.remove(*addr
);
584 MacDbRemove(((Interface
*)pObject
)->getMacAddr());
587 g_idxZoneByGUID
.remove(((Zone
*)pObject
)->getZoneId());
589 case OBJECT_CONDITION
:
590 g_idxConditionById
.remove(pObject
->getId());
592 case OBJECT_SLMCHECK
:
593 g_idxServiceCheckById
.remove(pObject
->getId());
595 case OBJECT_NETWORKMAP
:
596 g_idxNetMapById
.remove(pObject
->getId());
600 bool processed
= false;
601 for(UINT32 i
= 0; i
< g_dwNumModules
; i
++)
603 if (g_pModuleList
[i
].pfNetObjDelete
!= NULL
)
605 if (g_pModuleList
[i
].pfNetObjDelete(pObject
))
610 nxlog_write(MSG_BAD_NETOBJ_TYPE
, EVENTLOG_ERROR_TYPE
, "d", pObject
->getObjectClass());
617 * Find access point by MAC address
619 AccessPoint NXCORE_EXPORTABLE
*FindAccessPointByMAC(const BYTE
*macAddr
)
621 if (!memcmp(macAddr
, "\x00\x00\x00\x00\x00\x00", 6))
624 NetObj
*object
= MacDbFind(macAddr
);
625 return ((object
!= NULL
) && (object
->getObjectClass() == OBJECT_ACCESSPOINT
)) ? (AccessPoint
*)object
: NULL
;
629 * Mobile device id comparator
631 static bool DeviceIdComparator(NetObj
*object
, void *deviceId
)
633 return ((object
->getObjectClass() == OBJECT_MOBILEDEVICE
) && !object
->isDeleted() &&
634 !_tcscmp((const TCHAR
*)deviceId
, ((MobileDevice
*)object
)->getDeviceId()));
638 * Find mobile device by device ID
640 MobileDevice NXCORE_EXPORTABLE
*FindMobileDeviceByDeviceID(const TCHAR
*deviceId
)
642 if ((deviceId
== NULL
) || (*deviceId
== 0))
645 return (MobileDevice
*)g_idxMobileDeviceById
.find(DeviceIdComparator
, (void *)deviceId
);
648 static Node
*FindNodeByIPInternal(UINT32 zoneId
, const InetAddress
& ipAddr
)
650 Zone
*zone
= IsZoningEnabled() ? (Zone
*)g_idxZoneByGUID
.get(zoneId
) : NULL
;
653 if (IsZoningEnabled())
657 node
= zone
->getNodeByAddr(ipAddr
);
662 node
= (Node
*)g_idxNodeByAddr
.get(ipAddr
);
667 Interface
*iface
= NULL
;
668 if (IsZoningEnabled())
672 iface
= zone
->getInterfaceByAddr(ipAddr
);
677 iface
= (Interface
*)g_idxInterfaceByAddr
.get(ipAddr
);
679 return (iface
!= NULL
) ? iface
->getParentNode() : NULL
;
683 * Data for node find callback
685 struct NodeFindCBData
687 const InetAddress
*addr
;
692 * Callback for finding node in all zones
694 static bool NodeFindCB(NetObj
*zone
, void *data
)
696 Node
*node
= ((Zone
*)zone
)->getNodeByAddr(*((NodeFindCBData
*)data
)->addr
);
699 Interface
*iface
= ((Zone
*)zone
)->getInterfaceByAddr(*((NodeFindCBData
*)data
)->addr
);
701 node
= iface
->getParentNode();
707 ((NodeFindCBData
*)data
)->node
= node
;
712 * Find node by IP address
714 Node NXCORE_EXPORTABLE
*FindNodeByIP(UINT32 zoneId
, const InetAddress
& ipAddr
)
716 if (!ipAddr
.isValidUnicast())
719 if ((zoneId
== ALL_ZONES
) && IsZoningEnabled())
724 g_idxZoneByGUID
.find(NodeFindCB
, &data
);
729 return FindNodeByIPInternal(zoneId
, ipAddr
);
734 * Find node by IP address using first match from IP address list
736 Node NXCORE_EXPORTABLE
*FindNodeByIP(UINT32 zoneId
, const InetAddressList
*ipAddrList
)
738 for(int i
= 0; i
< ipAddrList
->size(); i
++)
740 Node
*node
= FindNodeByIP(zoneId
, ipAddrList
->get(i
));
748 * Find interface by IP address
750 Interface NXCORE_EXPORTABLE
*FindInterfaceByIP(UINT32 zoneId
, const InetAddress
& ipAddr
)
752 if (!ipAddr
.isValidUnicast())
755 Zone
*zone
= IsZoningEnabled() ? (Zone
*)g_idxZoneByGUID
.get(zoneId
) : NULL
;
757 Interface
*iface
= NULL
;
758 if (IsZoningEnabled())
762 iface
= zone
->getInterfaceByAddr(ipAddr
);
767 iface
= (Interface
*)g_idxInterfaceByAddr
.get(ipAddr
);
773 * Find node by MAC address
775 Node NXCORE_EXPORTABLE
*FindNodeByMAC(const BYTE
*macAddr
)
777 Interface
*pInterface
= FindInterfaceByMAC(macAddr
);
778 return (pInterface
!= NULL
) ? pInterface
->getParentNode() : NULL
;
782 * Find interface by MAC address
784 Interface NXCORE_EXPORTABLE
*FindInterfaceByMAC(const BYTE
*macAddr
)
786 if (!memcmp(macAddr
, "\x00\x00\x00\x00\x00\x00", 6))
789 NetObj
*object
= MacDbFind(macAddr
);
790 return ((object
!= NULL
) && (object
->getObjectClass() == OBJECT_INTERFACE
)) ? (Interface
*)object
: NULL
;
794 * Interface description comparator
796 static bool DescriptionComparator(NetObj
*object
, void *description
)
798 return ((object
->getObjectClass() == OBJECT_INTERFACE
) && !object
->isDeleted() &&
799 !_tcscmp((const TCHAR
*)description
, ((Interface
*)object
)->getDescription()));
803 * Find interface by description
805 Interface NXCORE_EXPORTABLE
*FindInterfaceByDescription(const TCHAR
*description
)
807 return (Interface
*)g_idxObjectById
.find(DescriptionComparator
, (void *)description
);
813 static bool LldpIdComparator(NetObj
*object
, void *lldpId
)
815 const TCHAR
*id
= ((Node
*)object
)->getLLDPNodeId();
816 return (id
!= NULL
) && !_tcscmp(id
, (const TCHAR
*)lldpId
);
820 * Find node by LLDP ID
822 Node NXCORE_EXPORTABLE
*FindNodeByLLDPId(const TCHAR
*lldpId
)
824 return (Node
*)g_idxNodeById
.find(LldpIdComparator
, (void *)lldpId
);
828 * SNMP sysName comparator
830 static bool SysNameComparator(NetObj
*object
, void *sysName
)
832 const TCHAR
*n
= ((Node
*)object
)->getSysName();
833 return (n
!= NULL
) && !_tcscmp(n
, (const TCHAR
*)sysName
);
837 * Find node by SNMP sysName
839 Node NXCORE_EXPORTABLE
*FindNodeBySysName(const TCHAR
*sysName
)
841 if ((sysName
== NULL
) || (sysName
[0] == 0))
843 return (Node
*)g_idxNodeById
.find(SysNameComparator
, (void *)sysName
);
847 * Bridge ID comparator
849 static bool BridgeIdComparator(NetObj
*object
, void *bridgeId
)
851 return ((Node
*)object
)->isBridge() && !memcmp(((Node
*)object
)->getBridgeId(), bridgeId
, MAC_ADDR_LENGTH
);
855 * Find node by bridge ID (bridge base address)
857 Node NXCORE_EXPORTABLE
*FindNodeByBridgeId(const BYTE
*bridgeId
)
859 return (Node
*)g_idxNodeById
.find(BridgeIdComparator
, (void *)bridgeId
);
863 * Find subnet by IP address
865 Subnet NXCORE_EXPORTABLE
*FindSubnetByIP(UINT32 zoneId
, const InetAddress
& ipAddr
)
867 if (!ipAddr
.isValidUnicast())
870 Subnet
*subnet
= NULL
;
871 if (IsZoningEnabled())
873 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(zoneId
);
876 subnet
= zone
->getSubnetByAddr(ipAddr
);
881 subnet
= (Subnet
*)g_idxSubnetByAddr
.get(ipAddr
);
887 * Subnet matching data
889 struct SUBNET_MATCHING_DATA
891 InetAddress ipAddr
; // IP address to find subnet for
892 int maskLen
; // Current match mask length
893 Subnet
*subnet
; // search result
897 * Subnet matching callback
899 static void SubnetMatchCallback(const InetAddress
& addr
, NetObj
*object
, void *arg
)
901 SUBNET_MATCHING_DATA
*data
= (SUBNET_MATCHING_DATA
*)arg
;
902 if (((Subnet
*)object
)->getIpAddress().contain(data
->ipAddr
))
904 int maskLen
= ((Subnet
*)object
)->getIpAddress().getMaskBits();
905 if (maskLen
> data
->maskLen
)
907 data
->maskLen
= maskLen
;
908 data
->subnet
= (Subnet
*)object
;
914 * Find subnet for given IP address
916 Subnet NXCORE_EXPORTABLE
*FindSubnetForNode(UINT32 zoneId
, const InetAddress
& nodeAddr
)
918 if (!nodeAddr
.isValidUnicast())
921 SUBNET_MATCHING_DATA matchData
;
922 matchData
.ipAddr
= nodeAddr
;
923 matchData
.maskLen
= -1;
924 matchData
.subnet
= NULL
;
925 if (IsZoningEnabled())
927 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(zoneId
);
930 zone
->forEachSubnet(SubnetMatchCallback
, &matchData
);
935 g_idxSubnetByAddr
.forEach(SubnetMatchCallback
, &matchData
);
937 return matchData
.subnet
;
943 NetObj NXCORE_EXPORTABLE
*FindObjectById(UINT32 dwId
, int objClass
)
945 NetObj
*object
= g_idxObjectById
.get(dwId
);
946 if ((object
== NULL
) || (objClass
== -1))
948 return (objClass
== object
->getObjectClass()) ? object
: NULL
;
952 * Get object name by ID
954 const TCHAR NXCORE_EXPORTABLE
*GetObjectName(DWORD id
, const TCHAR
*defaultName
)
956 NetObj
*object
= g_idxObjectById
.get(id
);
957 return (object
!= NULL
) ? object
->getName() : defaultName
;
961 * Callback data for FindObjectByName
963 struct __find_object_data
970 * Object name comparator for FindObjectByName
972 static bool ObjectNameComparator(NetObj
*object
, void *data
)
974 struct __find_object_data
*fd
= (struct __find_object_data
*)data
;
975 return ((fd
->objClass
== -1) || (fd
->objClass
== object
->getObjectClass())) &&
976 !object
->isDeleted() && !_tcsicmp(object
->getName(), fd
->name
);
980 * Find object by name
982 NetObj NXCORE_EXPORTABLE
*FindObjectByName(const TCHAR
*name
, int objClass
)
984 struct __find_object_data data
;
986 data
.objClass
= objClass
;
988 return g_idxObjectById
.find(ObjectNameComparator
, &data
);
992 * GUID comparator for FindObjectByGUID
994 static bool ObjectGuidComparator(NetObj
*object
, void *data
)
996 return !object
->isDeleted() && object
->getGuid().equals(*((const uuid
*)data
));
1000 * Find object by GUID
1002 NetObj NXCORE_EXPORTABLE
*FindObjectByGUID(const uuid
& guid
, int objClass
)
1004 NetObj
*object
= g_idxObjectById
.find(ObjectGuidComparator
, (void *)&guid
);
1005 return (object
!= NULL
) ? (((objClass
== -1) || (objClass
== object
->getObjectClass())) ? object
: NULL
) : NULL
;
1009 * Template name comparator for FindTemplateByName
1011 static bool TemplateNameComparator(NetObj
*object
, void *name
)
1013 return (object
->getObjectClass() == OBJECT_TEMPLATE
) && !object
->isDeleted() && !_tcsicmp(object
->getName(), (const TCHAR
*)name
);
1017 * Find template object by name
1019 Template NXCORE_EXPORTABLE
*FindTemplateByName(const TCHAR
*pszName
)
1021 return (Template
*)g_idxObjectById
.find(TemplateNameComparator
, (void *)pszName
);
1025 * Callback for FindClusterByResourceIP
1027 static bool ClusterResourceIPComparator(NetObj
*object
, void *ipAddr
)
1029 return (object
->getObjectClass() == OBJECT_CLUSTER
) && !object
->isDeleted() && ((Cluster
*)object
)->isVirtualAddr(*((const InetAddress
*)ipAddr
));
1033 * Find cluster by resource IP
1035 Cluster NXCORE_EXPORTABLE
*FindClusterByResourceIP(const InetAddress
& ipAddr
)
1037 return (Cluster
*)g_idxObjectById
.find(ClusterResourceIPComparator
, (void *)&ipAddr
);
1041 * Data structure for IsClusterIP callback
1043 struct __cluster_ip_data
1050 * Cluster IP comparator - returns true if given address in given zone is cluster IP address
1052 static bool ClusterIPComparator(NetObj
*object
, void *data
)
1054 struct __cluster_ip_data
*d
= (struct __cluster_ip_data
*)data
;
1055 return (object
->getObjectClass() == OBJECT_CLUSTER
) && !object
->isDeleted() &&
1056 (((Cluster
*)object
)->getZoneId() == d
->zoneId
) &&
1057 (((Cluster
*)object
)->isVirtualAddr(d
->ipAddr
) ||
1058 ((Cluster
*)object
)->isSyncAddr(d
->ipAddr
));
1062 * Check if given IP address is used by cluster (it's either
1063 * resource IP or located on one of sync subnets)
1065 bool NXCORE_EXPORTABLE
IsClusterIP(UINT32 zoneId
, const InetAddress
& ipAddr
)
1067 struct __cluster_ip_data data
;
1068 data
.zoneId
= zoneId
;
1069 data
.ipAddr
= ipAddr
;
1070 return g_idxObjectById
.find(ClusterIPComparator
, &data
) != NULL
;
1074 * Find zone object by GUID
1076 Zone NXCORE_EXPORTABLE
*FindZoneByGUID(UINT32 dwZoneGUID
)
1078 return (Zone
*)g_idxZoneByGUID
.get(dwZoneGUID
);
1082 * Object comparator for FindLocalMgmtNode()
1084 static bool LocalMgmtNodeComparator(NetObj
*object
, void *data
)
1086 return (((Node
*)object
)->getFlags() & NF_IS_LOCAL_MGMT
) ? true : false;
1090 * Find local management node ID
1092 UINT32
FindLocalMgmtNode()
1094 NetObj
*object
= g_idxNodeById
.find(LocalMgmtNodeComparator
, NULL
);
1095 return (object
!= NULL
) ? object
->getId() : 0;
1099 * ObjectIndex::forEach callback which recalculates object's status
1101 static void RecalcStatusCallback(NetObj
*object
, void *data
)
1103 object
->calculateCompoundStatus();
1107 * ObjectIndex::forEach callback which links objects after loading
1109 static void LinkObjects(NetObj
*object
, void *data
)
1111 object
->linkObjects();
1115 * Load objects from database at stratup
1119 // Prevent objects to change it's modification flag
1120 g_bModificationsLocked
= TRUE
;
1122 DB_HANDLE hdb
= DBConnectionPoolAcquireConnection();
1124 // Load built-in object properties
1125 DbgPrintf(2, _T("Loading built-in object properties..."));
1126 g_pEntireNet
->loadFromDatabase(hdb
);
1127 g_pServiceRoot
->loadFromDatabase(hdb
);
1128 g_pTemplateRoot
->loadFromDatabase(hdb
);
1129 g_pPolicyRoot
->loadFromDatabase(hdb
);
1130 g_pMapRoot
->loadFromDatabase(hdb
);
1131 g_pDashboardRoot
->loadFromDatabase(hdb
);
1132 g_pBusinessServiceRoot
->loadFromDatabase(hdb
);
1135 if (g_flags
& AF_ENABLE_ZONING
)
1139 DbgPrintf(2, _T("Loading zones..."));
1141 // Load (or create) default zone
1143 pZone
->generateGuid();
1144 pZone
->loadFromDatabase(hdb
, BUILTIN_OID_ZONE0
);
1145 NetObjInsert(pZone
, false, false);
1146 g_pEntireNet
->AddZone(pZone
);
1148 DB_RESULT hResult
= DBSelect(hdb
, _T("SELECT id FROM zones WHERE id<>4"));
1149 if (hResult
!= NULL
)
1151 int count
= DBGetNumRows(hResult
);
1152 for(int i
= 0; i
< count
; i
++)
1154 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1156 if (pZone
->loadFromDatabase(hdb
, id
))
1158 if (!pZone
->isDeleted())
1159 g_pEntireNet
->AddZone(pZone
);
1160 NetObjInsert(pZone
, false, false); // Insert into indexes
1162 else // Object load failed
1165 nxlog_write(MSG_ZONE_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1168 DBFreeResult(hResult
);
1173 // We should load conditions before nodes because
1174 // DCI cache size calculation uses information from condition objects
1175 DbgPrintf(2, _T("Loading conditions..."));
1176 DB_RESULT hResult
= DBSelect(hdb
, _T("SELECT id FROM conditions"));
1177 if (hResult
!= NULL
)
1179 int count
= DBGetNumRows(hResult
);
1180 for(int i
= 0; i
< count
; i
++)
1182 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1183 Condition
*condition
= new Condition
;
1184 if (condition
->loadFromDatabase(hdb
, id
))
1186 NetObjInsert(condition
, false, false); // Insert into indexes
1188 else // Object load failed
1191 nxlog_write(MSG_CONDITION_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1194 DBFreeResult(hResult
);
1198 DbgPrintf(2, _T("Loading subnets..."));
1199 hResult
= DBSelect(hdb
, _T("SELECT id FROM subnets"));
1200 if (hResult
!= NULL
)
1202 int count
= DBGetNumRows(hResult
);
1203 for(int i
= 0; i
< count
; i
++)
1205 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1206 Subnet
*subnet
= new Subnet
;
1207 if (subnet
->loadFromDatabase(hdb
, id
))
1209 if (!subnet
->isDeleted())
1211 if (g_flags
& AF_ENABLE_ZONING
)
1215 pZone
= FindZoneByGUID(subnet
->getZoneId());
1217 pZone
->addSubnet(subnet
);
1221 g_pEntireNet
->AddSubnet(subnet
);
1224 NetObjInsert(subnet
, false, false); // Insert into indexes
1226 else // Object load failed
1229 nxlog_write(MSG_SUBNET_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1232 DBFreeResult(hResult
);
1236 DbgPrintf(2, _T("Loading racks..."));
1237 hResult
= DBSelect(hdb
, _T("SELECT id FROM racks"));
1238 if (hResult
!= NULL
)
1240 int count
= DBGetNumRows(hResult
);
1241 for(int i
= 0; i
< count
; i
++)
1243 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1244 Rack
*rack
= new Rack
;
1245 if (rack
->loadFromDatabase(hdb
, id
))
1247 NetObjInsert(rack
, false, false); // Insert into indexes
1249 else // Object load failed
1251 nxlog_write(MSG_RACK_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1255 DBFreeResult(hResult
);
1259 DbgPrintf(2, _T("Loading chassis..."));
1260 hResult
= DBSelect(hdb
, _T("SELECT id FROM chassis"));
1261 if (hResult
!= NULL
)
1263 int count
= DBGetNumRows(hResult
);
1264 for(int i
= 0; i
< count
; i
++)
1266 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1267 Chassis
*chassis
= new Chassis
;
1268 if (chassis
->loadFromDatabase(hdb
, id
))
1270 NetObjInsert(chassis
, false, false); // Insert into indexes
1272 else // Object load failed
1274 nxlog_write(MSG_CHASSIS_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1278 DBFreeResult(hResult
);
1281 // Load mobile devices
1282 DbgPrintf(2, _T("Loading mobile devices..."));
1283 hResult
= DBSelect(hdb
, _T("SELECT id FROM mobile_devices"));
1284 if (hResult
!= NULL
)
1286 int count
= DBGetNumRows(hResult
);
1287 for(int i
= 0; i
< count
; i
++)
1289 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1290 MobileDevice
*md
= new MobileDevice
;
1291 if (md
->loadFromDatabase(hdb
, id
))
1293 NetObjInsert(md
, false, false); // Insert into indexes
1295 else // Object load failed
1298 nxlog_write(MSG_MOBILEDEVICE_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1301 DBFreeResult(hResult
);
1305 DbgPrintf(2, _T("Loading nodes..."));
1306 hResult
= DBSelect(hdb
, _T("SELECT id FROM nodes"));
1307 if (hResult
!= NULL
)
1309 int count
= DBGetNumRows(hResult
);
1310 for(int i
= 0; i
< count
; i
++)
1312 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1313 Node
*node
= new Node
;
1314 if (node
->loadFromDatabase(hdb
, id
))
1316 NetObjInsert(node
, false, false); // Insert into indexes
1318 else // Object load failed
1321 nxlog_write(MSG_NODE_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1324 DBFreeResult(hResult
);
1327 // Load access points
1328 DbgPrintf(2, _T("Loading access points..."));
1329 hResult
= DBSelect(hdb
, _T("SELECT id FROM access_points"));
1330 if (hResult
!= NULL
)
1332 int count
= DBGetNumRows(hResult
);
1333 for(int i
= 0; i
< count
; i
++)
1335 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1336 AccessPoint
*ap
= new AccessPoint
;
1337 if (ap
->loadFromDatabase(hdb
, id
))
1339 NetObjInsert(ap
, false, false); // Insert into indexes
1341 else // Object load failed
1343 nxlog_write(MSG_AP_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1347 DBFreeResult(hResult
);
1351 DbgPrintf(2, _T("Loading interfaces..."));
1352 hResult
= DBSelect(hdb
, _T("SELECT id FROM interfaces"));
1353 if (hResult
!= NULL
)
1355 int count
= DBGetNumRows(hResult
);
1356 for(int i
= 0; i
< count
; i
++)
1358 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1359 Interface
*iface
= new Interface
;
1360 if (iface
->loadFromDatabase(hdb
, id
))
1362 NetObjInsert(iface
, false, false); // Insert into indexes
1364 else // Object load failed
1366 nxlog_write(MSG_INTERFACE_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1370 DBFreeResult(hResult
);
1373 // Load network services
1374 DbgPrintf(2, _T("Loading network services..."));
1375 hResult
= DBSelect(hdb
, _T("SELECT id FROM network_services"));
1376 if (hResult
!= NULL
)
1378 int count
= DBGetNumRows(hResult
);
1379 for(int i
= 0; i
< count
; i
++)
1381 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1382 NetworkService
*service
= new NetworkService
;
1383 if (service
->loadFromDatabase(hdb
, id
))
1385 NetObjInsert(service
, false, false); // Insert into indexes
1387 else // Object load failed
1390 nxlog_write(MSG_NETSRV_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1393 DBFreeResult(hResult
);
1396 // Load VPN connectors
1397 DbgPrintf(2, _T("Loading VPN connectors..."));
1398 hResult
= DBSelect(hdb
, _T("SELECT id FROM vpn_connectors"));
1399 if (hResult
!= NULL
)
1401 int count
= DBGetNumRows(hResult
);
1402 for(int i
= 0; i
< count
; i
++)
1404 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1405 VPNConnector
*connector
= new VPNConnector
;
1406 if (connector
->loadFromDatabase(hdb
, id
))
1408 NetObjInsert(connector
, false, false); // Insert into indexes
1410 else // Object load failed
1413 nxlog_write(MSG_VPNC_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1416 DBFreeResult(hResult
);
1420 DbgPrintf(2, _T("Loading clusters..."));
1421 hResult
= DBSelect(hdb
, _T("SELECT id FROM clusters"));
1422 if (hResult
!= NULL
)
1424 int count
= DBGetNumRows(hResult
);
1425 for(int i
= 0; i
< count
; i
++)
1427 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1428 Cluster
*cluster
= new Cluster
;
1429 if (cluster
->loadFromDatabase(hdb
, id
))
1431 NetObjInsert(cluster
, false, false); // Insert into indexes
1433 else // Object load failed
1436 nxlog_write(MSG_CLUSTER_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1439 DBFreeResult(hResult
);
1442 // Start cache loading thread.
1443 // All data collection targets must be loaded at this point.
1444 ThreadCreate(CacheLoadingThread
, 0, NULL
);
1447 DbgPrintf(2, _T("Loading templates..."));
1448 hResult
= DBSelect(hdb
, _T("SELECT id FROM templates"));
1449 if (hResult
!= NULL
)
1451 int count
= DBGetNumRows(hResult
);
1452 for(int i
= 0; i
< count
; i
++)
1454 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1455 Template
*tmpl
= new Template
;
1456 if (tmpl
->loadFromDatabase(hdb
, id
))
1458 NetObjInsert(tmpl
, false, false); // Insert into indexes
1459 tmpl
->calculateCompoundStatus(); // Force status change to NORMAL
1461 else // Object load failed
1464 nxlog_write(MSG_TEMPLATE_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1467 DBFreeResult(hResult
);
1470 // Load agent policies
1471 DbgPrintf(2, _T("Loading agent policies..."));
1472 hResult
= DBSelect(hdb
, _T("SELECT id,policy_type FROM ap_common"));
1473 if (hResult
!= NULL
)
1475 int count
= DBGetNumRows(hResult
);
1476 for(int i
= 0; i
< count
; i
++)
1478 AgentPolicy
*policy
;
1480 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1481 int type
= DBGetFieldLong(hResult
, i
, 1);
1484 case AGENT_POLICY_CONFIG
:
1485 policy
= new AgentPolicyConfig();
1487 case AGENT_POLICY_LOG_PARSER
:
1488 policy
= new AgentPolicyLogParser();
1491 policy
= new AgentPolicy(type
);
1494 if (policy
->loadFromDatabase(hdb
, id
))
1496 NetObjInsert(policy
, false, false); // Insert into indexes
1497 policy
->calculateCompoundStatus(); // Force status change to NORMAL
1499 else // Object load failed
1502 nxlog_write(MSG_AGENTPOLICY_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1505 DBFreeResult(hResult
);
1508 // Load network maps
1509 DbgPrintf(2, _T("Loading network maps..."));
1510 hResult
= DBSelect(hdb
, _T("SELECT id FROM network_maps"));
1511 if (hResult
!= NULL
)
1513 int count
= DBGetNumRows(hResult
);
1514 for(int i
= 0; i
< count
; i
++)
1516 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1517 NetworkMap
*map
= new NetworkMap
;
1518 if (map
->loadFromDatabase(hdb
, id
))
1520 NetObjInsert(map
, false, false); // Insert into indexes
1522 else // Object load failed
1525 nxlog_write(MSG_NETMAP_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1528 DBFreeResult(hResult
);
1531 // Load container objects
1532 DbgPrintf(2, _T("Loading containers..."));
1534 _sntprintf(query
, sizeof(query
) / sizeof(TCHAR
), _T("SELECT id FROM object_containers WHERE object_class=%d"), OBJECT_CONTAINER
);
1535 hResult
= DBSelect(hdb
, query
);
1536 if (hResult
!= NULL
)
1538 Container
*pContainer
;
1540 int count
= DBGetNumRows(hResult
);
1541 for(int i
= 0; i
< count
; i
++)
1543 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1544 pContainer
= new Container
;
1545 if (pContainer
->loadFromDatabase(hdb
, id
))
1547 NetObjInsert(pContainer
, false, false); // Insert into indexes
1549 else // Object load failed
1552 nxlog_write(MSG_CONTAINER_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1555 DBFreeResult(hResult
);
1558 // Load template group objects
1559 DbgPrintf(2, _T("Loading template groups..."));
1560 _sntprintf(query
, sizeof(query
) / sizeof(TCHAR
), _T("SELECT id FROM object_containers WHERE object_class=%d"), OBJECT_TEMPLATEGROUP
);
1561 hResult
= DBSelect(hdb
, query
);
1562 if (hResult
!= NULL
)
1564 TemplateGroup
*pGroup
;
1566 int count
= DBGetNumRows(hResult
);
1567 for(int i
= 0; i
< count
; i
++)
1569 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1570 pGroup
= new TemplateGroup
;
1571 if (pGroup
->loadFromDatabase(hdb
, id
))
1573 NetObjInsert(pGroup
, false, false); // Insert into indexes
1575 else // Object load failed
1578 nxlog_write(MSG_TG_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1581 DBFreeResult(hResult
);
1584 // Load policy group objects
1585 DbgPrintf(2, _T("Loading policy groups..."));
1586 _sntprintf(query
, sizeof(query
) / sizeof(TCHAR
), _T("SELECT id FROM object_containers WHERE object_class=%d"), OBJECT_POLICYGROUP
);
1587 hResult
= DBSelect(hdb
, query
);
1588 if (hResult
!= NULL
)
1590 int count
= DBGetNumRows(hResult
);
1591 for(int i
= 0; i
< count
; i
++)
1593 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1594 PolicyGroup
*group
= new PolicyGroup
;
1595 if (group
->loadFromDatabase(hdb
, id
))
1597 NetObjInsert(group
, false, false); // Insert into indexes
1599 else // Object load failed
1602 nxlog_write(MSG_PG_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1605 DBFreeResult(hResult
);
1608 // Load map group objects
1609 DbgPrintf(2, _T("Loading map groups..."));
1610 _sntprintf(query
, sizeof(query
) / sizeof(TCHAR
), _T("SELECT id FROM object_containers WHERE object_class=%d"), OBJECT_NETWORKMAPGROUP
);
1611 hResult
= DBSelect(hdb
, query
);
1612 if (hResult
!= NULL
)
1614 int count
= DBGetNumRows(hResult
);
1615 for(int i
= 0; i
< count
; i
++)
1617 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1618 NetworkMapGroup
*group
= new NetworkMapGroup
;
1619 if (group
->loadFromDatabase(hdb
, id
))
1621 NetObjInsert(group
, false, false); // Insert into indexes
1623 else // Object load failed
1626 nxlog_write(MSG_MG_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1629 DBFreeResult(hResult
);
1632 // Load dashboard objects
1633 DbgPrintf(2, _T("Loading dashboards..."));
1634 hResult
= DBSelect(hdb
, _T("SELECT id FROM dashboards"));
1635 if (hResult
!= NULL
)
1637 int count
= DBGetNumRows(hResult
);
1638 for(int i
= 0; i
< count
; i
++)
1640 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1641 Dashboard
*dashboard
= new Dashboard
;
1642 if (dashboard
->loadFromDatabase(hdb
, id
))
1644 NetObjInsert(dashboard
, false, false); // Insert into indexes
1646 else // Object load failed
1649 nxlog_write(MSG_DASHBOARD_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1652 DBFreeResult(hResult
);
1655 // Loading business service objects
1656 DbgPrintf(2, _T("Loading business services..."));
1657 _sntprintf(query
, sizeof(query
) / sizeof(TCHAR
), _T("SELECT id FROM object_containers WHERE object_class=%d"), OBJECT_BUSINESSSERVICE
);
1658 hResult
= DBSelect(hdb
, query
);
1659 if (hResult
!= NULL
)
1661 int count
= DBGetNumRows(hResult
);
1662 for(int i
= 0; i
< count
; i
++)
1664 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1665 BusinessService
*service
= new BusinessService
;
1666 if (service
->loadFromDatabase(hdb
, id
))
1668 NetObjInsert(service
, false, false); // Insert into indexes
1670 else // Object load failed
1673 nxlog_write(MSG_BUSINESS_SERVICE_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1676 DBFreeResult(hResult
);
1679 // Loading business service objects
1680 DbgPrintf(2, _T("Loading node links..."));
1681 _sntprintf(query
, sizeof(query
) / sizeof(TCHAR
), _T("SELECT id FROM object_containers WHERE object_class=%d"), OBJECT_NODELINK
);
1682 hResult
= DBSelect(hdb
, query
);
1683 if (hResult
!= NULL
)
1685 int count
= DBGetNumRows(hResult
);
1686 for(int i
= 0; i
< count
; i
++)
1688 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1689 NodeLink
*nl
= new NodeLink
;
1690 if (nl
->loadFromDatabase(hdb
, id
))
1692 NetObjInsert(nl
, false, false); // Insert into indexes
1694 else // Object load failed
1697 nxlog_write(MSG_NODE_LINK_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1700 DBFreeResult(hResult
);
1703 // Load service check objects
1704 DbgPrintf(2, _T("Loading service checks..."));
1705 hResult
= DBSelect(hdb
, _T("SELECT id FROM slm_checks"));
1706 if (hResult
!= NULL
)
1708 int count
= DBGetNumRows(hResult
);
1709 for(int i
= 0; i
< count
; i
++)
1711 UINT32 id
= DBGetFieldULong(hResult
, i
, 0);
1712 SlmCheck
*check
= new SlmCheck
;
1713 if (check
->loadFromDatabase(hdb
, id
))
1715 NetObjInsert(check
, false, false); // Insert into indexes
1717 else // Object load failed
1720 nxlog_write(MSG_SERVICE_CHECK_LOAD_FAILED
, NXLOG_ERROR
, "d", id
);
1723 DBFreeResult(hResult
);
1726 DBConnectionPoolReleaseConnection(hdb
);
1728 // Load custom object classes provided by modules
1729 CALL_ALL_MODULES(pfLoadObjects
, ());
1731 // Link children to container and template group objects
1732 DbgPrintf(2, _T("Linking objects..."));
1733 g_idxObjectById
.forEach(LinkObjects
, NULL
);
1735 // Link custom object classes provided by modules
1736 CALL_ALL_MODULES(pfLinkObjects
, ());
1738 // Allow objects to change it's modification flag
1739 g_bModificationsLocked
= FALSE
;
1741 // Recalculate status for built-in objects
1742 g_pEntireNet
->calculateCompoundStatus();
1743 g_pServiceRoot
->calculateCompoundStatus();
1744 g_pTemplateRoot
->calculateCompoundStatus();
1745 g_pPolicyRoot
->calculateCompoundStatus();
1746 g_pMapRoot
->calculateCompoundStatus();
1747 g_pBusinessServiceRoot
->calculateCompoundStatus();
1749 // Recalculate status for zone objects
1750 if (g_flags
& AF_ENABLE_ZONING
)
1752 g_idxZoneByGUID
.forEach(RecalcStatusCallback
, NULL
);
1755 // Start map update thread
1756 ThreadCreate(MapUpdateThread
, 0, NULL
);
1758 // Start template update applying thread
1759 ThreadCreate(ApplyTemplateThread
, 0, NULL
);
1765 * Callback for DeleteUserFromAllObjects
1767 static void DropUserAccess(NetObj
*object
, void *userId
)
1769 object
->dropUserAccess(CAST_FROM_POINTER(userId
, UINT32
));
1773 * Delete user or group from all objects' ACLs
1775 void DeleteUserFromAllObjects(UINT32 dwUserId
)
1777 g_idxObjectById
.forEach(DropUserAccess
, CAST_TO_POINTER(dwUserId
, void *));
1781 * User data for DumpObjectCallback
1783 struct __dump_objects_data
1785 CONSOLE_CTX console
;
1787 const TCHAR
*filter
;
1791 * Enumeration callback for DumpObjects
1793 static void DumpObjectCallback(NetObj
*object
, void *data
)
1795 struct __dump_objects_data
*dd
= (struct __dump_objects_data
*)data
;
1797 // Apply name filter
1798 if ((dd
->filter
!= NULL
) && !MatchString(dd
->filter
, object
->getName(), false))
1801 CONSOLE_CTX pCtx
= dd
->console
;
1803 ConsolePrintf(pCtx
, _T("Object ID %d \"%s\"\n")
1804 _T(" Class: %s Status: %s IsModified: %d IsDeleted: %d\n"),
1805 object
->getId(), object
->getName(), object
->getObjectClassName(),
1806 GetStatusAsText(object
->getStatus(), true),
1807 object
->isModified(), object
->isDeleted());
1808 ConsolePrintf(pCtx
, _T(" Parents: <%s>\n Childs: <%s>\n"),
1809 object
->dbgGetParentList(dd
->buffer
), object
->dbgGetChildList(&dd
->buffer
[4096]));
1810 time_t t
= object
->getTimeStamp();
1811 struct tm
*ltm
= localtime(&t
);
1812 _tcsftime(dd
->buffer
, 256, _T("%d.%b.%Y %H:%M:%S"), ltm
);
1813 ConsolePrintf(pCtx
, _T(" Last change: %s\n"), dd
->buffer
);
1814 switch(object
->getObjectClass())
1817 ConsolePrintf(pCtx
, _T(" Primary IP: %s\n IsSNMP: %d IsAgent: %d IsLocal: %d OID: %s\n"),
1818 ((Node
*)object
)->getIpAddress().toString(dd
->buffer
),
1819 ((Node
*)object
)->isSNMPSupported(),
1820 ((Node
*)object
)->isNativeAgent(),
1821 ((Node
*)object
)->isLocalManagement(),
1822 ((Node
*)object
)->getObjectId());
1825 ConsolePrintf(pCtx
, _T(" IP address: %s/%d\n"), ((Subnet
*)object
)->getIpAddress().toString(dd
->buffer
), ((Subnet
*)object
)->getIpAddress().getMaskBits());
1827 case OBJECT_ACCESSPOINT
:
1828 ConsolePrintf(pCtx
, _T(" IP address: %s\n"), ((AccessPoint
*)object
)->getIpAddress().toString(dd
->buffer
));
1830 case OBJECT_INTERFACE
:
1831 ConsolePrintf(pCtx
, _T(" MAC address: %s\n"), MACToStr(((Interface
*)object
)->getMacAddr(), dd
->buffer
));
1832 for(int n
= 0; n
< ((Interface
*)object
)->getIpAddressList()->size(); n
++)
1834 const InetAddress
& a
= ((Interface
*)object
)->getIpAddressList()->get(n
);
1835 ConsolePrintf(pCtx
, _T(" IP address: %s/%d\n"), a
.toString(dd
->buffer
), a
.getMaskBits());
1838 case OBJECT_TEMPLATE
:
1839 ConsolePrintf(pCtx
, _T(" Version: %d.%d\n"),
1840 ((Template
*)(object
))->getVersionMajor(),
1841 ((Template
*)(object
))->getVersionMinor());
1847 * Dump objects to debug console
1849 void DumpObjects(CONSOLE_CTX pCtx
, const TCHAR
*filter
)
1851 struct __dump_objects_data data
;
1853 data
.buffer
= (TCHAR
*)malloc(128000 * sizeof(TCHAR
));
1854 data
.console
= pCtx
;
1855 data
.filter
= filter
;
1856 g_idxObjectById
.forEach(DumpObjectCallback
, &data
);
1861 * Check is given object class is a valid parent class for other object
1862 * This function is used to check manually created bindings, so it won't
1863 * return TRUE for node -- subnet for example
1865 bool IsValidParentClass(int childClass
, int parentClass
)
1869 case OBJECT_NETWORK
:
1870 if ((childClass
== OBJECT_ZONE
) && (g_flags
& AF_ENABLE_ZONING
))
1873 case OBJECT_SERVICEROOT
:
1874 case OBJECT_CONTAINER
:
1875 if ((childClass
== OBJECT_CHASSIS
) ||
1876 (childClass
== OBJECT_CLUSTER
) ||
1877 (childClass
== OBJECT_CONDITION
) ||
1878 (childClass
== OBJECT_CONTAINER
) ||
1879 (childClass
== OBJECT_MOBILEDEVICE
) ||
1880 (childClass
== OBJECT_NODE
) ||
1881 (childClass
== OBJECT_RACK
) ||
1882 (childClass
== OBJECT_SUBNET
))
1885 case OBJECT_CHASSIS
:
1887 if (childClass
== OBJECT_NODE
)
1890 case OBJECT_TEMPLATEROOT
:
1891 case OBJECT_TEMPLATEGROUP
:
1892 if ((childClass
== OBJECT_TEMPLATEGROUP
) ||
1893 (childClass
== OBJECT_TEMPLATE
))
1896 case OBJECT_TEMPLATE
:
1897 if ((childClass
== OBJECT_NODE
) ||
1898 (childClass
== OBJECT_CLUSTER
) ||
1899 (childClass
== OBJECT_MOBILEDEVICE
))
1902 case OBJECT_NETWORKMAPROOT
:
1903 case OBJECT_NETWORKMAPGROUP
:
1904 if ((childClass
== OBJECT_NETWORKMAPGROUP
) ||
1905 (childClass
== OBJECT_NETWORKMAP
))
1908 case OBJECT_DASHBOARDROOT
:
1909 case OBJECT_DASHBOARD
:
1910 if (childClass
== OBJECT_DASHBOARD
)
1913 case OBJECT_POLICYROOT
:
1914 case OBJECT_POLICYGROUP
:
1915 if ((childClass
== OBJECT_POLICYGROUP
) ||
1916 (childClass
== OBJECT_AGENTPOLICY
) ||
1917 (childClass
== OBJECT_AGENTPOLICY_CONFIG
) ||
1918 (childClass
== OBJECT_AGENTPOLICY_LOGPARSER
))
1922 if ((childClass
== OBJECT_NETWORKSERVICE
) ||
1923 (childClass
== OBJECT_VPNCONNECTOR
) ||
1924 (childClass
== OBJECT_INTERFACE
))
1927 case OBJECT_CLUSTER
:
1928 if (childClass
== OBJECT_NODE
)
1931 case OBJECT_BUSINESSSERVICEROOT
:
1932 if ((childClass
== OBJECT_BUSINESSSERVICE
) ||
1933 (childClass
== OBJECT_NODELINK
))
1936 case OBJECT_BUSINESSSERVICE
:
1937 if ((childClass
== OBJECT_BUSINESSSERVICE
) ||
1938 (childClass
== OBJECT_NODELINK
) ||
1939 (childClass
== OBJECT_SLMCHECK
))
1942 case OBJECT_NODELINK
:
1943 if (childClass
== OBJECT_SLMCHECK
)
1946 case -1: // Creating object without parent
1947 if (childClass
== OBJECT_NODE
)
1948 return true; // OK only for nodes, because parent subnet will be created automatically
1952 // Additional check by loaded modules
1953 for(UINT32 i
= 0; i
< g_dwNumModules
; i
++)
1955 if (g_pModuleList
[i
].pfIsValidParentClass
!= NULL
)
1957 if (g_pModuleList
[i
].pfIsValidParentClass(childClass
, parentClass
))
1958 return true; // accepted by module
1966 * Callback for postponed object deletion
1968 static void DeleteObjectCallback(void *arg
)
1970 NetObj
*object
= (NetObj
*)arg
;
1971 while(object
->getRefCount() > 0)
1973 DbgPrintf(4, _T("Executing postponed delete of object %s [%d]"), object
->getName(), object
->getId());
1978 * Delete object (final step)
1979 * This function should be called ONLY from syncer thread
1980 * Object will be removed from index by ID and destroyed.
1982 void NetObjDelete(NetObj
*object
)
1984 DbgPrintf(4, _T("Final delete step for object %s [%d]"), object
->getName(), object
->getId());
1986 // Delete object from index by ID and object itself
1987 g_idxObjectById
.remove(object
->getId());
1988 if (object
->getRefCount() == 0)
1994 DbgPrintf(4, _T("Object %s [%d] has %d references at final delete step - postpone deletion"), object
->getName(), object
->getId());
1995 ThreadPoolExecuteSerialized(g_mainThreadPool
, _T("DeleteObject"), DeleteObjectCallback
, object
);
2000 * Update interface index when IP address changes
2002 void UpdateInterfaceIndex(const InetAddress
& oldIpAddr
, const InetAddress
& newIpAddr
, Interface
*iface
)
2004 if (IsZoningEnabled())
2006 Zone
*zone
= (Zone
*)g_idxZoneByGUID
.get(iface
->getZoneId());
2009 zone
->updateInterfaceIndex(oldIpAddr
, newIpAddr
, iface
);
2013 DbgPrintf(1, _T("UpdateInterfaceIndex: Cannot find zone object for interface %s [%d] (zone id %d)"),
2014 iface
->getName(), (int)iface
->getId(), (int)iface
->getZoneId());
2019 g_idxInterfaceByAddr
.remove(oldIpAddr
);
2020 g_idxInterfaceByAddr
.put(newIpAddr
, iface
);
2025 * Calculate propagated status for object using default algorithm
2027 int DefaultPropagatedStatus(int iObjectStatus
)
2031 switch(m_iStatusPropAlg
)
2033 case SA_PROPAGATE_UNCHANGED
:
2034 iStatus
= iObjectStatus
;
2036 case SA_PROPAGATE_FIXED
:
2037 iStatus
= ((iObjectStatus
> STATUS_NORMAL
) && (iObjectStatus
< STATUS_UNKNOWN
)) ? m_iFixedStatus
: iObjectStatus
;
2039 case SA_PROPAGATE_RELATIVE
:
2040 if ((iObjectStatus
> STATUS_NORMAL
) && (iObjectStatus
< STATUS_UNKNOWN
))
2042 iStatus
= iObjectStatus
+ m_iStatusShift
;
2045 if (iStatus
> STATUS_CRITICAL
)
2046 iStatus
= STATUS_CRITICAL
;
2050 iStatus
= iObjectStatus
;
2053 case SA_PROPAGATE_TRANSLATED
:
2054 if ((iObjectStatus
> STATUS_NORMAL
) && (iObjectStatus
< STATUS_UNKNOWN
))
2056 iStatus
= m_iStatusTranslation
[iObjectStatus
- 1];
2060 iStatus
= iObjectStatus
;
2064 iStatus
= STATUS_UNKNOWN
;
2071 * Get default data for status calculation
2073 int GetDefaultStatusCalculation(int *pnSingleThreshold
, int **ppnThresholds
)
2075 *pnSingleThreshold
= m_iStatusSingleThreshold
;
2076 *ppnThresholds
= m_iStatusThresholds
;
2077 return m_iStatusCalcAlg
;
2081 * Check if given object is an agent policy object
2083 bool IsAgentPolicyObject(NetObj
*object
)
2085 return (object
->getObjectClass() == OBJECT_AGENTPOLICY
) || (object
->getObjectClass() == OBJECT_AGENTPOLICY_CONFIG
) || (object
->getObjectClass() == OBJECT_AGENTPOLICY_LOGPARSER
);
2089 * Returns true if object of given class can be event source
2091 bool IsEventSource(int objectClass
)
2093 return (objectClass
== OBJECT_NODE
) ||
2094 (objectClass
== OBJECT_CONTAINER
) ||
2095 (objectClass
== OBJECT_CLUSTER
) ||
2096 (objectClass
== OBJECT_MOBILEDEVICE
);